From 2c032d8f1c6292c1338a615e6ec40252889ba85c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 22 Jan 2015 00:29:39 +0100 Subject: Imported Upstream version 1.0.0 --- Makefile.am | 26 +- Makefile.in | 290 +- NEWS | 51 +- autogen.sh | 7 - build-aux/config.guess | 313 +- build-aux/config.sub | 56 +- callouts/Makefile.am | 46 +- callouts/Makefile.in | 84 +- callouts/nm-avahi-autoipd-action.c | 150 +- callouts/nm-dispatcher-api.h | 10 +- callouts/nm-dispatcher-utils.c | 448 +- callouts/nm-dispatcher-utils.h | 24 +- callouts/nm-dispatcher.c | 262 +- callouts/nm-dispatcher.xml | 4 +- callouts/tests/Makefile.am | 17 +- callouts/tests/Makefile.in | 154 +- callouts/tests/dispatcher-old-up | 1 + callouts/tests/dispatcher-old-vpn-down | 1 + callouts/tests/dispatcher-old-vpn-up | 1 + callouts/tests/test-dispatcher-envp.c | 374 +- cli/Makefile.am | 2 - cli/Makefile.in | 753 -- cli/completion/Makefile.am | 2 - cli/completion/Makefile.in | 630 -- cli/completion/nmcli | 1236 --- cli/src/Makefile.am | 40 - cli/src/Makefile.in | 809 -- cli/src/common.c | 1168 --- cli/src/common.h | 66 - cli/src/connections.c | 8706 ------------------- cli/src/connections.h | 27 - cli/src/devices.c | 2718 ------ cli/src/devices.h | 27 - cli/src/network-manager.c | 917 -- cli/src/network-manager.h | 29 - cli/src/nmcli.c | 449 - cli/src/nmcli.h | 140 - cli/src/settings.c | 7333 ---------------- cli/src/settings.h | 89 - cli/src/utils.c | 1128 --- cli/src/utils.h | 97 - clients/Makefile.am | 21 + clients/Makefile.in | 917 ++ clients/cli/Makefile.am | 72 + clients/cli/Makefile.in | 862 ++ clients/cli/agent.c | 252 + clients/cli/agent.h | 29 + clients/cli/common.c | 1146 +++ clients/cli/common.h | 69 + clients/cli/connections.c | 9020 +++++++++++++++++++ clients/cli/connections.h | 27 + clients/cli/devices.c | 2925 +++++++ clients/cli/devices.h | 27 + clients/cli/general.c | 899 ++ clients/cli/general.h | 29 + clients/cli/nmcli-completion | 1287 +++ clients/cli/nmcli.c | 621 ++ clients/cli/nmcli.h | 156 + clients/cli/polkit-agent.c | 166 + clients/cli/polkit-agent.h | 30 + clients/cli/settings-docs.c | 388 + clients/cli/settings-docs.xsl | 86 + clients/cli/settings.c | 7445 ++++++++++++++++ clients/cli/settings.h | 66 + clients/cli/utils.c | 1151 +++ clients/cli/utils.h | 96 + clients/common/nm-polkit-listener.c | 415 + clients/common/nm-polkit-listener.h | 104 + clients/common/nm-secret-agent-simple.c | 695 ++ clients/common/nm-secret-agent-simple.h | 62 + clients/nm-online.c | 249 + clients/tui/Makefile.am | 128 + clients/tui/Makefile.in | 1131 +++ clients/tui/newt/Makefile.am | 53 + clients/tui/newt/Makefile.in | 805 ++ clients/tui/newt/nmt-newt-button-box.c | 386 + clients/tui/newt/nmt-newt-button-box.h | 65 + clients/tui/newt/nmt-newt-button.c | 261 + clients/tui/newt/nmt-newt-button.h | 53 + clients/tui/newt/nmt-newt-checkbox.c | 237 + clients/tui/newt/nmt-newt-checkbox.h | 53 + clients/tui/newt/nmt-newt-component.c | 309 + clients/tui/newt/nmt-newt-component.h | 57 + clients/tui/newt/nmt-newt-container.c | 252 + clients/tui/newt/nmt-newt-container.h | 61 + clients/tui/newt/nmt-newt-entry-numeric.c | 215 + clients/tui/newt/nmt-newt-entry-numeric.h | 51 + clients/tui/newt/nmt-newt-entry.c | 540 ++ clients/tui/newt/nmt-newt-entry.h | 74 + clients/tui/newt/nmt-newt-form.c | 753 ++ clients/tui/newt/nmt-newt-form.h | 66 + clients/tui/newt/nmt-newt-grid.c | 472 + clients/tui/newt/nmt-newt-grid.h | 72 + clients/tui/newt/nmt-newt-hacks.c | 103 + clients/tui/newt/nmt-newt-hacks.h | 42 + clients/tui/newt/nmt-newt-label.c | 326 + clients/tui/newt/nmt-newt-label.h | 66 + clients/tui/newt/nmt-newt-listbox.c | 548 ++ clients/tui/newt/nmt-newt-listbox.h | 71 + clients/tui/newt/nmt-newt-popup.c | 360 + clients/tui/newt/nmt-newt-popup.h | 62 + clients/tui/newt/nmt-newt-section.c | 447 + clients/tui/newt/nmt-newt-section.h | 57 + clients/tui/newt/nmt-newt-separator.c | 66 + clients/tui/newt/nmt-newt-separator.h | 49 + clients/tui/newt/nmt-newt-stack.c | 368 + clients/tui/newt/nmt-newt-stack.h | 61 + clients/tui/newt/nmt-newt-textbox.c | 295 + clients/tui/newt/nmt-newt-textbox.h | 59 + clients/tui/newt/nmt-newt-toggle-button.c | 237 + clients/tui/newt/nmt-newt-toggle-button.h | 54 + clients/tui/newt/nmt-newt-types.h | 50 + clients/tui/newt/nmt-newt-utils.c | 393 + clients/tui/newt/nmt-newt-utils.h | 53 + clients/tui/newt/nmt-newt-widget.c | 668 ++ clients/tui/newt/nmt-newt-widget.h | 118 + clients/tui/newt/nmt-newt.h | 39 + clients/tui/nm-editor-bindings.c | 1101 +++ clients/tui/nm-editor-bindings.h | 76 + clients/tui/nm-editor-utils.c | 414 + clients/tui/nm-editor-utils.h | 43 + clients/tui/nmt-address-list.c | 285 + clients/tui/nmt-address-list.h | 57 + clients/tui/nmt-connect-connection-list.c | 701 ++ clients/tui/nmt-connect-connection-list.h | 61 + clients/tui/nmt-device-entry.c | 573 ++ clients/tui/nmt-device-entry.h | 60 + clients/tui/nmt-edit-connection-list.c | 554 ++ clients/tui/nmt-edit-connection-list.h | 59 + clients/tui/nmt-editor-grid.c | 463 + clients/tui/nmt-editor-grid.h | 62 + clients/tui/nmt-editor-page-device.c | 131 + clients/tui/nmt-editor-page-device.h | 50 + clients/tui/nmt-editor-page.c | 179 + clients/tui/nmt-editor-page.h | 58 + clients/tui/nmt-editor-section.c | 282 + clients/tui/nmt-editor-section.h | 56 + clients/tui/nmt-editor.c | 520 ++ clients/tui/nmt-editor.h | 51 + clients/tui/nmt-ip-entry.c | 268 + clients/tui/nmt-ip-entry.h | 52 + clients/tui/nmt-mac-entry.c | 227 + clients/tui/nmt-mac-entry.h | 51 + clients/tui/nmt-mtu-entry.c | 192 + clients/tui/nmt-mtu-entry.h | 49 + clients/tui/nmt-page-bond.c | 437 + clients/tui/nmt-page-bond.h | 50 + clients/tui/nmt-page-bridge-port.c | 95 + clients/tui/nmt-page-bridge-port.h | 49 + clients/tui/nmt-page-bridge.c | 150 + clients/tui/nmt-page-bridge.h | 50 + clients/tui/nmt-page-dsl.c | 141 + clients/tui/nmt-page-dsl.h | 50 + clients/tui/nmt-page-ethernet.c | 99 + clients/tui/nmt-page-ethernet.h | 50 + clients/tui/nmt-page-infiniband.c | 110 + clients/tui/nmt-page-infiniband.h | 50 + clients/tui/nmt-page-ip4.c | 202 + clients/tui/nmt-page-ip4.h | 49 + clients/tui/nmt-page-ip6.c | 200 + clients/tui/nmt-page-ip6.h | 49 + clients/tui/nmt-page-ppp.c | 288 + clients/tui/nmt-page-ppp.h | 49 + clients/tui/nmt-page-team-port.c | 129 + clients/tui/nmt-page-team-port.h | 49 + clients/tui/nmt-page-team.c | 193 + clients/tui/nmt-page-team.h | 50 + clients/tui/nmt-page-vlan.c | 158 + clients/tui/nmt-page-vlan.h | 50 + clients/tui/nmt-page-wifi.c | 400 + clients/tui/nmt-page-wifi.h | 50 + clients/tui/nmt-password-dialog.c | 345 + clients/tui/nmt-password-dialog.h | 57 + clients/tui/nmt-password-fields.c | 319 + clients/tui/nmt-password-fields.h | 55 + clients/tui/nmt-route-editor.c | 210 + clients/tui/nmt-route-editor.h | 51 + clients/tui/nmt-route-entry.c | 291 + clients/tui/nmt-route-entry.h | 51 + clients/tui/nmt-route-table.c | 334 + clients/tui/nmt-route-table.h | 49 + clients/tui/nmt-slave-list.c | 266 + clients/tui/nmt-slave-list.h | 52 + clients/tui/nmt-utils.c | 151 + clients/tui/nmt-utils.h | 46 + clients/tui/nmt-widget-list.c | 496 ++ clients/tui/nmt-widget-list.h | 69 + clients/tui/nmtui-connect.c | 365 + clients/tui/nmtui-connect.h | 28 + clients/tui/nmtui-edit.c | 577 ++ clients/tui/nmtui-edit.h | 44 + clients/tui/nmtui-hostname.c | 128 + clients/tui/nmtui-hostname.h | 28 + clients/tui/nmtui.c | 293 + clients/tui/nmtui.h | 32 + config.h.in | 40 +- configure | 1099 ++- configure.ac | 247 +- data/Makefile.in | 6 +- data/NetworkManager.service.in | 1 + docs/Makefile.am | 2 +- docs/Makefile.in | 8 +- docs/api/Makefile.am | 36 +- docs/api/Makefile.in | 31 +- docs/api/html/index.html | 2 +- docs/api/html/ref-migrating.html | 6 +- docs/api/html/ref-settings.html | 1565 ++-- docs/api/html/spec.html | 140 +- docs/api/network-manager-docs.xml | 12 +- docs/api/settings-spec.xml | 2110 +---- docs/api/settings-spec.xsl | 49 + docs/api/spec.html | 140 +- docs/api/version.xml | 2 +- docs/libnm-glib/Makefile.am | 23 +- docs/libnm-glib/Makefile.in | 29 +- docs/libnm-glib/html/NMAccessPoint.html | 20 +- docs/libnm-glib/html/NMActiveConnection.html | 16 +- docs/libnm-glib/html/NMClient.html | 81 +- docs/libnm-glib/html/NMDevice.html | 123 +- docs/libnm-glib/html/NMDeviceBond.html | 2 +- docs/libnm-glib/html/NMDeviceBridge.html | 2 +- docs/libnm-glib/html/NMDeviceBt.html | 8 +- docs/libnm-glib/html/NMDeviceModem.html | 8 +- docs/libnm-glib/html/NMDeviceTeam.html | 2 +- docs/libnm-glib/html/NMDeviceVlan.html | 44 + docs/libnm-glib/html/NMDeviceWifi.html | 10 +- docs/libnm-glib/html/NMDeviceWimax.html | 2 +- docs/libnm-glib/html/NMIP4Config.html | 4 +- docs/libnm-glib/html/NMIP6Config.html | 4 +- docs/libnm-glib/html/NMObject.html | 4 +- docs/libnm-glib/html/NMRemoteConnection.html | 10 +- docs/libnm-glib/html/NMRemoteSettings.html | 42 +- docs/libnm-glib/html/NMSecretAgent.html | 10 +- docs/libnm-glib/html/NMWimaxNsp.html | 13 +- docs/libnm-glib/html/api-index-full.html | 24 + docs/libnm-glib/html/index.html | 2 +- docs/libnm-glib/html/index.sgml | 8 +- .../html/libnm-glib-nm-vpn-plugin-utils.html | 6 +- docs/libnm-glib/html/libnm-glib.devhelp2 | 8 +- docs/libnm-glib/libnm-glib-sections.txt | 7 +- docs/libnm-glib/tmpl/nm-device-vlan.sgml | 21 + docs/libnm-glib/tmpl/nm-device.sgml | 31 +- docs/libnm-glib/version.xml | 2 +- docs/libnm-util/Makefile.am | 4 +- docs/libnm-util/Makefile.in | 10 +- docs/libnm-util/html/NMConnection.html | 116 +- docs/libnm-util/html/NMSetting.html | 42 +- docs/libnm-util/html/NMSetting8021x.html | 32 +- docs/libnm-util/html/NMSettingBluetooth.html | 3 +- docs/libnm-util/html/NMSettingBond.html | 9 + docs/libnm-util/html/NMSettingConnection.html | 3 + docs/libnm-util/html/NMSettingIP4Config.html | 68 +- docs/libnm-util/html/NMSettingIP6Config.html | 59 + docs/libnm-util/html/NMSettingVPN.html | 44 + docs/libnm-util/html/NMSettingWireless.html | 22 +- docs/libnm-util/html/annotation-glossary.html | 5 + docs/libnm-util/html/api-index-full.html | 544 +- docs/libnm-util/html/ch01.html | 6 + docs/libnm-util/html/index.html | 8 +- docs/libnm-util/html/index.sgml | 322 +- .../libnm-util/html/libnm-util-NetworkManager.html | 1635 ++++ .../html/libnm-util-NetworkManagerVPN.html | 861 ++ docs/libnm-util/html/libnm-util-nm-utils.html | 205 +- docs/libnm-util/html/libnm-util.devhelp2 | 315 +- docs/libnm-util/html/object-tree.html | 4 +- docs/libnm-util/libnm-util-docs.sgml | 2 + docs/libnm-util/libnm-util-sections.txt | 136 + docs/libnm-util/tmpl/NetworkManager.sgml | 535 ++ docs/libnm-util/tmpl/NetworkManagerVPN.sgml | 484 ++ docs/libnm-util/tmpl/nm-connection.sgml | 29 + docs/libnm-util/tmpl/nm-setting-bond.sgml | 7 + docs/libnm-util/tmpl/nm-setting-ip4-config.sgml | 26 +- docs/libnm-util/tmpl/nm-setting-ip6-config.sgml | 21 + docs/libnm-util/tmpl/nm-setting-vpn.sgml | 21 + docs/libnm-util/tmpl/nm-setting.sgml | 4 + docs/libnm-util/tmpl/nm-utils.sgml | 25 + docs/libnm-util/version.xml | 2 +- docs/libnm/Makefile.am | 94 + docs/libnm/Makefile.in | 944 ++ docs/libnm/html/NMAccessPoint.html | 613 ++ docs/libnm/html/NMActiveConnection.html | 816 ++ docs/libnm/html/NMClient.html | 3059 +++++++ docs/libnm/html/NMDevice.html | 1858 ++++ docs/libnm/html/NMDeviceAdsl.html | 147 + docs/libnm/html/NMDeviceBond.html | 243 + docs/libnm/html/NMDeviceBridge.html | 243 + docs/libnm/html/NMDeviceBt.html | 237 + docs/libnm/html/NMDeviceEthernet.html | 286 + docs/libnm/html/NMDeviceGeneric.html | 167 + docs/libnm/html/NMDeviceInfiniband.html | 193 + docs/libnm/html/NMDeviceModem.html | 202 + docs/libnm/html/NMDeviceOlpcMesh.html | 239 + docs/libnm/html/NMDeviceTeam.html | 243 + docs/libnm/html/NMDeviceVlan.html | 278 + docs/libnm/html/NMDeviceWifi.html | 668 ++ docs/libnm/html/NMDeviceWimax.html | 597 ++ docs/libnm/html/NMDhcpConfig.html | 232 + docs/libnm/html/NMIPConfig.html | 473 + docs/libnm/html/NMObject.html | 188 + docs/libnm/html/NMRemoteConnection.html | 761 ++ docs/libnm/html/NMSecretAgentOld.html | 911 ++ docs/libnm/html/NMSetting.html | 932 ++ docs/libnm/html/NMSetting8021x.html | 3251 +++++++ docs/libnm/html/NMSettingAdsl.html | 463 + docs/libnm/html/NMSettingBluetooth.html | 244 + docs/libnm/html/NMSettingBond.html | 573 ++ docs/libnm/html/NMSettingBridge.html | 426 + docs/libnm/html/NMSettingBridgePort.html | 257 + docs/libnm/html/NMSettingCdma.html | 297 + docs/libnm/html/NMSettingConnection.html | 1246 +++ docs/libnm/html/NMSettingDcb.html | 1140 +++ docs/libnm/html/NMSettingGeneric.html | 119 + docs/libnm/html/NMSettingGsm.html | 521 ++ docs/libnm/html/NMSettingIP4Config.html | 251 + docs/libnm/html/NMSettingIP6Config.html | 316 + docs/libnm/html/NMSettingIPConfig.html | 2580 ++++++ docs/libnm/html/NMSettingInfiniband.html | 391 + docs/libnm/html/NMSettingOlpcMesh.html | 213 + docs/libnm/html/NMSettingPpp.html | 905 ++ docs/libnm/html/NMSettingPppoe.html | 297 + docs/libnm/html/NMSettingSerial.html | 381 + docs/libnm/html/NMSettingTeam.html | 168 + docs/libnm/html/NMSettingTeamPort.html | 168 + docs/libnm/html/NMSettingVlan.html | 727 ++ docs/libnm/html/NMSettingVpn.html | 682 ++ docs/libnm/html/NMSettingWimax.html | 217 + docs/libnm/html/NMSettingWired.html | 1015 +++ docs/libnm/html/NMSettingWireless.html | 1053 +++ docs/libnm/html/NMSettingWirelessSecurity.html | 1450 ++++ docs/libnm/html/NMSimpleConnection.html | 175 + docs/libnm/html/NMVpnConnection.html | 233 + docs/libnm/html/NMWimaxNsp.html | 357 + docs/libnm/html/annotation-glossary.html | 77 + docs/libnm/html/api-index-full.html | 7247 ++++++++++++++++ docs/libnm/html/ch02.html | 47 + docs/libnm/html/ch03.html | 126 + docs/libnm/html/ch04.html | 95 + docs/libnm/html/ch05.html | 38 + docs/libnm/html/ch06.html | 38 + docs/libnm/html/home.png | Bin 0 -> 654 bytes docs/libnm/html/index.html | 259 + docs/libnm/html/index.sgml | 2622 ++++++ docs/libnm/html/left.png | Bin 0 -> 459 bytes docs/libnm/html/libnm-NMConnection.html | 1868 ++++ docs/libnm/html/libnm-NMVpnEditorPlugin.html | 382 + docs/libnm/html/libnm-nm-dbus-interface.html | 1806 ++++ docs/libnm/html/libnm-nm-errors.html | 844 ++ docs/libnm/html/libnm-nm-utils.html | 2042 +++++ docs/libnm/html/libnm-nm-version.html | 249 + docs/libnm/html/libnm-nm-vpn-dbus-interface.html | 882 ++ docs/libnm/html/libnm.devhelp2 | 2207 +++++ docs/libnm/html/libnm.png | Bin 0 -> 82140 bytes docs/libnm/html/object-tree.html | 136 + docs/libnm/html/ref-overview.html | 48 + docs/libnm/html/right.png | Bin 0 -> 472 bytes docs/libnm/html/style.css | 266 + docs/libnm/html/up.png | Bin 0 -> 406 bytes docs/libnm/libnm-docs.xml | 161 + docs/libnm/libnm-overrides.txt | 0 docs/libnm/libnm-sections.txt | 2285 +++++ docs/libnm/libnm.png | Bin 0 -> 82140 bytes docs/libnm/libnm.types | 103 + docs/libnm/tmpl/libnm-unused.sgml | 0 docs/libnm/tmpl/nm-access-point.sgml | 258 + docs/libnm/tmpl/nm-active-connection.sgml | 352 + docs/libnm/tmpl/nm-client.sgml | 952 ++ docs/libnm/tmpl/nm-connection.sgml | 573 ++ docs/libnm/tmpl/nm-core-enum-types.sgml | 24 + docs/libnm/tmpl/nm-dbus-interface.sgml | 548 ++ docs/libnm/tmpl/nm-device-adsl.sgml | 58 + docs/libnm/tmpl/nm-device-bond.sgml | 100 + docs/libnm/tmpl/nm-device-bridge.sgml | 100 + docs/libnm/tmpl/nm-device-bt.sgml | 100 + docs/libnm/tmpl/nm-device-ethernet.sgml | 121 + docs/libnm/tmpl/nm-device-generic.sgml | 70 + docs/libnm/tmpl/nm-device-infiniband.sgml | 79 + docs/libnm/tmpl/nm-device-modem.sgml | 79 + docs/libnm/tmpl/nm-device-olpc-mesh.sgml | 100 + docs/libnm/tmpl/nm-device-team.sgml | 100 + docs/libnm/tmpl/nm-device-vlan.sgml | 121 + docs/libnm/tmpl/nm-device-wifi.sgml | 245 + docs/libnm/tmpl/nm-device-wimax.sgml | 233 + docs/libnm/tmpl/nm-device.sgml | 696 ++ docs/libnm/tmpl/nm-dhcp-config.sgml | 89 + docs/libnm/tmpl/nm-enum-types.sgml | 24 + docs/libnm/tmpl/nm-errors.sgml | 263 + docs/libnm/tmpl/nm-ip-config.sgml | 205 + docs/libnm/tmpl/nm-object.sgml | 77 + docs/libnm/tmpl/nm-remote-connection.sgml | 229 + docs/libnm/tmpl/nm-secret-agent-old.sgml | 234 + docs/libnm/tmpl/nm-setting-8021x.sgml | 1091 +++ docs/libnm/tmpl/nm-setting-adsl.sgml | 235 + docs/libnm/tmpl/nm-setting-bluetooth.sgml | 109 + docs/libnm/tmpl/nm-setting-bond.sgml | 251 + docs/libnm/tmpl/nm-setting-bridge-port.sgml | 116 + docs/libnm/tmpl/nm-setting-bridge.sgml | 200 + docs/libnm/tmpl/nm-setting-cdma.sgml | 137 + docs/libnm/tmpl/nm-setting-connection.sgml | 473 + docs/libnm/tmpl/nm-setting-dcb.sgml | 458 + docs/libnm/tmpl/nm-setting-generic.sgml | 53 + docs/libnm/tmpl/nm-setting-gsm.sgml | 242 + docs/libnm/tmpl/nm-setting-infiniband.sgml | 167 + docs/libnm/tmpl/nm-setting-ip-config.sgml | 872 ++ docs/libnm/tmpl/nm-setting-ip4-config.sgml | 109 + docs/libnm/tmpl/nm-setting-ip6-config.sgml | 126 + docs/libnm/tmpl/nm-setting-olpc-mesh.sgml | 116 + docs/libnm/tmpl/nm-setting-ppp.sgml | 431 + docs/libnm/tmpl/nm-setting-pppoe.sgml | 137 + docs/libnm/tmpl/nm-setting-serial.sgml | 167 + docs/libnm/tmpl/nm-setting-team-port.sgml | 74 + docs/libnm/tmpl/nm-setting-team.sgml | 74 + docs/libnm/tmpl/nm-setting-vlan.sgml | 245 + docs/libnm/tmpl/nm-setting-vpn.sgml | 248 + docs/libnm/tmpl/nm-setting-wimax.sgml | 95 + docs/libnm/tmpl/nm-setting-wired.sgml | 392 + docs/libnm/tmpl/nm-setting-wireless-security.sgml | 545 ++ docs/libnm/tmpl/nm-setting-wireless.sgml | 437 + docs/libnm/tmpl/nm-setting.sgml | 252 + docs/libnm/tmpl/nm-simple-connection.sgml | 65 + docs/libnm/tmpl/nm-utils.sgml | 578 ++ docs/libnm/tmpl/nm-version.sgml | 158 + docs/libnm/tmpl/nm-vpn-connection.sgml | 89 + docs/libnm/tmpl/nm-vpn-dbus-interface.sgml | 484 ++ docs/libnm/tmpl/nm-vpn-editor-plugin.sgml | 169 + docs/libnm/tmpl/nm-wimax-nsp.sgml | 130 + docs/libnm/version.xml | 1 + docs/libnm/version.xml.in | 1 + examples/C/Makefile.in | 6 +- examples/C/glib/Makefile.am | 96 +- examples/C/glib/Makefile.in | 282 +- examples/C/glib/add-connection-dbus-glib.c | 126 - examples/C/glib/add-connection-gdbus.c | 150 + examples/C/glib/add-connection-libnm-glib.c | 138 - examples/C/glib/add-connection-libnm.c | 134 + examples/C/glib/get-active-connections-dbus-glib.c | 223 - examples/C/glib/get-active-connections-gdbus.c | 274 + examples/C/glib/get-ap-info-libnm-glib.c | 233 - examples/C/glib/get-ap-info-libnm.c | 233 + examples/C/glib/list-connections-dbus-glib.c | 91 - examples/C/glib/list-connections-gdbus.c | 90 + examples/C/glib/list-connections-libnm-glib.c | 178 - examples/C/glib/list-connections-libnm.c | 101 + examples/C/glib/monitor-nm-running-GDBus.c | 88 - examples/C/glib/monitor-nm-running-dbus-glib.c | 127 - examples/C/glib/monitor-nm-running-gdbus.c | 89 + examples/C/glib/monitor-nm-state-GDBus.c | 134 - examples/C/glib/monitor-nm-state-gdbus.c | 136 + examples/C/qt/Makefile.am | 4 +- examples/C/qt/Makefile.in | 10 +- examples/C/qt/add-connection-wired.cpp | 4 +- examples/C/qt/change-ipv4-addresses.cpp | 12 +- examples/C/qt/list-connections.cpp | 4 +- examples/Makefile.in | 6 +- examples/dispatcher/Makefile.in | 6 +- examples/python/Makefile.in | 6 +- examples/python/dbus/Makefile.am | 1 + examples/python/dbus/Makefile.in | 7 +- examples/python/dbus/add-connection-compat.py | 66 + examples/python/dbus/add-connection.py | 24 +- examples/python/dbus/is-wwan-default.py | 58 +- examples/python/dbus/update-ip4-method.py | 33 +- examples/python/gi/Makefile.in | 6 +- examples/python/gi/add_connection.py | 52 +- examples/python/gi/device-state-ip4config.py | 4 +- examples/python/gi/firewall-zone.py | 30 +- examples/python/gi/get-active-connections.py | 4 +- examples/python/gi/get_ips.py | 90 +- examples/python/gi/list-connections.py | 34 +- examples/python/gi/show-wifi-networks.py | 36 +- examples/python/gi/update-ip4-method.py | 91 +- examples/ruby/Makefile.in | 6 +- examples/ruby/add-connection.rb | 7 +- examples/shell/Makefile.in | 6 +- include/Makefile.am | 14 +- include/Makefile.in | 185 +- include/NetworkManager.h | 592 -- include/NetworkManagerVPN.h | 232 - include/gsystem-local-alloc.h | 183 + include/nm-dbus-glib-types.h | 18 +- include/nm-glib-compat.h | 125 +- include/nm-gvaluearray-compat.h | 11 +- include/nm-settings-flags.h | 39 - include/nm-test-utils.h | 465 +- include/nm-utils-internal.h | 103 + include/nm-version.h | 118 - include/nm-version.h.in | 118 - introspection/Makefile.am | 131 +- introspection/Makefile.in | 363 +- introspection/nm-device-ethernet.xml | 1 + introspection/nm-device-vlan.xml | 6 + introspection/nm-device-wifi.xml | 2 + introspection/nm-device.xml | 12 +- introspection/nm-ip4-config.xml | 40 +- introspection/nm-ip6-config.xml | 31 +- introspection/nm-manager.xml | 31 +- introspection/nm-ppp-manager.xml | 7 + introspection/nm-settings-connection.xml | 8 + introspection/nm-vpn-connection.xml | 2 + introspection/nm-vpn-plugin.xml | 44 +- libgsystem/COPYING | 481 -- libgsystem/Makefile-libgsystem.am | 42 - libgsystem/README | 10 - libgsystem/gsystem-console.c | 443 - libgsystem/gsystem-console.h | 59 - libgsystem/gsystem-file-utils.c | 1644 ---- libgsystem/gsystem-file-utils.h | 172 - libgsystem/gsystem-glib-compat.h | 54 - libgsystem/gsystem-local-alloc.c | 72 - libgsystem/gsystem-local-alloc.h | 164 - libgsystem/gsystem-log.c | 167 - libgsystem/gsystem-log.h | 42 - libgsystem/gsystem-shutil.c | 460 - libgsystem/gsystem-shutil.h | 47 - libgsystem/gsystem-subprocess-context-private.h | 65 - libgsystem/gsystem-subprocess-context.c | 501 -- libgsystem/gsystem-subprocess-context.h | 128 - libgsystem/gsystem-subprocess.c | 966 --- libgsystem/gsystem-subprocess.h | 101 - libgsystem/libgsystem.h | 49 - libnm-core/Makefile.am | 48 + libnm-core/Makefile.in | 1350 +++ libnm-core/Makefile.libnm-core | 91 + libnm-core/crypto.c | 816 ++ libnm-core/crypto.h | 133 + libnm-core/crypto_gnutls.c | 454 + libnm-core/crypto_nss.c | 526 ++ libnm-core/nm-connection-private.h | 35 + libnm-core/nm-connection.c | 2077 +++++ libnm-core/nm-connection.h | 219 + libnm-core/nm-core-enum-types.c | 1031 +++ libnm-core/nm-core-enum-types.h | 97 + libnm-core/nm-core-internal.h | 135 + libnm-core/nm-core-types.h | 60 + libnm-core/nm-dbus-interface.h | 611 ++ libnm-core/nm-errors.c | 90 + libnm-core/nm-errors.h | 319 + libnm-core/nm-property-compare.c | 122 + libnm-core/nm-property-compare.h | 30 + libnm-core/nm-setting-8021x.c | 3864 +++++++++ libnm-core/nm-setting-8021x.h | 278 + libnm-core/nm-setting-adsl.c | 448 + libnm-core/nm-setting-adsl.h | 81 + libnm-core/nm-setting-bluetooth.c | 285 + libnm-core/nm-setting-bluetooth.h | 81 + libnm-core/nm-setting-bond.c | 760 ++ libnm-core/nm-setting-bond.h | 98 + libnm-core/nm-setting-bridge-port.c | 321 + libnm-core/nm-setting-bridge-port.h | 69 + libnm-core/nm-setting-bridge.c | 540 ++ libnm-core/nm-setting-bridge.h | 81 + libnm-core/nm-setting-cdma.c | 336 + libnm-core/nm-setting-cdma.h | 69 + libnm-core/nm-setting-connection.c | 1569 ++++ libnm-core/nm-setting-connection.h | 125 + libnm-core/nm-setting-dcb.c | 1280 +++ libnm-core/nm-setting-dcb.h | 164 + libnm-core/nm-setting-generic.c | 73 + libnm-core/nm-setting-generic.h | 59 + libnm-core/nm-setting-gsm.c | 616 ++ libnm-core/nm-setting-gsm.h | 80 + libnm-core/nm-setting-infiniband.c | 522 ++ libnm-core/nm-setting-infiniband.h | 72 + libnm-core/nm-setting-ip-config.c | 2363 +++++ libnm-core/nm-setting-ip-config.h | 221 + libnm-core/nm-setting-ip4-config.c | 695 ++ libnm-core/nm-setting-ip4-config.h | 108 + libnm-core/nm-setting-ip6-config.c | 610 ++ libnm-core/nm-setting-ip6-config.h | 136 + libnm-core/nm-setting-olpc-mesh.c | 268 + libnm-core/nm-setting-olpc-mesh.h | 67 + libnm-core/nm-setting-ppp.c | 803 ++ libnm-core/nm-setting-ppp.h | 97 + libnm-core/nm-setting-pppoe.c | 322 + libnm-core/nm-setting-pppoe.h | 69 + libnm-core/nm-setting-private.h | 158 + libnm-core/nm-setting-serial.c | 351 + libnm-core/nm-setting-serial.h | 85 + libnm-core/nm-setting-team-port.c | 192 + libnm-core/nm-setting-team-port.h | 62 + libnm-core/nm-setting-team.c | 186 + libnm-core/nm-setting-team.h | 62 + libnm-core/nm-setting-vlan.c | 822 ++ libnm-core/nm-setting-vlan.h | 134 + libnm-core/nm-setting-vpn.c | 913 ++ libnm-core/nm-setting-vpn.h | 102 + libnm-core/nm-setting-wimax.c | 245 + libnm-core/nm-setting-wimax.h | 64 + libnm-core/nm-setting-wired.c | 1103 +++ libnm-core/nm-setting-wired.h | 109 + libnm-core/nm-setting-wireless-security.c | 1704 ++++ libnm-core/nm-setting-wireless-security.h | 147 + libnm-core/nm-setting-wireless.c | 1335 +++ libnm-core/nm-setting-wireless.h | 138 + libnm-core/nm-setting.c | 1818 ++++ libnm-core/nm-setting.h | 282 + libnm-core/nm-simple-connection.c | 123 + libnm-core/nm-simple-connection.h | 61 + libnm-core/nm-utils-private.h | 51 + libnm-core/nm-utils.c | 3215 +++++++ libnm-core/nm-utils.h | 190 + libnm-core/nm-version.h | 123 + libnm-core/nm-version.h.in | 123 + libnm-core/nm-vpn-dbus-interface.h | 307 + libnm-core/tests/Makefile.am | 56 + libnm-core/tests/Makefile.in | 959 +++ libnm-core/tests/certs/ca-no-ending-newline.pem | 15 + libnm-core/tests/certs/pkcs8-decrypted.der | Bin 0 -> 1194 bytes libnm-core/tests/certs/pkcs8-enc-key.pem | 29 + libnm-core/tests/certs/pkcs8-noenc-key.pem | 28 + libnm-core/tests/certs/test-aes-key.pem | 30 + libnm-core/tests/certs/test-cert.p12 | Bin 0 -> 4092 bytes libnm-core/tests/certs/test-key-only-decrypted.der | Bin 0 -> 1192 bytes libnm-core/tests/certs/test-key-only-decrypted.pem | 27 + libnm-core/tests/certs/test-key-only.pem | 92 + libnm-core/tests/certs/test2-cert.p12 | Bin 0 -> 4136 bytes libnm-core/tests/certs/test2_ca_cert.pem | 27 + libnm-core/tests/certs/test2_key_and_cert.pem | 119 + libnm-core/tests/certs/test_ca_cert.der | Bin 0 -> 1162 bytes libnm-core/tests/certs/test_ca_cert.pem | 27 + libnm-core/tests/certs/test_key_and_cert.pem | 119 + libnm-core/tests/test-compare.c | 248 + libnm-core/tests/test-crypto.c | 501 ++ libnm-core/tests/test-general.c | 3961 +++++++++ libnm-core/tests/test-secrets.c | 766 ++ libnm-core/tests/test-setting-8021x.c | 458 + libnm-core/tests/test-setting-dcb.c | 326 + libnm-core/tests/test-settings-defaults.c | 133 + libnm-glib/Makefile.am | 27 +- libnm-glib/Makefile.in | 339 +- libnm-glib/libnm-glib-test.c | 2 + libnm-glib/libnm-glib.ver | 3 + libnm-glib/libnm_glib.c | 2 + libnm-glib/nm-access-point.c | 103 +- libnm-glib/nm-access-point.h | 6 +- libnm-glib/nm-active-connection.c | 145 +- libnm-glib/nm-active-connection.h | 6 +- libnm-glib/nm-client.c | 282 +- libnm-glib/nm-client.h | 6 +- libnm-glib/nm-dbus-helpers-private.h | 4 +- libnm-glib/nm-dbus-helpers.c | 15 +- libnm-glib/nm-device-adsl.c | 11 +- libnm-glib/nm-device-adsl.h | 4 +- libnm-glib/nm-device-bond.c | 44 +- libnm-glib/nm-device-bond.h | 4 +- libnm-glib/nm-device-bridge.c | 30 +- libnm-glib/nm-device-bridge.h | 4 +- libnm-glib/nm-device-bt.c | 31 +- libnm-glib/nm-device-bt.h | 6 +- libnm-glib/nm-device-ethernet.c | 52 +- libnm-glib/nm-device-ethernet.h | 6 +- libnm-glib/nm-device-generic.c | 19 +- libnm-glib/nm-device-generic.h | 2 - libnm-glib/nm-device-infiniband.c | 36 +- libnm-glib/nm-device-infiniband.h | 4 +- libnm-glib/nm-device-modem.c | 38 +- libnm-glib/nm-device-modem.h | 6 +- libnm-glib/nm-device-olpc-mesh.c | 38 +- libnm-glib/nm-device-olpc-mesh.h | 5 +- libnm-glib/nm-device-private.h | 4 +- libnm-glib/nm-device-team.c | 44 +- libnm-glib/nm-device-team.h | 4 +- libnm-glib/nm-device-vlan.c | 74 +- libnm-glib/nm-device-vlan.h | 7 +- libnm-glib/nm-device-wifi.c | 100 +- libnm-glib/nm-device-wifi.h | 6 +- libnm-glib/nm-device-wimax.c | 105 +- libnm-glib/nm-device-wimax.h | 10 +- libnm-glib/nm-device.c | 313 +- libnm-glib/nm-device.h | 21 +- libnm-glib/nm-dhcp4-config.c | 24 +- libnm-glib/nm-dhcp4-config.h | 6 +- libnm-glib/nm-dhcp6-config.c | 24 +- libnm-glib/nm-dhcp6-config.h | 6 +- libnm-glib/nm-ip4-config.c | 64 +- libnm-glib/nm-ip4-config.h | 6 +- libnm-glib/nm-ip6-config.c | 67 +- libnm-glib/nm-ip6-config.h | 6 +- libnm-glib/nm-object-cache.c | 33 +- libnm-glib/nm-object-cache.h | 6 +- libnm-glib/nm-object-private.h | 8 +- libnm-glib/nm-object.c | 76 +- libnm-glib/nm-object.h | 6 +- libnm-glib/nm-remote-connection-private.h | 5 +- libnm-glib/nm-remote-connection.c | 67 +- libnm-glib/nm-remote-connection.h | 7 +- libnm-glib/nm-remote-settings.c | 117 +- libnm-glib/nm-remote-settings.h | 6 +- libnm-glib/nm-secret-agent.c | 66 +- libnm-glib/nm-secret-agent.h | 6 +- libnm-glib/nm-types-private.h | 10 +- libnm-glib/nm-types.c | 13 +- libnm-glib/nm-types.h | 4 +- libnm-glib/nm-vpn-connection.c | 58 +- libnm-glib/nm-vpn-connection.h | 6 +- libnm-glib/nm-vpn-plugin-ui-interface.c | 74 +- libnm-glib/nm-vpn-plugin-ui-interface.h | 6 +- libnm-glib/nm-vpn-plugin-utils.c | 4 +- libnm-glib/nm-vpn-plugin-utils.h | 2 +- libnm-glib/nm-vpn-plugin.c | 48 +- libnm-glib/nm-vpn-plugin.h | 6 +- libnm-glib/nm-wimax-nsp.c | 40 +- libnm-glib/nm-wimax-nsp.h | 15 +- libnm-glib/tests/Makefile.am | 30 +- libnm-glib/tests/Makefile.in | 167 +- libnm-glib/tests/common.c | 121 + libnm-glib/tests/common.h | 31 + libnm-glib/tests/libnm-glib-test-launch.sh | 9 + libnm-glib/tests/test-fake-nm.py | 776 -- libnm-glib/tests/test-nm-client.c | 499 +- libnm-glib/tests/test-remote-settings-client.c | 212 +- libnm-glib/tests/test-remote-settings-service.py | 150 - libnm-util/Makefile.am | 20 +- libnm-util/Makefile.in | 74 +- libnm-util/NetworkManager.h | 563 ++ libnm-util/NetworkManagerVPN.h | 307 + libnm-util/crypto.c | 35 +- libnm-util/crypto.h | 4 +- libnm-util/crypto_gnutls.c | 25 +- libnm-util/crypto_nss.c | 10 +- libnm-util/libnm-util.ver | 5 + libnm-util/nm-connection.c | 471 +- libnm-util/nm-connection.h | 27 +- libnm-util/nm-param-spec-specialized.c | 37 +- libnm-util/nm-param-spec-specialized.h | 15 +- libnm-util/nm-setting-8021x.c | 540 +- libnm-util/nm-setting-8021x.h | 9 +- libnm-util/nm-setting-adsl.c | 89 +- libnm-util/nm-setting-adsl.h | 6 +- libnm-util/nm-setting-bluetooth.c | 42 +- libnm-util/nm-setting-bluetooth.h | 8 +- libnm-util/nm-setting-bond.c | 75 +- libnm-util/nm-setting-bond.h | 5 +- libnm-util/nm-setting-bridge-port.c | 45 +- libnm-util/nm-setting-bridge-port.h | 4 +- libnm-util/nm-setting-bridge.c | 153 +- libnm-util/nm-setting-bridge.h | 4 +- libnm-util/nm-setting-cdma.c | 57 +- libnm-util/nm-setting-cdma.h | 7 +- libnm-util/nm-setting-connection.c | 312 +- libnm-util/nm-setting-connection.h | 9 +- libnm-util/nm-setting-dcb.c | 165 +- libnm-util/nm-setting-dcb.h | 4 +- libnm-util/nm-setting-gsm.c | 152 +- libnm-util/nm-setting-gsm.h | 7 +- libnm-util/nm-setting-infiniband.c | 95 +- libnm-util/nm-setting-ip4-config.c | 391 +- libnm-util/nm-setting-ip4-config.h | 11 +- libnm-util/nm-setting-ip6-config.c | 246 +- libnm-util/nm-setting-ip6-config.h | 11 +- libnm-util/nm-setting-olpc-mesh.c | 47 +- libnm-util/nm-setting-olpc-mesh.h | 11 +- libnm-util/nm-setting-ppp.c | 230 +- libnm-util/nm-setting-ppp.h | 7 +- libnm-util/nm-setting-pppoe.c | 58 +- libnm-util/nm-setting-pppoe.h | 7 +- libnm-util/nm-setting-private.h | 40 +- libnm-util/nm-setting-serial.c | 70 +- libnm-util/nm-setting-serial.h | 7 +- libnm-util/nm-setting-team-port.c | 20 +- libnm-util/nm-setting-team-port.h | 4 +- libnm-util/nm-setting-team.c | 54 +- libnm-util/nm-setting-team.h | 4 +- libnm-util/nm-setting-vlan.c | 123 +- libnm-util/nm-setting-vlan.h | 4 +- libnm-util/nm-setting-vpn.c | 123 +- libnm-util/nm-setting-vpn.h | 9 +- libnm-util/nm-setting-wimax.c | 34 +- libnm-util/nm-setting-wimax.h | 2 +- libnm-util/nm-setting-wired.c | 152 +- libnm-util/nm-setting-wired.h | 7 +- libnm-util/nm-setting-wireless-security.c | 239 +- libnm-util/nm-setting-wireless-security.h | 7 +- libnm-util/nm-setting-wireless.c | 198 +- libnm-util/nm-setting-wireless.h | 11 +- libnm-util/nm-setting.c | 306 +- libnm-util/nm-setting.h | 34 +- libnm-util/nm-utils-enum-types.c | 5 + libnm-util/nm-utils-enum-types.h | 101 - libnm-util/nm-utils-private.h | 37 +- libnm-util/nm-utils.c | 279 +- libnm-util/nm-utils.h | 24 +- libnm-util/nm-value-transforms.c | 23 +- libnm-util/nm-version.h.in | 123 + libnm-util/tests/Makefile.am | 81 +- libnm-util/tests/Makefile.in | 290 +- libnm-util/tests/certs/Makefile.am | 25 - libnm-util/tests/certs/Makefile.in | 597 -- libnm-util/tests/certs/ca-no-ending-newline.pem | 15 - libnm-util/tests/certs/pkcs8-decrypted.der | Bin 1194 -> 0 bytes libnm-util/tests/certs/pkcs8-enc-key.pem | 29 - libnm-util/tests/certs/pkcs8-noenc-key.pem | 28 - libnm-util/tests/certs/test-aes-key.pem | 30 - libnm-util/tests/certs/test-cert.p12 | Bin 4092 -> 0 bytes libnm-util/tests/certs/test-key-only-decrypted.der | Bin 1192 -> 0 bytes libnm-util/tests/certs/test-key-only.pem | 92 - libnm-util/tests/certs/test2-cert.p12 | Bin 4136 -> 0 bytes libnm-util/tests/certs/test2_ca_cert.pem | 27 - libnm-util/tests/certs/test2_key_and_cert.pem | 119 - libnm-util/tests/certs/test_ca_cert.der | Bin 1162 -> 0 bytes libnm-util/tests/certs/test_ca_cert.pem | 27 - libnm-util/tests/certs/test_key_and_cert.pem | 119 - libnm-util/tests/test-crypto.c | 178 +- libnm-util/tests/test-general.c | 379 +- libnm-util/tests/test-libnm-linking.c | 48 + libnm-util/tests/test-secrets.c | 6 +- libnm-util/tests/test-setting-8021x.c | 67 +- libnm-util/tests/test-setting-dcb.c | 4 +- libnm-util/tests/test-settings-defaults.c | 4 +- libnm/Makefile.am | 224 + libnm/Makefile.in | 1349 +++ libnm/NetworkManager.h | 89 + libnm/generate-plugin-docs.pl | 198 + libnm/generate-setting-docs.py | 235 + libnm/libnm.pc.in | 13 + libnm/libnm.ver | 846 ++ libnm/nm-access-point.c | 598 ++ libnm/nm-access-point.h | 85 + libnm/nm-active-connection.c | 714 ++ libnm/nm-active-connection.h | 87 + libnm/nm-client.c | 2238 +++++ libnm/nm-client.h | 341 + libnm/nm-dbus-helpers.c | 405 + libnm/nm-dbus-helpers.h | 78 + libnm/nm-device-adsl.c | 159 + libnm/nm-device-adsl.h | 58 + libnm/nm-device-bond.c | 271 + libnm/nm-device-bond.h | 62 + libnm/nm-device-bridge.c | 271 + libnm/nm-device-bridge.h | 62 + libnm/nm-device-bt.c | 305 + libnm/nm-device-bt.h | 65 + libnm/nm-device-ethernet.c | 317 + libnm/nm-device-ethernet.h | 65 + libnm/nm-device-generic.c | 214 + libnm/nm-device-generic.h | 59 + libnm/nm-device-infiniband.c | 236 + libnm/nm-device-infiniband.h | 60 + libnm/nm-device-modem.c | 254 + libnm/nm-device-modem.h | 61 + libnm/nm-device-olpc-mesh.c | 261 + libnm/nm-device-olpc-mesh.h | 62 + libnm/nm-device-private.h | 26 + libnm/nm-device-team.c | 271 + libnm/nm-device-team.h | 62 + libnm/nm-device-vlan.c | 305 + libnm/nm-device-vlan.h | 64 + libnm/nm-device-wifi.c | 837 ++ libnm/nm-device-wifi.h | 91 + libnm/nm-device-wimax.c | 678 ++ libnm/nm-device-wimax.h | 81 + libnm/nm-device.c | 2232 +++++ libnm/nm-device.h | 161 + libnm/nm-dhcp-config.c | 222 + libnm/nm-dhcp-config.h | 62 + libnm/nm-dhcp4-config.c | 39 + libnm/nm-dhcp4-config.h | 49 + libnm/nm-dhcp6-config.c | 39 + libnm/nm-dhcp6-config.h | 49 + libnm/nm-enum-types.c | 152 + libnm/nm-enum-types.h | 28 + libnm/nm-ifcfg-rh-docs.xml | 263 + libnm/nm-ip-config.c | 502 ++ libnm/nm-ip-config.h | 73 + libnm/nm-ip4-config.c | 39 + libnm/nm-ip4-config.h | 51 + libnm/nm-ip6-config.c | 39 + libnm/nm-ip6-config.h | 51 + libnm/nm-keyfile-docs.xml | 96 + libnm/nm-manager.c | 1730 ++++ libnm/nm-manager.h | 170 + libnm/nm-object-cache.c | 90 + libnm/nm-object-cache.h | 37 + libnm/nm-object-private.h | 83 + libnm/nm-object.c | 1761 ++++ libnm/nm-object.h | 70 + libnm/nm-property-docs.xml | 296 + libnm/nm-remote-connection-private.h | 33 + libnm/nm-remote-connection.c | 857 ++ libnm/nm-remote-connection.h | 114 + libnm/nm-remote-settings.c | 832 ++ libnm/nm-remote-settings.h | 127 + libnm/nm-secret-agent-old.c | 1366 +++ libnm/nm-secret-agent-old.h | 238 + libnm/nm-setting-docs-overrides.xml | 141 + libnm/nm-setting-docs.xml | 305 + libnm/nm-types.h | 53 + libnm/nm-vpn-connection.c | 233 + libnm/nm-vpn-connection.h | 67 + libnm/nm-vpn-editor-plugin.c | 181 + libnm/nm-vpn-editor-plugin.h | 189 + libnm/nm-vpn-plugin-old.c | 1206 +++ libnm/nm-vpn-plugin-old.h | 136 + libnm/nm-wimax-nsp.c | 290 + libnm/nm-wimax-nsp.h | 85 + libnm/tests/Makefile.am | 41 + libnm/tests/Makefile.in | 918 ++ libnm/tests/common.c | 187 + libnm/tests/common.h | 37 + libnm/tests/libnm-test-launch.sh | 9 + libnm/tests/test-nm-client.c | 1193 +++ libnm/tests/test-remote-settings-client.c | 547 ++ libnm/tests/test-secret-agent.c | 655 ++ m4/ax_lib_readline.m4 | 15 + m4/compiler_warnings.m4 | 33 +- man/Makefile.am | 88 +- man/Makefile.in | 126 +- man/NetworkManager.8 | 17 +- man/NetworkManager.conf.5 | 46 +- man/NetworkManager.conf.xml.in | 560 ++ man/nm-settings-ifcfg-rh.5 | 2325 +++++ man/nm-settings-ifcfg-rh.xml | 335 + man/nm-settings-ifcfg-rh.xsl | 405 + man/nm-settings-keyfile.5 | 698 ++ man/nm-settings-keyfile.xml | 233 + man/nm-settings-keyfile.xsl | 308 + man/nm-settings.5 | 1631 ++-- man/nm-settings.xml | 343 + man/nm-settings.xsl | 162 + man/nmcli-examples.5 | 43 +- man/nmcli.1.in | 96 +- man/nmtui.1.in | 66 + po/POTFILES.in | 148 +- po/POTFILES.skip | 3 +- po/as.po | 6285 ++++++++------ po/bn_IN.po | 8498 ++++++++++++++---- po/de.po | 5699 ++++++------ po/el.po | 7938 +++++++++++++---- po/en_GB.po | 4 +- po/eo.po | 2 +- po/es.po | 7416 +++++++++++++--- po/fr.po | 7454 +++++++++++++--- po/gl.po | 4 +- po/hi.po | 6825 +++++++++------ po/id.po | 4 +- po/ja.po | 4382 ++++++---- po/kn.po | 7033 +++++++++------ po/ko.po | 7633 ++++++++++++---- po/ml.po | 6074 ++++++++++--- po/mr.po | 6563 +++++++------- po/pa.po | 7066 +++++++++++---- po/pl.po | 1024 +-- po/ru.po | 6789 ++++++++++++--- po/sl.po | 4 +- po/sv.po | 9084 ++++++++++++++----- po/ta.po | 7932 ++++++++++------- po/te.po | 6937 +++++++++------ po/tr.po | 9087 ++++++++++++++++---- po/uk.po | 6842 +++++++++------ po/zh_CN.po | 7420 +++++++++++++--- po/zh_TW.po | 7409 +++++++++++++--- policy/Makefile.in | 6 +- policy/org.freedesktop.NetworkManager.policy.in.in | 1 + src/Makefile.am | 308 +- src/Makefile.in | 1265 ++- src/NetworkManagerUtils.c | 1580 +++- src/NetworkManagerUtils.h | 136 +- src/config/nm-config-device.c | 82 - src/config/nm-config-device.h | 47 - src/config/nm-config.c | 604 -- src/config/nm-config.h | 78 - src/config/tests/Makefile.am | 30 - src/config/tests/Makefile.in | 864 -- src/config/tests/NetworkManager.conf | 15 - src/config/tests/bad.conf | 1 - src/config/tests/conf.d/00-overrides.conf | 11 - src/config/tests/conf.d/10-more.conf | 11 - src/config/tests/conf.d/90-last.conf | 5 - src/config/tests/nm-test-device.c | 101 - src/config/tests/nm-test-device.h | 52 - src/config/tests/test-config.c | 305 - src/devices/adsl/Makefile.am | 11 +- src/devices/adsl/Makefile.in | 17 +- src/devices/adsl/exports.ver | 1 - src/devices/adsl/nm-atm-manager.c | 34 +- src/devices/adsl/nm-atm-manager.h | 6 +- src/devices/adsl/nm-device-adsl.c | 129 +- src/devices/adsl/nm-device-adsl.h | 4 +- src/devices/bluetooth/Makefile.am | 26 +- src/devices/bluetooth/Makefile.in | 92 +- src/devices/bluetooth/exports.ver | 1 - src/devices/bluetooth/nm-bluez-common.h | 4 +- src/devices/bluetooth/nm-bluez-device.c | 285 +- src/devices/bluetooth/nm-bluez-device.h | 11 +- src/devices/bluetooth/nm-bluez-manager.c | 35 +- src/devices/bluetooth/nm-bluez-manager.h | 6 +- src/devices/bluetooth/nm-bluez4-adapter.c | 20 +- src/devices/bluetooth/nm-bluez4-adapter.h | 6 +- src/devices/bluetooth/nm-bluez4-manager.c | 2 + src/devices/bluetooth/nm-bluez4-manager.h | 6 +- src/devices/bluetooth/nm-bluez5-dun.c | 410 + src/devices/bluetooth/nm-bluez5-dun.h | 46 + src/devices/bluetooth/nm-bluez5-manager.c | 4 +- src/devices/bluetooth/nm-bluez5-manager.h | 6 +- src/devices/bluetooth/nm-bt-enum-types.c | 3 +- src/devices/bluetooth/nm-bt-error.c | 35 + src/devices/bluetooth/nm-bt-error.h | 35 + src/devices/bluetooth/nm-device-bt.c | 262 +- src/devices/bluetooth/nm-device-bt.h | 12 +- src/devices/nm-device-bond.c | 227 +- src/devices/nm-device-bond.h | 24 +- src/devices/nm-device-bridge.c | 288 +- src/devices/nm-device-bridge.h | 26 +- src/devices/nm-device-ethernet-utils.c | 55 + src/devices/nm-device-ethernet-utils.h | 26 + src/devices/nm-device-ethernet.c | 523 +- src/devices/nm-device-ethernet.h | 25 +- src/devices/nm-device-factory.c | 52 + src/devices/nm-device-factory.h | 125 +- src/devices/nm-device-generic.c | 24 +- src/devices/nm-device-generic.h | 11 +- src/devices/nm-device-gre.c | 117 +- src/devices/nm-device-gre.h | 16 +- src/devices/nm-device-infiniband.c | 231 +- src/devices/nm-device-infiniband.h | 25 +- src/devices/nm-device-logging.h | 46 + src/devices/nm-device-macvlan.c | 64 +- src/devices/nm-device-macvlan.h | 16 +- src/devices/nm-device-private.h | 23 +- src/devices/nm-device-team.c | 894 -- src/devices/nm-device-team.h | 64 - src/devices/nm-device-tun.c | 109 +- src/devices/nm-device-tun.h | 16 +- src/devices/nm-device-veth.c | 49 +- src/devices/nm-device-veth.h | 16 +- src/devices/nm-device-vlan.c | 333 +- src/devices/nm-device-vlan.h | 22 +- src/devices/nm-device-vxlan.c | 155 +- src/devices/nm-device-vxlan.h | 16 +- src/devices/nm-device.c | 4414 ++++++---- src/devices/nm-device.h | 92 +- src/devices/team/Makefile.am | 68 + src/devices/team/Makefile.in | 845 ++ src/devices/team/exports.ver | 6 + src/devices/team/nm-device-team-glue.h | 73 + src/devices/team/nm-device-team.c | 777 ++ src/devices/team/nm-device-team.h | 56 + src/devices/team/nm-team-enum-types.c | 12 + src/devices/team/nm-team-enum-types.h | 17 + src/devices/team/nm-team-factory.c | 93 + src/devices/team/nm-team-factory.h | 37 + src/devices/wifi/Makefile.am | 12 +- src/devices/wifi/Makefile.in | 18 +- src/devices/wifi/exports.ver | 1 - src/devices/wifi/nm-device-olpc-mesh.c | 127 +- src/devices/wifi/nm-device-olpc-mesh.h | 12 +- src/devices/wifi/nm-device-wifi.c | 931 +- src/devices/wifi/nm-device-wifi.h | 16 +- src/devices/wifi/nm-wifi-ap-utils.c | 316 +- src/devices/wifi/nm-wifi-ap-utils.h | 9 +- src/devices/wifi/nm-wifi-ap.c | 211 +- src/devices/wifi/nm-wifi-ap.h | 76 +- src/devices/wifi/nm-wifi-enum-types.c | 44 - src/devices/wifi/nm-wifi-enum-types.h | 4 - src/devices/wifi/nm-wifi-factory.c | 18 +- src/devices/wifi/tests/Makefile.am | 9 +- src/devices/wifi/tests/Makefile.in | 15 +- src/devices/wifi/tests/test-wifi-ap-utils.c | 231 +- src/devices/wimax/Makefile.am | 12 +- src/devices/wimax/Makefile.in | 18 +- src/devices/wimax/exports.ver | 1 - src/devices/wimax/iwmxsdk.c | 10 +- src/devices/wimax/iwmxsdk.h | 9 +- src/devices/wimax/nm-device-wimax.c | 132 +- src/devices/wimax/nm-device-wimax.h | 13 +- src/devices/wimax/nm-wimax-factory.c | 18 +- src/devices/wimax/nm-wimax-nsp.c | 33 +- src/devices/wimax/nm-wimax-nsp.h | 4 +- src/devices/wimax/nm-wimax-types.h | 4 +- src/devices/wimax/nm-wimax-util.c | 3 +- src/devices/wimax/nm-wimax-util.h | 9 +- src/devices/wwan/Makefile.am | 19 +- src/devices/wwan/Makefile.in | 46 +- src/devices/wwan/README | 45 - src/devices/wwan/exports.ver | 1 - src/devices/wwan/nm-device-modem.c | 207 +- src/devices/wwan/nm-device-modem.h | 6 +- src/devices/wwan/nm-modem-broadband.c | 283 +- src/devices/wwan/nm-modem-broadband.h | 7 +- src/devices/wwan/nm-modem-enum-types.c | 34 +- src/devices/wwan/nm-modem-enum-types.h | 6 +- src/devices/wwan/nm-modem-manager.c | 460 +- src/devices/wwan/nm-modem-manager.h | 6 +- src/devices/wwan/nm-modem-old-types.h | 70 - src/devices/wwan/nm-modem-old.c | 1139 --- src/devices/wwan/nm-modem-old.h | 53 - src/devices/wwan/nm-modem.c | 482 +- src/devices/wwan/nm-modem.h | 74 +- src/devices/wwan/nm-wwan-factory.c | 28 +- src/devices/wwan/nm-wwan-factory.h | 6 +- src/devices/wwan/wwan-exports.ver | 2 +- src/dhcp-manager/Makefile.am | 6 +- src/dhcp-manager/Makefile.in | 12 +- src/dhcp-manager/nm-dhcp-client.c | 1524 +--- src/dhcp-manager/nm-dhcp-client.h | 162 +- src/dhcp-manager/nm-dhcp-dhclient-utils.c | 152 +- src/dhcp-manager/nm-dhcp-dhclient-utils.h | 15 +- src/dhcp-manager/nm-dhcp-dhclient.c | 228 +- src/dhcp-manager/nm-dhcp-dhclient.h | 26 +- src/dhcp-manager/nm-dhcp-dhcpcd.c | 131 +- src/dhcp-manager/nm-dhcp-dhcpcd.h | 22 +- src/dhcp-manager/nm-dhcp-helper.c | 327 +- src/dhcp-manager/nm-dhcp-listener.c | 290 + src/dhcp-manager/nm-dhcp-listener.h | 39 + src/dhcp-manager/nm-dhcp-manager.c | 607 +- src/dhcp-manager/nm-dhcp-manager.h | 68 +- src/dhcp-manager/nm-dhcp-systemd.c | 849 ++ src/dhcp-manager/nm-dhcp-systemd.h | 45 + src/dhcp-manager/nm-dhcp-utils.c | 732 ++ src/dhcp-manager/nm-dhcp-utils.h | 41 + src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c | 209 + src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h | 109 + .../src/libsystemd-network/dhcp-internal.h | 76 + .../src/libsystemd-network/dhcp-lease-internal.h | 87 + .../src/libsystemd-network/dhcp-network.c | 241 + .../src/libsystemd-network/dhcp-option.c | 257 + .../src/libsystemd-network/dhcp-packet.c | 204 + .../src/libsystemd-network/dhcp-protocol.h | 141 + .../src/libsystemd-network/dhcp6-internal.h | 81 + .../src/libsystemd-network/dhcp6-lease-internal.h | 64 + .../src/libsystemd-network/dhcp6-network.c | 198 + .../src/libsystemd-network/dhcp6-option.c | 323 + .../src/libsystemd-network/dhcp6-protocol.h | 141 + .../src/libsystemd-network/network-internal.c | 484 ++ .../src/libsystemd-network/network-internal.h | 78 + .../src/libsystemd-network/sd-dhcp-client.c | 1726 ++++ .../src/libsystemd-network/sd-dhcp-lease.c | 865 ++ .../src/libsystemd-network/sd-dhcp6-client.c | 1242 +++ .../src/libsystemd-network/sd-dhcp6-lease.c | 223 + src/dhcp-manager/systemd-dhcp/src/shared/async.h | 27 + src/dhcp-manager/systemd-dhcp/src/shared/fileio.c | 817 ++ src/dhcp-manager/systemd-dhcp/src/shared/fileio.h | 45 + .../systemd-dhcp/src/shared/in-addr-util.c | 294 + .../systemd-dhcp/src/shared/in-addr-util.h | 49 + src/dhcp-manager/systemd-dhcp/src/shared/list.h | 138 + src/dhcp-manager/systemd-dhcp/src/shared/macro.h | 413 + src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h | 34 + .../systemd-dhcp/src/shared/siphash24.c | 137 + .../systemd-dhcp/src/shared/siphash24.h | 6 + .../systemd-dhcp/src/shared/socket-util.h | 118 + .../systemd-dhcp/src/shared/sparse-endian.h | 88 + src/dhcp-manager/systemd-dhcp/src/shared/strv.c | 616 ++ src/dhcp-manager/systemd-dhcp/src/shared/strv.h | 137 + .../systemd-dhcp/src/shared/time-util.c | 1003 +++ .../systemd-dhcp/src/shared/time-util.h | 111 + .../systemd-dhcp/src/shared/unaligned.h | 66 + src/dhcp-manager/systemd-dhcp/src/shared/utf8.c | 314 + src/dhcp-manager/systemd-dhcp/src/shared/utf8.h | 42 + src/dhcp-manager/systemd-dhcp/src/shared/util.c | 7350 ++++++++++++++++ src/dhcp-manager/systemd-dhcp/src/shared/util.h | 1038 +++ .../systemd-dhcp/src/systemd/_sd-common.h | 78 + .../systemd-dhcp/src/systemd/sd-dhcp-client.h | 75 + .../systemd-dhcp/src/systemd/sd-dhcp-lease.h | 54 + .../systemd-dhcp/src/systemd/sd-dhcp6-client.h | 66 + .../systemd-dhcp/src/systemd/sd-dhcp6-lease.h | 42 + .../systemd-dhcp/src/systemd/sd-event.h | 135 + .../systemd-dhcp/src/systemd/sd-id128.h | 113 + src/dhcp-manager/tests/Makefile.am | 28 +- src/dhcp-manager/tests/Makefile.in | 77 +- src/dhcp-manager/tests/test-dhcp-dhclient.c | 158 +- src/dhcp-manager/tests/test-dhcp-utils.c | 723 ++ src/dns-manager/nm-dns-dnsmasq.c | 33 +- src/dns-manager/nm-dns-dnsmasq.h | 6 +- src/dns-manager/nm-dns-manager.c | 74 +- src/dns-manager/nm-dns-manager.h | 17 +- src/dns-manager/nm-dns-plugin.c | 43 +- src/dns-manager/nm-dns-plugin.h | 6 +- src/dns-manager/nm-dns-unbound.c | 2 + src/dns-manager/nm-dns-unbound.h | 6 +- src/dns-manager/nm-dns-utils.c | 3 + src/dns-manager/nm-dns-utils.h | 4 +- src/dnsmasq-manager/nm-dnsmasq-manager.c | 95 +- src/dnsmasq-manager/nm-dnsmasq-manager.h | 11 +- src/dnsmasq-manager/nm-dnsmasq-utils.c | 3 +- src/dnsmasq-manager/nm-dnsmasq-utils.h | 6 +- src/dnsmasq-manager/tests/Makefile.am | 6 +- src/dnsmasq-manager/tests/Makefile.in | 12 +- src/dnsmasq-manager/tests/test-dnsmasq-utils.c | 2 + src/firewall-manager/nm-firewall-manager.c | 360 - src/firewall-manager/nm-firewall-manager.h | 73 - src/logging/nm-logging.c | 482 -- src/logging/nm-logging.h | 142 - src/main-utils.c | 279 + src/main-utils.h | 39 + src/main.c | 265 +- src/nm-activation-request.c | 9 +- src/nm-activation-request.h | 14 +- src/nm-active-connection.c | 345 +- src/nm-active-connection.h | 18 +- src/nm-auth-manager.c | 657 ++ src/nm-auth-manager.h | 78 + src/nm-auth-subject.c | 416 +- src/nm-auth-subject.h | 55 +- src/nm-auth-utils.c | 480 ++ src/nm-auth-utils.h | 97 + src/nm-config.c | 675 ++ src/nm-config.h | 80 + src/nm-connection-provider.c | 2 + src/nm-connection-provider.h | 10 +- src/nm-connectivity.c | 30 +- src/nm-connectivity.h | 13 +- src/nm-dbus-manager.c | 23 +- src/nm-dbus-manager.h | 6 +- src/nm-dcb.c | 56 +- src/nm-dcb.h | 30 +- src/nm-default-route-manager.c | 1365 +++ src/nm-default-route-manager.h | 74 + src/nm-device-glue.h | 5 +- src/nm-device-team-glue.h | 73 - src/nm-device-vlan-glue.h | 2 +- src/nm-dhcp4-config.c | 41 +- src/nm-dhcp4-config.h | 32 +- src/nm-dhcp6-config.c | 41 +- src/nm-dhcp6-config.h | 32 +- src/nm-dispatcher.c | 21 +- src/nm-dispatcher.h | 10 +- src/nm-enum-types.c | 533 +- src/nm-enum-types.h | 55 +- src/nm-firewall-manager.c | 440 + src/nm-firewall-manager.h | 75 + src/nm-iface-helper.c | 538 ++ src/nm-ip4-config-glue.h | 2 +- src/nm-ip4-config.c | 440 +- src/nm-ip4-config.h | 30 +- src/nm-ip6-config-glue.h | 2 +- src/nm-ip6-config.c | 394 +- src/nm-ip6-config.h | 26 +- src/nm-logging.c | 487 ++ src/nm-logging.h | 159 + src/nm-manager-auth.c | 656 -- src/nm-manager-auth.h | 108 - src/nm-manager-glue.h | 2 +- src/nm-manager.c | 988 ++- src/nm-manager.h | 97 +- src/nm-policy.c | 634 +- src/nm-policy.h | 13 +- src/nm-posix-signals.c | 62 + src/nm-posix-signals.h | 36 + src/nm-ppp-manager-glue.h | 7 +- src/nm-properties-changed-signal.c | 2 + src/nm-rfkill-manager.c | 2 +- src/nm-rfkill-manager.h | 10 +- src/nm-session-monitor-ck.c | 46 +- src/nm-session-monitor-null.c | 1 + src/nm-session-monitor-systemd.c | 1 + src/nm-session-monitor.h | 9 +- src/nm-session-utils.c | 23 +- src/nm-session-utils.h | 15 +- src/nm-settings-connection-glue.h | 7 +- src/nm-sleep-monitor-systemd.c | 56 +- src/nm-sleep-monitor-upower.c | 1 + src/nm-sleep-monitor.h | 9 +- src/nm-types.h | 94 +- src/platform/Makefile.in | 6 +- src/platform/nm-fake-platform.c | 108 +- src/platform/nm-fake-platform.h | 6 +- src/platform/nm-linux-platform.c | 623 +- src/platform/nm-linux-platform.h | 6 +- src/platform/nm-platform.c | 293 +- src/platform/nm-platform.h | 201 +- src/platform/tests/Makefile.am | 9 +- src/platform/tests/Makefile.in | 16 +- src/platform/tests/dump.c | 6 +- src/platform/tests/monitor.c | 2 + src/platform/tests/platform.c | 28 +- src/platform/tests/test-address.c | 8 +- src/platform/tests/test-cleanup.c | 24 +- src/platform/tests/test-common.c | 2 + src/platform/tests/test-link.c | 13 +- src/platform/tests/test-route.c | 48 +- src/platform/wifi/wifi-utils-nl80211.c | 59 +- src/platform/wifi/wifi-utils-nl80211.h | 8 +- src/platform/wifi/wifi-utils-private.h | 12 +- src/platform/wifi/wifi-utils-wext.c | 19 +- src/platform/wifi/wifi-utils-wext.h | 6 +- src/platform/wifi/wifi-utils.c | 23 +- src/platform/wifi/wifi-utils.h | 16 +- src/posix-signals/nm-posix-signals.c | 62 - src/posix-signals/nm-posix-signals.h | 36 - src/ppp-manager/Makefile.am | 10 +- src/ppp-manager/Makefile.in | 20 +- src/ppp-manager/nm-ppp-manager.c | 293 +- src/ppp-manager/nm-ppp-manager.h | 17 +- src/ppp-manager/nm-ppp-status.h | 6 +- src/ppp-manager/nm-pppd-plugin.c | 264 +- src/ppp-manager/nm-pppd-plugin.h | 19 +- src/rdisc/Makefile.in | 6 +- src/rdisc/nm-fake-rdisc.c | 2 + src/rdisc/nm-fake-rdisc.h | 6 +- src/rdisc/nm-lndp-rdisc.c | 150 +- src/rdisc/nm-lndp-rdisc.h | 6 +- src/rdisc/nm-rdisc.c | 23 +- src/rdisc/nm-rdisc.h | 16 +- src/rdisc/tests/Makefile.am | 14 +- src/rdisc/tests/Makefile.in | 24 +- src/rdisc/tests/rdisc.c | 5 +- src/settings/nm-agent-manager.c | 120 +- src/settings/nm-agent-manager.h | 27 +- src/settings/nm-inotify-helper.c | 2 + src/settings/nm-secret-agent.c | 47 +- src/settings/nm-secret-agent.h | 26 +- src/settings/nm-settings-connection.c | 644 +- src/settings/nm-settings-connection.h | 59 +- src/settings/nm-settings-error.c | 33 - src/settings/nm-settings-error.h | 53 - src/settings/nm-settings-utils.c | 66 - src/settings/nm-settings-utils.h | 26 - src/settings/nm-settings.c | 272 +- src/settings/nm-settings.h | 9 +- src/settings/nm-system-config-interface.c | 45 +- src/settings/nm-system-config-interface.h | 6 +- src/settings/plugins/Makefile.am | 4 + src/settings/plugins/Makefile.in | 19 +- src/settings/plugins/example/Makefile.am | 15 +- src/settings/plugins/example/Makefile.in | 30 +- src/settings/plugins/example/common.h | 11 - src/settings/plugins/example/errors.c | 40 - .../plugins/example/nm-example-connection.c | 13 +- .../plugins/example/nm-example-connection.h | 6 +- src/settings/plugins/example/plugin.c | 13 +- src/settings/plugins/example/reader.c | 5 +- src/settings/plugins/example/writer.c | 3 +- src/settings/plugins/ibft/Makefile.am | 38 + src/settings/plugins/ibft/Makefile.in | 956 ++ src/settings/plugins/ibft/nm-ibft-connection.c | 66 + src/settings/plugins/ibft/nm-ibft-connection.h | 50 + src/settings/plugins/ibft/plugin.c | 210 + src/settings/plugins/ibft/plugin.h | 47 + src/settings/plugins/ibft/reader.c | 558 ++ src/settings/plugins/ibft/reader.h | 36 + src/settings/plugins/ibft/tests/Makefile.am | 49 + src/settings/plugins/ibft/tests/Makefile.in | 899 ++ .../plugins/ibft/tests/iscsiadm-test-bad-dns1 | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-dns2 | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-entry | 20 + .../plugins/ibft/tests/iscsiadm-test-bad-gateway | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-ipaddr | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-record | 18 + src/settings/plugins/ibft/tests/iscsiadm-test-dhcp | 33 + .../plugins/ibft/tests/iscsiadm-test-static | 35 + src/settings/plugins/ibft/tests/iscsiadm-test-vlan | 19 + src/settings/plugins/ibft/tests/test-ibft.c | 292 + src/settings/plugins/ifcfg-rh/Makefile.am | 18 +- src/settings/plugins/ifcfg-rh/Makefile.in | 35 +- src/settings/plugins/ifcfg-rh/common.h | 4 - src/settings/plugins/ifcfg-rh/errors.c | 35 - .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 78 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 8 +- src/settings/plugins/ifcfg-rh/plugin.c | 30 +- src/settings/plugins/ifcfg-rh/reader.c | 1461 ++-- src/settings/plugins/ifcfg-rh/reader.h | 1 - src/settings/plugins/ifcfg-rh/shvar.c | 45 +- src/settings/plugins/ifcfg-rh/shvar.h | 2 + src/settings/plugins/ifcfg-rh/tests/Makefile.am | 27 +- src/settings/plugins/ifcfg-rh/tests/Makefile.in | 60 +- .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 | 21 - .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 | 21 - .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry | 35 - .../ifcfg-rh/tests/iscsiadm-test-bad-gateway | 21 - .../ifcfg-rh/tests/iscsiadm-test-bad-ipaddr | 21 - .../ifcfg-rh/tests/iscsiadm-test-bad-record | 18 - .../plugins/ifcfg-rh/tests/iscsiadm-test-dhcp | 33 - .../plugins/ifcfg-rh/tests/iscsiadm-test-static | 35 - .../ifcfg-rh/tests/network-scripts/Makefile.am | 10 +- .../ifcfg-rh/tests/network-scripts/Makefile.in | 16 +- .../ifcfg-rh/tests/network-scripts/ifcfg-test-ibft | 10 + .../tests/network-scripts/ifcfg-test-ibft-dhcp | 4 - .../tests/network-scripts/ifcfg-test-ibft-static | 4 - .../network-scripts/ifcfg-test-misc-variables | 3 + .../ifcfg-test-vlan-trailing-spaces | 11 + .../tests/network-scripts/ifcfg-test-wifi-band-a | 13 + .../ifcfg-test-wifi-band-a-channel-mismatch | 9 + .../ifcfg-test-wifi-band-bg-channel-mismatch | 9 + .../tests/network-scripts/ifcfg-test-wifi-open | 1 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c | 2 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 4159 ++++----- src/settings/plugins/ifcfg-rh/utils.c | 7 +- src/settings/plugins/ifcfg-rh/writer.c | 562 +- src/settings/plugins/ifcfg-suse/Makefile.am | 13 +- src/settings/plugins/ifcfg-suse/Makefile.in | 24 +- src/settings/plugins/ifcfg-suse/plugin.c | 16 +- src/settings/plugins/ifcfg-suse/plugin.h | 2 - src/settings/plugins/ifnet/Makefile.am | 27 +- src/settings/plugins/ifnet/Makefile.in | 46 +- src/settings/plugins/ifnet/connection_parser.c | 710 +- src/settings/plugins/ifnet/errors.c | 35 - src/settings/plugins/ifnet/errors.h | 30 - src/settings/plugins/ifnet/net_parser.c | 2 + src/settings/plugins/ifnet/net_utils.c | 229 +- src/settings/plugins/ifnet/net_utils.h | 22 +- src/settings/plugins/ifnet/nm-ifnet-connection.c | 5 +- src/settings/plugins/ifnet/nm-ifnet-connection.h | 4 +- src/settings/plugins/ifnet/plugin.c | 4 +- src/settings/plugins/ifnet/tests/Makefile.am | 18 +- src/settings/plugins/ifnet/tests/Makefile.in | 53 +- src/settings/plugins/ifnet/tests/test_all.c | 68 +- src/settings/plugins/ifnet/wpa_parser.c | 4 +- src/settings/plugins/ifupdown/Makefile.am | 21 +- src/settings/plugins/ifupdown/Makefile.in | 36 +- src/settings/plugins/ifupdown/interface_parser.c | 1 + .../plugins/ifupdown/nm-ifupdown-connection.c | 12 +- .../plugins/ifupdown/nm-ifupdown-connection.h | 6 +- src/settings/plugins/ifupdown/parser.c | 157 +- src/settings/plugins/ifupdown/plugin.c | 24 +- src/settings/plugins/ifupdown/plugin.h | 2 - src/settings/plugins/ifupdown/tests/Makefile.am | 19 +- src/settings/plugins/ifupdown/tests/Makefile.in | 39 +- .../plugins/ifupdown/tests/test-ifupdown.c | 215 +- src/settings/plugins/keyfile/Makefile.am | 17 +- src/settings/plugins/keyfile/Makefile.in | 35 +- src/settings/plugins/keyfile/common.h | 3 - src/settings/plugins/keyfile/errors.c | 35 - .../plugins/keyfile/nm-keyfile-connection.c | 14 +- .../plugins/keyfile/nm-keyfile-connection.h | 6 +- src/settings/plugins/keyfile/plugin.c | 18 +- src/settings/plugins/keyfile/plugin.h | 2 - src/settings/plugins/keyfile/reader.c | 619 +- src/settings/plugins/keyfile/tests/Makefile.am | 12 +- src/settings/plugins/keyfile/tests/Makefile.in | 39 +- .../keyfile/tests/keyfiles/ATT_Data_Connect_BT | 1 + .../keyfile/tests/keyfiles/ATT_Data_Connect_Plain | 1 + .../plugins/keyfile/tests/keyfiles/Makefile.am | 11 +- .../plugins/keyfile/tests/keyfiles/Makefile.in | 17 +- .../keyfile/tests/keyfiles/Test_Enum_Property | 8 + .../keyfile/tests/keyfiles/Test_Flags_Property | 11 + .../keyfile/tests/keyfiles/Test_Missing_ID_UUID | 9 + .../plugins/keyfile/tests/keyfiles/Test_minimal_1 | 2 + .../plugins/keyfile/tests/keyfiles/Test_minimal_2 | 1 + .../keyfile/tests/keyfiles/Test_minimal_slave_1 | 4 + .../keyfile/tests/keyfiles/Test_minimal_slave_2 | 7 + .../keyfile/tests/keyfiles/Test_minimal_slave_3 | 4 + .../keyfile/tests/keyfiles/Test_minimal_slave_4 | 4 + src/settings/plugins/keyfile/tests/test-keyfile.c | 1276 +-- src/settings/plugins/keyfile/utils.c | 3 + src/settings/plugins/keyfile/utils.h | 1 + src/settings/plugins/keyfile/writer.c | 515 +- src/settings/tests/Makefile.am | 23 - src/settings/tests/Makefile.in | 854 -- src/settings/tests/test-wired-defname.c | 139 - src/supplicant-manager/nm-call-store.c | 10 +- src/supplicant-manager/nm-call-store.h | 6 +- src/supplicant-manager/nm-supplicant-config.c | 115 +- src/supplicant-manager/nm-supplicant-config.h | 4 +- src/supplicant-manager/nm-supplicant-interface.c | 20 +- src/supplicant-manager/nm-supplicant-interface.h | 5 +- src/supplicant-manager/nm-supplicant-manager.c | 14 +- src/supplicant-manager/nm-supplicant-manager.h | 6 +- .../nm-supplicant-settings-verify.c | 4 +- .../nm-supplicant-settings-verify.h | 6 +- src/supplicant-manager/nm-supplicant-types.h | 4 +- src/supplicant-manager/tests/Makefile.am | 6 +- src/supplicant-manager/tests/Makefile.in | 12 +- .../tests/test-supplicant-config.c | 77 +- src/tests/Makefile.am | 69 +- src/tests/Makefile.in | 304 +- src/tests/config/Makefile.am | 33 + src/tests/config/Makefile.in | 871 ++ src/tests/config/NetworkManager.conf | 15 + src/tests/config/bad.conf | 1 + src/tests/config/conf.d/00-overrides.conf | 11 + src/tests/config/conf.d/10-more.conf | 11 + src/tests/config/conf.d/90-last.conf | 5 + src/tests/config/nm-test-device.c | 99 + src/tests/config/nm-test-device.h | 50 + src/tests/config/test-config.c | 308 + src/tests/test-dcb.c | 2 + src/tests/test-dhcp-options.c | 937 -- src/tests/test-general-with-expect.c | 349 + src/tests/test-general.c | 357 +- src/tests/test-ip4-config.c | 49 +- src/tests/test-ip6-config.c | 87 +- src/tests/test-resolvconf-capture.c | 5 + src/tests/test-wired-defname.c | 130 + src/vpn-manager/nm-vpn-connection.c | 550 +- src/vpn-manager/nm-vpn-connection.h | 77 +- src/vpn-manager/nm-vpn-manager.c | 79 +- src/vpn-manager/nm-vpn-manager.h | 42 +- src/vpn-manager/nm-vpn-service.c | 92 +- src/vpn-manager/nm-vpn-service.h | 28 +- test/Makefile.am | 39 - test/Makefile.in | 857 -- test/libnm-glib-test.c | 113 - test/nm-online.c | 216 - tools/Makefile.am | 29 +- tools/Makefile.in | 224 +- tools/check-exports.sh | 57 +- tools/debug-helper.py | 61 + tools/generate-settings-spec.c | 457 - tools/run-test-valgrind.sh | 26 + tools/test-networkmanager-service.py | 1170 +++ tools/test-sudo-wrapper.sh | 29 + tui/Makefile.am | 126 - tui/Makefile.in | 1106 --- tui/newt/Makefile.am | 54 - tui/newt/Makefile.in | 802 -- tui/newt/nmt-newt-button-box.c | 385 - tui/newt/nmt-newt-button-box.h | 65 - tui/newt/nmt-newt-button.c | 260 - tui/newt/nmt-newt-button.h | 53 - tui/newt/nmt-newt-checkbox.c | 235 - tui/newt/nmt-newt-checkbox.h | 53 - tui/newt/nmt-newt-component.c | 307 - tui/newt/nmt-newt-component.h | 57 - tui/newt/nmt-newt-container.c | 252 - tui/newt/nmt-newt-container.h | 61 - tui/newt/nmt-newt-entry-numeric.c | 213 - tui/newt/nmt-newt-entry-numeric.h | 51 - tui/newt/nmt-newt-entry.c | 536 -- tui/newt/nmt-newt-entry.h | 74 - tui/newt/nmt-newt-form.c | 743 -- tui/newt/nmt-newt-form.h | 66 - tui/newt/nmt-newt-grid.c | 472 - tui/newt/nmt-newt-grid.h | 72 - tui/newt/nmt-newt-hacks.c | 103 - tui/newt/nmt-newt-hacks.h | 42 - tui/newt/nmt-newt-label.c | 323 - tui/newt/nmt-newt-label.h | 66 - tui/newt/nmt-newt-listbox.c | 543 -- tui/newt/nmt-newt-listbox.h | 71 - tui/newt/nmt-newt-popup.c | 343 - tui/newt/nmt-newt-popup.h | 62 - tui/newt/nmt-newt-section.c | 408 - tui/newt/nmt-newt-section.h | 57 - tui/newt/nmt-newt-separator.c | 66 - tui/newt/nmt-newt-separator.h | 49 - tui/newt/nmt-newt-stack.c | 366 - tui/newt/nmt-newt-stack.h | 61 - tui/newt/nmt-newt-textbox.c | 292 - tui/newt/nmt-newt-textbox.h | 59 - tui/newt/nmt-newt-toggle-button.c | 234 - tui/newt/nmt-newt-toggle-button.h | 54 - tui/newt/nmt-newt-types.h | 50 - tui/newt/nmt-newt-utils.c | 392 - tui/newt/nmt-newt-utils.h | 53 - tui/newt/nmt-newt-widget.c | 664 -- tui/newt/nmt-newt-widget.h | 118 - tui/newt/nmt-newt.h | 39 - tui/nm-editor-bindings.c | 1676 ---- tui/nm-editor-bindings.h | 99 - tui/nm-editor-utils.c | 423 - tui/nm-editor-utils.h | 44 - tui/nmt-address-list.c | 284 - tui/nmt-address-list.h | 57 - tui/nmt-connect-connection-list.c | 720 -- tui/nmt-connect-connection-list.h | 61 - tui/nmt-device-entry.c | 589 -- tui/nmt-device-entry.h | 61 - tui/nmt-edit-connection-list.c | 568 -- tui/nmt-edit-connection-list.h | 61 - tui/nmt-editor-page.c | 227 - tui/nmt-editor-page.h | 57 - tui/nmt-editor.c | 330 - tui/nmt-editor.h | 51 - tui/nmt-ip-entry.c | 265 - tui/nmt-ip-entry.h | 52 - tui/nmt-mac-entry.c | 236 - tui/nmt-mac-entry.h | 54 - tui/nmt-mtu-entry.c | 191 - tui/nmt-mtu-entry.h | 49 - tui/nmt-page-bond.c | 436 - tui/nmt-page-bond.h | 50 - tui/nmt-page-bridge-port.c | 92 - tui/nmt-page-bridge-port.h | 49 - tui/nmt-page-bridge.c | 153 - tui/nmt-page-bridge.h | 50 - tui/nmt-page-device.c | 151 - tui/nmt-page-device.h | 51 - tui/nmt-page-ethernet.c | 97 - tui/nmt-page-ethernet.h | 50 - tui/nmt-page-grid.c | 458 - tui/nmt-page-grid.h | 62 - tui/nmt-page-infiniband.c | 107 - tui/nmt-page-infiniband.h | 50 - tui/nmt-page-ip4.c | 203 - tui/nmt-page-ip4.h | 51 - tui/nmt-page-ip6.c | 201 - tui/nmt-page-ip6.h | 51 - tui/nmt-page-main.c | 327 - tui/nmt-page-main.h | 51 - tui/nmt-page-team-port.c | 125 - tui/nmt-page-team-port.h | 49 - tui/nmt-page-team.c | 195 - tui/nmt-page-team.h | 50 - tui/nmt-page-vlan.c | 163 - tui/nmt-page-vlan.h | 50 - tui/nmt-page-wifi.c | 389 - tui/nmt-page-wifi.h | 50 - tui/nmt-password-dialog.c | 343 - tui/nmt-password-dialog.h | 57 - tui/nmt-password-fields.c | 310 - tui/nmt-password-fields.h | 55 - tui/nmt-route-editor.c | 219 - tui/nmt-route-editor.h | 51 - tui/nmt-route-entry.c | 323 - tui/nmt-route-entry.h | 51 - tui/nmt-route-table.c | 395 - tui/nmt-route-table.h | 49 - tui/nmt-secret-agent.c | 646 -- tui/nmt-secret-agent.h | 57 - tui/nmt-slave-list.c | 264 - tui/nmt-slave-list.h | 52 - tui/nmt-utils.c | 151 - tui/nmt-utils.h | 46 - tui/nmt-widget-list.c | 491 -- tui/nmt-widget-list.h | 69 - tui/nmtui-connect.c | 353 - tui/nmtui-connect.h | 28 - tui/nmtui-edit.c | 505 -- tui/nmtui-edit.h | 44 - tui/nmtui-hostname.c | 124 - tui/nmtui-hostname.h | 28 - tui/nmtui.c | 310 - tui/nmtui.h | 34 - vapi/Makefile.in | 10 +- vapi/Makefile.vapigen | 4 +- vapi/NMClient-1.0.metadata | 4 +- 1615 files changed, 400710 insertions(+), 147101 deletions(-) delete mode 100644 cli/Makefile.am delete mode 100644 cli/Makefile.in delete mode 100644 cli/completion/Makefile.am delete mode 100644 cli/completion/Makefile.in delete mode 100644 cli/completion/nmcli delete mode 100644 cli/src/Makefile.am delete mode 100644 cli/src/Makefile.in delete mode 100644 cli/src/common.c delete mode 100644 cli/src/common.h delete mode 100644 cli/src/connections.c delete mode 100644 cli/src/connections.h delete mode 100644 cli/src/devices.c delete mode 100644 cli/src/devices.h delete mode 100644 cli/src/network-manager.c delete mode 100644 cli/src/network-manager.h delete mode 100644 cli/src/nmcli.c delete mode 100644 cli/src/nmcli.h delete mode 100644 cli/src/settings.c delete mode 100644 cli/src/settings.h delete mode 100644 cli/src/utils.c delete mode 100644 cli/src/utils.h create mode 100644 clients/Makefile.am create mode 100644 clients/Makefile.in create mode 100644 clients/cli/Makefile.am create mode 100644 clients/cli/Makefile.in create mode 100644 clients/cli/agent.c create mode 100644 clients/cli/agent.h create mode 100644 clients/cli/common.c create mode 100644 clients/cli/common.h create mode 100644 clients/cli/connections.c create mode 100644 clients/cli/connections.h create mode 100644 clients/cli/devices.c create mode 100644 clients/cli/devices.h create mode 100644 clients/cli/general.c create mode 100644 clients/cli/general.h create mode 100644 clients/cli/nmcli-completion create mode 100644 clients/cli/nmcli.c create mode 100644 clients/cli/nmcli.h create mode 100644 clients/cli/polkit-agent.c create mode 100644 clients/cli/polkit-agent.h create mode 100644 clients/cli/settings-docs.c create mode 100644 clients/cli/settings-docs.xsl create mode 100644 clients/cli/settings.c create mode 100644 clients/cli/settings.h create mode 100644 clients/cli/utils.c create mode 100644 clients/cli/utils.h create mode 100644 clients/common/nm-polkit-listener.c create mode 100644 clients/common/nm-polkit-listener.h create mode 100644 clients/common/nm-secret-agent-simple.c create mode 100644 clients/common/nm-secret-agent-simple.h create mode 100644 clients/nm-online.c create mode 100644 clients/tui/Makefile.am create mode 100644 clients/tui/Makefile.in create mode 100644 clients/tui/newt/Makefile.am create mode 100644 clients/tui/newt/Makefile.in create mode 100644 clients/tui/newt/nmt-newt-button-box.c create mode 100644 clients/tui/newt/nmt-newt-button-box.h create mode 100644 clients/tui/newt/nmt-newt-button.c create mode 100644 clients/tui/newt/nmt-newt-button.h create mode 100644 clients/tui/newt/nmt-newt-checkbox.c create mode 100644 clients/tui/newt/nmt-newt-checkbox.h create mode 100644 clients/tui/newt/nmt-newt-component.c create mode 100644 clients/tui/newt/nmt-newt-component.h create mode 100644 clients/tui/newt/nmt-newt-container.c create mode 100644 clients/tui/newt/nmt-newt-container.h create mode 100644 clients/tui/newt/nmt-newt-entry-numeric.c create mode 100644 clients/tui/newt/nmt-newt-entry-numeric.h create mode 100644 clients/tui/newt/nmt-newt-entry.c create mode 100644 clients/tui/newt/nmt-newt-entry.h create mode 100644 clients/tui/newt/nmt-newt-form.c create mode 100644 clients/tui/newt/nmt-newt-form.h create mode 100644 clients/tui/newt/nmt-newt-grid.c create mode 100644 clients/tui/newt/nmt-newt-grid.h create mode 100644 clients/tui/newt/nmt-newt-hacks.c create mode 100644 clients/tui/newt/nmt-newt-hacks.h create mode 100644 clients/tui/newt/nmt-newt-label.c create mode 100644 clients/tui/newt/nmt-newt-label.h create mode 100644 clients/tui/newt/nmt-newt-listbox.c create mode 100644 clients/tui/newt/nmt-newt-listbox.h create mode 100644 clients/tui/newt/nmt-newt-popup.c create mode 100644 clients/tui/newt/nmt-newt-popup.h create mode 100644 clients/tui/newt/nmt-newt-section.c create mode 100644 clients/tui/newt/nmt-newt-section.h create mode 100644 clients/tui/newt/nmt-newt-separator.c create mode 100644 clients/tui/newt/nmt-newt-separator.h create mode 100644 clients/tui/newt/nmt-newt-stack.c create mode 100644 clients/tui/newt/nmt-newt-stack.h create mode 100644 clients/tui/newt/nmt-newt-textbox.c create mode 100644 clients/tui/newt/nmt-newt-textbox.h create mode 100644 clients/tui/newt/nmt-newt-toggle-button.c create mode 100644 clients/tui/newt/nmt-newt-toggle-button.h create mode 100644 clients/tui/newt/nmt-newt-types.h create mode 100644 clients/tui/newt/nmt-newt-utils.c create mode 100644 clients/tui/newt/nmt-newt-utils.h create mode 100644 clients/tui/newt/nmt-newt-widget.c create mode 100644 clients/tui/newt/nmt-newt-widget.h create mode 100644 clients/tui/newt/nmt-newt.h create mode 100644 clients/tui/nm-editor-bindings.c create mode 100644 clients/tui/nm-editor-bindings.h create mode 100644 clients/tui/nm-editor-utils.c create mode 100644 clients/tui/nm-editor-utils.h create mode 100644 clients/tui/nmt-address-list.c create mode 100644 clients/tui/nmt-address-list.h create mode 100644 clients/tui/nmt-connect-connection-list.c create mode 100644 clients/tui/nmt-connect-connection-list.h create mode 100644 clients/tui/nmt-device-entry.c create mode 100644 clients/tui/nmt-device-entry.h create mode 100644 clients/tui/nmt-edit-connection-list.c create mode 100644 clients/tui/nmt-edit-connection-list.h create mode 100644 clients/tui/nmt-editor-grid.c create mode 100644 clients/tui/nmt-editor-grid.h create mode 100644 clients/tui/nmt-editor-page-device.c create mode 100644 clients/tui/nmt-editor-page-device.h create mode 100644 clients/tui/nmt-editor-page.c create mode 100644 clients/tui/nmt-editor-page.h create mode 100644 clients/tui/nmt-editor-section.c create mode 100644 clients/tui/nmt-editor-section.h create mode 100644 clients/tui/nmt-editor.c create mode 100644 clients/tui/nmt-editor.h create mode 100644 clients/tui/nmt-ip-entry.c create mode 100644 clients/tui/nmt-ip-entry.h create mode 100644 clients/tui/nmt-mac-entry.c create mode 100644 clients/tui/nmt-mac-entry.h create mode 100644 clients/tui/nmt-mtu-entry.c create mode 100644 clients/tui/nmt-mtu-entry.h create mode 100644 clients/tui/nmt-page-bond.c create mode 100644 clients/tui/nmt-page-bond.h create mode 100644 clients/tui/nmt-page-bridge-port.c create mode 100644 clients/tui/nmt-page-bridge-port.h create mode 100644 clients/tui/nmt-page-bridge.c create mode 100644 clients/tui/nmt-page-bridge.h create mode 100644 clients/tui/nmt-page-dsl.c create mode 100644 clients/tui/nmt-page-dsl.h create mode 100644 clients/tui/nmt-page-ethernet.c create mode 100644 clients/tui/nmt-page-ethernet.h create mode 100644 clients/tui/nmt-page-infiniband.c create mode 100644 clients/tui/nmt-page-infiniband.h create mode 100644 clients/tui/nmt-page-ip4.c create mode 100644 clients/tui/nmt-page-ip4.h create mode 100644 clients/tui/nmt-page-ip6.c create mode 100644 clients/tui/nmt-page-ip6.h create mode 100644 clients/tui/nmt-page-ppp.c create mode 100644 clients/tui/nmt-page-ppp.h create mode 100644 clients/tui/nmt-page-team-port.c create mode 100644 clients/tui/nmt-page-team-port.h create mode 100644 clients/tui/nmt-page-team.c create mode 100644 clients/tui/nmt-page-team.h create mode 100644 clients/tui/nmt-page-vlan.c create mode 100644 clients/tui/nmt-page-vlan.h create mode 100644 clients/tui/nmt-page-wifi.c create mode 100644 clients/tui/nmt-page-wifi.h create mode 100644 clients/tui/nmt-password-dialog.c create mode 100644 clients/tui/nmt-password-dialog.h create mode 100644 clients/tui/nmt-password-fields.c create mode 100644 clients/tui/nmt-password-fields.h create mode 100644 clients/tui/nmt-route-editor.c create mode 100644 clients/tui/nmt-route-editor.h create mode 100644 clients/tui/nmt-route-entry.c create mode 100644 clients/tui/nmt-route-entry.h create mode 100644 clients/tui/nmt-route-table.c create mode 100644 clients/tui/nmt-route-table.h create mode 100644 clients/tui/nmt-slave-list.c create mode 100644 clients/tui/nmt-slave-list.h create mode 100644 clients/tui/nmt-utils.c create mode 100644 clients/tui/nmt-utils.h create mode 100644 clients/tui/nmt-widget-list.c create mode 100644 clients/tui/nmt-widget-list.h create mode 100644 clients/tui/nmtui-connect.c create mode 100644 clients/tui/nmtui-connect.h create mode 100644 clients/tui/nmtui-edit.c create mode 100644 clients/tui/nmtui-edit.h create mode 100644 clients/tui/nmtui-hostname.c create mode 100644 clients/tui/nmtui-hostname.h create mode 100644 clients/tui/nmtui.c create mode 100644 clients/tui/nmtui.h create mode 100644 docs/api/settings-spec.xsl create mode 100644 docs/libnm-util/html/libnm-util-NetworkManager.html create mode 100644 docs/libnm-util/html/libnm-util-NetworkManagerVPN.html create mode 100644 docs/libnm-util/tmpl/NetworkManager.sgml create mode 100644 docs/libnm-util/tmpl/NetworkManagerVPN.sgml create mode 100644 docs/libnm/Makefile.am create mode 100644 docs/libnm/Makefile.in create mode 100644 docs/libnm/html/NMAccessPoint.html create mode 100644 docs/libnm/html/NMActiveConnection.html create mode 100644 docs/libnm/html/NMClient.html create mode 100644 docs/libnm/html/NMDevice.html create mode 100644 docs/libnm/html/NMDeviceAdsl.html create mode 100644 docs/libnm/html/NMDeviceBond.html create mode 100644 docs/libnm/html/NMDeviceBridge.html create mode 100644 docs/libnm/html/NMDeviceBt.html create mode 100644 docs/libnm/html/NMDeviceEthernet.html create mode 100644 docs/libnm/html/NMDeviceGeneric.html create mode 100644 docs/libnm/html/NMDeviceInfiniband.html create mode 100644 docs/libnm/html/NMDeviceModem.html create mode 100644 docs/libnm/html/NMDeviceOlpcMesh.html create mode 100644 docs/libnm/html/NMDeviceTeam.html create mode 100644 docs/libnm/html/NMDeviceVlan.html create mode 100644 docs/libnm/html/NMDeviceWifi.html create mode 100644 docs/libnm/html/NMDeviceWimax.html create mode 100644 docs/libnm/html/NMDhcpConfig.html create mode 100644 docs/libnm/html/NMIPConfig.html create mode 100644 docs/libnm/html/NMObject.html create mode 100644 docs/libnm/html/NMRemoteConnection.html create mode 100644 docs/libnm/html/NMSecretAgentOld.html create mode 100644 docs/libnm/html/NMSetting.html create mode 100644 docs/libnm/html/NMSetting8021x.html create mode 100644 docs/libnm/html/NMSettingAdsl.html create mode 100644 docs/libnm/html/NMSettingBluetooth.html create mode 100644 docs/libnm/html/NMSettingBond.html create mode 100644 docs/libnm/html/NMSettingBridge.html create mode 100644 docs/libnm/html/NMSettingBridgePort.html create mode 100644 docs/libnm/html/NMSettingCdma.html create mode 100644 docs/libnm/html/NMSettingConnection.html create mode 100644 docs/libnm/html/NMSettingDcb.html create mode 100644 docs/libnm/html/NMSettingGeneric.html create mode 100644 docs/libnm/html/NMSettingGsm.html create mode 100644 docs/libnm/html/NMSettingIP4Config.html create mode 100644 docs/libnm/html/NMSettingIP6Config.html create mode 100644 docs/libnm/html/NMSettingIPConfig.html create mode 100644 docs/libnm/html/NMSettingInfiniband.html create mode 100644 docs/libnm/html/NMSettingOlpcMesh.html create mode 100644 docs/libnm/html/NMSettingPpp.html create mode 100644 docs/libnm/html/NMSettingPppoe.html create mode 100644 docs/libnm/html/NMSettingSerial.html create mode 100644 docs/libnm/html/NMSettingTeam.html create mode 100644 docs/libnm/html/NMSettingTeamPort.html create mode 100644 docs/libnm/html/NMSettingVlan.html create mode 100644 docs/libnm/html/NMSettingVpn.html create mode 100644 docs/libnm/html/NMSettingWimax.html create mode 100644 docs/libnm/html/NMSettingWired.html create mode 100644 docs/libnm/html/NMSettingWireless.html create mode 100644 docs/libnm/html/NMSettingWirelessSecurity.html create mode 100644 docs/libnm/html/NMSimpleConnection.html create mode 100644 docs/libnm/html/NMVpnConnection.html create mode 100644 docs/libnm/html/NMWimaxNsp.html create mode 100644 docs/libnm/html/annotation-glossary.html create mode 100644 docs/libnm/html/api-index-full.html create mode 100644 docs/libnm/html/ch02.html create mode 100644 docs/libnm/html/ch03.html create mode 100644 docs/libnm/html/ch04.html create mode 100644 docs/libnm/html/ch05.html create mode 100644 docs/libnm/html/ch06.html create mode 100644 docs/libnm/html/home.png create mode 100644 docs/libnm/html/index.html create mode 100644 docs/libnm/html/index.sgml create mode 100644 docs/libnm/html/left.png create mode 100644 docs/libnm/html/libnm-NMConnection.html create mode 100644 docs/libnm/html/libnm-NMVpnEditorPlugin.html create mode 100644 docs/libnm/html/libnm-nm-dbus-interface.html create mode 100644 docs/libnm/html/libnm-nm-errors.html create mode 100644 docs/libnm/html/libnm-nm-utils.html create mode 100644 docs/libnm/html/libnm-nm-version.html create mode 100644 docs/libnm/html/libnm-nm-vpn-dbus-interface.html create mode 100644 docs/libnm/html/libnm.devhelp2 create mode 100644 docs/libnm/html/libnm.png create mode 100644 docs/libnm/html/object-tree.html create mode 100644 docs/libnm/html/ref-overview.html create mode 100644 docs/libnm/html/right.png create mode 100644 docs/libnm/html/style.css create mode 100644 docs/libnm/html/up.png create mode 100644 docs/libnm/libnm-docs.xml create mode 100644 docs/libnm/libnm-overrides.txt create mode 100644 docs/libnm/libnm-sections.txt create mode 100644 docs/libnm/libnm.png create mode 100644 docs/libnm/libnm.types create mode 100644 docs/libnm/tmpl/libnm-unused.sgml create mode 100644 docs/libnm/tmpl/nm-access-point.sgml create mode 100644 docs/libnm/tmpl/nm-active-connection.sgml create mode 100644 docs/libnm/tmpl/nm-client.sgml create mode 100644 docs/libnm/tmpl/nm-connection.sgml create mode 100644 docs/libnm/tmpl/nm-core-enum-types.sgml create mode 100644 docs/libnm/tmpl/nm-dbus-interface.sgml create mode 100644 docs/libnm/tmpl/nm-device-adsl.sgml create mode 100644 docs/libnm/tmpl/nm-device-bond.sgml create mode 100644 docs/libnm/tmpl/nm-device-bridge.sgml create mode 100644 docs/libnm/tmpl/nm-device-bt.sgml create mode 100644 docs/libnm/tmpl/nm-device-ethernet.sgml create mode 100644 docs/libnm/tmpl/nm-device-generic.sgml create mode 100644 docs/libnm/tmpl/nm-device-infiniband.sgml create mode 100644 docs/libnm/tmpl/nm-device-modem.sgml create mode 100644 docs/libnm/tmpl/nm-device-olpc-mesh.sgml create mode 100644 docs/libnm/tmpl/nm-device-team.sgml create mode 100644 docs/libnm/tmpl/nm-device-vlan.sgml create mode 100644 docs/libnm/tmpl/nm-device-wifi.sgml create mode 100644 docs/libnm/tmpl/nm-device-wimax.sgml create mode 100644 docs/libnm/tmpl/nm-device.sgml create mode 100644 docs/libnm/tmpl/nm-dhcp-config.sgml create mode 100644 docs/libnm/tmpl/nm-enum-types.sgml create mode 100644 docs/libnm/tmpl/nm-errors.sgml create mode 100644 docs/libnm/tmpl/nm-ip-config.sgml create mode 100644 docs/libnm/tmpl/nm-object.sgml create mode 100644 docs/libnm/tmpl/nm-remote-connection.sgml create mode 100644 docs/libnm/tmpl/nm-secret-agent-old.sgml create mode 100644 docs/libnm/tmpl/nm-setting-8021x.sgml create mode 100644 docs/libnm/tmpl/nm-setting-adsl.sgml create mode 100644 docs/libnm/tmpl/nm-setting-bluetooth.sgml create mode 100644 docs/libnm/tmpl/nm-setting-bond.sgml create mode 100644 docs/libnm/tmpl/nm-setting-bridge-port.sgml create mode 100644 docs/libnm/tmpl/nm-setting-bridge.sgml create mode 100644 docs/libnm/tmpl/nm-setting-cdma.sgml create mode 100644 docs/libnm/tmpl/nm-setting-connection.sgml create mode 100644 docs/libnm/tmpl/nm-setting-dcb.sgml create mode 100644 docs/libnm/tmpl/nm-setting-generic.sgml create mode 100644 docs/libnm/tmpl/nm-setting-gsm.sgml create mode 100644 docs/libnm/tmpl/nm-setting-infiniband.sgml create mode 100644 docs/libnm/tmpl/nm-setting-ip-config.sgml create mode 100644 docs/libnm/tmpl/nm-setting-ip4-config.sgml create mode 100644 docs/libnm/tmpl/nm-setting-ip6-config.sgml create mode 100644 docs/libnm/tmpl/nm-setting-olpc-mesh.sgml create mode 100644 docs/libnm/tmpl/nm-setting-ppp.sgml create mode 100644 docs/libnm/tmpl/nm-setting-pppoe.sgml create mode 100644 docs/libnm/tmpl/nm-setting-serial.sgml create mode 100644 docs/libnm/tmpl/nm-setting-team-port.sgml create mode 100644 docs/libnm/tmpl/nm-setting-team.sgml create mode 100644 docs/libnm/tmpl/nm-setting-vlan.sgml create mode 100644 docs/libnm/tmpl/nm-setting-vpn.sgml create mode 100644 docs/libnm/tmpl/nm-setting-wimax.sgml create mode 100644 docs/libnm/tmpl/nm-setting-wired.sgml create mode 100644 docs/libnm/tmpl/nm-setting-wireless-security.sgml create mode 100644 docs/libnm/tmpl/nm-setting-wireless.sgml create mode 100644 docs/libnm/tmpl/nm-setting.sgml create mode 100644 docs/libnm/tmpl/nm-simple-connection.sgml create mode 100644 docs/libnm/tmpl/nm-utils.sgml create mode 100644 docs/libnm/tmpl/nm-version.sgml create mode 100644 docs/libnm/tmpl/nm-vpn-connection.sgml create mode 100644 docs/libnm/tmpl/nm-vpn-dbus-interface.sgml create mode 100644 docs/libnm/tmpl/nm-vpn-editor-plugin.sgml create mode 100644 docs/libnm/tmpl/nm-wimax-nsp.sgml create mode 100644 docs/libnm/version.xml create mode 100644 docs/libnm/version.xml.in delete mode 100644 examples/C/glib/add-connection-dbus-glib.c create mode 100644 examples/C/glib/add-connection-gdbus.c delete mode 100644 examples/C/glib/add-connection-libnm-glib.c create mode 100644 examples/C/glib/add-connection-libnm.c delete mode 100644 examples/C/glib/get-active-connections-dbus-glib.c create mode 100644 examples/C/glib/get-active-connections-gdbus.c delete mode 100644 examples/C/glib/get-ap-info-libnm-glib.c create mode 100644 examples/C/glib/get-ap-info-libnm.c delete mode 100644 examples/C/glib/list-connections-dbus-glib.c create mode 100644 examples/C/glib/list-connections-gdbus.c delete mode 100644 examples/C/glib/list-connections-libnm-glib.c create mode 100644 examples/C/glib/list-connections-libnm.c delete mode 100644 examples/C/glib/monitor-nm-running-GDBus.c delete mode 100644 examples/C/glib/monitor-nm-running-dbus-glib.c create mode 100644 examples/C/glib/monitor-nm-running-gdbus.c delete mode 100644 examples/C/glib/monitor-nm-state-GDBus.c create mode 100644 examples/C/glib/monitor-nm-state-gdbus.c create mode 100755 examples/python/dbus/add-connection-compat.py delete mode 100644 include/NetworkManager.h delete mode 100644 include/NetworkManagerVPN.h create mode 100644 include/gsystem-local-alloc.h delete mode 100644 include/nm-settings-flags.h create mode 100644 include/nm-utils-internal.h delete mode 100644 include/nm-version.h delete mode 100644 include/nm-version.h.in delete mode 100644 libgsystem/COPYING delete mode 100644 libgsystem/Makefile-libgsystem.am delete mode 100644 libgsystem/README delete mode 100644 libgsystem/gsystem-console.c delete mode 100644 libgsystem/gsystem-console.h delete mode 100644 libgsystem/gsystem-file-utils.c delete mode 100644 libgsystem/gsystem-file-utils.h delete mode 100644 libgsystem/gsystem-glib-compat.h delete mode 100644 libgsystem/gsystem-local-alloc.c delete mode 100644 libgsystem/gsystem-local-alloc.h delete mode 100644 libgsystem/gsystem-log.c delete mode 100644 libgsystem/gsystem-log.h delete mode 100644 libgsystem/gsystem-shutil.c delete mode 100644 libgsystem/gsystem-shutil.h delete mode 100644 libgsystem/gsystem-subprocess-context-private.h delete mode 100644 libgsystem/gsystem-subprocess-context.c delete mode 100644 libgsystem/gsystem-subprocess-context.h delete mode 100644 libgsystem/gsystem-subprocess.c delete mode 100644 libgsystem/gsystem-subprocess.h delete mode 100644 libgsystem/libgsystem.h create mode 100644 libnm-core/Makefile.am create mode 100644 libnm-core/Makefile.in create mode 100644 libnm-core/Makefile.libnm-core create mode 100644 libnm-core/crypto.c create mode 100644 libnm-core/crypto.h create mode 100644 libnm-core/crypto_gnutls.c create mode 100644 libnm-core/crypto_nss.c create mode 100644 libnm-core/nm-connection-private.h create mode 100644 libnm-core/nm-connection.c create mode 100644 libnm-core/nm-connection.h create mode 100644 libnm-core/nm-core-enum-types.c create mode 100644 libnm-core/nm-core-enum-types.h create mode 100644 libnm-core/nm-core-internal.h create mode 100644 libnm-core/nm-core-types.h create mode 100644 libnm-core/nm-dbus-interface.h create mode 100644 libnm-core/nm-errors.c create mode 100644 libnm-core/nm-errors.h create mode 100644 libnm-core/nm-property-compare.c create mode 100644 libnm-core/nm-property-compare.h create mode 100644 libnm-core/nm-setting-8021x.c create mode 100644 libnm-core/nm-setting-8021x.h create mode 100644 libnm-core/nm-setting-adsl.c create mode 100644 libnm-core/nm-setting-adsl.h create mode 100644 libnm-core/nm-setting-bluetooth.c create mode 100644 libnm-core/nm-setting-bluetooth.h create mode 100644 libnm-core/nm-setting-bond.c create mode 100644 libnm-core/nm-setting-bond.h create mode 100644 libnm-core/nm-setting-bridge-port.c create mode 100644 libnm-core/nm-setting-bridge-port.h create mode 100644 libnm-core/nm-setting-bridge.c create mode 100644 libnm-core/nm-setting-bridge.h create mode 100644 libnm-core/nm-setting-cdma.c create mode 100644 libnm-core/nm-setting-cdma.h create mode 100644 libnm-core/nm-setting-connection.c create mode 100644 libnm-core/nm-setting-connection.h create mode 100644 libnm-core/nm-setting-dcb.c create mode 100644 libnm-core/nm-setting-dcb.h create mode 100644 libnm-core/nm-setting-generic.c create mode 100644 libnm-core/nm-setting-generic.h create mode 100644 libnm-core/nm-setting-gsm.c create mode 100644 libnm-core/nm-setting-gsm.h create mode 100644 libnm-core/nm-setting-infiniband.c create mode 100644 libnm-core/nm-setting-infiniband.h create mode 100644 libnm-core/nm-setting-ip-config.c create mode 100644 libnm-core/nm-setting-ip-config.h create mode 100644 libnm-core/nm-setting-ip4-config.c create mode 100644 libnm-core/nm-setting-ip4-config.h create mode 100644 libnm-core/nm-setting-ip6-config.c create mode 100644 libnm-core/nm-setting-ip6-config.h create mode 100644 libnm-core/nm-setting-olpc-mesh.c create mode 100644 libnm-core/nm-setting-olpc-mesh.h create mode 100644 libnm-core/nm-setting-ppp.c create mode 100644 libnm-core/nm-setting-ppp.h create mode 100644 libnm-core/nm-setting-pppoe.c create mode 100644 libnm-core/nm-setting-pppoe.h create mode 100644 libnm-core/nm-setting-private.h create mode 100644 libnm-core/nm-setting-serial.c create mode 100644 libnm-core/nm-setting-serial.h create mode 100644 libnm-core/nm-setting-team-port.c create mode 100644 libnm-core/nm-setting-team-port.h create mode 100644 libnm-core/nm-setting-team.c create mode 100644 libnm-core/nm-setting-team.h create mode 100644 libnm-core/nm-setting-vlan.c create mode 100644 libnm-core/nm-setting-vlan.h create mode 100644 libnm-core/nm-setting-vpn.c create mode 100644 libnm-core/nm-setting-vpn.h create mode 100644 libnm-core/nm-setting-wimax.c create mode 100644 libnm-core/nm-setting-wimax.h create mode 100644 libnm-core/nm-setting-wired.c create mode 100644 libnm-core/nm-setting-wired.h create mode 100644 libnm-core/nm-setting-wireless-security.c create mode 100644 libnm-core/nm-setting-wireless-security.h create mode 100644 libnm-core/nm-setting-wireless.c create mode 100644 libnm-core/nm-setting-wireless.h create mode 100644 libnm-core/nm-setting.c create mode 100644 libnm-core/nm-setting.h create mode 100644 libnm-core/nm-simple-connection.c create mode 100644 libnm-core/nm-simple-connection.h create mode 100644 libnm-core/nm-utils-private.h create mode 100644 libnm-core/nm-utils.c create mode 100644 libnm-core/nm-utils.h create mode 100644 libnm-core/nm-version.h create mode 100644 libnm-core/nm-version.h.in create mode 100644 libnm-core/nm-vpn-dbus-interface.h create mode 100644 libnm-core/tests/Makefile.am create mode 100644 libnm-core/tests/Makefile.in create mode 100644 libnm-core/tests/certs/ca-no-ending-newline.pem create mode 100644 libnm-core/tests/certs/pkcs8-decrypted.der create mode 100644 libnm-core/tests/certs/pkcs8-enc-key.pem create mode 100644 libnm-core/tests/certs/pkcs8-noenc-key.pem create mode 100644 libnm-core/tests/certs/test-aes-key.pem create mode 100644 libnm-core/tests/certs/test-cert.p12 create mode 100644 libnm-core/tests/certs/test-key-only-decrypted.der create mode 100644 libnm-core/tests/certs/test-key-only-decrypted.pem create mode 100644 libnm-core/tests/certs/test-key-only.pem create mode 100644 libnm-core/tests/certs/test2-cert.p12 create mode 100644 libnm-core/tests/certs/test2_ca_cert.pem create mode 100644 libnm-core/tests/certs/test2_key_and_cert.pem create mode 100644 libnm-core/tests/certs/test_ca_cert.der create mode 100644 libnm-core/tests/certs/test_ca_cert.pem create mode 100644 libnm-core/tests/certs/test_key_and_cert.pem create mode 100644 libnm-core/tests/test-compare.c create mode 100644 libnm-core/tests/test-crypto.c create mode 100644 libnm-core/tests/test-general.c create mode 100644 libnm-core/tests/test-secrets.c create mode 100644 libnm-core/tests/test-setting-8021x.c create mode 100644 libnm-core/tests/test-setting-dcb.c create mode 100644 libnm-core/tests/test-settings-defaults.c create mode 100644 libnm-glib/tests/common.c create mode 100644 libnm-glib/tests/common.h create mode 100755 libnm-glib/tests/libnm-glib-test-launch.sh delete mode 100755 libnm-glib/tests/test-fake-nm.py delete mode 100755 libnm-glib/tests/test-remote-settings-service.py create mode 100644 libnm-util/NetworkManager.h create mode 100644 libnm-util/NetworkManagerVPN.h delete mode 100644 libnm-util/nm-utils-enum-types.h create mode 100644 libnm-util/nm-version.h.in delete mode 100644 libnm-util/tests/certs/Makefile.am delete mode 100644 libnm-util/tests/certs/Makefile.in delete mode 100644 libnm-util/tests/certs/ca-no-ending-newline.pem delete mode 100644 libnm-util/tests/certs/pkcs8-decrypted.der delete mode 100644 libnm-util/tests/certs/pkcs8-enc-key.pem delete mode 100644 libnm-util/tests/certs/pkcs8-noenc-key.pem delete mode 100644 libnm-util/tests/certs/test-aes-key.pem delete mode 100644 libnm-util/tests/certs/test-cert.p12 delete mode 100644 libnm-util/tests/certs/test-key-only-decrypted.der delete mode 100644 libnm-util/tests/certs/test-key-only.pem delete mode 100644 libnm-util/tests/certs/test2-cert.p12 delete mode 100644 libnm-util/tests/certs/test2_ca_cert.pem delete mode 100644 libnm-util/tests/certs/test2_key_and_cert.pem delete mode 100644 libnm-util/tests/certs/test_ca_cert.der delete mode 100644 libnm-util/tests/certs/test_ca_cert.pem delete mode 100644 libnm-util/tests/certs/test_key_and_cert.pem create mode 100644 libnm-util/tests/test-libnm-linking.c create mode 100644 libnm/Makefile.am create mode 100644 libnm/Makefile.in create mode 100644 libnm/NetworkManager.h create mode 100755 libnm/generate-plugin-docs.pl create mode 100755 libnm/generate-setting-docs.py create mode 100644 libnm/libnm.pc.in create mode 100644 libnm/libnm.ver create mode 100644 libnm/nm-access-point.c create mode 100644 libnm/nm-access-point.h create mode 100644 libnm/nm-active-connection.c create mode 100644 libnm/nm-active-connection.h create mode 100644 libnm/nm-client.c create mode 100644 libnm/nm-client.h create mode 100644 libnm/nm-dbus-helpers.c create mode 100644 libnm/nm-dbus-helpers.h create mode 100644 libnm/nm-device-adsl.c create mode 100644 libnm/nm-device-adsl.h create mode 100644 libnm/nm-device-bond.c create mode 100644 libnm/nm-device-bond.h create mode 100644 libnm/nm-device-bridge.c create mode 100644 libnm/nm-device-bridge.h create mode 100644 libnm/nm-device-bt.c create mode 100644 libnm/nm-device-bt.h create mode 100644 libnm/nm-device-ethernet.c create mode 100644 libnm/nm-device-ethernet.h create mode 100644 libnm/nm-device-generic.c create mode 100644 libnm/nm-device-generic.h create mode 100644 libnm/nm-device-infiniband.c create mode 100644 libnm/nm-device-infiniband.h create mode 100644 libnm/nm-device-modem.c create mode 100644 libnm/nm-device-modem.h create mode 100644 libnm/nm-device-olpc-mesh.c create mode 100644 libnm/nm-device-olpc-mesh.h create mode 100644 libnm/nm-device-private.h create mode 100644 libnm/nm-device-team.c create mode 100644 libnm/nm-device-team.h create mode 100644 libnm/nm-device-vlan.c create mode 100644 libnm/nm-device-vlan.h create mode 100644 libnm/nm-device-wifi.c create mode 100644 libnm/nm-device-wifi.h create mode 100644 libnm/nm-device-wimax.c create mode 100644 libnm/nm-device-wimax.h create mode 100644 libnm/nm-device.c create mode 100644 libnm/nm-device.h create mode 100644 libnm/nm-dhcp-config.c create mode 100644 libnm/nm-dhcp-config.h create mode 100644 libnm/nm-dhcp4-config.c create mode 100644 libnm/nm-dhcp4-config.h create mode 100644 libnm/nm-dhcp6-config.c create mode 100644 libnm/nm-dhcp6-config.h create mode 100644 libnm/nm-enum-types.c create mode 100644 libnm/nm-enum-types.h create mode 100644 libnm/nm-ifcfg-rh-docs.xml create mode 100644 libnm/nm-ip-config.c create mode 100644 libnm/nm-ip-config.h create mode 100644 libnm/nm-ip4-config.c create mode 100644 libnm/nm-ip4-config.h create mode 100644 libnm/nm-ip6-config.c create mode 100644 libnm/nm-ip6-config.h create mode 100644 libnm/nm-keyfile-docs.xml create mode 100644 libnm/nm-manager.c create mode 100644 libnm/nm-manager.h create mode 100644 libnm/nm-object-cache.c create mode 100644 libnm/nm-object-cache.h create mode 100644 libnm/nm-object-private.h create mode 100644 libnm/nm-object.c create mode 100644 libnm/nm-object.h create mode 100644 libnm/nm-property-docs.xml create mode 100644 libnm/nm-remote-connection-private.h create mode 100644 libnm/nm-remote-connection.c create mode 100644 libnm/nm-remote-connection.h create mode 100644 libnm/nm-remote-settings.c create mode 100644 libnm/nm-remote-settings.h create mode 100644 libnm/nm-secret-agent-old.c create mode 100644 libnm/nm-secret-agent-old.h create mode 100644 libnm/nm-setting-docs-overrides.xml create mode 100644 libnm/nm-setting-docs.xml create mode 100644 libnm/nm-types.h create mode 100644 libnm/nm-vpn-connection.c create mode 100644 libnm/nm-vpn-connection.h create mode 100644 libnm/nm-vpn-editor-plugin.c create mode 100644 libnm/nm-vpn-editor-plugin.h create mode 100644 libnm/nm-vpn-plugin-old.c create mode 100644 libnm/nm-vpn-plugin-old.h create mode 100644 libnm/nm-wimax-nsp.c create mode 100644 libnm/nm-wimax-nsp.h create mode 100644 libnm/tests/Makefile.am create mode 100644 libnm/tests/Makefile.in create mode 100644 libnm/tests/common.c create mode 100644 libnm/tests/common.h create mode 100755 libnm/tests/libnm-test-launch.sh create mode 100644 libnm/tests/test-nm-client.c create mode 100644 libnm/tests/test-remote-settings-client.c create mode 100644 libnm/tests/test-secret-agent.c create mode 100644 man/NetworkManager.conf.xml.in create mode 100644 man/nm-settings-ifcfg-rh.5 create mode 100644 man/nm-settings-ifcfg-rh.xml create mode 100644 man/nm-settings-ifcfg-rh.xsl create mode 100644 man/nm-settings-keyfile.5 create mode 100644 man/nm-settings-keyfile.xml create mode 100644 man/nm-settings-keyfile.xsl create mode 100644 man/nm-settings.xml create mode 100644 man/nm-settings.xsl create mode 100644 man/nmtui.1.in delete mode 100644 src/config/nm-config-device.c delete mode 100644 src/config/nm-config-device.h delete mode 100644 src/config/nm-config.c delete mode 100644 src/config/nm-config.h delete mode 100644 src/config/tests/Makefile.am delete mode 100644 src/config/tests/Makefile.in delete mode 100644 src/config/tests/NetworkManager.conf delete mode 100644 src/config/tests/bad.conf delete mode 100644 src/config/tests/conf.d/00-overrides.conf delete mode 100644 src/config/tests/conf.d/10-more.conf delete mode 100644 src/config/tests/conf.d/90-last.conf delete mode 100644 src/config/tests/nm-test-device.c delete mode 100644 src/config/tests/nm-test-device.h delete mode 100644 src/config/tests/test-config.c create mode 100644 src/devices/bluetooth/nm-bluez5-dun.c create mode 100644 src/devices/bluetooth/nm-bluez5-dun.h create mode 100644 src/devices/bluetooth/nm-bt-error.c create mode 100644 src/devices/bluetooth/nm-bt-error.h create mode 100644 src/devices/nm-device-ethernet-utils.c create mode 100644 src/devices/nm-device-ethernet-utils.h create mode 100644 src/devices/nm-device-logging.h delete mode 100644 src/devices/nm-device-team.c delete mode 100644 src/devices/nm-device-team.h create mode 100644 src/devices/team/Makefile.am create mode 100644 src/devices/team/Makefile.in create mode 100644 src/devices/team/exports.ver create mode 100644 src/devices/team/nm-device-team-glue.h create mode 100644 src/devices/team/nm-device-team.c create mode 100644 src/devices/team/nm-device-team.h create mode 100644 src/devices/team/nm-team-enum-types.c create mode 100644 src/devices/team/nm-team-enum-types.h create mode 100644 src/devices/team/nm-team-factory.c create mode 100644 src/devices/team/nm-team-factory.h delete mode 100644 src/devices/wwan/README delete mode 100644 src/devices/wwan/nm-modem-old-types.h delete mode 100644 src/devices/wwan/nm-modem-old.c delete mode 100644 src/devices/wwan/nm-modem-old.h create mode 100644 src/dhcp-manager/nm-dhcp-listener.c create mode 100644 src/dhcp-manager/nm-dhcp-listener.h create mode 100644 src/dhcp-manager/nm-dhcp-systemd.c create mode 100644 src/dhcp-manager/nm-dhcp-systemd.h create mode 100644 src/dhcp-manager/nm-dhcp-utils.c create mode 100644 src/dhcp-manager/nm-dhcp-utils.h create mode 100644 src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c create mode 100644 src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/async.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/fileio.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/fileio.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/list.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/macro.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/strv.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/strv.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/time-util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/time-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/utf8.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/utf8.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h create mode 100644 src/dhcp-manager/tests/test-dhcp-utils.c delete mode 100644 src/firewall-manager/nm-firewall-manager.c delete mode 100644 src/firewall-manager/nm-firewall-manager.h delete mode 100644 src/logging/nm-logging.c delete mode 100644 src/logging/nm-logging.h create mode 100644 src/main-utils.c create mode 100644 src/main-utils.h create mode 100644 src/nm-auth-manager.c create mode 100644 src/nm-auth-manager.h create mode 100644 src/nm-auth-utils.c create mode 100644 src/nm-auth-utils.h create mode 100644 src/nm-config.c create mode 100644 src/nm-config.h create mode 100644 src/nm-default-route-manager.c create mode 100644 src/nm-default-route-manager.h delete mode 100644 src/nm-device-team-glue.h create mode 100644 src/nm-firewall-manager.c create mode 100644 src/nm-firewall-manager.h create mode 100644 src/nm-iface-helper.c create mode 100644 src/nm-logging.c create mode 100644 src/nm-logging.h delete mode 100644 src/nm-manager-auth.c delete mode 100644 src/nm-manager-auth.h create mode 100644 src/nm-posix-signals.c create mode 100644 src/nm-posix-signals.h delete mode 100644 src/posix-signals/nm-posix-signals.c delete mode 100644 src/posix-signals/nm-posix-signals.h delete mode 100644 src/settings/nm-settings-error.c delete mode 100644 src/settings/nm-settings-error.h delete mode 100644 src/settings/nm-settings-utils.c delete mode 100644 src/settings/nm-settings-utils.h delete mode 100644 src/settings/plugins/example/errors.c create mode 100644 src/settings/plugins/ibft/Makefile.am create mode 100644 src/settings/plugins/ibft/Makefile.in create mode 100644 src/settings/plugins/ibft/nm-ibft-connection.c create mode 100644 src/settings/plugins/ibft/nm-ibft-connection.h create mode 100644 src/settings/plugins/ibft/plugin.c create mode 100644 src/settings/plugins/ibft/plugin.h create mode 100644 src/settings/plugins/ibft/reader.c create mode 100644 src/settings/plugins/ibft/reader.h create mode 100644 src/settings/plugins/ibft/tests/Makefile.am create mode 100644 src/settings/plugins/ibft/tests/Makefile.in create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns1 create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns2 create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-entry create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-gateway create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-ipaddr create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-record create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-dhcp create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-static create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-vlan create mode 100644 src/settings/plugins/ibft/tests/test-ibft.c delete mode 100644 src/settings/plugins/ifcfg-rh/errors.c delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-misc-variables create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-trailing-spaces create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch delete mode 100644 src/settings/plugins/ifnet/errors.c delete mode 100644 src/settings/plugins/ifnet/errors.h delete mode 100644 src/settings/plugins/keyfile/errors.c create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 delete mode 100644 src/settings/tests/Makefile.am delete mode 100644 src/settings/tests/Makefile.in delete mode 100644 src/settings/tests/test-wired-defname.c create mode 100644 src/tests/config/Makefile.am create mode 100644 src/tests/config/Makefile.in create mode 100644 src/tests/config/NetworkManager.conf create mode 100644 src/tests/config/bad.conf create mode 100644 src/tests/config/conf.d/00-overrides.conf create mode 100644 src/tests/config/conf.d/10-more.conf create mode 100644 src/tests/config/conf.d/90-last.conf create mode 100644 src/tests/config/nm-test-device.c create mode 100644 src/tests/config/nm-test-device.h create mode 100644 src/tests/config/test-config.c delete mode 100644 src/tests/test-dhcp-options.c create mode 100644 src/tests/test-general-with-expect.c create mode 100644 src/tests/test-wired-defname.c delete mode 100644 test/Makefile.am delete mode 100644 test/Makefile.in delete mode 100644 test/libnm-glib-test.c delete mode 100644 test/nm-online.c create mode 100755 tools/debug-helper.py delete mode 100644 tools/generate-settings-spec.c create mode 100755 tools/run-test-valgrind.sh create mode 100755 tools/test-networkmanager-service.py create mode 100755 tools/test-sudo-wrapper.sh delete mode 100644 tui/Makefile.am delete mode 100644 tui/Makefile.in delete mode 100644 tui/newt/Makefile.am delete mode 100644 tui/newt/Makefile.in delete mode 100644 tui/newt/nmt-newt-button-box.c delete mode 100644 tui/newt/nmt-newt-button-box.h delete mode 100644 tui/newt/nmt-newt-button.c delete mode 100644 tui/newt/nmt-newt-button.h delete mode 100644 tui/newt/nmt-newt-checkbox.c delete mode 100644 tui/newt/nmt-newt-checkbox.h delete mode 100644 tui/newt/nmt-newt-component.c delete mode 100644 tui/newt/nmt-newt-component.h delete mode 100644 tui/newt/nmt-newt-container.c delete mode 100644 tui/newt/nmt-newt-container.h delete mode 100644 tui/newt/nmt-newt-entry-numeric.c delete mode 100644 tui/newt/nmt-newt-entry-numeric.h delete mode 100644 tui/newt/nmt-newt-entry.c delete mode 100644 tui/newt/nmt-newt-entry.h delete mode 100644 tui/newt/nmt-newt-form.c delete mode 100644 tui/newt/nmt-newt-form.h delete mode 100644 tui/newt/nmt-newt-grid.c delete mode 100644 tui/newt/nmt-newt-grid.h delete mode 100644 tui/newt/nmt-newt-hacks.c delete mode 100644 tui/newt/nmt-newt-hacks.h delete mode 100644 tui/newt/nmt-newt-label.c delete mode 100644 tui/newt/nmt-newt-label.h delete mode 100644 tui/newt/nmt-newt-listbox.c delete mode 100644 tui/newt/nmt-newt-listbox.h delete mode 100644 tui/newt/nmt-newt-popup.c delete mode 100644 tui/newt/nmt-newt-popup.h delete mode 100644 tui/newt/nmt-newt-section.c delete mode 100644 tui/newt/nmt-newt-section.h delete mode 100644 tui/newt/nmt-newt-separator.c delete mode 100644 tui/newt/nmt-newt-separator.h delete mode 100644 tui/newt/nmt-newt-stack.c delete mode 100644 tui/newt/nmt-newt-stack.h delete mode 100644 tui/newt/nmt-newt-textbox.c delete mode 100644 tui/newt/nmt-newt-textbox.h delete mode 100644 tui/newt/nmt-newt-toggle-button.c delete mode 100644 tui/newt/nmt-newt-toggle-button.h delete mode 100644 tui/newt/nmt-newt-types.h delete mode 100644 tui/newt/nmt-newt-utils.c delete mode 100644 tui/newt/nmt-newt-utils.h delete mode 100644 tui/newt/nmt-newt-widget.c delete mode 100644 tui/newt/nmt-newt-widget.h delete mode 100644 tui/newt/nmt-newt.h delete mode 100644 tui/nm-editor-bindings.c delete mode 100644 tui/nm-editor-bindings.h delete mode 100644 tui/nm-editor-utils.c delete mode 100644 tui/nm-editor-utils.h delete mode 100644 tui/nmt-address-list.c delete mode 100644 tui/nmt-address-list.h delete mode 100644 tui/nmt-connect-connection-list.c delete mode 100644 tui/nmt-connect-connection-list.h delete mode 100644 tui/nmt-device-entry.c delete mode 100644 tui/nmt-device-entry.h delete mode 100644 tui/nmt-edit-connection-list.c delete mode 100644 tui/nmt-edit-connection-list.h delete mode 100644 tui/nmt-editor-page.c delete mode 100644 tui/nmt-editor-page.h delete mode 100644 tui/nmt-editor.c delete mode 100644 tui/nmt-editor.h delete mode 100644 tui/nmt-ip-entry.c delete mode 100644 tui/nmt-ip-entry.h delete mode 100644 tui/nmt-mac-entry.c delete mode 100644 tui/nmt-mac-entry.h delete mode 100644 tui/nmt-mtu-entry.c delete mode 100644 tui/nmt-mtu-entry.h delete mode 100644 tui/nmt-page-bond.c delete mode 100644 tui/nmt-page-bond.h delete mode 100644 tui/nmt-page-bridge-port.c delete mode 100644 tui/nmt-page-bridge-port.h delete mode 100644 tui/nmt-page-bridge.c delete mode 100644 tui/nmt-page-bridge.h delete mode 100644 tui/nmt-page-device.c delete mode 100644 tui/nmt-page-device.h delete mode 100644 tui/nmt-page-ethernet.c delete mode 100644 tui/nmt-page-ethernet.h delete mode 100644 tui/nmt-page-grid.c delete mode 100644 tui/nmt-page-grid.h delete mode 100644 tui/nmt-page-infiniband.c delete mode 100644 tui/nmt-page-infiniband.h delete mode 100644 tui/nmt-page-ip4.c delete mode 100644 tui/nmt-page-ip4.h delete mode 100644 tui/nmt-page-ip6.c delete mode 100644 tui/nmt-page-ip6.h delete mode 100644 tui/nmt-page-main.c delete mode 100644 tui/nmt-page-main.h delete mode 100644 tui/nmt-page-team-port.c delete mode 100644 tui/nmt-page-team-port.h delete mode 100644 tui/nmt-page-team.c delete mode 100644 tui/nmt-page-team.h delete mode 100644 tui/nmt-page-vlan.c delete mode 100644 tui/nmt-page-vlan.h delete mode 100644 tui/nmt-page-wifi.c delete mode 100644 tui/nmt-page-wifi.h delete mode 100644 tui/nmt-password-dialog.c delete mode 100644 tui/nmt-password-dialog.h delete mode 100644 tui/nmt-password-fields.c delete mode 100644 tui/nmt-password-fields.h delete mode 100644 tui/nmt-route-editor.c delete mode 100644 tui/nmt-route-editor.h delete mode 100644 tui/nmt-route-entry.c delete mode 100644 tui/nmt-route-entry.h delete mode 100644 tui/nmt-route-table.c delete mode 100644 tui/nmt-route-table.h delete mode 100644 tui/nmt-secret-agent.c delete mode 100644 tui/nmt-secret-agent.h delete mode 100644 tui/nmt-slave-list.c delete mode 100644 tui/nmt-slave-list.h delete mode 100644 tui/nmt-utils.c delete mode 100644 tui/nmt-utils.h delete mode 100644 tui/nmt-widget-list.c delete mode 100644 tui/nmt-widget-list.h delete mode 100644 tui/nmtui-connect.c delete mode 100644 tui/nmtui-connect.h delete mode 100644 tui/nmtui-edit.c delete mode 100644 tui/nmtui-edit.h delete mode 100644 tui/nmtui-hostname.c delete mode 100644 tui/nmtui-hostname.h delete mode 100644 tui/nmtui.c delete mode 100644 tui/nmtui.h diff --git a/Makefile.am b/Makefile.am index b41bfa90..18bb6c68 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,17 +3,17 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ include \ + introspection \ + libnm-core \ + libnm \ libnm-util \ libnm-glib \ - introspection \ src \ callouts \ - cli \ - tui \ + clients \ tools \ policy \ data \ - test \ po \ docs \ man \ @@ -44,6 +44,16 @@ DISTCHECK_CONFIGURE_FLAGS = \ --enable-ifupdown \ --enable-ifnet +if BUILD_SETTING_DOCS +dist-check-setting-docs: +else +dist-check-setting-docs: + @echo "*** gobject-introspection and pygobject are needed to run 'make dist'. ***" + @false +endif + +dist: dist-check-setting-docs + DISTCLEANFILES = intltool-extract intltool-merge intltool-update pkgconfigdir = $(libdir)/pkgconfig @@ -54,12 +64,6 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} CLEANFILES = cscope.in.out cscope.out cscope.po.out cscope: - cscope -b -q -R -Iinclude -ssrc -slibnm-glib -slibnm-util -scli/src; - -libgsystem_srcpath := libgsystem -libgsystem_cflags := $(filter-out -DGLIB_VERSION%,$(GLIB_CFLAGS)) -I$(srcdir)/libgsystem -libgsystem_libs = $(GLIB_LIBS) -include libgsystem/Makefile-libgsystem.am -noinst_LTLIBRARIES = libgsystem.la + cscope -b -q -R -Iinclude -ssrc -slibnm-core -slibnm -slibnm-glib -slibnm-util -sclients; .PHONY: cscope diff --git a/Makefile.in b/Makefile.in index fbbc632b..fb24b2e8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,24 +14,6 @@ @SET_MAKE@ -# Copyright (C) 2012 Colin Walters -# -# 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -96,10 +78,11 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -DIST_COMMON = $(srcdir)/libgsystem/Makefile-libgsystem.am INSTALL NEWS \ - README AUTHORS ChangeLog $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(srcdir)/config.h.in \ +subdir = . +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in \ $(top_srcdir)/initscript/RedHat/NetworkManager.in \ $(top_srcdir)/initscript/Debian/NetworkManager.in \ $(top_srcdir)/initscript/Slackware/rc.networkmanager.in \ @@ -107,11 +90,10 @@ DIST_COMMON = $(srcdir)/libgsystem/Makefile-libgsystem.am INSTALL NEWS \ $(top_srcdir)/initscript/Arch/networkmanager.in \ $(top_srcdir)/initscript/Mandriva/networkmanager.in \ $(top_srcdir)/initscript/linexa/networkmanager.in \ - $(srcdir)/NetworkManager.pc.in ABOUT-NLS \ - $(top_srcdir)/build-aux/depcomp COPYING TODO build-aux/compile \ - build-aux/config.guess build-aux/config.rpath \ - build-aux/config.sub build-aux/depcomp build-aux/install-sh \ - build-aux/missing build-aux/ltmain.sh \ + $(srcdir)/NetworkManager.pc.in ABOUT-NLS COPYING TODO \ + build-aux/compile build-aux/config.guess \ + build-aux/config.rpath build-aux/config.sub \ + build-aux/install-sh build-aux/missing build-aux/ltmain.sh \ $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.rpath \ @@ -119,7 +101,6 @@ DIST_COMMON = $(srcdir)/libgsystem/Makefile-libgsystem.am INSTALL NEWS \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing -subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -147,24 +128,6 @@ CONFIG_CLEAN_FILES = initscript/RedHat/NetworkManager \ initscript/Mandriva/networkmanager \ initscript/linexa/networkmanager NetworkManager.pc CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -libgsystem_la_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_libgsystem_la_OBJECTS = libgsystem_la-gsystem-local-alloc.lo \ - libgsystem_la-gsystem-console.lo \ - libgsystem_la-gsystem-file-utils.lo \ - libgsystem_la-gsystem-shutil.lo libgsystem_la-gsystem-log.lo \ - libgsystem_la-gsystem-subprocess-context.lo \ - libgsystem_la-gsystem-subprocess.lo -libgsystem_la_OBJECTS = $(am_libgsystem_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libgsystem_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgsystem_la_CFLAGS) \ - $(CFLAGS) $(libgsystem_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -177,30 +140,8 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -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_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -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_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libgsystem_la_SOURCES) -DIST_SOURCES = $(libgsystem_la_SOURCES) +SOURCES = +DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -324,6 +265,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -447,6 +390,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -466,6 +410,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -492,7 +437,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -574,27 +519,33 @@ with_valgrind = @with_valgrind@ SUBDIRS = \ . \ include \ + introspection \ + libnm-core \ + libnm \ libnm-util \ libnm-glib \ - introspection \ src \ callouts \ - cli \ - tui \ + clients \ tools \ policy \ data \ - test \ po \ docs \ man \ examples \ vapi -EXTRA_DIST = CONTRIBUTING NetworkManager.pc.in intltool-extract.in \ - intltool-merge.in intltool-update.in Makefile.glib autogen.sh \ - valgrind.suppressions $(libgsystem_srcpath)/README \ - $(libgsystem_srcpath)/COPYING +EXTRA_DIST = \ + CONTRIBUTING \ + NetworkManager.pc.in \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + Makefile.glib \ + autogen.sh \ + valgrind.suppressions + DISTCHECK_CONFIGURE_FLAGS = \ --enable-tests=yes \ --with-valgrind=no \ @@ -612,41 +563,13 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = NetworkManager.pc ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} CLEANFILES = cscope.in.out cscope.out cscope.po.out -libgsystem_srcpath := libgsystem -libgsystem_cflags := $(filter-out -DGLIB_VERSION%,$(GLIB_CFLAGS)) -I$(srcdir)/libgsystem -libgsystem_libs = $(GLIB_LIBS) -libgsystem_la_SOURCES = \ - $(libgsystem_srcpath)/gsystem-local-alloc.h \ - $(libgsystem_srcpath)/gsystem-local-alloc.c \ - $(libgsystem_srcpath)/gsystem-console.h \ - $(libgsystem_srcpath)/gsystem-console.c \ - $(libgsystem_srcpath)/gsystem-file-utils.h \ - $(libgsystem_srcpath)/gsystem-file-utils.c \ - $(libgsystem_srcpath)/gsystem-glib-compat.h \ - $(libgsystem_srcpath)/gsystem-shutil.h \ - $(libgsystem_srcpath)/gsystem-shutil.c \ - $(libgsystem_srcpath)/gsystem-log.h \ - $(libgsystem_srcpath)/gsystem-log.c \ - $(libgsystem_srcpath)/gsystem-subprocess-context.h \ - $(libgsystem_srcpath)/gsystem-subprocess-context-private.h \ - $(libgsystem_srcpath)/gsystem-subprocess-context.c \ - $(libgsystem_srcpath)/gsystem-subprocess.h \ - $(libgsystem_srcpath)/gsystem-subprocess.c \ - $(libgsystem_srcpath)/libgsystem.h \ - $(NULL) - -libgsystem_la_CFLAGS = $(AM_CFLAGS) $(libgsystem_cflags) -libgsystem_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^gs_" -no-undefined -export-dynamic -libgsystem_la_LIBADD = $(libgsystem_libs) -noinst_LTLIBRARIES = libgsystem.la all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: -.SUFFIXES: .c .lo .o .obj am--refresh: Makefile @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/libgsystem/Makefile-libgsystem.am $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -669,7 +592,6 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; -$(srcdir)/libgsystem/Makefile-libgsystem.am: $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -711,104 +633,6 @@ initscript/linexa/networkmanager: $(top_builddir)/config.status $(top_srcdir)/in NetworkManager.pc: $(top_builddir)/config.status $(srcdir)/NetworkManager.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libgsystem.la: $(libgsystem_la_OBJECTS) $(libgsystem_la_DEPENDENCIES) $(EXTRA_libgsystem_la_DEPENDENCIES) - $(AM_V_CCLD)$(libgsystem_la_LINK) $(libgsystem_la_OBJECTS) $(libgsystem_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-console.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-file-utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-local-alloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-log.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-shutil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-subprocess-context.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgsystem_la-gsystem-subprocess.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libgsystem_la-gsystem-local-alloc.lo: $(libgsystem_srcpath)/gsystem-local-alloc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-local-alloc.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-local-alloc.Tpo -c -o libgsystem_la-gsystem-local-alloc.lo `test -f '$(libgsystem_srcpath)/gsystem-local-alloc.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-local-alloc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-local-alloc.Tpo $(DEPDIR)/libgsystem_la-gsystem-local-alloc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-local-alloc.c' object='libgsystem_la-gsystem-local-alloc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-local-alloc.lo `test -f '$(libgsystem_srcpath)/gsystem-local-alloc.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-local-alloc.c - -libgsystem_la-gsystem-console.lo: $(libgsystem_srcpath)/gsystem-console.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-console.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-console.Tpo -c -o libgsystem_la-gsystem-console.lo `test -f '$(libgsystem_srcpath)/gsystem-console.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-console.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-console.Tpo $(DEPDIR)/libgsystem_la-gsystem-console.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-console.c' object='libgsystem_la-gsystem-console.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-console.lo `test -f '$(libgsystem_srcpath)/gsystem-console.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-console.c - -libgsystem_la-gsystem-file-utils.lo: $(libgsystem_srcpath)/gsystem-file-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-file-utils.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-file-utils.Tpo -c -o libgsystem_la-gsystem-file-utils.lo `test -f '$(libgsystem_srcpath)/gsystem-file-utils.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-file-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-file-utils.Tpo $(DEPDIR)/libgsystem_la-gsystem-file-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-file-utils.c' object='libgsystem_la-gsystem-file-utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-file-utils.lo `test -f '$(libgsystem_srcpath)/gsystem-file-utils.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-file-utils.c - -libgsystem_la-gsystem-shutil.lo: $(libgsystem_srcpath)/gsystem-shutil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-shutil.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-shutil.Tpo -c -o libgsystem_la-gsystem-shutil.lo `test -f '$(libgsystem_srcpath)/gsystem-shutil.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-shutil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-shutil.Tpo $(DEPDIR)/libgsystem_la-gsystem-shutil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-shutil.c' object='libgsystem_la-gsystem-shutil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-shutil.lo `test -f '$(libgsystem_srcpath)/gsystem-shutil.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-shutil.c - -libgsystem_la-gsystem-log.lo: $(libgsystem_srcpath)/gsystem-log.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-log.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-log.Tpo -c -o libgsystem_la-gsystem-log.lo `test -f '$(libgsystem_srcpath)/gsystem-log.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-log.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-log.Tpo $(DEPDIR)/libgsystem_la-gsystem-log.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-log.c' object='libgsystem_la-gsystem-log.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-log.lo `test -f '$(libgsystem_srcpath)/gsystem-log.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-log.c - -libgsystem_la-gsystem-subprocess-context.lo: $(libgsystem_srcpath)/gsystem-subprocess-context.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-subprocess-context.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-subprocess-context.Tpo -c -o libgsystem_la-gsystem-subprocess-context.lo `test -f '$(libgsystem_srcpath)/gsystem-subprocess-context.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-subprocess-context.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-subprocess-context.Tpo $(DEPDIR)/libgsystem_la-gsystem-subprocess-context.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-subprocess-context.c' object='libgsystem_la-gsystem-subprocess-context.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-subprocess-context.lo `test -f '$(libgsystem_srcpath)/gsystem-subprocess-context.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-subprocess-context.c - -libgsystem_la-gsystem-subprocess.lo: $(libgsystem_srcpath)/gsystem-subprocess.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -MT libgsystem_la-gsystem-subprocess.lo -MD -MP -MF $(DEPDIR)/libgsystem_la-gsystem-subprocess.Tpo -c -o libgsystem_la-gsystem-subprocess.lo `test -f '$(libgsystem_srcpath)/gsystem-subprocess.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-subprocess.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgsystem_la-gsystem-subprocess.Tpo $(DEPDIR)/libgsystem_la-gsystem-subprocess.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(libgsystem_srcpath)/gsystem-subprocess.c' object='libgsystem_la-gsystem-subprocess.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgsystem_la_CFLAGS) $(CFLAGS) -c -o libgsystem_la-gsystem-subprocess.lo `test -f '$(libgsystem_srcpath)/gsystem-subprocess.c' || echo '$(srcdir)/'`$(libgsystem_srcpath)/gsystem-subprocess.c - mostlyclean-libtool: -rm -f *.lo @@ -1124,7 +948,7 @@ distcleancheck: distclean exit 1; } >&2 check-am: all-am check: check-recursive -all-am: Makefile $(LTLIBRARIES) $(DATA) config.h +all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ @@ -1164,15 +988,13 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags dvi: dvi-recursive @@ -1217,14 +1039,12 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -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 +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive @@ -1240,28 +1060,34 @@ uninstall-am: uninstall-pkgconfigDATA .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscope cscopelist-am \ - ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \ - dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck 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-pkgconfigDATA 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-am uninstall uninstall-am uninstall-pkgconfigDATA + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck 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-pkgconfigDATA \ + 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-am uninstall \ + uninstall-am uninstall-pkgconfigDATA include $(GLIB_MAKEFILE) @GNOME_CODE_COVERAGE_RULES@ +@BUILD_SETTING_DOCS_TRUE@dist-check-setting-docs: +@BUILD_SETTING_DOCS_FALSE@dist-check-setting-docs: +@BUILD_SETTING_DOCS_FALSE@ @echo "*** gobject-introspection and pygobject are needed to run 'make dist'. ***" +@BUILD_SETTING_DOCS_FALSE@ @false + +dist: dist-check-setting-docs + cscope: - cscope -b -q -R -Iinclude -ssrc -slibnm-glib -slibnm-util -scli/src; + cscope -b -q -R -Iinclude -ssrc -slibnm-core -slibnm -slibnm-glib -slibnm-util -sclients; .PHONY: cscope diff --git a/NEWS b/NEWS index 6de29520..2de014eb 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,51 @@ +=============================================== +NetworkManager-1.0 +Overview of changes since NetworkManager-0.9.10 +=============================================== + +This is a new stable release of NetworkManager. Notable changes include: + +* A new 'libnm' GObject-based client library to replace libnm-util/libnm-glib + - IP address, IP route, hardware address, and other properties are now + represented as strings + - Based on GIO's GDBus bindings instead of dbus-glib + - Uses modern GObject APIs including GAsyncResult and GVariant + - For more information see https://wiki.gnome.org/Projects/NetworkManager/libnm +* Devices and VPN connections now have individual default routes. Priorities + are handled through configurable route metrics. +* nmcli now supports password requests and PolicyKit authorizations +* A faster, lighter-weight (though less capable) internal DHCP client has been + added and may be selected with the "dhcp=internal" option. It supports + fewer DHCP options and does not yet support DHCPv6. +* A new 'configure-and-quit=yes' option has been added for environments with + less dynamic network configuration +* When running on 3.17 and later kernels, NetworkManager handles IPv6LL address + assignment to ensure that IPv6 connectivity is not enabled until + intentionally configured by the user +* NetworkManager no longer causes the nl80211 kernel module to be loaded on + systems with no Wi-Fi devices +* Bluetooth DUN support now works with Bluez 5.x +* VPN connections can now persist across link changes and suspend/resume if + their VPN plugin supports this feature +* A new 'ibft' settings plugin has been added to support firmware-based + iBFT/iSCSI configurations. This functionality has been moved to 'ibft' + from the 'ifcfg-rh' plugin. +* IPv6 router advertisement MTUs are now respected +* NetworkManager no longer requires polkit libraries at runtime when Polkit + support is enabled, and Polkit can be disabled at build time too +* Automatically created connections are now deleted when their device goes away +* 'nmcli dev connect' now attemts to create a connection if none exists +* Manually configured static IPv6 configuration is kept even if SLAAC fails +* Manpages for the 'keyfile' and 'ifcfg-rh' plugins now describe their + configuration syntax and available options +* WWAN connections now support IPv6 if the modem and provider support IPv6 +* Software devices (bridge, bond, team, etc) can now be deleted from the D-Bus + API or with nmcli +* The manpages, documentation, and API annotations have received many cleanups +* Externally created virtual interfaces are no longer managed by NetworkManager + until they are set "up" or activated via nmcli + + ============================================== NetworkManager-0.9.10 Overview of changes since NetworkManager-0.9.8 @@ -52,8 +100,7 @@ This is a new stable release of NetworkManager. Notable changes include: * VPN connection IP details are now available via the D-Bus interface * VPN plugins can now request additional/new secrets from the user during the connection process -* 'veth' interfaces are now unmanaged by default to cooperate better with - external tools + ============================================== NetworkManager-0.9.8 diff --git a/autogen.sh b/autogen.sh index 1b56207a..141bcf12 100755 --- a/autogen.sh +++ b/autogen.sh @@ -22,13 +22,6 @@ PKG_NAME=NetworkManager cd $srcdir -# Fetch submodules if needed -if test -d $srcdir/.git; then - echo "+ Setting up submodules" - git submodule init - git submodule update -fi - gtkdocize autopoint --force AUTOPOINT='intltoolize --automake --copy' autoreconf --force --install --verbose diff --git a/build-aux/config.guess b/build-aux/config.guess index 1804e9fc..1f5c50c0 100755 --- a/build-aux/config.guess +++ b/build-aux/config.guess @@ -1,10 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright 1992-2014 Free Software Foundation, Inc. -timestamp='2012-12-29' +timestamp='2014-03-23' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -26,7 +24,7 @@ timestamp='2012-12-29' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD @@ -52,9 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -136,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in @@ -809,7 +826,7 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; - i*:MSYS*:*) + *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) @@ -857,21 +874,21 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -884,59 +901,54 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -955,54 +967,63 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1235,19 +1256,31 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) @@ -1338,154 +1371,6 @@ EOF exit ;; esac -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - cat >&2 <." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -256,12 +252,12 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc \ + | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ - | c4x | clipper \ + | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ @@ -269,6 +265,7 @@ case $basic_machine in | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ @@ -286,20 +283,22 @@ case $basic_machine in | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ - | open8 \ - | or32 \ + | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -327,7 +326,7 @@ case $basic_machine in c6x) basic_machine=tic6x-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; @@ -369,13 +368,13 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ @@ -384,6 +383,7 @@ case $basic_machine in | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ @@ -403,18 +403,22 @@ case $basic_machine in | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ + | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ @@ -796,7 +800,7 @@ case $basic_machine in os=-mingw64 ;; mingw32) - basic_machine=i386-pc + basic_machine=i686-pc os=-mingw32 ;; mingw32ce) @@ -824,6 +828,10 @@ case $basic_machine in basic_machine=powerpc-unknown os=-morphos ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; msdos) basic_machine=i386-pc os=-msdos @@ -832,7 +840,7 @@ case $basic_machine in basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) - basic_machine=i386-pc + basic_machine=i686-pc os=-msys ;; mvs) @@ -1354,7 +1362,7 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1369,14 +1377,14 @@ case $os in | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1500,9 +1508,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1551,6 +1556,9 @@ case $basic_machine in c4x-* | tic4x-*) os=-coff ;; + c8051-*) + os=-elf + ;; hexagon-*) os=-elf ;; diff --git a/callouts/Makefile.am b/callouts/Makefile.am index a8c9026f..f682579e 100644 --- a/callouts/Makefile.am +++ b/callouts/Makefile.am @@ -2,11 +2,11 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DNMCONFDIR=\"$(nmconfdir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ @@ -45,12 +45,31 @@ nm_dispatcher_SOURCES = \ nm-dispatcher-utils.h nm_dispatcher_LDADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ + $(top_builddir)/libnm/libnm.la \ + libnmdbus-dispatcher.la \ $(GLIB_LIBS) -nm-dispatcher-glue.h: nm-dispatcher.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_dispatcher --mode=glib-server --output=$@ $< +# See note about gdbus-codegen in introspection/Makefile.am + +noinst_LTLIBRARIES += libnmdbus-dispatcher.la + +nodist_libnmdbus_dispatcher_la_SOURCES = \ + nmdbus-dispatcher.c \ + nmdbus-dispatcher.h + +libnmdbus_dispatcher_la_CPPFLAGS = $(filter-out -DGLIB_VERSION_MAX_ALLOWED%,$(AM_CPPFLAGS)) + +nmdbus-dispatcher.h: nm-dispatcher.xml + $(AM_V_GEN) gdbus-codegen \ + --generate-c-code $(basename $@) \ + --c-namespace NMDBus \ + --interface-prefix org.freedesktop \ + $< + +nmdbus-dispatcher.c: nmdbus-dispatcher.h + @true + +BUILT_SOURCES = nmdbus-dispatcher.h nmdbus-dispatcher.c ########################################### # dispatcher envp @@ -64,13 +83,14 @@ libtest_dispatcher_envp_la_CPPFLAGS = \ $(AM_CPPFLAGS) libtest_dispatcher_envp_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) + $(top_builddir)/libnm/libnm.la \ + $(GLIB_LIBS) -udevrulesdir = $(UDEV_BASE_DIR)/rules.d +if WITH_UDEV_DIR +udevrulesdir = $(UDEV_DIR)/rules.d udevrules_DATA = 77-nm-olpc-mesh.rules +endif dbusactivationdir = $(datadir)/dbus-1/system-services dbusactivation_in_files = org.freedesktop.nm_dispatcher.service.in @@ -91,9 +111,7 @@ install-data-hook: $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-down.d $(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-up.d -BUILT_SOURCES = nm-dispatcher-glue.h - -CLEANFILES = $(BUILT_SOURCES) $(dbusactivation_DATA) +CLEANFILES = $(nodist_libnmdbus_dispatcher_la_SOURCES) $(dbusactivation_DATA) EXTRA_DIST = \ $(dbusservice_DATA) \ diff --git a/callouts/Makefile.in b/callouts/Makefile.in index 06abda44..83151fcc 100644 --- a/callouts/Makefile.in +++ b/callouts/Makefile.in @@ -106,18 +106,22 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) +libnmdbus_dispatcher_la_LIBADD = +nodist_libnmdbus_dispatcher_la_OBJECTS = \ + libnmdbus_dispatcher_la-nmdbus-dispatcher.lo +libnmdbus_dispatcher_la_OBJECTS = \ + $(nodist_libnmdbus_dispatcher_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = am__DEPENDENCIES_1 = libtest_dispatcher_envp_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(top_builddir)/libnm/libnm.la $(am__DEPENDENCIES_1) am_libtest_dispatcher_envp_la_OBJECTS = \ libtest_dispatcher_envp_la-nm-dispatcher-utils.lo libtest_dispatcher_envp_la_OBJECTS = \ $(am_libtest_dispatcher_envp_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = am__installdirs = "$(DESTDIR)$(libexecdir)" \ "$(DESTDIR)$(dbusactivationdir)" "$(DESTDIR)$(dbusservicedir)" \ "$(DESTDIR)$(udevrulesdir)" @@ -131,8 +135,8 @@ nm_avahi_autoipd_action_DEPENDENCIES = $(am__DEPENDENCIES_1) \ am_nm_dispatcher_OBJECTS = nm-dispatcher.$(OBJEXT) \ nm-dispatcher-utils.$(OBJEXT) nm_dispatcher_OBJECTS = $(am_nm_dispatcher_OBJECTS) -nm_dispatcher_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +nm_dispatcher_DEPENDENCIES = $(top_builddir)/libnm/libnm.la \ + libnmdbus-dispatcher.la $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -167,7 +171,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libtest_dispatcher_envp_la_SOURCES) \ +SOURCES = $(nodist_libnmdbus_dispatcher_la_SOURCES) \ + $(libtest_dispatcher_envp_la_SOURCES) \ $(nm_avahi_autoipd_action_SOURCES) $(nm_dispatcher_SOURCES) DIST_SOURCES = $(libtest_dispatcher_envp_la_SOURCES) \ $(nm_avahi_autoipd_action_SOURCES) $(nm_dispatcher_SOURCES) @@ -275,6 +280,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -398,6 +405,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -417,6 +425,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -443,7 +452,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -525,11 +534,11 @@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DNMCONFDIR=\"$(nmconfdir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ @@ -539,9 +548,10 @@ AM_CPPFLAGS = \ ########################################### # Test libraries ########################################### -noinst_LTLIBRARIES = \ - libtest-dispatcher-envp.la +# See note about gdbus-codegen in introspection/Makefile.am +noinst_LTLIBRARIES = libtest-dispatcher-envp.la \ + libnmdbus-dispatcher.la dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = \ nm-dispatcher.conf \ @@ -561,10 +571,16 @@ nm_dispatcher_SOURCES = \ nm-dispatcher-utils.h nm_dispatcher_LDADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ + $(top_builddir)/libnm/libnm.la \ + libnmdbus-dispatcher.la \ $(GLIB_LIBS) +nodist_libnmdbus_dispatcher_la_SOURCES = \ + nmdbus-dispatcher.c \ + nmdbus-dispatcher.h + +libnmdbus_dispatcher_la_CPPFLAGS = $(filter-out -DGLIB_VERSION_MAX_ALLOWED%,$(AM_CPPFLAGS)) +BUILT_SOURCES = nmdbus-dispatcher.h nmdbus-dispatcher.c ########################################### # dispatcher envp @@ -577,12 +593,11 @@ libtest_dispatcher_envp_la_CPPFLAGS = \ $(AM_CPPFLAGS) libtest_dispatcher_envp_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) + $(top_builddir)/libnm/libnm.la \ + $(GLIB_LIBS) -udevrulesdir = $(UDEV_BASE_DIR)/rules.d -udevrules_DATA = 77-nm-olpc-mesh.rules +@WITH_UDEV_DIR_TRUE@udevrulesdir = $(UDEV_DIR)/rules.d +@WITH_UDEV_DIR_TRUE@udevrules_DATA = 77-nm-olpc-mesh.rules dbusactivationdir = $(datadir)/dbus-1/system-services dbusactivation_in_files = org.freedesktop.nm_dispatcher.service.in dbusactivation_DATA = $(dbusactivation_in_files:.service.in=.service) @@ -593,8 +608,7 @@ edit = @sed \ -e 's|@libexecdir[@]|$(libexecdir)|g' dispatcherdir = $(sysconfdir)/NetworkManager/dispatcher.d -BUILT_SOURCES = nm-dispatcher-glue.h -CLEANFILES = $(BUILT_SOURCES) $(dbusactivation_DATA) +CLEANFILES = $(nodist_libnmdbus_dispatcher_la_SOURCES) $(dbusactivation_DATA) EXTRA_DIST = \ $(dbusservice_DATA) \ $(udevrules_DATA) \ @@ -648,6 +662,9 @@ clean-noinstLTLIBRARIES: rm -f $${locs}; \ } +libnmdbus-dispatcher.la: $(libnmdbus_dispatcher_la_OBJECTS) $(libnmdbus_dispatcher_la_DEPENDENCIES) $(EXTRA_libnmdbus_dispatcher_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libnmdbus_dispatcher_la_OBJECTS) $(libnmdbus_dispatcher_la_LIBADD) $(LIBS) + libtest-dispatcher-envp.la: $(libtest_dispatcher_envp_la_OBJECTS) $(libtest_dispatcher_envp_la_DEPENDENCIES) $(EXTRA_libtest_dispatcher_envp_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtest_dispatcher_envp_la_OBJECTS) $(libtest_dispatcher_envp_la_LIBADD) $(LIBS) install-libexecPROGRAMS: $(libexec_PROGRAMS) @@ -714,6 +731,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnmdbus_dispatcher_la-nmdbus-dispatcher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dispatcher_envp_la-nm-dispatcher-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-avahi-autoipd-action.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dispatcher-utils.Po@am__quote@ @@ -740,6 +758,13 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +libnmdbus_dispatcher_la-nmdbus-dispatcher.lo: nmdbus-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnmdbus_dispatcher_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnmdbus_dispatcher_la-nmdbus-dispatcher.lo -MD -MP -MF $(DEPDIR)/libnmdbus_dispatcher_la-nmdbus-dispatcher.Tpo -c -o libnmdbus_dispatcher_la-nmdbus-dispatcher.lo `test -f 'nmdbus-dispatcher.c' || echo '$(srcdir)/'`nmdbus-dispatcher.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnmdbus_dispatcher_la-nmdbus-dispatcher.Tpo $(DEPDIR)/libnmdbus_dispatcher_la-nmdbus-dispatcher.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nmdbus-dispatcher.c' object='libnmdbus_dispatcher_la-nmdbus-dispatcher.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnmdbus_dispatcher_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnmdbus_dispatcher_la-nmdbus-dispatcher.lo `test -f 'nmdbus-dispatcher.c' || echo '$(srcdir)/'`nmdbus-dispatcher.c + libtest_dispatcher_envp_la-nm-dispatcher-utils.lo: nm-dispatcher-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_dispatcher_envp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtest_dispatcher_envp_la-nm-dispatcher-utils.lo -MD -MP -MF $(DEPDIR)/libtest_dispatcher_envp_la-nm-dispatcher-utils.Tpo -c -o libtest_dispatcher_envp_la-nm-dispatcher-utils.lo `test -f 'nm-dispatcher-utils.c' || echo '$(srcdir)/'`nm-dispatcher-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtest_dispatcher_envp_la-nm-dispatcher-utils.Tpo $(DEPDIR)/libtest_dispatcher_envp_la-nm-dispatcher-utils.Plo @@ -1109,8 +1134,15 @@ uninstall-am: uninstall-dbusactivationDATA uninstall-dbusserviceDATA \ uninstall-libexecPROGRAMS uninstall-udevrulesDATA -nm-dispatcher-glue.h: nm-dispatcher.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_dispatcher --mode=glib-server --output=$@ $< +nmdbus-dispatcher.h: nm-dispatcher.xml + $(AM_V_GEN) gdbus-codegen \ + --generate-c-code $(basename $@) \ + --c-namespace NMDBus \ + --interface-prefix org.freedesktop \ + $< + +nmdbus-dispatcher.c: nmdbus-dispatcher.h + @true %.service: %.service.in $(edit) $< >$@ diff --git a/callouts/nm-avahi-autoipd-action.c b/callouts/nm-avahi-autoipd-action.c index f84eed71..b28dae5d 100644 --- a/callouts/nm-avahi-autoipd-action.c +++ b/callouts/nm-avahi-autoipd-action.c @@ -15,87 +15,50 @@ * 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 Red Hat, Inc. + * Copyright 2008, 2014 Red Hat, Inc. */ -#include -#include +#include "config.h" + #include #include -#include -#include -#include -#include +#include -#define NM_AVAHI_AUTOIPD_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" -#define NM_AVAHI_AUTOIPD_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" +#define NM_AVAHI_AUTOIPD_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" +#define NM_AVAHI_AUTOIPD_DBUS_INTERFACE "org.freedesktop.nm_avahi_autoipd" -static DBusConnection * -dbus_init (void) +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer loop) { - DBusConnection * connection; - DBusError error; - int ret; - - dbus_connection_set_change_sigpipe (TRUE); - - dbus_error_init (&error); - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (dbus_error_is_set (&error)) { - fprintf (stderr, "Error: could not get the system bus. Make sure " - "the message bus daemon is running! Message: (%s) %s\n", - error.name, - error.message); - goto error; - } - - dbus_connection_set_exit_on_disconnect (connection, FALSE); - - dbus_error_init (&error); - ret = dbus_bus_request_name (connection, - NM_AVAHI_AUTOIPD_DBUS_SERVICE, - DBUS_NAME_FLAG_DO_NOT_QUEUE, - &error); - if (dbus_error_is_set (&error)) { - fprintf (stderr, "Error: Could not acquire the NM DHCP client service. " - "Message: (%s) %s\n", - error.name, - error.message); - goto error; - } - - if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - fprintf (stderr, "Error: Could not acquire the NM DHCP client service " - "as it is already taken. Return: %d\n", - ret); - goto error; - } - - return connection; + g_main_loop_quit (loop); +} -error: - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - if (connection) - dbus_connection_unref (connection); - return NULL; +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + g_printerr ("Error: Could not acquire the NM autoipd service."); + exit (1); } int main (int argc, char *argv[]) { - DBusConnection *connection; - DBusMessage *message; - dbus_bool_t result; + GDBusConnection *connection; char *event, *iface, *address; + GMainLoop *loop; + GError *error = NULL; #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); #endif if (argc != 4) { - fprintf (stderr, "Error: expected 3 arguments (event, interface, address).\n"); + g_printerr ("Error: expected 3 arguments (event, interface, address).\n"); exit (1); } @@ -104,41 +67,60 @@ main (int argc, char *argv[]) address = argv[3] ? argv[3] : ""; if (!event || !iface || !strlen (event) || !strlen (iface)) { - fprintf (stderr, "Error: unexpected arguments received from avahi-autoipd.\n"); + g_printerr ("Error: unexpected arguments received from avahi-autoipd.\n"); exit (1); } /* Get a connection to the system bus */ - connection = dbus_init (); - if (connection == NULL) - exit (1); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (error) { + char *remote_error = g_dbus_error_get_remote_error (error); - message = dbus_message_new_signal ("/", NM_AVAHI_AUTOIPD_DBUS_IFACE, "Event"); - if (message == NULL) { - fprintf (stderr, "Error: not enough memory to send autoip Event signal.\n"); - exit (1); + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: could not get the system bus. Make sure " + "the message bus daemon is running! Message: (%s) %s\n", + remote_error, error->message); + g_free (remote_error); + g_error_free (error); + return 1; } - if (!dbus_message_append_args (message, - DBUS_TYPE_STRING, &event, - DBUS_TYPE_STRING, &iface, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) { - fprintf (stderr, "Error: failed to construct autoip Event signal.\n"); - exit (1); + /* Acquire the bus name */ + loop = g_main_loop_new (NULL, FALSE); + g_bus_own_name_on_connection (connection, + NM_AVAHI_AUTOIPD_DBUS_SERVICE, + 0, + on_name_acquired, + on_name_lost, + loop, NULL); + g_main_loop_run (loop); + g_main_loop_unref (loop); + + /* Send the signal */ + if (!g_dbus_connection_emit_signal (connection, + NULL, + "/", + NM_AVAHI_AUTOIPD_DBUS_INTERFACE, + "Event", + g_variant_new ("(sss)", + event, + iface, + address), + &error)) { + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: Could not send autoipd Event signal: %s\n", error->message); + g_error_free (error); + return 1; } - /* queue the message */ - result = dbus_connection_send (connection, message, NULL); - if (!result) { - fprintf (stderr, "Error: could not send send autoip Event signal.\n"); - exit (1); + if (!g_dbus_connection_flush_sync (connection, NULL, &error)) { + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: Could not flush D-Bus connection: %s\n", error->message); + g_error_free (error); + return 1; } - dbus_message_unref (message); - - /* Send out the message */ - dbus_connection_flush (connection); + g_object_unref (connection); return 0; } diff --git a/callouts/nm-dispatcher-api.h b/callouts/nm-dispatcher-api.h index 03e40f77..df1bced4 100644 --- a/callouts/nm-dispatcher-api.h +++ b/callouts/nm-dispatcher-api.h @@ -18,19 +18,17 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#include - #define NMD_SCRIPT_DIR_DEFAULT NMCONFDIR "/dispatcher.d" #define NMD_SCRIPT_DIR_PRE_UP NMD_SCRIPT_DIR_DEFAULT "/pre-up.d" #define NMD_SCRIPT_DIR_PRE_DOWN NMD_SCRIPT_DIR_DEFAULT "/pre-down.d" -/* dbus-glib types for dispatcher call return value */ +/* dbus-glib types for dispatcher call return value (used by src/nm-dispatcher.c) */ #define DISPATCHER_TYPE_RESULT (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID)) #define DISPATCHER_TYPE_RESULT_ARRAY (dbus_g_type_get_collection ("GPtrArray", DISPATCHER_TYPE_RESULT)) -#define NM_DISPATCHER_DBUS_SERVICE "org.freedesktop.nm_dispatcher" -#define NM_DISPATCHER_DBUS_IFACE "org.freedesktop.nm_dispatcher" -#define NM_DISPATCHER_DBUS_PATH "/org/freedesktop/nm_dispatcher" +#define NM_DISPATCHER_DBUS_SERVICE "org.freedesktop.nm_dispatcher" +#define NM_DISPATCHER_DBUS_INTERFACE "org.freedesktop.nm_dispatcher" +#define NM_DISPATCHER_DBUS_PATH "/org/freedesktop/nm_dispatcher" #define NMD_CONNECTION_PROPS_PATH "path" diff --git a/callouts/nm-dispatcher-utils.c b/callouts/nm-dispatcher-utils.c index b1d11daf..99616c1a 100644 --- a/callouts/nm-dispatcher-utils.c +++ b/callouts/nm-dispatcher-utils.c @@ -18,13 +18,13 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include -#include -#include +#include #include #include #include @@ -53,51 +53,62 @@ construct_basic_items (GSList *list, return list; } +static GSList *_list_append_val_strv (GSList *items, char **values, const char *format, ...) G_GNUC_PRINTF(3, 4); + +static GSList * +_list_append_val_strv (GSList *items, char **values, const char *format, ...) +{ + if (!values) + g_return_val_if_reached (items); + + /* Only add an item if the list of @values is not empty */ + if (values[0]) { + va_list args; + guint i; + GString *str = g_string_new (NULL); + + va_start (args, format); + g_string_append_vprintf (str, format, args); + va_end (args); + + g_string_append (str, values[0]); + for (i = 1; values[i]; i++) { + g_string_append_c (str, ' '); + g_string_append (str, values[i]); + } + items = g_slist_prepend (items, g_string_free (str, FALSE)); + } + + /* we take ownership of the values array and free it. */ + g_strfreev (values); + return items; +} + static GSList * add_domains (GSList *items, - GHashTable *hash, + GVariant *dict, const char *prefix, const char four_or_six) { - GValue *val; - char **domains = NULL; - GString *tmp; - guint i; + GVariant *val; /* Search domains */ - val = g_hash_table_lookup (hash, "domains"); - if (!val) - return items; - - g_return_val_if_fail (G_VALUE_HOLDS (val, G_TYPE_STRV), items); - - domains = (char **) g_value_get_boxed (val); - if (!domains || !domains[0]) - return items; - - tmp = g_string_new (NULL); - g_string_append_printf (tmp, "%sIP%c_DOMAINS=", prefix, four_or_six); - for (i = 0; domains[i]; i++) { - if (i > 0) - g_string_append_c (tmp, ' '); - g_string_append (tmp, domains[i]); + val = g_variant_lookup_value (dict, "domains", G_VARIANT_TYPE_STRING_ARRAY); + if (val) { + items = _list_append_val_strv (items, g_variant_dup_strv (val, NULL), + "%sIP%c_DOMAINS=", prefix, four_or_six); + g_variant_unref (val); } - items = g_slist_prepend (items, tmp->str); - g_string_free (tmp, FALSE); - return items; } static GSList * -construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix) +construct_ip4_items (GSList *items, GVariant *ip4_config, const char *prefix) { - GSList *addresses = NULL, *routes = NULL, *iter; - GArray *dns = NULL, *wins = NULL; - guint32 num, i; - GString *tmp; - GValue *val; - char str_addr[INET_ADDRSTRLEN]; - char str_gw[INET_ADDRSTRLEN]; + GPtrArray *addresses, *routes; + char *gateway; + GVariant *val; + int i; if (ip4_config == NULL) return items; @@ -106,114 +117,97 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix) prefix = ""; /* IP addresses */ - val = g_hash_table_lookup (ip4_config, "addresses"); - if (val) - addresses = nm_utils_ip4_addresses_from_gvalue (val); - - for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - guint32 ip_prefix = nm_ip4_address_get_prefix (addr); - char *addrtmp; + val = g_variant_lookup_value (ip4_config, "addresses", G_VARIANT_TYPE ("aau")); + if (val) { + addresses = nm_utils_ip4_addresses_from_variant (val, &gateway); + if (!gateway) + gateway = g_strdup ("0.0.0.0"); + + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + char *addrtmp; + + addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, i, + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr), + gateway); + items = g_slist_prepend (items, addrtmp); + } + if (addresses->len) + items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, addresses->len)); - nm_utils_inet4_ntop (nm_ip4_address_get_address (addr), str_addr); - nm_utils_inet4_ntop (nm_ip4_address_get_gateway (addr), str_gw); + /* Write gateway to a separate variable, too. */ + items = g_slist_prepend (items, g_strdup_printf ("%sIP4_GATEWAY=%s", prefix, gateway)); - addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw); - items = g_slist_prepend (items, addrtmp); + g_ptr_array_unref (addresses); + g_free (gateway); + g_variant_unref (val); } - if (num) - items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, num)); - if (addresses) - g_slist_free_full (addresses, (GDestroyNotify) nm_ip4_address_unref); /* DNS servers */ - val = g_hash_table_lookup (ip4_config, "nameservers"); - if (val && G_VALUE_HOLDS (val, DBUS_TYPE_G_UINT_ARRAY)) - dns = (GArray *) g_value_get_boxed (val); - - if (dns && (dns->len > 0)) { - gboolean first = TRUE; - - tmp = g_string_new (NULL); - g_string_append_printf (tmp, "%sIP4_NAMESERVERS=", prefix); - for (i = 0; i < dns->len; i++) { - guint32 addr; - - addr = g_array_index (dns, guint32, i); - if (!first) - g_string_append_c (tmp, ' '); - g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL)); - first = FALSE; - } - items = g_slist_prepend (items, tmp->str); - g_string_free (tmp, FALSE); + val = g_variant_lookup_value (ip4_config, "nameservers", G_VARIANT_TYPE ("au")); + if (val) { + items = _list_append_val_strv (items, nm_utils_ip4_dns_from_variant (val), + "%sIP4_NAMESERVERS=", prefix); + g_variant_unref (val); } /* Search domains */ items = add_domains (items, ip4_config, prefix, '4'); /* WINS servers */ - val = g_hash_table_lookup (ip4_config, "wins-servers"); - if (val && G_VALUE_HOLDS (val, DBUS_TYPE_G_UINT_ARRAY)) - wins = (GArray *) g_value_get_boxed (val); - - if (wins && wins->len) { - gboolean first = TRUE; - - tmp = g_string_new (NULL); - g_string_append_printf (tmp, "%sIP4_WINS_SERVERS=", prefix); - for (i = 0; i < wins->len; i++) { - guint32 addr; - - addr = g_array_index (wins, guint32, i); - if (!first) - g_string_append_c (tmp, ' '); - g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL)); - first = FALSE; - } - items = g_slist_prepend (items, tmp->str); - g_string_free (tmp, FALSE); + val = g_variant_lookup_value (ip4_config, "wins-servers", G_VARIANT_TYPE ("au")); + if (val) { + items = _list_append_val_strv (items, nm_utils_ip4_dns_from_variant (val), + "%sIP4_WINS_SERVERS=", prefix); + g_variant_unref (val); } /* Static routes */ - val = g_hash_table_lookup (ip4_config, "routes"); - if (val) - routes = nm_utils_ip4_routes_from_gvalue (val); - - for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) { - NMIP4Route *route = (NMIP4Route *) iter->data; - guint32 ip_prefix = nm_ip4_route_get_prefix (route); - guint32 metric = nm_ip4_route_get_metric (route); - char *routetmp; - - nm_utils_inet4_ntop (nm_ip4_route_get_dest (route), str_addr); - nm_utils_inet4_ntop (nm_ip4_route_get_next_hop (route), str_gw); - - routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric); - items = g_slist_prepend (items, routetmp); - } - items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, num)); - if (routes) - g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref); + val = g_variant_lookup_value (ip4_config, "routes", G_VARIANT_TYPE ("aau")); + if (val) { + routes = nm_utils_ip4_routes_from_variant (val); + + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + const char *next_hop; + char *routetmp; + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "0.0.0.0"; + + routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %u", prefix, i, + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop, + (guint32) MAX (0, nm_ip_route_get_metric (route))); + items = g_slist_prepend (items, routetmp); + } + items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, routes->len)); + g_ptr_array_unref (routes); + g_variant_unref (val); + } else + items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=0", prefix)); return items; } static GSList * -construct_device_dhcp4_items (GSList *items, GHashTable *dhcp4_config) +construct_device_dhcp4_items (GSList *items, GVariant *dhcp4_config) { - GHashTableIter iter; + GVariantIter iter; const char *key, *tmp; - GValue *val; + GVariant *val; char *ucased; if (dhcp4_config == NULL) return items; - g_hash_table_iter_init (&iter, dhcp4_config); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) { + g_variant_iter_init (&iter, dhcp4_config); + while (g_variant_iter_next (&iter, "{&sv}", &key, &val)) { ucased = g_ascii_strup (key, -1); - tmp = g_value_get_string (val); + tmp = g_variant_get_string (val, NULL); items = g_slist_prepend (items, g_strdup_printf ("DHCP4_%s=%s", ucased, tmp)); g_free (ucased); } @@ -221,14 +215,12 @@ construct_device_dhcp4_items (GSList *items, GHashTable *dhcp4_config) } static GSList * -construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix) +construct_ip6_items (GSList *items, GVariant *ip6_config, const char *prefix) { - GSList *addresses = NULL, *routes = NULL, *dns = NULL, *iter; - guint32 num; - GString *tmp; - GValue *val; - char str_addr[INET6_ADDRSTRLEN]; - char str_gw[INET6_ADDRSTRLEN]; + GPtrArray *addresses, *routes; + char *gateway = NULL; + GVariant *val; + int i; if (ip6_config == NULL) return items; @@ -237,93 +229,89 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix) prefix = ""; /* IP addresses */ - val = g_hash_table_lookup (ip6_config, "addresses"); - if (val) - addresses = nm_utils_ip6_addresses_from_gvalue (val); - - for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) { - NMIP6Address *addr = (NMIP6Address *) iter->data; - guint32 ip_prefix = nm_ip6_address_get_prefix (addr); - char *addrtmp; + val = g_variant_lookup_value (ip6_config, "addresses", G_VARIANT_TYPE ("a(ayuay)")); + if (val) { + addresses = nm_utils_ip6_addresses_from_variant (val, &gateway); + if (!gateway) + gateway = g_strdup ("::"); + + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + char *addrtmp; + + addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, i, + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr), + gateway); + items = g_slist_prepend (items, addrtmp); + } + if (addresses->len) + items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, addresses->len)); - nm_utils_inet6_ntop (nm_ip6_address_get_address (addr), str_addr); - nm_utils_inet6_ntop (nm_ip6_address_get_gateway (addr), str_gw); + /* Write gateway to a separate variable, too. */ + items = g_slist_prepend (items, g_strdup_printf ("%sIP6_GATEWAY=%s", prefix, gateway)); - addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw); - items = g_slist_prepend (items, addrtmp); + g_ptr_array_unref (addresses); + g_free (gateway); + g_variant_unref (val); } - if (num) - items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, num)); - if (addresses) - g_slist_free_full (addresses, (GDestroyNotify) nm_ip6_address_unref); /* DNS servers */ - val = g_hash_table_lookup (ip6_config, "nameservers"); - if (val) - dns = nm_utils_ip6_dns_from_gvalue (val); - - if (g_slist_length (dns)) { - gboolean first = TRUE; - - tmp = g_string_new (NULL); - g_string_append_printf (tmp, "%sIP6_NAMESERVERS=", prefix); - - for (iter = dns; iter; iter = g_slist_next (iter)) { - const struct in6_addr *addr = iter->data; - - if (!first) - g_string_append_c (tmp, ' '); - g_string_append (tmp, nm_utils_inet6_ntop (addr, NULL)); - first = FALSE; - } - - items = g_slist_prepend (items, tmp->str); - g_string_free (tmp, FALSE); + val = g_variant_lookup_value (ip6_config, "nameservers", G_VARIANT_TYPE ("aay")); + if (val) { + items = _list_append_val_strv (items, nm_utils_ip6_dns_from_variant (val), + "%sIP6_NAMESERVERS=", prefix); + g_variant_unref (val); } /* Search domains */ items = add_domains (items, ip6_config, prefix, '6'); /* Static routes */ - val = g_hash_table_lookup (ip6_config, "routes"); - if (val) - routes = nm_utils_ip6_routes_from_gvalue (val); - - for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) { - NMIP6Route *route = (NMIP6Route *) iter->data; - guint32 ip_prefix = nm_ip6_route_get_prefix (route); - guint32 metric = nm_ip6_route_get_metric (route); - char *routetmp; - - nm_utils_inet6_ntop (nm_ip6_route_get_dest (route), str_addr); - nm_utils_inet6_ntop (nm_ip6_route_get_next_hop (route), str_gw); - - routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric); - items = g_slist_prepend (items, routetmp); + val = g_variant_lookup_value (ip6_config, "routes", G_VARIANT_TYPE ("a(ayuayu)")); + if (val) { + routes = nm_utils_ip6_routes_from_variant (val); + + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + const char *next_hop; + char *routetmp; + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "::"; + + routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %u", prefix, i, + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop, + (guint32) MAX (0, nm_ip_route_get_metric (route))); + items = g_slist_prepend (items, routetmp); + } + if (routes->len) + items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, routes->len)); + g_ptr_array_unref (routes); + g_variant_unref (val); } - if (num) - items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, num)); - if (routes) - g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref); return items; } static GSList * -construct_device_dhcp6_items (GSList *items, GHashTable *dhcp6_config) +construct_device_dhcp6_items (GSList *items, GVariant *dhcp6_config) { - GHashTableIter iter; + GVariantIter iter; const char *key, *tmp; - GValue *val; + GVariant *val; char *ucased; if (dhcp6_config == NULL) return items; - g_hash_table_iter_init (&iter, dhcp6_config); - while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) { + g_variant_iter_init (&iter, dhcp6_config); + while (g_variant_iter_next (&iter, "{&sv}", &key, &val)) { ucased = g_ascii_strup (key, -1); - tmp = g_value_get_string (val); + tmp = g_variant_get_string (val, NULL); items = g_slist_prepend (items, g_strdup_printf ("DHCP6_%s=%s", ucased, tmp)); g_free (ucased); } @@ -332,26 +320,26 @@ construct_device_dhcp6_items (GSList *items, GHashTable *dhcp6_config) char ** nm_dispatcher_utils_construct_envp (const char *action, - GHashTable *connection_hash, - GHashTable *connection_props, - GHashTable *device_props, - GHashTable *device_ip4_props, - GHashTable *device_ip6_props, - GHashTable *device_dhcp4_props, - GHashTable *device_dhcp6_props, + GVariant *connection_dict, + GVariant *connection_props, + GVariant *device_props, + GVariant *device_ip4_props, + GVariant *device_ip6_props, + GVariant *device_dhcp4_props, + GVariant *device_dhcp6_props, const char *vpn_ip_iface, - GHashTable *vpn_ip4_props, - GHashTable *vpn_ip6_props, + GVariant *vpn_ip4_props, + GVariant *vpn_ip6_props, char **out_iface) { const char *iface = NULL, *ip_iface = NULL; const char *uuid = NULL, *id = NULL, *path; NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN; - GValue *value; + GVariant *value; char **envp = NULL, *path_item; GSList *items = NULL, *iter; guint i; - GHashTable *con_setting_hash; + GVariant *con_setting; g_return_val_if_fail (action != NULL, NULL); g_return_val_if_fail (out_iface != NULL, NULL); @@ -367,69 +355,67 @@ nm_dispatcher_utils_construct_envp (const char *action, if (vpn_ip_iface && !strlen (vpn_ip_iface)) vpn_ip_iface = NULL; - con_setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_CONNECTION_SETTING_NAME); - if (!con_setting_hash) { - g_warning ("Failed to read connection setting"); - return NULL; - } - - value = g_hash_table_lookup (con_setting_hash, NM_SETTING_CONNECTION_UUID); - if (!value || !G_VALUE_HOLDS (value, G_TYPE_STRING)) { - g_warning ("Connection hash did not contain the UUID"); - return NULL; - } - uuid = g_value_get_string (value); - - value = g_hash_table_lookup (con_setting_hash, NM_SETTING_CONNECTION_ID); - if (!value || !G_VALUE_HOLDS (value, G_TYPE_STRING)) { - g_warning ("Connection hash did not contain the ID"); - return NULL; - } - id = g_value_get_string (value); - /* interface name */ - value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE); - if (!value || !G_VALUE_HOLDS_STRING (value)) { + if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE, "&s", &iface)) { g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_INTERFACE "!"); return NULL; } - iface = g_value_get_string (value); - if (iface && !strlen (iface)) + if (!*iface) iface = NULL; /* IP interface name */ - value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE); + value = g_variant_lookup_value (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, NULL); if (value) { - if (!G_VALUE_HOLDS_STRING (value)) { - g_warning ("Invalid required value " NMD_DEVICE_PROPS_IP_INTERFACE "!"); + if (!g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { + g_warning ("Invalid value " NMD_DEVICE_PROPS_IP_INTERFACE "!"); return NULL; } - ip_iface = g_value_get_string (value); + g_variant_unref (value); + g_variant_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, "&s", &ip_iface); } /* Device type */ - value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_TYPE); - if (!value || !G_VALUE_HOLDS_UINT (value)) { + if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_TYPE, "u", NULL)) { g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_TYPE "!"); return NULL; } /* Device state */ - value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_STATE); - if (!value || !G_VALUE_HOLDS_UINT (value)) { + value = g_variant_lookup_value (device_props, NMD_DEVICE_PROPS_STATE, G_VARIANT_TYPE_UINT32); + if (!value) { g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_STATE "!"); return NULL; } - dev_state = g_value_get_uint (value); + dev_state = g_variant_get_uint32 (value); + g_variant_unref (value); /* device itself */ - value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_PATH); - if (!value || (G_VALUE_TYPE (value) != DBUS_TYPE_G_OBJECT_PATH)) { + if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_PATH, "o", NULL)) { g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_PATH "!"); return NULL; } + /* UUID and ID */ + con_setting = g_variant_lookup_value (connection_dict, NM_SETTING_CONNECTION_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!con_setting) { + g_warning ("Failed to read connection setting"); + return NULL; + } + + if (!g_variant_lookup (con_setting, NM_SETTING_CONNECTION_UUID, "&s", &uuid)) { + g_warning ("Connection hash did not contain the UUID"); + g_variant_unref (con_setting); + return NULL; + } + + if (!g_variant_lookup (con_setting, NM_SETTING_CONNECTION_ID, "&s", &id)) { + g_warning ("Connection hash did not contain the ID"); + g_variant_unref (con_setting); + return NULL; + } + items = construct_basic_items (items, uuid, id, iface, ip_iface); + g_variant_unref (con_setting); /* Device it's aren't valid if the device isn't activated */ if (iface && (dev_state == NM_DEVICE_STATE_ACTIVATED)) { diff --git a/callouts/nm-dispatcher-utils.h b/callouts/nm-dispatcher-utils.h index 33202e0e..665a0d4e 100644 --- a/callouts/nm-dispatcher-utils.h +++ b/callouts/nm-dispatcher-utils.h @@ -18,24 +18,24 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ -#ifndef NM_DISPATCHER_UTILS_H -#define NM_DISPATCHER_UTILS_H +#ifndef __NETWORKMANAGER_DISPATCHER_UTILS_H__ +#define __NETWORKMANAGER_DISPATCHER_UTILS_H__ #include char ** nm_dispatcher_utils_construct_envp (const char *action, - GHashTable *connection_hash, - GHashTable *connection_props, - GHashTable *device_props, - GHashTable *device_ip4_props, - GHashTable *device_ip6_props, - GHashTable *device_dhcp4_props, - GHashTable *device_dhcp6_props, + GVariant *connection_dict, + GVariant *connection_props, + GVariant *device_props, + GVariant *device_ip4_props, + GVariant *device_ip6_props, + GVariant *device_dhcp4_props, + GVariant *device_dhcp6_props, const char *vpn_ip_iface, - GHashTable *vpn_ip4_props, - GHashTable *vpn_ip6_props, + GVariant *vpn_ip4_props, + GVariant *vpn_ip6_props, char **out_iface); -#endif /* NM_DISPATCHER_UTILS_H */ +#endif /* __NETWORKMANAGER_DISPATCHER_UTILS_H__ */ diff --git a/callouts/nm-dispatcher.c b/callouts/nm-dispatcher.c index 733af511..0cd2531d 100644 --- a/callouts/nm-dispatcher.c +++ b/callouts/nm-dispatcher.c @@ -18,6 +18,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -32,17 +34,18 @@ #include #include -#include -#include -#include #include "nm-dispatcher-api.h" #include "nm-dispatcher-utils.h" #include "nm-glib-compat.h" +#include "nmdbus-dispatcher.h" + static GMainLoop *loop = NULL; static gboolean debug = FALSE; +static gboolean persist = FALSE; +static guint quit_id; typedef struct Request Request; @@ -50,10 +53,10 @@ typedef struct { GObject parent; /* Private data */ + NMDBusDispatcher *dbus_dispatcher; + Request *current_request; GQueue *pending_requests; - guint quit_id; - gboolean persist; } Handler; typedef struct { @@ -68,28 +71,30 @@ GType handler_get_type (void); G_DEFINE_TYPE(Handler, handler, G_TYPE_OBJECT) -static void -impl_dispatch (Handler *h, - const char *action, - GHashTable *connection_hash, - GHashTable *connection_props, - GHashTable *device_props, - GHashTable *device_ip4_props, - GHashTable *device_ip6_props, - GHashTable *device_dhcp4_props, - GHashTable *device_dhcp6_props, +static gboolean +handle_action (NMDBusDispatcher *dbus_dispatcher, + GDBusMethodInvocation *context, + const char *str_action, + GVariant *connection_dict, + GVariant *connection_props, + GVariant *device_props, + GVariant *device_ip4_props, + GVariant *device_ip6_props, + GVariant *device_dhcp4_props, + GVariant *device_dhcp6_props, const char *vpn_ip_iface, - GHashTable *vpn_ip4_props, - GHashTable *vpn_ip6_props, + GVariant *vpn_ip4_props, + GVariant *vpn_ip6_props, gboolean request_debug, - DBusGMethodInvocation *context); - -#include "nm-dispatcher-glue.h" - + gpointer user_data); static void handler_init (Handler *h) { + h->pending_requests = g_queue_new (); + h->dbus_dispatcher = nmdbus_dispatcher_skeleton_new (); + g_signal_connect (h->dbus_dispatcher, "handle-action", + G_CALLBACK (handle_action), h); } static void @@ -111,7 +116,7 @@ typedef struct { struct Request { Handler *handler; - DBusGMethodInvocation *context; + GDBusMethodInvocation *context; char *action; char *iface; char **envp; @@ -152,20 +157,20 @@ quit_timeout_cb (gpointer user_data) } static void -quit_timeout_cancel (Handler *h) +quit_timeout_cancel (void) { - if (h->quit_id) { - g_source_remove (h->quit_id); - h->quit_id = 0; + if (quit_id) { + g_source_remove (quit_id); + quit_id = 0; } } static void -quit_timeout_reschedule (Handler *h) +quit_timeout_reschedule (void) { - quit_timeout_cancel (h); - if (!h->persist) - h->quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL); + quit_timeout_cancel (); + if (!persist) + quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL); } static void @@ -191,7 +196,7 @@ next_request (Handler *h) } h->current_request = NULL; - quit_timeout_reschedule (h); + quit_timeout_reschedule (); } static gboolean @@ -199,8 +204,8 @@ next_script (gpointer user_data) { Request *request = user_data; Handler *h = request->handler; - GPtrArray *results; - GValueArray *item; + GVariantBuilder results; + GVariant *ret; guint i; request->idx++; @@ -210,36 +215,18 @@ next_script (gpointer user_data) } /* All done */ - results = g_ptr_array_new_full (request->scripts->len, (GDestroyNotify) g_value_array_free); + g_variant_builder_init (&results, G_VARIANT_TYPE ("a(sus)")); for (i = 0; i < request->scripts->len; i++) { ScriptInfo *script = g_ptr_array_index (request->scripts, i); - GValue elt = G_VALUE_INIT; - - item = g_value_array_new (3); - - /* Script path */ - g_value_init (&elt, G_TYPE_STRING); - g_value_set_string (&elt, script->script); - g_value_array_append (item, &elt); - g_value_unset (&elt); - - /* Result */ - g_value_init (&elt, G_TYPE_UINT); - g_value_set_uint (&elt, script->result); - g_value_array_append (item, &elt); - g_value_unset (&elt); - /* Error */ - g_value_init (&elt, G_TYPE_STRING); - g_value_set_string (&elt, script->error ? script->error : ""); - g_value_array_append (item, &elt); - g_value_unset (&elt); - - g_ptr_array_add (results, item); + g_variant_builder_add (&results, "(sus)", + script->script, + script->result, + script->error ? script->error : ""); } - dbus_g_method_return (request->context, results); - g_ptr_array_unref (results); + ret = g_variant_new ("(a(sus))", &results); + g_dbus_method_invocation_return_value (request->context, ret); if (request->debug) { if (request->iface) @@ -309,7 +296,7 @@ script_timeout_cb (gpointer user_data) if (kill (script->pid, 0) == 0) kill (script->pid, SIGKILL); - waitpid (script->pid, NULL, 0); + (void) waitpid (script->pid, NULL, 0); script->error = g_strdup_printf ("Script '%s' timed out.", script->script); script->result = DISPATCH_RESULT_TIMEOUT; @@ -470,22 +457,24 @@ find_scripts (const char *str_action) return sorted; } -static void -impl_dispatch (Handler *h, +static gboolean +handle_action (NMDBusDispatcher *dbus_dispatcher, + GDBusMethodInvocation *context, const char *str_action, - GHashTable *connection_hash, - GHashTable *connection_props, - GHashTable *device_props, - GHashTable *device_ip4_props, - GHashTable *device_ip6_props, - GHashTable *device_dhcp4_props, - GHashTable *device_dhcp6_props, + GVariant *connection_dict, + GVariant *connection_props, + GVariant *device_props, + GVariant *device_ip4_props, + GVariant *device_ip6_props, + GVariant *device_dhcp4_props, + GVariant *device_dhcp6_props, const char *vpn_ip_iface, - GHashTable *vpn_ip4_props, - GHashTable *vpn_ip6_props, + GVariant *vpn_ip4_props, + GVariant *vpn_ip6_props, gboolean request_debug, - DBusGMethodInvocation *context) + gpointer user_data) { + Handler *h = user_data; GSList *sorted_scripts = NULL; GSList *iter; Request *request; @@ -495,11 +484,14 @@ impl_dispatch (Handler *h, sorted_scripts = find_scripts (str_action); if (!sorted_scripts) { - dbus_g_method_return (context, g_ptr_array_new ()); - return; + GVariant *results; + + results = g_variant_new_array (G_VARIANT_TYPE ("(sus)"), NULL, 0); + g_dbus_method_invocation_return_value (context, g_variant_new ("(@a(sus))", results)); + return TRUE; } - quit_timeout_cancel (h); + quit_timeout_cancel (); request = g_malloc0 (sizeof (*request)); request->handler = h; @@ -508,7 +500,7 @@ impl_dispatch (Handler *h, request->action = g_strdup (str_action); request->envp = nm_dispatcher_utils_construct_envp (str_action, - connection_hash, + connection_dict, connection_props, device_props, device_ip4_props, @@ -543,76 +535,35 @@ impl_dispatch (Handler *h, g_queue_push_tail (h->pending_requests, request); else start_request (request); + + return TRUE; } +static gboolean ever_acquired_name = FALSE; + static void -destroy_cb (DBusGProxy *proxy, gpointer user_data) +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) { - g_warning ("Disconnected from the system bus, exiting."); - g_main_loop_quit (loop); + ever_acquired_name = TRUE; } -static DBusGConnection * -dbus_init (void) +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) { - GError *error = NULL; - DBusGConnection *bus; - DBusConnection *connection; - DBusGProxy *proxy; - int result; - - dbus_connection_set_change_sigpipe (TRUE); - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (!bus) { - g_warning ("Could not get the system bus. Make sure " - "the message bus daemon is running! Message: %s", - error->message); - g_error_free (error); - return NULL; - } - - /* Clean up nicely if we get kicked off the bus */ - connection = dbus_g_connection_get_connection (bus); - dbus_connection_set_exit_on_disconnect (connection, FALSE); - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - if (!proxy) { - g_warning ("Could not create the DBus proxy!"); - goto error; - } - - g_signal_connect (proxy, "destroy", G_CALLBACK (destroy_cb), NULL); - - if (!dbus_g_proxy_call (proxy, "RequestName", &error, - G_TYPE_STRING, NM_DISPATCHER_DBUS_SERVICE, - G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, - G_TYPE_INVALID, - G_TYPE_UINT, &result, - G_TYPE_INVALID)) { - g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service.\n" - " Message: '%s'", error->message); - g_error_free (error); - goto error; - } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service " - "as it is already taken. Result: %d", - result); - goto error; + if (!connection) { + g_warning ("Could not get the system bus. Make sure the message bus daemon is running!"); + exit (1); + } else if (!ever_acquired_name) { + g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service."); + exit (1); + } else { + g_message ("Lost the " NM_DISPATCHER_DBUS_SERVICE " name. Exiting"); + exit (0); } - - return bus; - -error: - if (proxy) - g_object_unref (proxy); - dbus_g_connection_unref (bus); - return NULL; } static void @@ -681,8 +632,7 @@ main (int argc, char **argv) { GOptionContext *opt_ctx; GError *error = NULL; - gboolean persist = FALSE; - DBusGConnection *bus; + GDBusConnection *bus; Handler *handler; GOptionEntry entries[] = { @@ -715,31 +665,41 @@ main (int argc, char **argv) loop = g_main_loop_new (NULL, FALSE); - bus = dbus_init (); - if (!bus) + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (!bus) { + g_warning ("Could not get the system bus (%s). Make sure the message bus daemon is running!", + error->message); + g_error_free (error); return 1; + } handler = g_object_new (HANDLER_TYPE, NULL); - if (!handler) + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (handler->dbus_dispatcher), + bus, + NM_DISPATCHER_DBUS_PATH, + &error); + if (error) { + g_warning ("Could not export Dispatcher D-Bus interface: %s", error->message); + g_error_free (error); return 1; - handler->persist = persist; - handler->pending_requests = g_queue_new (); + } - dbus_g_object_type_install_info (HANDLER_TYPE, &dbus_glib_nm_dispatcher_object_info); - dbus_g_connection_register_g_object (bus, - NM_DISPATCHER_DBUS_PATH, - G_OBJECT (handler)); + g_bus_own_name_on_connection (bus, + NM_DISPATCHER_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_name_acquired, + on_name_lost, + NULL, NULL); + g_object_unref (bus); if (!persist) - handler->quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL); + quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL); g_main_loop_run (loop); g_queue_free (handler->pending_requests); g_object_unref (handler); - dbus_g_connection_unref (bus); - if (!debug) logging_shutdown (); diff --git a/callouts/nm-dispatcher.xml b/callouts/nm-dispatcher.xml index 1ae138b3..b2c4a21a 100644 --- a/callouts/nm-dispatcher.xml +++ b/callouts/nm-dispatcher.xml @@ -2,15 +2,13 @@ + INTERNAL; not public API. Perform an action. - - - The action being performed. diff --git a/callouts/tests/Makefile.am b/callouts/tests/Makefile.am index de4b5f52..f8fd82b7 100644 --- a/callouts/tests/Makefile.am +++ b/callouts/tests/Makefile.am @@ -2,11 +2,13 @@ if ENABLE_TESTS AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I${top_builddir}/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/callouts \ + -I$(top_builddir)/callouts \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DSRCDIR=\"$(abs_srcdir)\" \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) @@ -19,20 +21,19 @@ test_dispatcher_envp_SOURCES = \ test-dispatcher-envp.c test_dispatcher_envp_LDADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm/libnm.la \ $(top_builddir)/callouts/libtest-dispatcher-envp.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) ########################################### -check-local: test-dispatcher-envp - $(abs_builddir)/test-dispatcher-envp $(abs_srcdir) +TESTS = test-dispatcher-envp + +endif EXTRA_DIST= \ dispatcher-old-down \ dispatcher-old-up \ dispatcher-old-vpn-down \ dispatcher-old-vpn-up - -endif diff --git a/callouts/tests/Makefile.in b/callouts/tests/Makefile.in index 25255b59..5372e352 100644 --- a/callouts/tests/Makefile.in +++ b/callouts/tests/Makefile.in @@ -79,6 +79,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-dispatcher-envp$(EXEEXT) +@ENABLE_TESTS_TRUE@TESTS = test-dispatcher-envp$(EXEEXT) subdir = callouts/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -109,7 +110,7 @@ am__test_dispatcher_envp_SOURCES_DIST = test-dispatcher-envp.c test_dispatcher_envp_OBJECTS = $(am_test_dispatcher_envp_OBJECTS) am__DEPENDENCIES_1 = @ENABLE_TESTS_TRUE@test_dispatcher_envp_DEPENDENCIES = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/callouts/libtest-dispatcher-envp.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) @@ -176,6 +177,28 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -186,6 +209,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -309,6 +334,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -328,6 +354,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -354,7 +381,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -435,11 +462,13 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I${top_builddir}/include \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/callouts \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/callouts \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ -DSRCDIR=\"$(abs_srcdir)\" \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) @@ -449,16 +478,16 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ test-dispatcher-envp.c @ENABLE_TESTS_TRUE@test_dispatcher_envp_LDADD = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/callouts/libtest-dispatcher-envp.la \ @ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) -@ENABLE_TESTS_TRUE@EXTRA_DIST = \ -@ENABLE_TESTS_TRUE@ dispatcher-old-down \ -@ENABLE_TESTS_TRUE@ dispatcher-old-up \ -@ENABLE_TESTS_TRUE@ dispatcher-old-vpn-down \ -@ENABLE_TESTS_TRUE@ dispatcher-old-vpn-up +EXTRA_DIST = \ + dispatcher-old-down \ + dispatcher-old-up \ + dispatcher-old-vpn-down \ + dispatcher-old-vpn-up all: all-am @@ -595,6 +624,99 @@ cscopelist-am: $(am__tagged_files) 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 $(AM_TESTS_FD_REDIRECT); 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 \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -625,9 +747,8 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done -@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -734,7 +855,7 @@ uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ @@ -749,11 +870,6 @@ uninstall-am: tags tags-am uninstall uninstall-am -########################################### - -@ENABLE_TESTS_TRUE@check-local: test-dispatcher-envp -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-dispatcher-envp $(abs_srcdir) - # 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/callouts/tests/dispatcher-old-up b/callouts/tests/dispatcher-old-up index a35812ee..53f35ace 100644 --- a/callouts/tests/dispatcher-old-up +++ b/callouts/tests/dispatcher-old-up @@ -39,6 +39,7 @@ DEVICE_IP_IFACE=wlan0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 IP4_NUM_ADDRESSES=1 IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 IP4_DOMAINS=hsd1.mn.comcast.net. IP4_NUM_ROUTES=0 DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 diff --git a/callouts/tests/dispatcher-old-vpn-down b/callouts/tests/dispatcher-old-vpn-down index 4fab5e95..1f1cf2b6 100644 --- a/callouts/tests/dispatcher-old-vpn-down +++ b/callouts/tests/dispatcher-old-vpn-down @@ -39,6 +39,7 @@ DEVICE_IP_IFACE=tun0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 IP4_NUM_ADDRESSES=1 IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 IP4_DOMAINS=hsd1.mn.comcast.net. IP4_NUM_ROUTES=0 DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 diff --git a/callouts/tests/dispatcher-old-vpn-up b/callouts/tests/dispatcher-old-vpn-up index 3c350dbf..7cda8a69 100644 --- a/callouts/tests/dispatcher-old-vpn-up +++ b/callouts/tests/dispatcher-old-vpn-up @@ -39,6 +39,7 @@ DEVICE_IP_IFACE=tun0 IP4_ADDRESS_0=192.168.1.119/24 192.168.1.1 IP4_NUM_ADDRESSES=1 IP4_NAMESERVERS=68.87.77.134 68.87.72.134 192.168.1.1 +IP4_GATEWAY=192.168.1.1 IP4_DOMAINS=hsd1.mn.comcast.net. IP4_NUM_ROUTES=0 DHCP4_NETBIOS_NAME_SERVERS=0.0.0.0 diff --git a/callouts/tests/test-dispatcher-envp.c b/callouts/tests/test-dispatcher-envp.c index a91ae2b2..460174b2 100644 --- a/callouts/tests/test-dispatcher-envp.c +++ b/callouts/tests/test-dispatcher-envp.c @@ -18,117 +18,24 @@ * */ -#include +#include "config.h" + #include #include #include #include #include -#include "nm-connection.h" -#include "nm-setting-connection.h" +#include "nm-core-internal.h" #include "nm-dispatcher-utils.h" -#include "nm-dbus-glib-types.h" #include "nm-dispatcher-api.h" -#include "nm-utils.h" /*******************************************/ -static void -value_destroy (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static GHashTable * -value_hash_create (void) -{ - return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, value_destroy); -} - -static void -value_hash_add (GHashTable *hash, - const char *key, - GValue *value) -{ - g_hash_table_insert (hash, g_strdup (key), value); -} - -static void -value_hash_add_string (GHashTable *hash, - const char *key, - const char *str) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, str); - - value_hash_add (hash, key, value); -} - -static void -value_hash_add_object_path (GHashTable *hash, - const char *key, - const char *op) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, DBUS_TYPE_G_OBJECT_PATH); - g_value_set_boxed (value, op); - - value_hash_add (hash, key, value); -} - -static void -value_hash_add_uint (GHashTable *hash, - const char *key, - guint32 val) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_UINT); - g_value_set_uint (value, val); - - value_hash_add (hash, key, value); -} - -static void -value_hash_add_strv (GHashTable *hash, - const char *key, - char **strv) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, G_TYPE_STRV); - g_value_take_boxed (value, strv); - value_hash_add (hash, key, value); -} - -static void -value_hash_add_uint_array (GHashTable *hash, - const char *key, - GArray *array) -{ - GValue *value; - - value = g_slice_new0 (GValue); - g_value_init (value, DBUS_TYPE_G_UINT_ARRAY); - g_value_take_boxed (value, array); - value_hash_add (hash, key, value); -} - static gboolean parse_main (GKeyFile *kf, - GHashTable **out_con_hash, - GHashTable **out_con_props, + GVariant **out_con_dict, + GVariant **out_con_props, char **out_expected_iface, char **out_action, char **out_vpn_ip_iface, @@ -137,6 +44,7 @@ parse_main (GKeyFile *kf, char *uuid, *id; NMConnection *connection; NMSettingConnection *s_con; + GVariantBuilder props; *out_expected_iface = g_key_file_get_string (kf, "main", "expected-iface", error); if (*out_expected_iface == NULL) @@ -155,7 +63,7 @@ parse_main (GKeyFile *kf, if (id == NULL) return FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); s_con = (NMSettingConnection *) nm_setting_connection_new (); g_assert (s_con); @@ -167,57 +75,72 @@ parse_main (GKeyFile *kf, g_free (id); nm_connection_add_setting (connection, NM_SETTING (s_con)); - *out_con_hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + *out_con_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (connection); - *out_con_props = value_hash_create (); - value_hash_add_object_path (*out_con_props, "connection-path", "/org/freedesktop/NetworkManager/Connections/5"); + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&props, "{sv}", + "connection-path", + g_variant_new_object_path ("/org/freedesktop/NetworkManager/Connections/5")); + *out_con_props = g_variant_builder_end (&props); return TRUE; } static gboolean -parse_device (GKeyFile *kf, GHashTable **out_device_props, GError **error) +parse_device (GKeyFile *kf, GVariant **out_device_props, GError **error) { + GVariantBuilder props; char *tmp; gint i; - *out_device_props = value_hash_create (); + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); i = g_key_file_get_integer (kf, "device", "state", error); if (i == 0) return FALSE; - value_hash_add_uint (*out_device_props, NMD_DEVICE_PROPS_STATE, (guint) i); + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_STATE, + g_variant_new_uint32 (i)); i = g_key_file_get_integer (kf, "device", "type", error); if (i == 0) return FALSE; - value_hash_add_uint (*out_device_props, NMD_DEVICE_PROPS_TYPE, (guint) i); + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_TYPE, + g_variant_new_uint32 (i)); tmp = g_key_file_get_string (kf, "device", "interface", error); if (tmp == NULL) return FALSE; - value_hash_add_string (*out_device_props, NMD_DEVICE_PROPS_INTERFACE, tmp); + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_INTERFACE, + g_variant_new_string (tmp)); g_free (tmp); tmp = g_key_file_get_string (kf, "device", "ip-interface", error); if (tmp == NULL) return FALSE; - value_hash_add_string (*out_device_props, NMD_DEVICE_PROPS_IP_INTERFACE, tmp); + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_IP_INTERFACE, + g_variant_new_string (tmp)); g_free (tmp); tmp = g_key_file_get_string (kf, "device", "path", error); if (tmp == NULL) return FALSE; - value_hash_add_object_path (*out_device_props, NMD_DEVICE_PROPS_PATH, tmp); + g_variant_builder_add (&props, "{sv}", + NMD_DEVICE_PROPS_PATH, + g_variant_new_object_path (tmp)); g_free (tmp); + *out_device_props = g_variant_builder_end (&props); return TRUE; } static gboolean add_uint_array (GKeyFile *kf, - GHashTable *props, + GVariantBuilder *props, const char *section, const char *key, GError **error) @@ -244,21 +167,26 @@ add_uint_array (GKeyFile *kf, g_array_append_val (items, addr); } } - value_hash_add_uint_array (props, key, items); + g_variant_builder_add (props, "{sv}", key, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + items->data, items->len, + sizeof (guint32))); + g_array_unref (items); } g_strfreev (split); return TRUE; } static gboolean -parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **error) +parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **error) { + GVariantBuilder props; char *tmp; char **split, **iter; - GSList *list; - GValue *val; + GPtrArray *addresses, *routes; + const char *gateway = NULL; - *out_props = value_hash_create (); + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); /* search domains */ /* Use char** for domains. (DBUS_TYPE_G_ARRAY_OF_STRING of NMIP4Config @@ -273,14 +201,15 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e if (g_strv_length (split) > 0) { for (iter = split; iter && *iter; iter++) g_strstrip (*iter); - value_hash_add_strv (*out_props, "domains", split); + g_variant_builder_add (&props, "{sv}", "domains", g_variant_new_strv ((gpointer) split, -1)); + g_strfreev (split); } /* nameservers */ - if (!add_uint_array (kf, *out_props, "ip4", "nameservers", error)) + if (!add_uint_array (kf, &props, "ip4", "nameservers", error)) return FALSE; /* wins-servers */ - if (!add_uint_array (kf, *out_props, "ip4", "wins-servers", error)) + if (!add_uint_array (kf, &props, "ip4", "wins-servers", error)) return FALSE; /* Addresses */ @@ -291,39 +220,37 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e g_free (tmp); if (g_strv_length (split) > 0) { - list = NULL; + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); for (iter = split; iter && *iter; iter++) { - NMIP4Address *addr; - guint32 a; - char *p; + NMIPAddress *addr; + char *ip, *prefix; if (strlen (g_strstrip (*iter)) == 0) continue; - addr = nm_ip4_address_new (); - - p = strchr (*iter, '/'); - g_assert (p); - *p++ = '\0'; - - g_assert_cmpint (inet_pton (AF_INET, *iter, &a), ==, 1); - nm_ip4_address_set_address (addr, a); - nm_ip4_address_set_prefix (addr, (guint) atoi (p)); + ip = *iter; - p = strchr (p, ' '); - g_assert (p); - p++; + prefix = strchr (ip, '/'); + g_assert (prefix); + *prefix++ = '\0'; - g_assert_cmpint (inet_pton (AF_INET, p, &a), ==, 1); - nm_ip4_address_set_gateway (addr, a); + if (addresses->len == 0) { + gateway = strchr (prefix, ' '); + g_assert (gateway); + gateway++; + } - list = g_slist_append (list, addr); + addr = nm_ip_address_new (AF_INET, ip, (guint) atoi (prefix), error); + if (!addr) { + g_ptr_array_unref (addresses); + return FALSE; + } + g_ptr_array_add (addresses, addr); } - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT); - nm_utils_ip4_addresses_to_gvalue (list, val); - value_hash_add (*out_props, "addresses", val); + g_variant_builder_add (&props, "{sv}", "addresses", + nm_utils_ip4_addresses_to_variant (addresses, gateway)); + g_ptr_array_unref (addresses); } g_strfreev (split); @@ -335,87 +262,88 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e g_free (tmp); if (g_strv_length (split) > 0) { - list = NULL; + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); for (iter = split; iter && *iter; iter++) { - NMIP4Route *route; - guint32 a; - char *p; + NMIPRoute *route; + char *dest, *prefix, *next_hop, *metric; if (strlen (g_strstrip (*iter)) == 0) continue; - route = nm_ip4_route_new (); - - p = strchr (*iter, '/'); - g_assert (p); - *p++ = '\0'; - - g_assert_cmpint (inet_pton (AF_INET, *iter, &a), ==, 1); - nm_ip4_route_set_dest (route, a); - nm_ip4_route_set_prefix (route, (guint) atoi (p)); - - p = strchr (p, ' '); - g_assert (p); - p++; - - g_assert_cmpint (inet_pton (AF_INET, p, &a), ==, 1); - nm_ip4_route_set_next_hop (route, a); - - p = strchr (p, ' '); - g_assert (p); - p++; - nm_ip4_route_set_metric (route, (guint) atoi (p)); - - list = g_slist_append (list, route); + dest = *iter; + + prefix = strchr (dest, '/'); + g_assert (prefix); + *prefix++ = '\0'; + + next_hop = strchr (prefix, ' '); + g_assert (next_hop); + next_hop++; + + metric = strchr (next_hop, ' '); + g_assert (metric); + metric++; + + route = nm_ip_route_new (AF_INET, + dest, (guint) atoi (prefix), + next_hop, (guint) atoi (metric), + error); + if (!route) { + g_ptr_array_unref (routes); + return FALSE; + } + g_ptr_array_add (routes, route); } - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT); - nm_utils_ip4_routes_to_gvalue (list, val); - value_hash_add (*out_props, "routes", val); + g_variant_builder_add (&props, "{sv}", "routes", + nm_utils_ip4_routes_to_variant (routes)); + g_ptr_array_unref (routes); } g_strfreev (split); } + *out_props = g_variant_builder_end (&props); return TRUE; } static gboolean parse_dhcp (GKeyFile *kf, const char *group_name, - GHashTable **out_props, + GVariant **out_props, GError **error) { char **keys, **iter, *val; + GVariantBuilder props; keys = g_key_file_get_keys (kf, group_name, NULL, error); if (!keys) return FALSE; - *out_props = value_hash_create (); + g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); for (iter = keys; iter && *iter; iter++) { val = g_key_file_get_string (kf, group_name, *iter, error); if (!val) return FALSE; - value_hash_add_string (*out_props, *iter, val); + g_variant_builder_add (&props, "{sv}", *iter, g_variant_new_string (val)); g_free (val); } + *out_props = g_variant_builder_end (&props); return TRUE; } static gboolean get_dispatcher_file (const char *file, - GHashTable **out_con_hash, - GHashTable **out_con_props, - GHashTable **out_device_props, - GHashTable **out_device_ip4_props, - GHashTable **out_device_ip6_props, - GHashTable **out_device_dhcp4_props, - GHashTable **out_device_dhcp6_props, + GVariant **out_con_dict, + GVariant **out_con_props, + GVariant **out_device_props, + GVariant **out_device_ip4_props, + GVariant **out_device_ip6_props, + GVariant **out_device_dhcp4_props, + GVariant **out_device_dhcp6_props, char **out_vpn_ip_iface, - GHashTable **out_vpn_ip4_props, - GHashTable **out_vpn_ip6_props, + GVariant **out_vpn_ip4_props, + GVariant **out_vpn_ip6_props, char **out_expected_iface, char **out_action, GHashTable **out_env, @@ -430,7 +358,7 @@ get_dispatcher_file (const char *file, return FALSE; if (!parse_main (kf, - out_con_hash, + out_con_dict, out_con_props, out_expected_iface, out_action, @@ -480,18 +408,18 @@ out: /*******************************************/ static void -test_generic (const char *path, const char *file, const char *override_vpn_ip_iface) +test_generic (const char *file, const char *override_vpn_ip_iface) { - GHashTable *con_hash = NULL; - GHashTable *con_props = NULL; - GHashTable *device_props = NULL; - GHashTable *device_ip4_props = NULL; - GHashTable *device_ip6_props = NULL; - GHashTable *device_dhcp4_props = NULL; - GHashTable *device_dhcp6_props = NULL; + GVariant *con_dict = NULL; + GVariant *con_props = NULL; + GVariant *device_props = NULL; + GVariant *device_ip4_props = NULL; + GVariant *device_ip6_props = NULL; + GVariant *device_dhcp4_props = NULL; + GVariant *device_dhcp6_props = NULL; char *vpn_ip_iface = NULL; - GHashTable *vpn_ip4_props = NULL; - GHashTable *vpn_ip6_props = NULL; + GVariant *vpn_ip4_props = NULL; + GVariant *vpn_ip6_props = NULL; char *expected_iface = NULL; char *action = NULL; char *out_iface = NULL; @@ -502,9 +430,9 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if char **denv, **iter; /* Read in the test file */ - p = g_strdup_printf ("%s/%s", path, file); + p = g_build_filename (SRCDIR, file, NULL); success = get_dispatcher_file (p, - &con_hash, + &con_dict, &con_props, &device_props, &device_ip4_props, @@ -524,7 +452,7 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if /* Get the environment from the dispatcher code */ denv = nm_dispatcher_utils_construct_envp (action, - con_hash, + con_dict, con_props, device_props, device_ip4_props, @@ -581,57 +509,57 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if g_free (vpn_ip_iface); g_free (expected_iface); g_free (action); - g_hash_table_destroy (con_hash); - g_hash_table_destroy (con_props); - g_hash_table_destroy (device_props); + g_variant_unref (con_dict); + g_variant_unref (con_props); + g_variant_unref (device_props); if (device_ip4_props) - g_hash_table_destroy (device_ip4_props); + g_variant_unref (device_ip4_props); if (device_ip6_props) - g_hash_table_destroy (device_ip6_props); + g_variant_unref (device_ip6_props); if (device_dhcp4_props) - g_hash_table_destroy (device_dhcp4_props); + g_variant_unref (device_dhcp4_props); if (device_dhcp6_props) - g_hash_table_destroy (device_dhcp6_props); + g_variant_unref (device_dhcp6_props); if (vpn_ip4_props) - g_hash_table_destroy (vpn_ip4_props); + g_variant_unref (vpn_ip4_props); if (vpn_ip6_props) - g_hash_table_destroy (vpn_ip6_props); + g_variant_unref (vpn_ip6_props); g_hash_table_destroy (expected_env); } /*******************************************/ static void -test_old_up (const char *path) +test_old_up (void) { - test_generic (path, "dispatcher-old-up", NULL); + test_generic ("dispatcher-old-up", NULL); } static void -test_old_down (const char *path) +test_old_down (void) { - test_generic (path, "dispatcher-old-down", NULL); + test_generic ("dispatcher-old-down", NULL); } static void -test_old_vpn_up (const char *path) +test_old_vpn_up (void) { - test_generic (path, "dispatcher-old-vpn-up", NULL); + test_generic ("dispatcher-old-vpn-up", NULL); } static void -test_old_vpn_down (const char *path) +test_old_vpn_down (void) { - test_generic (path, "dispatcher-old-vpn-down", NULL); + test_generic ("dispatcher-old-vpn-down", NULL); } static void -test_up_empty_vpn_iface (const char *path) +test_up_empty_vpn_iface (void) { /* Test that an empty VPN iface variable, like is passed through D-Bus * from NM, is ignored by the dispatcher environment construction code. */ - test_generic (path, "dispatcher-old-up", ""); + test_generic ("dispatcher-old-up", ""); } /*******************************************/ @@ -639,20 +567,18 @@ test_up_empty_vpn_iface (const char *path) int main (int argc, char **argv) { - g_assert (argc > 1); - g_test_init (&argc, &argv, NULL); #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); #endif - g_test_add_data_func ("/dispatcher/old_up", argv[1], (GTestDataFunc) test_old_up); - g_test_add_data_func ("/dispatcher/old_down", argv[1], (GTestDataFunc) test_old_down); - g_test_add_data_func ("/dispatcher/old_vpn_up", argv[1], (GTestDataFunc) test_old_vpn_up); - g_test_add_data_func ("/dispatcher/old_vpn_down", argv[1], (GTestDataFunc) test_old_vpn_down); + g_test_add_func ("/dispatcher/old_up", test_old_up); + g_test_add_func ("/dispatcher/old_down", test_old_down); + g_test_add_func ("/dispatcher/old_vpn_up", test_old_vpn_up); + g_test_add_func ("/dispatcher/old_vpn_down", test_old_vpn_down); - g_test_add_data_func ("/dispatcher/up_empty_vpn_iface", argv[1], (GTestDataFunc) test_up_empty_vpn_iface); + g_test_add_func ("/dispatcher/up_empty_vpn_iface", test_up_empty_vpn_iface); return g_test_run (); } diff --git a/cli/Makefile.am b/cli/Makefile.am deleted file mode 100644 index f436d46d..00000000 --- a/cli/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -SUBDIRS = src completion - diff --git a/cli/Makefile.in b/cli/Makefile.in deleted file mode 100644 index 11a64d42..00000000 --- a/cli/Makefile.in +++ /dev/null @@ -1,753 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 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@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -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 = cli -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-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 \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -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@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -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@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -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@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -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@ -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_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -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_CXX = @ac_ct_CXX@ -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@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -SUBDIRS = src completion -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 cli/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu cli/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. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - 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" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - 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; \ - $(am__define_uniq_tagged_files); \ - 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-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - 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" -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -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 \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - 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: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -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: $(am__recursive_targets) install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool cscopelist-am ctags \ - ctags-am 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-am 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/cli/completion/Makefile.am b/cli/completion/Makefile.am deleted file mode 100644 index 9a250f07..00000000 --- a/cli/completion/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -completiondir = $(datadir)/bash-completion/completions -dist_completion_DATA = nmcli diff --git a/cli/completion/Makefile.in b/cli/completion/Makefile.in deleted file mode 100644 index 7b45c2b4..00000000 --- a/cli/completion/Makefile.in +++ /dev/null @@ -1,630 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 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@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -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 = cli/completion -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(dist_completion_DATA) -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -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__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(completiondir)" -DATA = $(dist_completion_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -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@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -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@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -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@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -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@ -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_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -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_CXX = @ac_ct_CXX@ -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@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -completiondir = $(datadir)/bash-completion/completions -dist_completion_DATA = nmcli -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 cli/completion/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu cli/completion/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 -install-dist_completionDATA: $(dist_completion_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_completion_DATA)'; test -n "$(completiondir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(completiondir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(completiondir)" || exit 1; \ - fi; \ - 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)$(completiondir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(completiondir)" || exit $$?; \ - done - -uninstall-dist_completionDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_completion_DATA)'; test -n "$(completiondir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(completiondir)'; $(am__uninstall_files_from_dir) -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -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 $(DATA) -installdirs: - for dir in "$(DESTDIR)$(completiondir)"; 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: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -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-dist_completionDATA - -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: uninstall-dist_completionDATA - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_completionDATA 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 tags-am uninstall \ - uninstall-am uninstall-dist_completionDATA - - -# 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/cli/completion/nmcli b/cli/completion/nmcli deleted file mode 100644 index 343c7322..00000000 --- a/cli/completion/nmcli +++ /dev/null @@ -1,1236 +0,0 @@ -# nmcli(1) completion -*- shell-script -*- -# Originally based on -# https://github.com/GArik/bash-completion/blob/master/completions/nmcli - -_nmcli_list() -{ - COMPREPLY=( $( compgen -W '$1' -- $cur ) ) -} - -_nmcli_list_nl() -{ - local IFS=$'\n' - COMPREPLY=( $( compgen -W '$1' -- $cur ) ) - - # Now escape special characters (spaces, single and double quotes), - # so that the argument is really regarded a single argument by bash. - # See http://stackoverflow.com/questions/1146098/properly-handling-spaces-and-quotes-in-bash-completion - local escaped_single_quote="'\''" - local i=0 - local entry - for entry in ${COMPREPLY[*]} - do - if [[ "${cur:0:1}" == "'" ]]; then - # started with single quote, escaping only other single quotes - # [']bla'bla"bla\bla bla --> [']bla'\''bla"bla\bla bla - COMPREPLY[$i]="${entry//\'/${escaped_single_quote}}" - elif [[ "${cur:0:1}" == '"' ]]; then - # started with double quote, escaping all double quotes and all backslashes - # ["]bla'bla"bla\bla bla --> ["]bla'bla\"bla\\bla bla - entry="${entry//\\/\\\\}" - entry="${entry//\"/\\\"}" - COMPREPLY[$i]="$entry" - else - # no quotes in front, escaping _everything_ - # [ ]bla'bla"bla\bla bla --> [ ]bla\'bla\"bla\\bla\ bla - entry="${entry//\\/\\\\}" - entry="${entry//\'/\'}" - entry="${entry//\"/\\\"}" - entry="${entry// /\\ }" - COMPREPLY[$i]="$entry" - fi - (( i++ )) - done -} - -_nmcli_con_show() -{ - nmcli -t -f "$1" connection show $2 2> /dev/null -} - -_nmcli_wifi_list() -{ - nmcli -t -f "$1" device wifi list 2>/dev/null -} - -_nmcli_dev_status() -{ - nmcli -t -f "$1" device status 2>/dev/null -} - -_nmcli_array_has_value() { - # expects the name of an array as first parameter and - # returns true if if one of the remaining arguments is - # contained in the array ${$1[@]} - eval "local ARRAY=(\"\${$1[@]}\")" - local arg a - shift - for arg; do - for a in "${ARRAY[@]}"; do - if [[ "$a" = "$arg" ]]; then - return 0 - fi - done - done - return 1 -} - -_nmcli_array_delete_at() -{ - eval "local ARRAY=(\"\${$1[@]}\")" - local i - local tmp=() - local lower=$2 - local upper=${3:-$lower} - - # for some reason the following fails. So this clumsy workaround... - # A=(a "") - # echo " >> ${#A[@]}" - # >> 2 - # A=("${A[@]:1}") - # echo " >> ${#A[@]}" - # >> 0 - # ... seriously??? - - for i in "${!ARRAY[@]}"; do - if [[ "$i" -lt "$2" || "$i" -gt "${3-$2}" ]]; then - tmp=("${tmp[@]}" "${ARRAY[$i]}") - fi - done - eval "$1=(\"\${tmp[@]}\")" -} - -_nmcli_compl_match_option() -{ - local S="$1" - local V - shift - if [[ "${S:0:2}" == "--" ]]; then - S="${S:2}" - elif [[ "${S:0:1}" == "-" ]]; then - S="${S:1}" - fi - for V; do - case "$V" in - "$S"*) - printf "%s" "$V" - return 0 - ;; - esac - done - return 1 -} - -# OPTIONS appear first at the command line (before the OBJECT). -# This iterates over the argument list and tries to complete -# the options. If there are options that are to be completed, -# zero is returned and completion will be performed. -# Otherwise it will remove all the option parameters from the ${words[@]} -# array and return with zero (so that completion of OBJECT can continue). -_nmcli_compl_OPTIONS() -{ - local i W - - for (( ; ; )); do - if [[ "${#words[@]}" -le 1 ]]; then - return 1 - fi - W="$(_nmcli_compl_match_option "${words[0]}" "${LONG_OPTIONS[@]}")" - if [[ $? != 0 ]]; then - return 2 - fi - - # remove the options already seen. - for i in ${!LONG_OPTIONS[@]}; do - if [[ "${LONG_OPTIONS[$i]}" == "$W" ]]; then - _nmcli_array_delete_at LONG_OPTIONS $i - break - fi - done - - if [[ "$HELP_ONLY_AS_FIRST" == '1' ]]; then - for i in ${!LONG_OPTIONS[@]}; do - if [[ "${LONG_OPTIONS[$i]}" == "help" ]]; then - _nmcli_array_delete_at LONG_OPTIONS $i - break - fi - done - fi - - case "$W" in - terse) - _nmcli_array_delete_at words 0 - ;; - pretty) - _nmcli_array_delete_at words 0 - ;; - nocheck) - _nmcli_array_delete_at words 0 - ;; - ask) - _nmcli_array_delete_at words 0 - ;; - active) - _nmcli_array_delete_at words 0 - ;; - version) - _nmcli_array_delete_at words 0 - ;; - help) - _nmcli_array_delete_at words 0 - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - HELP_ONLY_AS_FIRST=0 - return 0 - fi - HELP_ONLY_AS_FIRST=0 - ;; - temporary) - _nmcli_array_delete_at words 0 - ;; - mode) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "tabular multiline" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - fields) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "all common - NAME UUID TYPE TIMESTAMP TIMESTAMP-REAL AUTOCONNECT READONLY DBUS-PATH ACTIVE DEVICE STATE ACTIVE-PATH - connection 802-3-ethernet 802-1x 802-11-wireless 802-11-wireless-security ipv4 ipv6 serial ppp pppoe gsm cdma bluetooth 802-11-olpc-mesh vpn wimax infiniband bond vlan adsl bridge bridge-port team team-port dcb - GENERAL IP4 DHCP4 IP6 DHCP6 VPN - profile active" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - escape) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "no yes" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - wait) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - *) - # something unexpected. We are finished with parsing the OPTIONS. - return 2 - ;; - esac - done -} - -# after the OPTIONS, the OBJECT, the COMMAND and possible the COMMAND_CONNECTION, the syntax for nmcli -# expects several options with parameters. This function can parse them and remove them from the words array. -_nmcli_compl_ARGS() -{ - local OPTIONS_ALL N_REMOVE_WORDS REMOVE_OPTIONS OPTIONS_HAS_MANDATORY i - OPTIONS_ALL=("${OPTIONS[@]}") - OPTIONS_UNKNOWN_OPTION= - - OPTIONS_HAS_MANDATORY=0 - if [[ "${#OPTIONS_MANDATORY[@]}" -ge 1 ]]; then - OPTIONS_HAS_MANDATORY=1 - fi - - for (( ; ; )); do - if [[ "${#words[@]}" -le 1 ]]; then - # we have no more words left... - if [[ ${#OPTIONS[@]} -eq 0 ]]; then - return 1; - fi - if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then - _nmcli_list "$(echo "${OPTIONS[@]}")" - return 0 - fi - COMMAND_ARGS_WAIT_OPTIONS=0 - return 1 - fi - if ! _nmcli_array_has_value OPTIONS_ALL "${words[0]}"; then - # This is an entirely unknown option. - OPTIONS_UNKNOWN_OPTION="?${words[0]}" - return 1 - fi - if [[ "$OPTIONS_HAS_MANDATORY" -eq 1 && "${#OPTIONS_MANDATORY[@]}" -eq 0 ]]; then - # we had some mandatory options, but they are all satisfied... stop here... - # This means, that we can continue with more additional options from the NEXT_GROUP. - return 1 - fi - - N_REMOVE_WORDS=2 - REMOVE_OPTIONS=("${words[0]}") - case "${words[0]}" in - level) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "ERR WARN INFO DEBUG" - return 0 - fi - ;; - domains) - if [[ "${#words[@]}" -eq 2 ]]; then - local OPTIONS_DOM=(ALL DEFAULT PLATFORM RFKILL ETHER WIFI BT MB DHCP4 DHCP6 PPP WIFI_SCAN IP4 IP6 AUTOIP4 DNS VPN SHARING SUPPLICANT AGENTS SETTINGS SUSPEND CORE DEVICE OLPC WIMAX INFINIBAND FIREWALL ADSL BOND VLAN BRIDGE DBUS_PROPS TEAM CONCHECK DCB DISPATCH) - if [[ "${words[1]}" != "" ]]; then - - # split the comma separaeted domain string into its parts LOGD - local oIFS="$IFS" - IFS="," - local LOGD=($(printf '%s' "${words[1]}" | sed 's/\(^\|,\)/,#/g')) - IFS="$oIFS" - unset oIFS - - local LOGDLAST LOGDLAST_IS_OPTION LOGDI i - # first we iterate over all present domains and remove them from OPTIONS_DOM - for LOGDI in ${LOGD[@]}; do - LOGDI="${LOGDI:1}" - LOGDLAST="$LOGDI" - LOGDLAST_IS_OPTION=0 - for i in ${!OPTIONS_DOM[*]}; do - if [[ "${OPTIONS_DOM[$i]}" = "$LOGDI" ]]; then - LOGDLAST_IS_OPTION=1 - unset OPTIONS_DOM[$i] - fi - done - done - - local OPTIONS_DOM2=() - if [[ "$LOGDLAST" = "" ]]; then - # we have a word that ends with ','. Just append all remaining options. - for i in ${!OPTIONS_DOM[*]}; do - OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}${OPTIONS_DOM[$i]}" - done - else - # if the last option is not "" we keep only those option with the same prefix - # as the last domain (LOGDLAST) - for i in ${!OPTIONS_DOM[*]}; do - if [[ "${OPTIONS_DOM[$i]:0:${#LOGDLAST}}" == "$LOGDLAST" ]]; then - # modify the option with the present prefix - OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}${OPTIONS_DOM[$i]:${#LOGDLAST}}" - fi - done - - if [[ $LOGDLAST_IS_OPTION -eq 1 ]]; then - # if the last logd itself was a valid iption, ${words[1]} is itself a valid match - OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]}" - - # also, add all remaining options by comma separated to the word. - for i in ${!OPTIONS_DOM[*]}; do - OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${words[1]},${OPTIONS_DOM[$i]}" - done - fi - if [[ ${#OPTIONS_DOM2[@]} -eq 1 ]]; then - for i in ${!OPTIONS_DOM[*]}; do - if [[ "$LOGDLAST" != "${OPTIONS_DOM[$i]:0:${#LOGDLAST}}" ]]; then - OPTIONS_DOM2[${#OPTIONS_DOM2[@]}]="${OPTIONS_DOM2[0]},${OPTIONS_DOM[$i]}" - fi - done - fi - - fi - OPTIONS_DOM=(${OPTIONS_DOM2[@]}) - fi - - _nmcli_list "$(echo "${OPTIONS_DOM[@]}")" - return 0 - fi - ;; - type) - if [[ "$OPTIONS_TYPE" != "" ]]; then - return 1 - fi - if [[ "${#words[@]}" -eq 2 ]]; then - if [[ "${words[1]:0:1}" = "8" ]]; then - # usually we don't want to show the 802-x types (because the shorter aliases are more - # user friendly. Only complete them, if the current word already starts with an "8". - _nmcli_list "802-3-ethernet 802-11-wireless 802-11-olpc-mesh" - else - _nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bond-slave bridge bridge-slave team team-slave pppoe" - fi - return 0 - fi - OPTIONS_TYPE="${words[1]}" - - if [[ "x$OPTIONS_MANDATORY_IFNAME" != x ]]; then - # the ifname is not a mandatory option for a few connection types... - # Check, if we have such a 'type' and remove the 'ifname' from the list - # of mandatory options. - case "$OPTIONS_TYPE" in - vl|vla|vlan| \ - bond| \ - team| \ - bridge) - for i in ${!OPTIONS_MANDATORY[*]}; do - if [[ "${OPTIONS_MANDATORY[$i]}" = "ifname" ]]; then - unset OPTIONS_MANDATORY[$i] - fi - done - ;; - *) - ;; - - esac - OPTIONS_MANDATORY_IFNAME= - fi - ;; - master) - if [[ "${#words[@]}" -eq 2 ]]; then - if [[ "${words[1]}" = "" ]]; then - _nmcli_list_nl "$(_nmcli_dev_status DEVICE)" - else - _nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_dev_status DEVICE)" "$(_nmcli_con_show UUID)")" - fi - return 0 - fi - ;; - dev) - if [[ "${#words[@]}" -eq 2 ]]; then - if [[ "${words[1]}" = "" ]]; then - _nmcli_list_nl "$(_nmcli_dev_status DEVICE)" - else - _nmcli_list_nl "$(printf "%s\n%s\n%s" "$(_nmcli_dev_status DEVICE)" "$(_nmcli_wifi_list BSSID)" "$(_nmcli_con_show UUID)")" - fi - return 0 - fi - ;; - primary| \ - ifname) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list_nl "$(_nmcli_dev_status DEVICE)" - return 0 - fi - ;; - mode) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb" - return 0 - fi - ;; - transport-mode) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "datagram connected" - return 0 - fi - ;; - vpn-type) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "vpnc openvpn pptp openconnect openswan libreswan ssh l2tp iodine" - return 0 - fi - ;; - bt-type) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "panu dun-gsm dun-cdma" - return 0 - fi - ;; - wep-key-type) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "key phrase" - return 0 - fi - ;; - autoconnect| \ - stp| \ - hairpin| \ - save| \ - private) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list "yes no" - return 0 - fi - ;; - config) - if [[ "${#words[@]}" -eq 2 ]]; then - compopt -o default - COMPREPLY=() - return 0 - fi - ;; - ip4| \ - ip6| \ - gw4| \ - gw6| \ - priority| \ - forward-delay| \ - hello-time| \ - max-age| \ - ageing-time| \ - nsp| \ - path-cost| \ - name| \ - mtu| \ - cloned-mac| \ - addr| \ - parent| \ - miimon| \ - arp-interval| \ - arp-ip-target| \ - downdelay| \ - updelay| \ - p-key| \ - mac| \ - id| \ - flags| \ - ingress| \ - dhcp-anycast| \ - channel| \ - egress| \ - apn| \ - con-name| \ - user| \ - username| \ - service| \ - password) - if [[ "${#words[@]}" -eq 2 ]]; then - return 0 - fi - ;; - ssid) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list_nl "$(_nmcli_wifi_list SSID)" - return 0 - fi - ;; - ap| \ - bssid) - if [[ "${#words[@]}" -eq 2 ]]; then - _nmcli_list_nl "$(_nmcli_wifi_list BSSID)" - return 0 - fi - ;; - *) - return 1 - ;; - esac - - - if [[ "${#OPTIONS_NEXT_GROUP[@]}" -gt 0 ]]; then - if _nmcli_array_has_value OPTIONS_NEXT_GROUP "${words[0]}"; then - # the current value is from the next group... - # We back off, because the current group is complete. - return 1 - fi - fi - - _nmcli_array_delete_at words 0 $((N_REMOVE_WORDS-1)) - # remove the options already seen. - for i in ${!OPTIONS[*]}; do - if [[ "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then - unset OPTIONS[$i] - fi - done - for i in ${!OPTIONS_MANDATORY[*]}; do - if [[ "${OPTIONS_MANDATORY[$i]}" = "${REMOVE_OPTIONS[0]}" || "${OPTIONS_MANDATORY[$i]}" = "${REMOVE_OPTIONS[1]}" ]]; then - unset OPTIONS_MANDATORY[$i] - fi - done - done -} - -# some commands expect a connection as parameter. This connection can either be given -# as id|uuid|path|apath. Parse that connection parameter. -_nmcli_compl_ARGS_CONNECTION() -{ - if ! _nmcli_array_has_value OPTIONS "${words[0]}"; then - COMMAND_CONNECTION_TYPE= - COMMAND_CONNECTION_ID="${words[0]}" - _nmcli_array_delete_at words 0 - return 1 - fi - COMMAND_CONNECTION_TYPE="${words[0]}" - COMMAND_CONNECTION_ID="${words[1]}" - local CON_TYPE= - if [[ "x$COMMAND_CONNECTION_ACTIVE" != x ]]; then - CON_TYPE=--active - fi - case "${words[0]}" in - id) - if [[ ${#words[@]} -le 2 ]]; then - _nmcli_list_nl "$(_nmcli_con_show NAME $CON_TYPE)" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - uuid) - if [[ ${#words[@]} -le 2 ]]; then - _nmcli_list_nl "$(_nmcli_con_show UUID $CON_TYPE)" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - path) - if [[ ${#words[@]} -le 2 ]]; then - _nmcli_list_nl "$(_nmcli_con_show DBUS-PATH $CON_TYPE)" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - apath) - if [[ ${#words[@]} -le 2 ]]; then - _nmcli_list_nl "$(_nmcli_con_show ACTIVE-PATH --active)" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - ifname) - if [[ ${#words[@]} -le 2 ]]; then - _nmcli_list_nl "$(_nmcli_dev_status DEVICE)" - return 0 - fi - _nmcli_array_delete_at words 0 1 - ;; - *) - COMMAND_CONNECTION_TYPE= - COMMAND_CONNECTION_ID="${words[0]}" - _nmcli_array_delete_at words 0 - ;; - esac - return 1 -} - -_nmcli_compl_COMMAND() { - local command="$1" - shift - local V=("$@") - local H= - if [[ "${command[0]:0:1}" != '-' ]]; then - H=help - elif [[ "${command[0]:1:1}" == '-' || "${command[0]}" == "-" ]]; then - H=--help - else - H=-help - fi - if [[ "x$COMPL_COMMAND_NO_HELP" == x ]]; then - V=("${V[@]}" "$H") - fi - _nmcli_list "${V[*]}" -} - -_nmcli_compl_COMMAND_nl() { - local command="$1" - local a="$2" - shift - shift - local V=("$@") - local H= - if [[ "${command[0]:0:1}" != '-' ]]; then - V=("${V[@]/#/--}") - H=help - elif [[ "${command[0]:1:1}" == '-' || "${command[0]}" == "-" ]]; then - V=("${V[@]/#/--}") - H=--help - else - V=("${V[@]/#/-}") - H=-help - fi - if [[ "x$COMPL_COMMAND_NO_HELP" == x ]]; then - V=("${V[@]}" "$H") - fi - local IFS=$'\n' - V="${V[*]}" - _nmcli_list_nl "$(printf "%s%s\n%s" "" "$V" "$a")" -} - -_nmcli() -{ - local cur prev words cword i - _init_completion || return - - # we don't care about any arguments after the current cursor position - # because we only parse from left to right. So, if there are some arguments - # right of the cursor, just ignore them. Also don't care about ${words[0]}. - _nmcli_array_delete_at words $((cword+1)) ${#words[@]} - _nmcli_array_delete_at words 0 - - # _init_completion returns the words with all the quotes and escaping - # characters. We don't care about them, drop them at first. - for i in ${!words[@]}; do - words[i]="$(printf '%s' "${words[i]}" | xargs printf '%s\n' 2>/dev/null || true)" - done - - # In case the cursor is not at the end of the line, - # $cur consists of spaces that we want do remove. - # For example: `nmcli connection modify id lo` - if [[ "$cur" =~ ^[[:space:]]+ ]]; then - cur='' - fi - - local OPTIONS_UNKNOWN_OPTION OPTIONS_TYPE OPTIONS_TYPED OPTIONS OPTIONS_MANDATORY COMMAND_ARGS_WAIT_OPTIONS OPTIONS_IP OPTIONS_MANDATORY OPTIONS_NEXT_GROUP - local COMMAND_CONNECTION_TYPE COMMAND_CONNECTION_ID OPTIONS_MANDATORY_IFNAME HELP_ONLY_AS_FIRST - local COMMAND_CONNECTION_ACTIVE="" - - HELP_ONLY_AS_FIRST= - local LONG_OPTIONS=(terse pretty mode fields escape nocheck ask wait version help) - _nmcli_compl_OPTIONS - i=$? - - if [[ "$HELP_ONLY_AS_FIRST" == '0' ]]; then - # got a --help. No more completion. - return 0 - fi - - case $i in - 0) - return 0 - ;; - 1) - # we show for completion either the (remaining) OPTIONS - # (if the current word starts with a dash) or the OBJECT list - # otherwise. - if [[ "${words[0]:0:1}" != '-' ]]; then - OPTIONS=(help general networking radio connection device) - elif [[ "${words[0]:1:1}" == '-' || "${words[0]}" == "-" ]]; then - OPTIONS=("${LONG_OPTIONS[@]/#/--}") - else - OPTIONS=("${LONG_OPTIONS[@]/#/-}") - fi - _nmcli_list "${OPTIONS[*]}" - return 0 - ;; - esac - - local command="${words[1]}" - case "${words[0]}" in - h|he|hel|help) - ;; - g|ge|gen|gene|gener|genera|general) - if [[ ${#words[@]} -eq 2 ]]; then - _nmcli_compl_COMMAND "$command" status permissions logging hostname - elif [[ ${#words[@]} -gt 2 ]]; then - case "$command" in - ho|hos|host|hostn|hostna|hostnam|hostname) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" \ - "$(printf '%s\n%s\n%s\n' \ - "$(nmcli general hostname 2>/dev/null)" \ - "$(cat /etc/hostname 2>/dev/null)" \ - "$(hostnamectl status 2>/dev/null | sed -n '1s/^.\+hostname: \(.\+\)$/\1/p')" \ - "$HOSTNAME")" - fi - ;; - l|lo|log|logg|loggi|loggin|logging) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND "${words[2]}" level domains - else - _nmcli_array_delete_at words 0 1 - OPTIONS=(level domains) - _nmcli_compl_ARGS - fi - ;; - esac - fi - ;; - n|ne|net|netw|netwo|networ|network|networki|networkin|networking) - if [[ ${#words[@]} -eq 2 ]]; then - _nmcli_compl_COMMAND "$command" on off connectivity - elif [[ ${#words[@]} -eq 3 ]]; then - case "$command" in - c|co|con|conn|conne|connec|connect|connecti|connectiv|connectivi|connectivit|connectivity) - _nmcli_compl_COMMAND "${words[2]}" "check" - ;; - esac - fi - ;; - r|ra|rad|radi|radio) - if [[ ${#words[@]} -eq 2 ]]; then - _nmcli_compl_COMMAND "$command" all wifi wwan wimax - elif [[ ${#words[@]} -eq 3 ]]; then - case "$command" in - a|al|all | w|wi|wif|wifi | ww|wwa|wwan | wim|wima|wimax) - _nmcli_compl_COMMAND "${words[2]}" "on off" - ;; - esac - fi - ;; - c|co|con|conn|conne|connec|connect|connecti|connectio|connection) - if [[ ${#words[@]} -eq 2 ]]; then - _nmcli_compl_COMMAND "$command" show up down add modify edit delete reload load - elif [[ ${#words[@]} -gt 2 ]]; then - case "$command" in - s|sh|sho|show) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" active - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help active) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - i=$? - - if ! _nmcli_array_has_value LONG_OPTIONS active; then - COMMAND_CONNECTION_ACTIVE=1 - fi - - case $i in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - if [[ "x$COMMAND_CONNECTION_ACTIVE" = x ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}" - - else - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" "${LONG_OPTIONS[@]}" - fi - fi - return 0 - ;; - esac - - OPTIONS=(id uuid path apath) - while [[ ${#words[@]} -gt 0 ]]; do - _nmcli_compl_ARGS_CONNECTION && return 0 - done - if [[ "x$COMMAND_CONNECTION_ACTIVE" = x ]]; then - _nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME)")" - else - _nmcli_list_nl "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" - fi - fi - ;; - u|up) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - - case $? in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "ifname\nid\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}" - fi - return 0 - ;; - esac - - local COMMAND_CONNECTION_TYPE='' - OPTIONS=(ifname id uuid path) - _nmcli_compl_ARGS_CONNECTION && return 0 - - if [[ "$COMMAND_CONNECTION_TYPE" = "ifname" ]]; then - OPTIONS=(ap nsp) - else - OPTIONS=(ifname ap nsp) - fi - _nmcli_compl_ARGS - fi - ;; - d|do|dow|down) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - case $? in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\napath\n%s" "$(_nmcli_con_show NAME --active)")" "${LONG_OPTIONS[@]}" - fi - return 0 - ;; - esac - - OPTIONS=(id uuid path apath) - COMMAND_CONNECTION_ACTIVE=1 - _nmcli_compl_ARGS_CONNECTION && return 0 - fi - ;; - a|ad|add) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - case $? in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - _nmcli_compl_COMMAND "${words[2]}" type ifname con-name autoconnect - fi - return 0 - ;; - esac - - OPTIONS_TYPE= - OPTIONS=(type ifname con-name autoconnect save) - OPTIONS_MANDATORY=(type ifname) - COMMAND_ARGS_WAIT_OPTIONS=1 - OPTIONS_MANDATORY_IFNAME=1 - _nmcli_compl_ARGS && return 0 - - OPTIONS_MANDATORY_IFNAME= - if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then - # we still have some missing mandatory options... - if [[ "$OPTIONS_UNKNOWN_OPTION" != '' ]]; then - if ! _nmcli_array_has_value OPTIONS "${OPTIONS_UNKNOWN_OPTION:1}"; then - # if we encountered an unknown option while having mandatory - # options, just return. - return 0 - fi - fi - _nmcli_list "$(echo "${OPTIONS[@]}")" - return 0 - fi - - OPTIONS_IP=(ip4 ip6 gw4 gw6) - OPTIONS_MANDATORY=() - case "$OPTIONS_TYPE" in - 802-3|802-3-|802-3-e|802-3-et|802-3-eth|802-3-ethe|802-3-ether|802-3-ethern|802-3-etherne|802-3-ethernet| \ - e|et|eth|ethe|ether|ethern|etherne|ethernet) - OPTIONS_TYPED=(mac cloned-mac mtu) - ;; - 802-11-w|802-11-wi|802-11-wir|802-11-wire|802-11-wirel|802-11-wirele|802-11-wireles|802-11-wireless| \ - wif|wifi) - OPTIONS_TYPED=(ssid mac cloned-mac mtu) - OPTIONS_MANDATORY=(ssid) - ;; - wim|wima|wimax) - OPTIONS_TYPED=(mac nsp) - ;; - g|gs|gsm) - OPTIONS_TYPED=(apn user password) - OPTIONS_MANDATORY=(apn) - ;; - c|cd|cdm|cdma) - OPTIONS_TYPED=(user password) - ;; - i|in|inf|infi|infin|infini|infinib|infiniba|infiniban|infiniband) - OPTIONS_TYPED=(mac mtu transport-mode parent p-key) - ;; - bl|blu|blue|bluet|blueto|bluetoo|bluetoot|bluetooth) - OPTIONS_TYPED=(addr bt-type) - ;; - vl|vla|vlan) - OPTIONS_TYPED=(dev id flags ingress egress mtu) - OPTIONS_MANDATORY=(dev) - ;; - bond) - OPTIONS_TYPED=(mode miimon downdelay updelay arp-interval arp-ip-target primary) - ;; - bond-|bond-s|bond-sl|bond-sla|bond-slav|bond-slave) - OPTIONS_TYPED=(master) - OPTIONS_MANDATORY=(master) - OPTIONS_IP=() - ;; - team) - OPTIONS_TYPED=(config) - ;; - team-|team-s|team-sl|team-sla|team-slav|team-slave) - OPTIONS_TYPED=(master config) - OPTIONS_MANDATORY=(master) - OPTIONS_IP=() - ;; - bridge) - OPTIONS_TYPED=(stp priority forward-delay hello-time max-age ageing-time mac) - ;; - bridge-|bridge-s|bridge-sl|bridge-sla|bridge-slav|bridge-slave) - OPTIONS_TYPED=(master priority path-cost hairpin) - OPTIONS_MANDATORY=(master) - OPTIONS_IP=() - ;; - vp|vpn) - OPTIONS_TYPED=(vpn-type user) - OPTIONS_MANDATORY=(vpn-type) - ;; - 802-11-o|802-11-ol|802-11-olp|802-11-olpc|802-11-olpc-|802-11-olpc-m|802-11-olpc-me|802-11-olpc-mes|802-11-olpc-mesh| \ - o|ol|olp|olpc|olpc-|olpc-m|olpc-me|olpc-mes|olpc-mesh) - OPTIONS_TYPED=(ssid channel dhcp-anycast) - OPTIONS_MANDATORY=(ssid) - ;; - p|pp|ppp|pppo|pppoe) - OPTIONS_TYPED=(username password service mtu mac) - OPTIONS_MANDATORY=(username) - ;; - *) - # for an unknown connection type, we stop completion here - return 0 - ;; - esac - if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then - # means, we are at the end of options. Nothing more to parse, just show - # what are the options now. - if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then - _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_TYPED[@]}")" - else - _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_TYPED[@]}") $(echo "${OPTIONS_IP[@]}")" - fi - return 0 - fi - if [[ "${#OPTIONS[@]}" -gt 0 ]]; then - # we still have some options from before, but no mandatory ones. Mix them with OPTIONS_TYPED - # and continue parsing the options... - OPTIONS=("${OPTIONS[@]}" "${OPTIONS_TYPED[@]}") - OPTIONS_NEXT_GROUP=("${OPTIONS_TYPED[@]}") - _nmcli_compl_ARGS && return 0 - - if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then - # means, we are at the end of options. Nothing more to parse, just show - # what are the options now. - if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then - _nmcli_list "$(echo "${OPTIONS[@]}")" - else - _nmcli_list "$(echo "${OPTIONS[@]}") $(echo "${OPTIONS_IP[@]}")" - fi - return 0 - fi - - if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then - # there was an unknown option specified. Maybe we have to stop with the completion. - if [[ "${#OPTIONS_MANDATORY[@]}" -gt 0 ]]; then - # we have an unknown option, but still mandatory ones that must be fullfiled first. - return 0 - fi - if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then - # the unknown option is NOT an IP option. - return 0 - fi - # The unknown option is an IP option, which is fine... continue... - fi - - fi - OPTIONS=("${OPTIONS_TYPED[@]}") - OPTIONS_NEXT_GROUP=() - - if [[ "${#OPTIONS_MANDATORY[@]}" -ge 1 ]]; then - # we have some mandatory options... don't check for IP options yet... - _nmcli_compl_ARGS && return 0 - - if _nmcli_array_has_value OPTIONS "${OPTIONS_MANDATORY[@]}"; then - _nmcli_list "$(echo "${OPTIONS[@]}")" - return 0 - fi - - if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then - if ! _nmcli_array_has_value OPTIONS_IP "${OPTIONS_UNKNOWN_OPTION:1}"; then - # the unknown option is NOT an IP option. - return 0 - fi - fi - fi - - - # no mandatory options... do final completion including IP options - OPTIONS=("${OPTIONS[@]}" "${OPTIONS_IP[@]}") - OPTIONS_NEXT_GROUP=("${OPTIONS_IP[@]}") - _nmcli_compl_ARGS && return 0 - - if [[ "$OPTIONS_UNKNOWN_OPTION" != "" ]]; then - return 0 - fi - - if [[ "$COMMAND_ARGS_WAIT_OPTIONS" -ne 1 ]]; then - # means, we are at the end of options. Nothing more to parse, just show - # what are the options now. - _nmcli_list "$(echo "${OPTIONS[@]}")" - return 0 - fi - - # process the last group of options, as the OPTIONS_TYPED are already handled... - OPTIONS=("${OPTIONS_IP[@]}") - OPTIONS_NEXT_GROUP=() - COMMAND_ARGS_WAIT_OPTIONS=0 - _nmcli_compl_ARGS && return 0 - fi - ;; - e|ed|edi|edit) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")" - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - - case $? in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\ntype\ncon-name\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}" - fi - return 0 - ;; - esac - - if [[ "${words[0]}" = 'type' || "${words[0]}" = 'con-name' ]]; then - OPTIONS=(type con-name) - _nmcli_compl_ARGS - else - OPTIONS=(id uuid path apath) - _nmcli_compl_ARGS_CONNECTION - fi - fi - ;; - m|mo|mod|modi|modif|modify) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" temporary - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help temporary) - HELP_ONLY_AS_FIRST=1 - _nmcli_compl_OPTIONS - case $? in - 0) - return 0 - ;; - 1) - if [[ "$HELP_ONLY_AS_FIRST" == 1 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" "${LONG_OPTIONS[@]}" - fi - return 0 - ;; - esac - - OPTIONS=(id uuid path apath) - _nmcli_compl_ARGS_CONNECTION && return 0 - while [[ "${#words[@]}" -gt 0 ]]; do - if [[ ${#words[@]} -le 1 ]]; then - _nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')" - return 0 - elif [[ ${#words[@]} -le 2 ]]; then - return 0 - fi - _nmcli_array_delete_at words 0 1 - done - _nmcli_list_nl "$(nmcli --fields profile connection show "${COMMAND_CONNECTION_TYPE:-id}" "$COMMAND_CONNECTION_ID" 2>/dev/null | sed -n 's/^\([^:]\+\):.*/\1/p')" - return 0 - fi - ;; - de|del|dele|delet|delete) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" - elif [[ ${#words[@]} -gt 3 ]]; then - _nmcli_array_delete_at words 0 1 - - LONG_OPTIONS=(help) - _nmcli_compl_OPTIONS - case $? in - 0) - return 0 - ;; - 1) - if ! _nmcli_array_has_value LONG_OPTIONS "help"; then - return 0 - fi - ;; - esac - - OPTIONS=(id uuid path apath) - while [[ ${#words[@]} -gt 0 ]]; do - _nmcli_compl_ARGS_CONNECTION && return 0 - done - _nmcli_list_nl "$(printf "id\nuuid\npath\n%s" "$(_nmcli_con_show NAME)")" - fi - ;; - l|lo|loa|load) - if [[ ${#words[@]} -gt 2 ]]; then - # we should also complete for help/--help, but who to mix that - # with file name completion? - compopt -o default - COMPREPLY=() - fi - ;; - esac - fi - ;; - d|de|dev|devi|devic|device) - if [[ ${#words[@]} -eq 2 ]]; then - _nmcli_compl_COMMAND "$command" status show connect disconnect wifi wimax - elif [[ ${#words[@]} -gt 2 ]]; then - case "$command" in - s|st|sta|stat|statu|status) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND "${words[2]}" - fi - ;; - sh|sho|show| \ - c|co|con|conn|conne|connec|connect| \ - d|di|dis|disc|disco|discon|disconn|disconne|disconnec|disconnect) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND_nl "${words[2]}" "$(_nmcli_dev_status DEVICE)" - fi - ;; - w|wi|wif|wifi) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND "${words[2]}" list connect rescan - else - case "${words[2]}" in - l|li|lis|list) - _nmcli_array_delete_at words 0 2 - OPTIONS=(ifname bssid) - _nmcli_compl_ARGS - ;; - c|co|con|conn|conne|connec|connect) - if [[ ${#words[@]} -eq 4 ]]; then - if [[ "${words[3]}" = "" ]]; then - _nmcli_list_nl "$(_nmcli_wifi_list SSID)" - else - _nmcli_list_nl "$(printf "%s\n%s" "$(_nmcli_wifi_list SSID)" "$(_nmcli_wifi_list BSSID)")" - fi - else - _nmcli_array_delete_at words 0 3 - local OPTIONS=(password wep-key-type ifname bssid name private) - _nmcli_compl_ARGS - fi - ;; - r|re|res|resc|resca|rescan) - _nmcli_array_delete_at words 0 2 - OPTIONS=(ifname) - _nmcli_compl_ARGS - ;; - esac - fi - ;; - wim|wima|wimax) - if [[ ${#words[@]} -eq 3 ]]; then - _nmcli_compl_COMMAND "${words[2]}" list - else - case "${words[2]}" in - l|li|lis|list) - _nmcli_array_delete_at words 0 2 - OPTIONS=(ifname nsp) - _nmcli_compl_ARGS - ;; - esac - fi - ;; - - esac - fi - ;; - esac - - return 0 -} && -complete -F _nmcli nmcli - -# ex: ts=4 sw=4 et filetype=sh diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am deleted file mode 100644 index e61c0368..00000000 --- a/cli/src/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -bin_PROGRAMS = \ - nmcli - -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - -DNMCLI_LOCALEDIR=\"$(datadir)/locale\" - -nmcli_SOURCES = \ - common.c \ - common.h \ - connections.c \ - connections.h \ - devices.c \ - devices.h \ - network-manager.c \ - network-manager.h \ - settings.c \ - settings.h \ - nmcli.c \ - nmcli.h \ - utils.c \ - utils.h - -nmcli_LDADD = \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(READLINE_LIBS) \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la - - diff --git a/cli/src/Makefile.in b/cli/src/Makefile.in deleted file mode 100644 index 8f3129c7..00000000 --- a/cli/src/Makefile.in +++ /dev/null @@ -1,809 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 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@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -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@ -bin_PROGRAMS = nmcli$(EXEEXT) -subdir = cli/src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am_nmcli_OBJECTS = common.$(OBJEXT) connections.$(OBJEXT) \ - devices.$(OBJEXT) network-manager.$(OBJEXT) settings.$(OBJEXT) \ - nmcli.$(OBJEXT) utils.$(OBJEXT) -nmcli_OBJECTS = $(am_nmcli_OBJECTS) -am__DEPENDENCIES_1 = -nmcli_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -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_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -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_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(nmcli_SOURCES) -DIST_SOURCES = $(nmcli_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -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@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -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@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -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@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -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@ -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_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -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_CXX = @ac_ct_CXX@ -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@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_builddir}/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ - $(DBUS_CFLAGS) \ - $(GLIB_CFLAGS) \ - -DG_LOG_DOMAIN=\""nmcli"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - -DNMCLI_LOCALEDIR=\"$(datadir)/locale\" - -nmcli_SOURCES = \ - common.c \ - common.h \ - connections.c \ - connections.h \ - devices.c \ - devices.h \ - network-manager.c \ - network-manager.h \ - settings.c \ - settings.h \ - nmcli.c \ - nmcli.h \ - utils.c \ - utils.h - -nmcli_LDADD = \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) \ - $(READLINE_LIBS) \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la - -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 cli/src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu cli/src/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-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_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 - -nmcli$(EXEEXT): $(nmcli_OBJECTS) $(nmcli_DEPENDENCIES) $(EXTRA_nmcli_DEPENDENCIES) - @rm -f nmcli$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(nmcli_OBJECTS) $(nmcli_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connections.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devices.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network-manager.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmcli.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - 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-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - 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" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -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 $(PROGRAMS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; 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: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -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-binPROGRAMS 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-binPROGRAMS - -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-binPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - 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 tags-am uninstall uninstall-am uninstall-binPROGRAMS - - -# 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/cli/src/common.c b/cli/src/common.c deleted file mode 100644 index e6712a8d..00000000 --- a/cli/src/common.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * nmcli - command-line tool for controlling NetworkManager - * Common functions and data shared between files. - * - * 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 2012 - 2014 Red Hat, Inc. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include "common.h" -#include "utils.h" - -/* Available fields for IPv4 group */ -NmcOutputField nmc_fields_ip4_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"ADDRESS", N_("ADDRESS"), 68}, /* 1 */ - {"ROUTE", N_("ROUTE"), 68}, /* 2 */ - {"DNS", N_("DNS"), 35}, /* 3 */ - {"DOMAIN", N_("DOMAIN"), 35}, /* 4 */ - {"WINS", N_("WINS"), 20}, /* 5 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_IP4_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN,WINS" - -/* Available fields for DHCPv4 group */ -NmcOutputField nmc_fields_dhcp4_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"OPTION", N_("OPTION"), 80}, /* 1 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_DHCP4_CONFIG_ALL "GROUP,OPTION" - -/* Available fields for IPv6 group */ -NmcOutputField nmc_fields_ip6_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"ADDRESS", N_("ADDRESS"), 95}, /* 1 */ - {"ROUTE", N_("ROUTE"), 95}, /* 2 */ - {"DNS", N_("DNS"), 60}, /* 3 */ - {"DOMAIN", N_("DOMAIN"), 35}, /* 4 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_IP6_CONFIG_ALL "GROUP,ADDRESS,ROUTE,DNS,DOMAIN" - -/* Available fields for DHCPv6 group */ -NmcOutputField nmc_fields_dhcp6_config[] = { - {"GROUP", N_("GROUP"), 15}, /* 0 */ - {"OPTION", N_("OPTION"), 80}, /* 1 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_DHCP6_CONFIG_ALL "GROUP,OPTION" - - -gboolean -print_ip4_config (NMIP4Config *cfg4, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GSList *list, *iter; - const GArray *array; - const GPtrArray *ptr_array; - char **addr_arr = NULL; - char **route_arr = NULL; - char **dns_arr = NULL; - char **domain_arr = NULL; - char **wins_arr = NULL; - int i = 0; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (cfg4 == NULL) - return FALSE; - - tmpl = nmc_fields_ip4_config; - tmpl_len = sizeof (nmc_fields_ip4_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP4_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* addresses */ - list = (GSList *) nm_ip4_config_get_addresses (cfg4); - addr_arr = g_new (char *, g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - guint32 prefix; - char *ip_str, *gw_str; - - ip_str = nmc_ip4_address_as_string (nm_ip4_address_get_address (addr), NULL); - prefix = nm_ip4_address_get_prefix (addr); - gw_str = nmc_ip4_address_as_string (nm_ip4_address_get_gateway (addr), NULL); - - addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); - g_free (ip_str); - g_free (gw_str); - } - addr_arr[i] = NULL; - - /* routes */ - list = (GSList *) nm_ip4_config_get_routes (cfg4); - route_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP4Route *route = (NMIP4Route *) iter->data; - guint32 prefix, metric; - char *dest_str, *nexthop_str; - - dest_str = nmc_ip4_address_as_string (nm_ip4_route_get_dest (route), NULL); - nexthop_str = nmc_ip4_address_as_string (nm_ip4_route_get_next_hop (route), NULL); - prefix = nm_ip4_route_get_prefix (route); - metric = nm_ip4_route_get_metric (route); - - route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); - g_free (dest_str); - g_free (nexthop_str); - } - route_arr[i] = NULL; - - /* DNS */ - array = nm_ip4_config_get_nameservers (cfg4); - if (array) { - dns_arr = g_new (char *, array->len + 1); - for (i = 0; i < array->len; i++) - dns_arr[i] = nmc_ip4_address_as_string (g_array_index (array, guint32, i), NULL); - - dns_arr[i] = NULL; - } - - /* domains */ - ptr_array = nm_ip4_config_get_domains (cfg4); - if (ptr_array) { - domain_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) - domain_arr[i] = g_strdup (g_ptr_array_index (ptr_array, i)); - - domain_arr[i] = NULL; - } - - /* WINS */ - array = nm_ip4_config_get_wins_servers (cfg4); - if (array) { - wins_arr = g_new (char *, array->len + 1); - for (i = 0; i < array->len; i++) - wins_arr[i] = nmc_ip4_address_as_string (g_array_index (array, guint32, i), NULL); - - wins_arr[i] = NULL; - } - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, addr_arr); - set_val_arr (arr, 2, route_arr); - set_val_arr (arr, 3, dns_arr); - set_val_arr (arr, 4, domain_arr); - set_val_arr (arr, 5, wins_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; -} - -gboolean -print_ip6_config (NMIP6Config *cfg6, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GSList *list, *iter; - const GPtrArray *ptr_array; - char **addr_arr = NULL; - char **route_arr = NULL; - char **dns_arr = NULL; - char **domain_arr = NULL; - int i = 0; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (cfg6 == NULL) - return FALSE; - - tmpl = nmc_fields_ip6_config; - tmpl_len = sizeof (nmc_fields_ip6_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP6_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* addresses */ - list = (GSList *) nm_ip6_config_get_addresses (cfg6); - addr_arr = g_new (char *, g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP6Address *addr = (NMIP6Address *) iter->data; - guint32 prefix; - char *ip_str, *gw_str; - - ip_str = nmc_ip6_address_as_string (nm_ip6_address_get_address (addr), NULL); - prefix = nm_ip6_address_get_prefix (addr); - gw_str = nmc_ip6_address_as_string (nm_ip6_address_get_gateway (addr), NULL); - - addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); - g_free (ip_str); - g_free (gw_str); - } - addr_arr[i] = NULL; - - /* routes */ - list = (GSList *) nm_ip6_config_get_routes (cfg6); - route_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) { - NMIP6Route *route = (NMIP6Route *) iter->data; - guint32 prefix, metric; - char *dest_str, *nexthop_str; - - dest_str = nmc_ip6_address_as_string (nm_ip6_route_get_dest (route), NULL); - nexthop_str = nmc_ip6_address_as_string (nm_ip6_route_get_next_hop (route), NULL); - prefix = nm_ip6_route_get_prefix (route); - metric = nm_ip6_route_get_metric (route); - - route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); - g_free (dest_str); - g_free (nexthop_str); - } - route_arr[i] = NULL; - - /* DNS */ - list = (GSList *) nm_ip6_config_get_nameservers (cfg6); - dns_arr = g_new (char *, g_slist_length (list) + 1); - i = 0; - for (iter = list; iter; iter = g_slist_next (iter)) - dns_arr[i++] = nmc_ip6_address_as_string (iter->data, NULL); - - dns_arr[i] = NULL; - - /* domains */ - ptr_array = nm_ip6_config_get_domains (cfg6); - if (ptr_array) { - domain_arr = g_new (char *, ptr_array->len + 1); - for (i = 0; i < ptr_array->len; i++) - domain_arr[i] = g_strdup (g_ptr_array_index (ptr_array, i)); - - domain_arr[i] = NULL; - } - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, addr_arr); - set_val_arr (arr, 2, route_arr); - set_val_arr (arr, 3, dns_arr); - set_val_arr (arr, 4, domain_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; -} - -gboolean -print_dhcp4_config (NMDHCP4Config *dhcp4, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GHashTable *table; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (dhcp4 == NULL) - return FALSE; - - table = nm_dhcp4_config_get_options (dhcp4); - if (table) { - GHashTableIter table_iter; - gpointer key, value; - char **options_arr = NULL; - int i = 0; - - tmpl = nmc_fields_dhcp4_config; - tmpl_len = sizeof (nmc_fields_dhcp4_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP4_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - options_arr = g_new (char *, g_hash_table_size (table) + 1); - g_hash_table_iter_init (&table_iter, table); - while (g_hash_table_iter_next (&table_iter, &key, &value)) - options_arr[i++] = g_strdup_printf ("%s = %s", (char *) key, (char *) value); - options_arr[i] = NULL; - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, options_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; - } - return FALSE; -} - -gboolean -print_dhcp6_config (NMDHCP6Config *dhcp6, - NmCli *nmc, - const char *group_prefix, - const char *one_field) -{ - GHashTable *table; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - - if (dhcp6 == NULL) - return FALSE; - - table = nm_dhcp6_config_get_options (dhcp6); - if (table) { - GHashTableIter table_iter; - gpointer key, value; - char **options_arr = NULL; - int i = 0; - - tmpl = nmc_fields_dhcp6_config; - tmpl_len = sizeof (nmc_fields_dhcp6_config); - nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_DHCP6_CONFIG_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - options_arr = g_new (char *, g_hash_table_size (table) + 1); - g_hash_table_iter_init (&table_iter, table); - while (g_hash_table_iter_next (&table_iter, &key, &value)) - options_arr[i++] = g_strdup_printf ("%s = %s", (char *) key, (char *) value); - options_arr[i] = NULL; - - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, group_prefix); - set_val_arr (arr, 1, options_arr); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - return TRUE; - } - return FALSE; -} - -/* - * Parse IPv4 address from string to NMIP4Address stucture. - * ip_str is the IPv4 address in the form address/prefix - * gw_str is the gateway address (it is optional) - */ -NMIP4Address * -nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error) -{ - NMIP4Address *addr = NULL; - guint32 ip4_addr, gw_addr; - char *tmp; - char *plen; - long int prefix; - - g_return_val_if_fail (ip_str != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - tmp = g_strdup (ip_str); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (AF_INET, tmp, &ip4_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid IPv4 address '%s'"), tmp); - goto finish; - } - - prefix = 32; - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, 32, &prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-32> allowed"), plen); - goto finish; - } - } - - if (inet_pton (AF_INET, gw_str ? gw_str : "0.0.0.0", &gw_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid gateway '%s'"), gw_str); - goto finish; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip4_addr); - nm_ip4_address_set_prefix (addr, (guint32) prefix); - nm_ip4_address_set_gateway (addr, gw_addr); - -finish: - g_free (tmp); - return addr; -} - -/* - * Parse IPv6 address from string to NMIP6Address stucture. - * ip_str is the IPv6 address in the form address/prefix - * gw_str is the gateway address (it is optional) - */ -NMIP6Address * -nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error) -{ - NMIP6Address *addr = NULL; - struct in6_addr ip_addr, gw_addr; - char *tmp; - char *plen; - long int prefix; - - g_return_val_if_fail (ip_str != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - tmp = g_strdup (ip_str); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (AF_INET6, tmp, &ip_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid IPv6 address '%s'"), tmp); - goto finish; - } - - prefix = 128; - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, 128, &prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-128> allowed"), plen); - goto finish; - } - } - - if (inet_pton (AF_INET6, gw_str ? gw_str : "::", &gw_addr) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid gateway '%s'"), gw_str); - goto finish; - } - - addr = nm_ip6_address_new (); - nm_ip6_address_set_address (addr, &ip_addr); - nm_ip6_address_set_prefix (addr, (guint32) prefix); - nm_ip6_address_set_gateway (addr, &gw_addr); - -finish: - g_free (tmp); - return addr; -} - -typedef struct { - long int prefix; - long int metric; - union _IpDest { - guint32 ip4_dst; - struct in6_addr ip6_dst; - } dst; - union _IpNextHop { - guint32 ip4_nh; - struct in6_addr ip6_nh; - } nh; -} ParsedRoute; - -/* - * _parse_and_build_route: - * @family: AF_INET or AF_INET6 - * @first: the route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @out: (out): route struct to fill - * @error: location to store GError - * - * Parse route from strings and fill @out parameter. - * - * Returns: %TRUE on success, %FALSE on failure - */ -static gboolean -_parse_and_build_route (int family, - const char *first, - const char *second, - const char *third, - ParsedRoute *out, - GError **error) -{ - int max_prefix; - char *tmp, *plen; - gboolean success = FALSE; - - g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE); - g_return_val_if_fail (first != NULL, FALSE); - g_return_val_if_fail (second || !third, FALSE); - g_return_val_if_fail (out, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - max_prefix = (family == AF_INET) ? 32 : 128; - /* initialize default values */ - out->prefix = max_prefix; - out->metric = 0; - if (family == AF_INET) - out->nh.ip4_nh = 0; - else - out->nh.ip6_nh = in6addr_any; - - tmp = g_strdup (first); - plen = strchr (tmp, '/'); /* prefix delimiter */ - if (plen) - *plen++ = '\0'; - - if (inet_pton (family, tmp, family == AF_INET ? (void *) &out->dst.ip4_dst : (void *) &out->dst.ip6_dst) < 1) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid route destination address '%s'"), tmp); - goto finish; - } - - if (plen) { - if (!nmc_string_to_int (plen, TRUE, 1, max_prefix, &out->prefix)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid prefix '%s'; <1-%d> allowed"), - plen, max_prefix); - goto finish; - } - } - - if (second) { - if (inet_pton (family, second, family == AF_INET ? (void *) &out->nh.ip4_nh : (void *) &out->nh.ip6_nh) < 1) { - if (third) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("invalid next hop address '%s'"), second); - goto finish; - } else { - /* 'second' can be a metric */ - if (!nmc_string_to_int (second, TRUE, 0, G_MAXUINT32, &out->metric)) { - g_set_error (error, 1, 0, _("the second component of route ('%s') is neither " - "a next hop address nor a metric"), second); - goto finish; - } - } - } - } - - if (third) { - if (!nmc_string_to_int (third, TRUE, 0, G_MAXUINT32, &out->metric)) { - g_set_error (error, 1, 0, _("invalid metric '%s'"), third); - goto finish; - } - } - - /* We don't accept default routes as NetworkManager handles it itself */ - if ( (family == AF_INET && out->dst.ip4_dst == 0) - || (family == AF_INET6 && IN6_IS_ADDR_UNSPECIFIED (&out->dst.ip6_dst))) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("default route cannot be added (NetworkManager handles it by itself)")); - goto finish; - } - - success = TRUE; - -finish: - g_free (tmp); - return success; -} - -/* - * nmc_parse_and_build_ip4_route: - * @first: the IPv4 route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @error: location to store GError - * - * Parse IPv4 route from strings to NMIP4Route stucture. - * - * Returns: route as a NMIP4Route object, or %NULL on failure - */ -NMIP4Route * -nmc_parse_and_build_ip4_route (const char *first, - const char *second, - const char *third, - GError **error) -{ - ParsedRoute tmp_route; - NMIP4Route *route = NULL; - - g_return_val_if_fail (first != NULL, NULL); - g_return_val_if_fail (second || !third, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (_parse_and_build_route (AF_INET, first, second, third, &tmp_route, error)) { - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, tmp_route.dst.ip4_dst); - nm_ip4_route_set_prefix (route, (guint32) tmp_route.prefix); - nm_ip4_route_set_next_hop (route, tmp_route.nh.ip4_nh); - nm_ip4_route_set_metric (route, (guint32) tmp_route.metric); - } - return route; -} - -/* - * nmc_parse_and_build_ip6_route: - * @first: the IPv6 route destination in the form of "address/prefix" - (/prefix is optional) - * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be - either next hop address or metric. (It can be NULL when @third is NULL). - * @third: (allow-none): route metric - * @error: location to store GError - * - * Parse IPv6 route from strings to NMIP6Route stucture. - * - * Returns: route as a NMIP6Route object, or %NULL on failure - */ -NMIP6Route * -nmc_parse_and_build_ip6_route (const char *first, - const char *second, - const char *third, - GError **error) -{ - ParsedRoute tmp_route; - NMIP6Route *route = NULL; - - g_return_val_if_fail (first != NULL, NULL); - g_return_val_if_fail (second || !third, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (_parse_and_build_route (AF_INET6, first, second, third, &tmp_route, error)) { - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, &tmp_route.dst.ip6_dst); - nm_ip6_route_set_prefix (route, (guint32) tmp_route.prefix); - nm_ip6_route_set_next_hop (route, &tmp_route.nh.ip6_nh); - nm_ip6_route_set_metric (route, (guint32) tmp_route.metric); - } - return route; -} - -const char * -nmc_device_state_to_string (NMDeviceState state) -{ - switch (state) { - case NM_DEVICE_STATE_UNMANAGED: - return _("unmanaged"); - case NM_DEVICE_STATE_UNAVAILABLE: - return _("unavailable"); - case NM_DEVICE_STATE_DISCONNECTED: - return _("disconnected"); - case NM_DEVICE_STATE_PREPARE: - return _("connecting (prepare)"); - case NM_DEVICE_STATE_CONFIG: - return _("connecting (configuring)"); - case NM_DEVICE_STATE_NEED_AUTH: - return _("connecting (need authentication)"); - case NM_DEVICE_STATE_IP_CONFIG: - return _("connecting (getting IP configuration)"); - case NM_DEVICE_STATE_IP_CHECK: - return _("connecting (checking IP connectivity)"); - case NM_DEVICE_STATE_SECONDARIES: - return _("connecting (starting secondary connections)"); - case NM_DEVICE_STATE_ACTIVATED: - return _("connected"); - case NM_DEVICE_STATE_DEACTIVATING: - return _("deactivating"); - case NM_DEVICE_STATE_FAILED: - return _("connection failed"); - default: - return _("unknown"); - } -} - -const char * -nmc_device_reason_to_string (NMDeviceStateReason reason) -{ - switch (reason) { - case NM_DEVICE_STATE_REASON_NONE: - return _("No reason given"); - - case NM_DEVICE_STATE_REASON_UNKNOWN: - return _("Unknown error"); - - case NM_DEVICE_STATE_REASON_NOW_MANAGED: - return _("Device is now managed"); - - case NM_DEVICE_STATE_REASON_NOW_UNMANAGED: - return _("Device is now unmanaged"); - - case NM_DEVICE_STATE_REASON_CONFIG_FAILED: - return _("The device could not be readied for configuration"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: - return _("IP configuration could not be reserved (no available address, timeout, etc.)"); - - case NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: - return _("The IP configuration is no longer valid"); - - case NM_DEVICE_STATE_REASON_NO_SECRETS: - return _("Secrets were required, but not provided"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: - return _("802.1X supplicant disconnected"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: - return _("802.1X supplicant configuration failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: - return _("802.1X supplicant failed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: - return _("802.1X supplicant took too long to authenticate"); - - case NM_DEVICE_STATE_REASON_PPP_START_FAILED: - return _("PPP service failed to start"); - - case NM_DEVICE_STATE_REASON_PPP_DISCONNECT: - return _("PPP service disconnected"); - - case NM_DEVICE_STATE_REASON_PPP_FAILED: - return _("PPP failed"); - - case NM_DEVICE_STATE_REASON_DHCP_START_FAILED: - return _("DHCP client failed to start"); - - case NM_DEVICE_STATE_REASON_DHCP_ERROR: - return _("DHCP client error"); - - case NM_DEVICE_STATE_REASON_DHCP_FAILED: - return _("DHCP client failed"); - - case NM_DEVICE_STATE_REASON_SHARED_START_FAILED: - return _("Shared connection service failed to start"); - - case NM_DEVICE_STATE_REASON_SHARED_FAILED: - return _("Shared connection service failed"); - - case NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: - return _("AutoIP service failed to start"); - - case NM_DEVICE_STATE_REASON_AUTOIP_ERROR: - return _("AutoIP service error"); - - case NM_DEVICE_STATE_REASON_AUTOIP_FAILED: - return _("AutoIP service failed"); - - case NM_DEVICE_STATE_REASON_MODEM_BUSY: - return _("The line is busy"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: - return _("No dial tone"); - - case NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: - return _("No carrier could be established"); - - case NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: - return _("The dialing request timed out"); - - case NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: - return _("The dialing attempt failed"); - - case NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: - return _("Modem initialization failed"); - - case NM_DEVICE_STATE_REASON_GSM_APN_FAILED: - return _("Failed to select the specified APN"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: - return _("Not searching for networks"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: - return _("Network registration denied"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: - return _("Network registration timed out"); - - case NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: - return _("Failed to register with the requested network"); - - case NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: - return _("PIN check failed"); - - case NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: - return _("Necessary firmware for the device may be missing"); - - case NM_DEVICE_STATE_REASON_REMOVED: - return _("The device was removed"); - - case NM_DEVICE_STATE_REASON_SLEEPING: - return _("NetworkManager went to sleep"); - - case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: - return _("The device's active connection disappeared"); - - case NM_DEVICE_STATE_REASON_USER_REQUESTED: - return _("Device disconnected by user or client"); - - case NM_DEVICE_STATE_REASON_CARRIER: - return _("Carrier/link changed"); - - case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: - return _("The device's existing connection was assumed"); - - case NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: - return _("The supplicant is now available"); - - case NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: - return _("The modem could not be found"); - - case NM_DEVICE_STATE_REASON_BT_FAILED: - return _("The Bluetooth connection failed or timed out"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: - return _("GSM Modem's SIM card not inserted"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: - return _("GSM Modem's SIM PIN required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: - return _("GSM Modem's SIM PUK required"); - - case NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: - return _("GSM Modem's SIM wrong"); - - case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: - return _("InfiniBand device does not support connected mode"); - - case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - return _("A dependency of the connection failed"); - - case NM_DEVICE_STATE_REASON_BR2684_FAILED: - return _("A problem with the RFC 2684 Ethernet over ADSL bridge"); - - case NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE: - return _("ModemManager is unavailable"); - - case NM_DEVICE_STATE_REASON_SSID_NOT_FOUND: - return _("The Wi-Fi network could not be found"); - - case NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED: - return _("A secondary connection of the base connection failed"); - - case NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED: - return _("DCB or FCoE setup failed"); - - case NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED: - return _("teamd control failed"); - - case NM_DEVICE_STATE_REASON_MODEM_FAILED: - return _("Modem failed or no longer available"); - - case NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: - return _("Modem now ready and available"); - - case NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: - return _("SIM PIN was incorrect"); - - default: - /* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */ - return _("Unknown"); - } -} - - -/* Max priority values from libnm-util/nm-setting-vlan.c */ -#define MAX_SKB_PRIO G_MAXUINT32 -#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ - -/* - * Parse VLAN priority mappings from the following format: 2:1,3:4,7:3 - * and verify if the priority numbers are valid - * - * Return: string array with split maps, or NULL on error - * Caller is responsible for freeing the array. - */ -char ** -nmc_vlan_parse_priority_maps (const char *priority_map, - NMVlanPriorityMap map_type, - GError **error) -{ - char **mapping = NULL, **iter; - unsigned long from, to, from_max, to_max; - - g_return_val_if_fail (priority_map != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (map_type == NM_VLAN_INGRESS_MAP) { - from_max = MAX_8021P_PRIO; - to_max = MAX_SKB_PRIO; - } else { - from_max = MAX_SKB_PRIO; - to_max = MAX_8021P_PRIO; - } - - mapping = g_strsplit (priority_map, ",", 0); - for (iter = mapping; iter && *iter; iter++) { - char *left, *right; - - left = g_strstrip (*iter); - right = strchr (left, ':'); - if (!right) { - g_set_error (error, 1, 0, _("invalid priority map '%s'"), *iter); - g_strfreev (mapping); - return NULL; - } - *right++ = '\0'; - - if (!nmc_string_to_uint (left, TRUE, 0, from_max, &from)) { - g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"), - left, from_max); - g_strfreev (mapping); - return NULL; - } - if (!nmc_string_to_uint (right, TRUE, 0, to_max, &to)) { - g_set_error (error, 1, 0, _("priority '%s' is not valid (<0-%ld>)"), - right, to_max); - g_strfreev (mapping); - return NULL; - } - *(right-1) = ':'; /* Put back ':' */ - } - return mapping; -} - -const char * -nmc_bond_validate_mode (const char *mode, GError **error) -{ - unsigned long mode_int; - static const char *valid_modes[] = { "balance-rr", - "active-backup", - "balance-xor", - "broadcast", - "802.3ad", - "balance-tlb", - "balance-alb", - NULL }; - if (nmc_string_to_uint (mode, TRUE, 0, 6, &mode_int)) { - /* Translate bonding mode numbers to mode names: - * https://www.kernel.org/doc/Documentation/networking/bonding.txt - */ - return valid_modes[mode_int]; - } else - return nmc_string_is_valid (mode, valid_modes, error); -} - -/* - * nmc_team_check_config: - * @config: file name with team config, or raw team JSON config data - * @out_config: raw team JSON config data (with removed new-line characters) - * @error: location to store error, or %NUL - * - * Check team config from @config parameter and return the checked/sanitized - * config in @out_config. - * - * Returns: %TRUE if the config is valid, %FALSE if it is invalid - */ -gboolean -nmc_team_check_config (const char *config, char **out_config, GError **error) -{ - char *contents = NULL; - size_t c_len = 0; - - *out_config = NULL; - - if (!config || strlen (config) == strspn (config, " \t")) - return TRUE; - - /* 'config' can be either a file name or raw JSON config data */ - if (g_file_test (config, G_FILE_TEST_EXISTS)) - (void) g_file_get_contents (config, &contents, NULL, NULL); - else - contents = g_strdup (config); - - if (contents) { - g_strstrip (contents); - c_len = strlen (contents); - } - - /* Do a simple validity check */ - if (!contents || !contents[0] || c_len > 100000 || contents[0] != '{' || contents[c_len-1] != '}') { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("'%s' is not a valid team configuration or file name."), config); - g_free (contents); - return FALSE; - } - *out_config = g_strdelimit (contents, "\r\n", ' '); - return TRUE; -} - -/* - * nmc_find_connection: - * @list: list of NMConnections to search in - * @filter_type: "id", "uuid", "path" or %NULL - * @filter_val: connection to find (connection name, UUID or path) - * @start: where to start in @list. The location is updated so that the function - * can be called multiple times (for connections with the same name). - * - * Find a connection in @list according to @filter_val. @filter_type determines - * what property is used for comparison. When @filter_type is NULL, compare - * @filter_val against all types. Otherwise, only compare against the specified - * type. If 'path' filter type is specified, comparison against numeric index - * (in addition to the whole path) is allowed. - * - * Returns: found connection, or %NULL - */ -NMConnection * -nmc_find_connection (GSList *list, - const char *filter_type, - const char *filter_val, - GSList **start) -{ - NMConnection *connection; - NMConnection *found = NULL; - GSList *iterator; - const char *id; - const char *uuid; - const char *path, *path_num; - - iterator = (start && *start) ? *start : list; - while (iterator) { - connection = NM_CONNECTION (iterator->data); - - id = nm_connection_get_id (connection); - uuid = nm_connection_get_uuid (connection); - path = nm_connection_get_path (connection); - path_num = path ? strrchr (path, '/') + 1 : NULL; - - /* When filter_type is NULL, compare connection ID (filter_val) - * against all types. Otherwise, only compare against the specific - * type. If 'path' filter type is specified, comparison against - * numeric index (in addition to the whole path) is allowed. - */ - if ( ( (!filter_type || strcmp (filter_type, "id") == 0) - && strcmp (filter_val, id) == 0) - || ( (!filter_type || strcmp (filter_type, "uuid") == 0) - && strcmp (filter_val, uuid) == 0) - || ( (!filter_type || strcmp (filter_type, "path") == 0) - && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) { - if (!start) - return connection; - if (found) { - *start = iterator; - return found; - } - found = connection; - } - - iterator = g_slist_next (iterator); - } - - if (start) - *start = NULL; - return found; -} - -/** - * nmc_cleanup_readline: - * - * Cleanup readline when nmcli is terminated with a signal. - * It makes sure the terminal is not garbled. - */ -void -nmc_cleanup_readline (void) -{ - rl_free_line_state (); - rl_cleanup_after_signal (); -} - -/** - * nmc_readline: - * @prompt_fmt: prompt to print (telling user what to enter). It is standard - * printf() format string - * @...: a list of arguments according to the @prompt_fmt format string - * - * Wrapper around libreadline's readline() function. - * - * Returns: the user provided string. In case the user entered empty string, - * this function returns NULL. - */ -char * -nmc_readline (const char *prompt_fmt, ...) -{ - va_list args; - char *prompt, *str; - - va_start (args, prompt_fmt); - prompt = g_strdup_vprintf (prompt_fmt, args); - va_end (args); - - str = readline (prompt); - /* Return NULL, not empty string */ - if (str && *str == '\0') { - g_free (str); - str = NULL; - } - - if (str && *str) - add_history (str); - - g_free (prompt); - return str; -} - -/** - * nmc_rl_gen_func_basic: - * @text: text to complete - * @state: readline state; says whether start from scratch (state == 0) - * @words: strings for completion - * - * Basic function generating list of completion strings for readline. - * See e.g. http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC49 - */ -char * -nmc_rl_gen_func_basic (const char *text, int state, const char **words) -{ - static int list_idx, len; - const char *name; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - /* Return the next name which partially matches one from the 'words' list. */ - while ((name = words[list_idx])) { - list_idx++; - - if (strncmp (name, text, len) == 0) - return g_strdup (name); - } - return NULL; -} - diff --git a/cli/src/common.h b/cli/src/common.h deleted file mode 100644 index 228375b9..00000000 --- a/cli/src/common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * nmcli - command-line tool for controlling NetworkManager - * Common functions and data shared between files. - * - * 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 2012 - 2014 Red Hat, Inc. - */ - -#ifndef NMC_COMMON_H -#define NMC_COMMON_H - -#include - -#include -#include -#include -#include -#include - -#include "nmcli.h" - -gboolean print_ip4_config (NMIP4Config *cfg4, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_dhcp4_config (NMDHCP4Config *dhcp4, NmCli *nmc, const char *group_prefix, const char *one_field); -gboolean print_dhcp6_config (NMDHCP6Config *dhcp6, NmCli *nmc, const char *group_prefix, const char *one_field); - -NMIP4Address *nmc_parse_and_build_ip4_address (const char *ip_str, const char *gw_str, GError **error); -NMIP6Address *nmc_parse_and_build_ip6_address (const char *ip_str, const char *gw_str, GError **error); - -NMIP4Route *nmc_parse_and_build_ip4_route (const char *first, const char *second, const char *third, GError **error); -NMIP6Route *nmc_parse_and_build_ip6_route (const char *first, const char *second, const char *third, GError **error); - -const char * nmc_device_state_to_string (NMDeviceState state); -const char * nmc_device_reason_to_string (NMDeviceStateReason reason); - -char ** -nmc_vlan_parse_priority_maps (const char *priority_map, - NMVlanPriorityMap map_type, - GError **error); - -const char *nmc_bond_validate_mode (const char *mode, GError **error); -gboolean nmc_team_check_config (const char *config, char **out_config, GError **error); - -NMConnection *nmc_find_connection (GSList *list, - const char *filter_type, - const char *filter_val, - GSList **start); - -void nmc_cleanup_readline (void); -char *nmc_readline (const char *prompt_fmt, ...) G_GNUC_PRINTF (1, 2); -char *nmc_rl_gen_func_basic (const char *text, int state, const char **words); - -#endif /* NMC_COMMON_H */ diff --git a/cli/src/connections.c b/cli/src/connections.c deleted file mode 100644 index d17f7f12..00000000 --- a/cli/src/connections.c +++ /dev/null @@ -1,8706 +0,0 @@ -/* nmcli - command-line tool to control NetworkManager - * - * 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 - 2014 Red Hat, Inc. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#if WITH_WIMAX -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "common.h" -#include "settings.h" -#include "connections.h" - -/* Activation timeout waiting for bond/team/bridge slaves (in seconds) */ -#define SLAVES_UP_TIMEOUT 10 - -/* define some prompts for connection editor */ -#define EDITOR_PROMPT_SETTING _("Setting name? ") -#define EDITOR_PROMPT_PROPERTY _("Property name? ") -#define EDITOR_PROMPT_CON_TYPE _("Enter connection type: ") - -/* define some other prompts */ -#define PROMPT_CON_TYPE _("Connection type: ") -#define PROMPT_VPN_TYPE _("VPN type: ") -#define PROMPT_BOND_MASTER _("Bond master: ") -#define PROMPT_TEAM_MASTER _("Team master: ") -#define PROMPT_BRIDGE_MASTER _("Bridge master: ") -#define PROMPT_CONNECTION _("Connection (name, UUID, or path): ") - -static const char *nmc_known_vpns[] = - { "openvpn", "vpnc", "pptp", "openconnect", "openswan", "libreswan", - "ssh", "l2tp", "iodine", NULL }; - -/* Available fields for 'connection show' */ -static NmcOutputField nmc_fields_con_show[] = { - {"NAME", N_("NAME"), 25}, /* 0 */ - {"UUID", N_("UUID"), 38}, /* 1 */ - {"TYPE", N_("TYPE"), 17}, /* 2 */ - {"TIMESTAMP", N_("TIMESTAMP"), 12}, /* 3 */ - {"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34}, /* 4 */ - {"AUTOCONNECT", N_("AUTOCONNECT"), 13}, /* 5 */ - {"READONLY", N_("READONLY"), 10}, /* 6 */ - {"DBUS-PATH", N_("DBUS-PATH"), 42}, /* 7 */ - {"ACTIVE", N_("ACTIVE"), 10}, /* 8 */ - {"DEVICE", N_("DEVICE"), 10}, /* 9 */ - {"STATE", N_("STATE"), 12}, /* 10 */ - {"ACTIVE-PATH", N_("ACTIVE-PATH"), 51}, /* 11 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_SHOW_ALL "NAME,UUID,TYPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY,DBUS-PATH,"\ - "ACTIVE,DEVICE,STATE,ACTIVE-PATH" -#define NMC_FIELDS_CON_SHOW_COMMON "NAME,UUID,TYPE,DEVICE" - -/* Helper macro to define fields */ -#define SETTING_FIELD(setting, props) { setting, N_(setting), 0, props, NULL, FALSE, FALSE, 0 } - -/* defined in settings.c */ -extern NmcOutputField nmc_fields_setting_connection[]; -extern NmcOutputField nmc_fields_setting_wired[]; -extern NmcOutputField nmc_fields_setting_8021X[]; -extern NmcOutputField nmc_fields_setting_wireless[]; -extern NmcOutputField nmc_fields_setting_wireless_security[]; -extern NmcOutputField nmc_fields_setting_ip4_config[]; -extern NmcOutputField nmc_fields_setting_ip6_config[]; -extern NmcOutputField nmc_fields_setting_serial[]; -extern NmcOutputField nmc_fields_setting_ppp[]; -extern NmcOutputField nmc_fields_setting_pppoe[]; -extern NmcOutputField nmc_fields_setting_adsl[]; -extern NmcOutputField nmc_fields_setting_gsm[]; -extern NmcOutputField nmc_fields_setting_cdma[]; -extern NmcOutputField nmc_fields_setting_bluetooth[]; -extern NmcOutputField nmc_fields_setting_olpc_mesh[]; -extern NmcOutputField nmc_fields_setting_vpn[]; -extern NmcOutputField nmc_fields_setting_wimax[]; -extern NmcOutputField nmc_fields_setting_infiniband[]; -extern NmcOutputField nmc_fields_setting_bond[]; -extern NmcOutputField nmc_fields_setting_vlan[]; -extern NmcOutputField nmc_fields_setting_bridge[]; -extern NmcOutputField nmc_fields_setting_bridge_port[]; -extern NmcOutputField nmc_fields_setting_team[]; -extern NmcOutputField nmc_fields_setting_team_port[]; -extern NmcOutputField nmc_fields_setting_dcb[]; - -/* Available settings for 'connection show ' - profile part */ -static NmcOutputField nmc_fields_settings_names[] = { - SETTING_FIELD (NM_SETTING_CONNECTION_SETTING_NAME, nmc_fields_setting_connection + 1), /* 0 */ - SETTING_FIELD (NM_SETTING_WIRED_SETTING_NAME, nmc_fields_setting_wired + 1), /* 1 */ - SETTING_FIELD (NM_SETTING_802_1X_SETTING_NAME, nmc_fields_setting_8021X + 1), /* 2 */ - SETTING_FIELD (NM_SETTING_WIRELESS_SETTING_NAME, nmc_fields_setting_wireless + 1), /* 3 */ - SETTING_FIELD (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, nmc_fields_setting_wireless_security + 1), /* 4 */ - SETTING_FIELD (NM_SETTING_IP4_CONFIG_SETTING_NAME, nmc_fields_setting_ip4_config + 1), /* 5 */ - SETTING_FIELD (NM_SETTING_IP6_CONFIG_SETTING_NAME, nmc_fields_setting_ip6_config + 1), /* 6 */ - SETTING_FIELD (NM_SETTING_SERIAL_SETTING_NAME, nmc_fields_setting_serial + 1), /* 7 */ - SETTING_FIELD (NM_SETTING_PPP_SETTING_NAME, nmc_fields_setting_ppp + 1), /* 8 */ - SETTING_FIELD (NM_SETTING_PPPOE_SETTING_NAME, nmc_fields_setting_pppoe + 1), /* 9 */ - SETTING_FIELD (NM_SETTING_GSM_SETTING_NAME, nmc_fields_setting_gsm + 1), /* 10 */ - SETTING_FIELD (NM_SETTING_CDMA_SETTING_NAME, nmc_fields_setting_cdma + 1), /* 11 */ - SETTING_FIELD (NM_SETTING_BLUETOOTH_SETTING_NAME, nmc_fields_setting_bluetooth + 1), /* 12 */ - SETTING_FIELD (NM_SETTING_OLPC_MESH_SETTING_NAME, nmc_fields_setting_olpc_mesh + 1), /* 13 */ - SETTING_FIELD (NM_SETTING_VPN_SETTING_NAME, nmc_fields_setting_vpn + 1), /* 14 */ - SETTING_FIELD (NM_SETTING_WIMAX_SETTING_NAME, nmc_fields_setting_wimax + 1), /* 15 */ - SETTING_FIELD (NM_SETTING_INFINIBAND_SETTING_NAME, nmc_fields_setting_infiniband + 1), /* 16 */ - SETTING_FIELD (NM_SETTING_BOND_SETTING_NAME, nmc_fields_setting_bond + 1), /* 17 */ - SETTING_FIELD (NM_SETTING_VLAN_SETTING_NAME, nmc_fields_setting_vlan + 1), /* 18 */ - SETTING_FIELD (NM_SETTING_ADSL_SETTING_NAME, nmc_fields_setting_adsl + 1), /* 19 */ - SETTING_FIELD (NM_SETTING_BRIDGE_SETTING_NAME, nmc_fields_setting_bridge + 1), /* 20 */ - SETTING_FIELD (NM_SETTING_BRIDGE_PORT_SETTING_NAME, nmc_fields_setting_bridge_port + 1), /* 21 */ - SETTING_FIELD (NM_SETTING_TEAM_SETTING_NAME, nmc_fields_setting_team + 1), /* 22 */ - SETTING_FIELD (NM_SETTING_TEAM_PORT_SETTING_NAME, nmc_fields_setting_team_port + 1), /* 23 */ - SETTING_FIELD (NM_SETTING_DCB_SETTING_NAME, nmc_fields_setting_dcb + 1), /* 24 */ - {NULL, NULL, 0, NULL, NULL, FALSE, FALSE, 0} -}; -#define NMC_FIELDS_SETTINGS_NAMES_ALL_X NM_SETTING_CONNECTION_SETTING_NAME","\ - NM_SETTING_WIRED_SETTING_NAME","\ - NM_SETTING_802_1X_SETTING_NAME","\ - NM_SETTING_WIRELESS_SETTING_NAME","\ - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME","\ - NM_SETTING_IP4_CONFIG_SETTING_NAME","\ - NM_SETTING_IP6_CONFIG_SETTING_NAME","\ - NM_SETTING_SERIAL_SETTING_NAME","\ - NM_SETTING_PPP_SETTING_NAME","\ - NM_SETTING_PPPOE_SETTING_NAME","\ - NM_SETTING_ADSL_SETTING_NAME","\ - NM_SETTING_GSM_SETTING_NAME","\ - NM_SETTING_CDMA_SETTING_NAME","\ - NM_SETTING_BLUETOOTH_SETTING_NAME","\ - NM_SETTING_OLPC_MESH_SETTING_NAME","\ - NM_SETTING_VPN_SETTING_NAME","\ - NM_SETTING_INFINIBAND_SETTING_NAME","\ - NM_SETTING_BOND_SETTING_NAME","\ - NM_SETTING_VLAN_SETTING_NAME","\ - NM_SETTING_BRIDGE_SETTING_NAME","\ - NM_SETTING_BRIDGE_PORT_SETTING_NAME","\ - NM_SETTING_TEAM_SETTING_NAME","\ - NM_SETTING_TEAM_PORT_SETTING_NAME"," \ - NM_SETTING_DCB_SETTING_NAME -#if WITH_WIMAX -#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X","\ - NM_SETTING_WIMAX_SETTING_NAME -#else -#define NMC_FIELDS_SETTINGS_NAMES_ALL NMC_FIELDS_SETTINGS_NAMES_ALL_X -#endif - -/* Active connection data */ -/* Available fields for GENERAL group */ -static NmcOutputField nmc_fields_con_active_details_general[] = { - {"GROUP", N_("GROUP"), 9}, /* 0 */ - {"NAME", N_("NAME"), 25}, /* 1 */ - {"UUID", N_("UUID"), 38}, /* 2 */ - {"DEVICES", N_("DEVICES"), 10}, /* 3 */ - {"STATE", N_("STATE"), 12}, /* 4 */ - {"DEFAULT", N_("DEFAULT"), 8}, /* 5 */ - {"DEFAULT6", N_("DEFAULT6"), 9}, /* 6 */ - {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10}, /* 7 */ - {"VPN", N_("VPN"), 5}, /* 8 */ - {"DBUS-PATH", N_("DBUS-PATH"), 51}, /* 9 */ - {"CON-PATH", N_("CON-PATH"), 44}, /* 10 */ - {"ZONE", N_("ZONE"), 15}, /* 11 */ - {"MASTER-PATH", N_("MASTER-PATH"), 44}, /* 12 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL "GROUP,NAME,UUID,DEVICES,STATE,DEFAULT,DEFAULT6,"\ - "VPN,ZONE,DBUS-PATH,CON-PATH,SPEC-OBJECT,MASTER-PATH" - -/* IP group is handled by common.c */ - -/* Available fields for VPN group */ -static NmcOutputField nmc_fields_con_active_details_vpn[] = { - {"GROUP", N_("GROUP"), 9}, /* 0 */ - {"TYPE", N_("TYPE"), 15}, /* 1 */ - {"USERNAME", N_("USERNAME"), 15}, /* 2 */ - {"GATEWAY", N_("GATEWAY"), 25}, /* 3 */ - {"BANNER", N_("BANNER"), 120}, /* 4 */ - {"VPN-STATE", N_("VPN-STATE"), 40}, /* 5 */ - {"CFG", N_("CFG"), 120}, /* 6 */ - {NULL, NULL, 0} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL "GROUP,TYPE,USERNAME,GATEWAY,BANNER,VPN-STATE,CFG" - -/* defined in common.c */ -extern NmcOutputField nmc_fields_ip4_config[]; -extern NmcOutputField nmc_fields_ip6_config[]; -extern NmcOutputField nmc_fields_dhcp4_config[]; -extern NmcOutputField nmc_fields_dhcp6_config[]; - -/* Available fields for 'connection show ' - active part */ -static NmcOutputField nmc_fields_con_active_details_groups[] = { - {"GENERAL", N_("GENERAL"), 0, nmc_fields_con_active_details_general + 1}, /* 0 */ - {"IP4", N_("IP4"), 0, nmc_fields_ip4_config + 1 }, /* 1 */ - {"DHCP4", N_("DHCP4"), 0, nmc_fields_dhcp4_config + 1 }, /* 2 */ - {"IP6", N_("IP6"), 0, nmc_fields_ip6_config + 1 }, /* 3 */ - {"DHCP6", N_("DHCP6"), 0, nmc_fields_dhcp6_config + 1 }, /* 4 */ - {"VPN", N_("VPN"), 0, nmc_fields_con_active_details_vpn + 1 }, /* 5 */ - {NULL, NULL, 0, NULL} -}; -#define NMC_FIELDS_CON_ACTIVE_DETAILS_ALL "GENERAL,IP4,DHCP4,IP6,DHCP6,VPN" - -/* Pseudo group names for 'connection show ' */ -/* e.g.: nmcli -f profile con show my-eth0 */ -/* e.g.: nmcli -f active con show my-eth0 */ -#define CON_SHOW_DETAIL_GROUP_PROFILE "profile" -#define CON_SHOW_DETAIL_GROUP_ACTIVE "active" - -typedef struct { - NmCli *nmc; - int argc; - char **argv; -} ArgsInfo; - -/* glib main loop variable - defined in nmcli.c */ -extern GMainLoop *loop; - -static ArgsInfo args_info; -static guint progress_id = 0; /* ID of event source for displaying progress */ - -/* for readline TAB completion in editor */ -typedef struct { - NmCli *nmc; - char *con_type; - NMConnection *connection; - NMSetting *setting; -} TabCompletionInfo; -static TabCompletionInfo nmc_tab_completion = {NULL, NULL, NULL, NULL}; - -/* Global variable defined in nmcli.c - used for TAB completion */ -extern NmCli nm_cli; - -static char *gen_connection_types (const char *text, int state); - -static void -usage (void) -{ - fprintf (stderr, - _("Usage: nmcli connection { COMMAND | help }\n\n" - "COMMAND := { show | up | down | add | modify | edit | delete | reload | load }\n\n" - " show [--active] [[id | uuid | path | apath] ] ...\n\n" -#if WITH_WIMAX - " up [[id | uuid | path] ] [ifname ] [ap ] [nsp ]\n\n" -#else - " up [[id | uuid | path] ] [ifname ] [ap ]\n\n" -#endif - " down [id | uuid | path | apath] \n\n" - " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " modify [--temporary] [id | uuid | path] ([+|-]. )+\n\n" - " edit [id | uuid | path] \n" - " edit [type ] [con-name ]\n\n" - " delete [id | uuid | path] \n\n" - " reload\n\n" - " load [ ... ]\n\n")); -} - -static void -usage_connection_show (void) -{ - fprintf (stderr, - _("Usage: nmcli connection show { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [--active]\n" - "\n" - "List in-memory and on-disk connection profiles, some of which may also be\n" - "active if a device is using that connection profile. Without a parameter, all\n" - "profiles are listed. When --active option is specified, only the active\n" - "profiles are shown.\n" - "\n" - "ARGUMENTS := [--active] [id | uuid | path | apath] ...\n" - "\n" - "Show details for specified connections. By default, both static configuration\n" - "and active connection data are displayed. It is possible to filter the output\n" - "using global '--fields' option. Refer to the manual page for more information.\n" - "When --active option is specified, only the active profiles are taken into\n" - "account.\n")); -} - -static void -usage_connection_up (void) -{ - fprintf (stderr, - _("Usage: nmcli connection up { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] [ifname ] [ap ] [nsp ]\n" - "\n" - "Activate a connection on a device. The profile to activate is identified by its\n" - "name, UUID or D-Bus path.\n" - "\n" - "ARGUMENTS := ifname [ap ] [nsp ]\n" - "\n" - "Activate a device with a connection. The connection profile is selected\n" - "automatically by NetworkManager.\n" - "\n" - "ifname - specifies the device to active the connection on\n" - "ap - specifies AP to connect to (only valid for Wi-Fi)\n" - "nsp - specifies NSP to connect to (only valid for WiMAX)\n\n")); -} - -static void -usage_connection_down (void) -{ - fprintf (stderr, - _("Usage: nmcli connection down { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path | apath] \n" - "\n" - "Deactivate a connection from a device (without preventing the device from\n" - "further auto-activation). The profile to deactivate is identified by its name,\n" - "UUID or D-Bus path.\n\n")); -} - -static void -usage_connection_add (void) -{ - fprintf (stderr, - _("Usage: nmcli connection add { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n\n" - " COMMON_OPTIONS:\n" - " type \n" - " ifname | \"*\"\n" - " [con-name ]\n" - " [autoconnect yes|no]\n\n" - " [save yes|no]\n\n" - " TYPE_SPECIFIC_OPTIONS:\n" - " ethernet: [mac ]\n" - " [cloned-mac ]\n" - " [mtu ]\n\n" - " wifi: ssid \n" - " [mac ]\n" - " [cloned-mac ]\n" - " [mtu ]\n\n" - " wimax: [mac ]\n" - " [nsp ]\n\n" - " pppoe: username \n" - " [password ]\n" - " [service ]\n" - " [mtu ]\n" - " [mac ]\n\n" - " gsm: apn \n" - " [user ]\n" - " [password ]\n\n" - " cdma: [user ]\n" - " [password ]\n\n" - " infiniband: [mac ]\n" - " [mtu ]\n" - " [transport-mode datagram | connected]\n" - " [parent ]\n" - " [p-key ]\n\n" - " bluetooth: [addr ]\n" - " [bt-type panu|dun-gsm|dun-cdma]\n\n" - " vlan: dev \n" - " id \n" - " [flags ]\n" - " [ingress ]\n" - " [egress ]\n" - " [mtu ]\n\n" - " bond: [mode balance-rr (0) | active-backup (1) | balance-xor (2) | broadcast (3) |\n" - " 802.3ad (4) | balance-tlb (5) | balance-alb (6)]\n" - " [primary ]\n" - " [miimon ]\n" - " [downdelay ]\n" - " [updelay ]\n" - " [arp-interval ]\n" - " [arp-ip-target ]\n\n" - " bond-slave: master \n\n" - " team: [config |]\n\n" - " team-slave: master \n" - " [config |]\n\n" - " bridge: [stp yes|no]\n" - " [priority ]\n" - " [forward-delay <2-30>]\n" - " [hello-time <1-10>]\n" - " [max-age <6-40>]\n" - " [ageing-time <0-1000000>]\n" - " [mac ]\n\n" - " bridge-slave: master \n" - " [priority <0-63>]\n" - " [path-cost <1-65535>]\n" - " [hairpin yes|no]\n\n" - " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|ssh|l2tp|iodine|...\n" - " [user ]\n\n" - " olpc-mesh: ssid \n" - " [channel <1-13>]\n" - " [dhcp-anycast ]\n\n" - " IP_OPTIONS:\n" - " [ip4 ] [gw4 ]\n" - " [ip6 ] [gw6 ]\n\n")); -} - -static void -usage_connection_modify (void) -{ - fprintf (stderr, - _("Usage: nmcli connection modify { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] ([+|-]. )+\n" - "\n" - "Modify one or more properties of the connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path. For multi-valued\n" - "properties you can use optional '+' or '-' prefix to the property name.\n" - "The '+' sign allows appending items instead of overwriting the whole value.\n" - "The '-' sign allows removing selected items instead of the whole value.\n" - "\n" - "Examples:\n" - "nmcli con mod home-wifi wifi.ssid rakosnicek\n" - "nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, 10.10.1.5/8\"\n" - "nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n" - "nmcli con mod em1-1 -ipv4.dns 1\n" - "nmcli con mod em1-1 -ipv6.addr \"abbe::cafe/56\"\n" - "nmcli con mod bond0 +bond.options mii=500\n" - "nmcli con mod bond0 -bond.options downdelay\n\n")); -} - -static void -usage_connection_edit (void) -{ - fprintf (stderr, - _("Usage: nmcli connection edit { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] \n" - "\n" - "Edit an existing connection profile in an interactive editor.\n" - "The profile is identified by its name, UUID or D-Bus path\n" - "\n" - "ARGUMENTS := [type ] [con-name ]\n" - "\n" - "Add a new connection profile in an interactive editor.\n\n")); -} - -static void -usage_connection_delete (void) -{ - fprintf (stderr, - _("Usage: nmcli connection delete { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [id | uuid | path] \n" - "\n" - "Delete a connection profile.\n" - "The profile is identified by its name, UUID or D-Bus path.\n\n")); -} - -static void -usage_connection_reload (void) -{ - fprintf (stderr, - _("Usage: nmcli connection reload { help }\n" - "\n" - "Reload all connection files from disk.\n\n")); -} - -static void -usage_connection_load (void) -{ - fprintf (stderr, - _("Usage: nmcli connection load { ARGUMENTS | help }\n" - "\n" - "ARGUMENTS := [...]\n" - "\n" - "Load/reload one or more connection files from disk. Use this after manually\n" - "editing a connection file to ensure that NetworkManager is aware of its latest\n" - "state.\n\n")); -} - - -/* The real commands that do something - i.e. not 'help', etc. */ -static const char *real_con_commands[] = { - "show", - "up", - "down", - "add", - "modify", - "edit", - "delete", - "reload", - "load", - NULL -}; - -/* quit main loop */ -static void -quit (void) -{ - if (progress_id) { - g_source_remove (progress_id); - progress_id = 0; - nmc_terminal_erase_line (); - } - - g_main_loop_quit (loop); /* quit main loop */ -} - -static const char * -construct_header_name (const char *base, const char *spec) -{ - static char header_name[128]; - - if (spec == NULL) - return base; - - g_strlcpy (header_name, base, sizeof (header_name)); - g_strlcat (header_name, " (", sizeof (header_name)); - g_strlcat (header_name, spec, sizeof (header_name)); - g_strlcat (header_name, ")", sizeof (header_name)); - - return header_name; -} - -static const char * -active_connection_state_to_string (NMActiveConnectionState state) -{ - switch (state) { - case NM_ACTIVE_CONNECTION_STATE_ACTIVATING: - return _("activating"); - case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: - return _("activated"); - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: - return _("deactivating"); - case NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: - return _("deactivated"); - case NM_ACTIVE_CONNECTION_STATE_UNKNOWN: - default: - return _("unknown"); - } -} - -static const char * -vpn_connection_state_to_string (NMVPNConnectionState state) -{ - switch (state) { - case NM_VPN_CONNECTION_STATE_PREPARE: - return _("VPN connecting (prepare)"); - case NM_VPN_CONNECTION_STATE_NEED_AUTH: - return _("VPN connecting (need authentication)"); - case NM_VPN_CONNECTION_STATE_CONNECT: - return _("VPN connecting"); - case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: - return _("VPN connecting (getting IP configuration)"); - case NM_VPN_CONNECTION_STATE_ACTIVATED: - return _("VPN connected"); - case NM_VPN_CONNECTION_STATE_FAILED: - return _("VPN connection failed"); - case NM_VPN_CONNECTION_STATE_DISCONNECTED: - return _("VPN disconnected"); - default: - return _("unknown"); - } -} - -/* Caller has to free the returned string */ -static char * -get_ac_device_string (NMActiveConnection *active) -{ - GString *dev_str; - const GPtrArray *devices; - int i; - - if (!active) - return NULL; - - /* Get devices of the active connection */ - dev_str = g_string_new (NULL); - devices = nm_active_connection_get_devices (active); - for (i = 0; devices && (i < devices->len); i++) { - NMDevice *device = g_ptr_array_index (devices, i); - const char *dev_iface = nm_device_get_iface (device); - - if (dev_iface) { - g_string_append (dev_str, dev_iface); - g_string_append_c (dev_str, ','); - } - } - if (dev_str->len > 0) - g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - - return g_string_free (dev_str, FALSE); -} - -static NMActiveConnection * -get_ac_for_connection (const GPtrArray *active_cons, NMConnection *connection) -{ - const char *con_path; - int i; - NMActiveConnection *ac = NULL; - - /* Is the connection active? */ - con_path = nm_connection_get_path (connection); - for (i = 0; active_cons && i < active_cons->len; i++) { - NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); - - if (!g_strcmp0 (nm_active_connection_get_connection (candidate), con_path)) { - ac = candidate; - break; - } - } - return ac; -} - -static NMConnection * -get_connection_for_active (const GSList *con_list, NMActiveConnection *active) -{ - const GSList *iter; - const char *path; - - path = nm_active_connection_get_connection (active); - g_return_val_if_fail (path != NULL, NULL); - - for (iter = con_list; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = NM_CONNECTION (iter->data); - - if (strcmp (nm_connection_get_path (candidate), path) == 0) - return candidate; - } - return NULL; -} - -static gboolean -nmc_connection_profile_details (NMConnection *connection, NmCli *nmc) -{ - GError *error = NULL; - GArray *print_settings_array; - GPtrArray *prop_array = NULL; - int i; - char *fields_str; - char *fields_all = NMC_FIELDS_SETTINGS_NAMES_ALL; - char *fields_common = NMC_FIELDS_SETTINGS_NAMES_ALL; - const char *base_hdr = _("Connection profile details"); - gboolean was_output = FALSE; - - if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) - fields_str = fields_common; - else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) - fields_str = fields_all; - else - fields_str = nmc->required_fields; - - print_settings_array = parse_output_fields (fields_str, nmc_fields_settings_names, TRUE, &prop_array, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: 'connection show': %s"), error->message); - g_error_free (error); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - g_assert (print_settings_array); - - /* Main header */ - nmc->print_fields.header_name = (char *) construct_header_name (base_hdr, nm_connection_get_id (connection)); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTINGS_NAMES_ALL, - nmc_fields_settings_names, FALSE, NULL, NULL); - - nmc_fields_settings_names[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; - print_required_fields (nmc, nmc_fields_settings_names); - - /* Loop through the required settings and print them. */ - for (i = 0; i < print_settings_array->len; i++) { - NMSetting *setting; - int section_idx = g_array_index (print_settings_array, int, i); - const char *prop_name = (const char *) g_ptr_array_index (prop_array, i); - - if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output) - printf ("\n"); /* Empty line */ - - was_output = FALSE; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - setting = nm_connection_get_setting_by_name (connection, nmc_fields_settings_names[section_idx].name); - if (setting) { - setting_details (setting, nmc, prop_name); - was_output = TRUE; - continue; - } - } - - g_array_free (print_settings_array, TRUE); - if (prop_array) - g_ptr_array_free (prop_array, TRUE); - - return TRUE; -} - -static NMActiveConnection * -find_active_connection (const GPtrArray *active_cons, - const GSList *cons, - const char *filter_type, - const char *filter_val, - int *idx) -{ - int i; - int start = (idx && *idx > 0) ? *idx : 0; - const char *path, *a_path, *path_num, *a_path_num; - const char *id; - const char *uuid; - NMConnection *con; - NMActiveConnection *found = NULL; - - for (i = start; active_cons && (i < active_cons->len); i++) { - NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); - - path = nm_active_connection_get_connection (candidate); - a_path = nm_object_get_path (NM_OBJECT (candidate)); - uuid = nm_active_connection_get_uuid (candidate); - path_num = path ? strrchr (path, '/') + 1 : NULL; - a_path_num = a_path ? strrchr (a_path, '/') + 1 : NULL; - - con = get_connection_for_active (cons, candidate); - id = nm_connection_get_id (con); - - /* When filter_type is NULL, compare connection ID (filter_val) - * against all types. Otherwise, only compare against the specific - * type. If 'path' or 'apath' filter types are specified, comparison - * against numeric index (in addition to the whole path) is allowed. - */ - if ( ( (!filter_type || strcmp (filter_type, "id") == 0) - && strcmp (filter_val, id) == 0) - || ( (!filter_type || strcmp (filter_type, "uuid") == 0) - && strcmp (filter_val, uuid) == 0) - || ( (!filter_type || strcmp (filter_type, "path") == 0) - && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0))) - || ( (!filter_type || strcmp (filter_type, "apath") == 0) - && (g_strcmp0 (filter_val, a_path) == 0 || (filter_type && g_strcmp0 (filter_val, a_path_num) == 0)))) { - if (!idx) - return candidate; - if (found) { - *idx = i; - return found; - } - found = candidate; - } - } - - if (idx) - *idx = 0; - return found; -} - -static void -fill_output_connection (gpointer data, gpointer user_data, gboolean active_only) -{ - NMConnection *connection = (NMConnection *) data; - NmCli *nmc = (NmCli *) user_data; - NMSettingConnection *s_con; - guint64 timestamp; - time_t timestamp_real; - char *timestamp_str; - char *timestamp_real_str = ""; - NmcOutputField *arr; - NMActiveConnection *ac = NULL; - const char *ac_path = NULL; - const char *ac_state = NULL; - char *ac_dev = NULL; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - ac = get_ac_for_connection (nm_client_get_active_connections (nmc->client), connection); - if (active_only && !ac) - return; - - if (ac) { - ac_path = nm_object_get_path (NM_OBJECT (ac)); - ac_state = active_connection_state_to_string (nm_active_connection_get_state (ac)); - ac_dev = get_ac_device_string (ac); - } - - /* Obtain field values */ - timestamp = nm_setting_connection_get_timestamp (s_con); - timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp); - if (timestamp) { - timestamp_real = timestamp; - timestamp_real_str = g_malloc0 (64); - strftime (timestamp_real_str, 64, "%c", localtime (×tamp_real)); - } - - arr = nmc_dup_fields_array (nmc_fields_con_show, - sizeof (nmc_fields_con_show), - 0); - set_val_strc (arr, 0, nm_setting_connection_get_id (s_con)); - set_val_strc (arr, 1, nm_setting_connection_get_uuid (s_con)); - set_val_strc (arr, 2, nm_setting_connection_get_connection_type (s_con)); - set_val_str (arr, 3, timestamp_str); - set_val_str (arr, 4, timestamp ? timestamp_real_str : g_strdup (_("never"))); - set_val_strc (arr, 5, nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 6, nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 7, nm_connection_get_path (connection)); - set_val_strc (arr, 8, ac ? _("yes") : _("no")); - set_val_str (arr, 9, ac_dev); - set_val_strc (arr, 10, ac_state); - set_val_strc (arr, 11, ac_path); - - g_ptr_array_add (nmc->output_data, arr); -} - -static void -fill_output_active_connection (NMActiveConnection *active, - NmCli *nmc, - gboolean with_group, - guint32 o_flags) -{ - GSList *iter; - const char *active_path; - NMSettingConnection *s_con; - const GPtrArray *devices; - GString *dev_str; - NMActiveConnectionState state; - int i; - GSList *con_list = nmc->system_connections; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - int idx_start = with_group ? 0 : 1; - - active_path = nm_active_connection_get_connection (active); - state = nm_active_connection_get_state (active); - - /* Get devices of the active connection */ - dev_str = g_string_new (NULL); - devices = nm_active_connection_get_devices (active); - for (i = 0; devices && (i < devices->len); i++) { - NMDevice *device = g_ptr_array_index (devices, i); - const char *dev_iface = nm_device_get_iface (device); - - if (dev_iface) { - g_string_append (dev_str, dev_iface); - g_string_append_c (dev_str, ','); - } - } - if (dev_str->len > 0) - g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - - tmpl = nmc_fields_con_active_details_general; - tmpl_len = sizeof (nmc_fields_con_active_details_general); - if (!with_group) { - tmpl++; - tmpl_len -= sizeof (NmcOutputField); - } - - /* Fill field values */ - arr = nmc_dup_fields_array (tmpl, tmpl_len, o_flags); - if (with_group) - set_val_strc (arr, 0, nmc_fields_con_active_details_groups[0].name); - set_val_strc (arr, 1-idx_start, _("N/A")); - set_val_strc (arr, 2-idx_start, nm_active_connection_get_uuid (active)); - set_val_str (arr, 3-idx_start, dev_str->str); - set_val_strc (arr, 4-idx_start, active_connection_state_to_string (state)); - set_val_strc (arr, 5-idx_start, nm_active_connection_get_default (active) ? _("yes") : _("no")); - set_val_strc (arr, 6-idx_start, nm_active_connection_get_default6 (active) ? _("yes") : _("no")); - set_val_strc (arr, 7-idx_start, nm_active_connection_get_specific_object (active)); - set_val_strc (arr, 8-idx_start, NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no")); - set_val_strc (arr, 9-idx_start, nm_object_get_path (NM_OBJECT (active))); - set_val_strc (arr, 10-idx_start, nm_active_connection_get_connection (active)); - set_val_strc (arr, 11-idx_start, _("N/A")); - set_val_strc (arr, 12-idx_start, nm_active_connection_get_master (active)); - - for (iter = con_list; iter; iter = g_slist_next (iter)) { - NMConnection *connection = (NMConnection *) iter->data; - const char *con_path = nm_connection_get_path (connection); - - if (!strcmp (active_path, con_path)) { - /* This connection is active */ - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con != NULL); - - /* Fill field values that depend on NMConnection */ - set_val_strc (arr, 1-idx_start, nm_setting_connection_get_id (s_con)); - set_val_strc (arr, 11-idx_start, nm_setting_connection_get_zone (s_con)); - - break; - } - } - g_ptr_array_add (nmc->output_data, arr); - - g_string_free (dev_str, FALSE); -} - -typedef struct { - char **array; - guint32 idx; -} FillVPNDataInfo; - -static void -fill_vpn_data_item (const char *key, const char *value, gpointer user_data) -{ - FillVPNDataInfo *info = (FillVPNDataInfo *) user_data; - - info->array[info->idx++] = g_strdup_printf ("%s = %s", key, value); -} - -// FIXME: The same or similar code for VPN info appears also in nm-applet (applet-dialogs.c), -// and in gnome-control-center as well. It could probably be shared somehow. -static char * -get_vpn_connection_type (NMConnection *connection) -{ - const char *type, *p; - - /* The service type is in form of "org.freedesktop.NetworkManager.vpnc". - * Extract end part after last dot, e.g. "vpnc" - */ - type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection)); - p = strrchr (type, '.'); - return g_strdup (p ? p + 1 : type); -} - -/* VPN parameters can be found at: - * http://git.gnome.org/browse/network-manager-openvpn/tree/src/nm-openvpn-service.h - * http://git.gnome.org/browse/network-manager-vpnc/tree/src/nm-vpnc-service.h - * http://git.gnome.org/browse/network-manager-pptp/tree/src/nm-pptp-service.h - * http://git.gnome.org/browse/network-manager-openconnect/tree/src/nm-openconnect-service.h - * http://git.gnome.org/browse/network-manager-openswan/tree/src/nm-openswan-service.h - * See also 'properties' directory in these plugins. - */ -static const gchar * -find_vpn_gateway_key (const char *vpn_type) -{ - if (g_strcmp0 (vpn_type, "openvpn") == 0) return "remote"; - if (g_strcmp0 (vpn_type, "vpnc") == 0) return "IPSec gateway"; - if (g_strcmp0 (vpn_type, "pptp") == 0) return "gateway"; - if (g_strcmp0 (vpn_type, "openconnect") == 0) return "gateway"; - if (g_strcmp0 (vpn_type, "openswan") == 0) return "right"; - if (g_strcmp0 (vpn_type, "libreswan") == 0) return "right"; - if (g_strcmp0 (vpn_type, "ssh") == 0) return "remote"; - if (g_strcmp0 (vpn_type, "l2tp") == 0) return "gateway"; - return ""; -} - -static const gchar * -find_vpn_username_key (const char *vpn_type) -{ - if (g_strcmp0 (vpn_type, "openvpn") == 0) return "username"; - if (g_strcmp0 (vpn_type, "vpnc") == 0) return "Xauth username"; - if (g_strcmp0 (vpn_type, "pptp") == 0) return "user"; - if (g_strcmp0 (vpn_type, "openconnect") == 0) return "username"; - if (g_strcmp0 (vpn_type, "openswan") == 0) return "leftxauthusername"; - if (g_strcmp0 (vpn_type, "libreswan") == 0) return "leftxauthusername"; - if (g_strcmp0 (vpn_type, "l2tp") == 0) return "user"; - return ""; -} - -enum VpnDataItem { - VPN_DATA_ITEM_GATEWAY, - VPN_DATA_ITEM_USERNAME -}; - -static const gchar * -get_vpn_data_item (NMConnection *connection, enum VpnDataItem vpn_data_item) -{ - const char *key; - char *type = get_vpn_connection_type (connection); - - switch (vpn_data_item) { - case VPN_DATA_ITEM_GATEWAY: - key = find_vpn_gateway_key (type); - break; - case VPN_DATA_ITEM_USERNAME: - key = find_vpn_username_key (type); - break; - default: - key = ""; - break; - } - g_free (type); - - return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (connection), key); -} -/* FIXME end */ - -static gboolean -nmc_active_connection_details (NMActiveConnection *acon, NmCli *nmc) -{ - GError *error = NULL; - GArray *print_groups; - GPtrArray *group_fields = NULL; - int i; - char *fields_str; - char *fields_all = NMC_FIELDS_CON_ACTIVE_DETAILS_ALL; - char *fields_common = NMC_FIELDS_CON_ACTIVE_DETAILS_ALL; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - const char *base_hdr = _("Activate connection details"); - gboolean was_output = FALSE; - - if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) - fields_str = fields_common; - else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) - fields_str = fields_all; - else - fields_str = nmc->required_fields; - - print_groups = parse_output_fields (fields_str, nmc_fields_con_active_details_groups, TRUE, &group_fields, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: 'connection show': %s"), error->message); - g_error_free (error); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - return FALSE; - } - g_assert (print_groups); - - /* Main header */ - nmc->print_fields.header_name = (char *) construct_header_name (base_hdr, nm_active_connection_get_uuid (acon)); - nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_CON_ACTIVE_DETAILS_ALL, - nmc_fields_con_active_details_groups, FALSE, NULL, NULL); - - nmc_fields_con_active_details_groups[0].flags = NMC_OF_FLAG_MAIN_HEADER_ONLY; - print_required_fields (nmc, nmc_fields_con_active_details_groups); - - /* Loop through the groups and print them. */ - for (i = 0; i < print_groups->len; i++) { - int group_idx = g_array_index (print_groups, int, i); - char *group_fld = (char *) g_ptr_array_index (group_fields, i); - - if (nmc->print_output != NMC_PRINT_TERSE && !nmc->multiline_output && was_output) - printf ("\n"); /* Empty line */ - - was_output = FALSE; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - /* GENERAL */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[0].name) == 0) { - /* Add field names */ - tmpl = nmc_fields_con_active_details_general; - tmpl_len = sizeof (nmc_fields_con_active_details_general); - nmc->print_fields.indices = parse_output_fields (group_fld ? group_fld : NMC_FIELDS_CON_ACTIVE_DETAILS_GENERAL_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* Fill in values */ - fill_output_active_connection (acon, nmc, TRUE, NMC_OF_FLAG_SECTION_PREFIX); - - print_data (nmc); /* Print all data */ - - was_output = TRUE; - } - - /* IP4 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[1].name) == 0) { - gboolean b1 = FALSE; - NMIP4Config *cfg4 = nm_active_connection_get_ip4_config (acon); - - b1 = print_ip4_config (cfg4, nmc, "IP4", group_fld); - was_output = was_output || b1; - } - - /* DHCP4 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[2].name) == 0) { - gboolean b1 = FALSE; - NMDHCP4Config *dhcp4 = nm_active_connection_get_dhcp4_config (acon); - - b1 = print_dhcp4_config (dhcp4, nmc, "DHCP4", group_fld); - was_output = was_output || b1; - } - - /* IP6 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[3].name) == 0) { - gboolean b1 = FALSE; - NMIP6Config *cfg6 = nm_active_connection_get_ip6_config (acon); - - b1 = print_ip6_config (cfg6, nmc, "IP6", group_fld); - was_output = was_output || b1; - } - - /* DHCP6 */ - if (strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[4].name) == 0) { - gboolean b1 = FALSE; - NMDHCP6Config *dhcp6 = nm_active_connection_get_dhcp6_config (acon); - - b1 = print_dhcp6_config (dhcp6, nmc, "DHCP6", group_fld); - was_output = was_output || b1; - } - - /* VPN */ - if (NM_IS_VPN_CONNECTION (acon) && - strcasecmp (nmc_fields_con_active_details_groups[group_idx].name, nmc_fields_con_active_details_groups[5].name) == 0) { - NMConnection *con; - NMSettingConnection *s_con; - NMSettingVPN *s_vpn; - NMVPNConnectionState vpn_state; - char *type_str, *banner_str, *vpn_state_str; - const char *username = NULL; - char **vpn_data_array = NULL; - guint32 items_num; - - con = get_connection_for_active (nmc->system_connections, acon); - - s_con = nm_connection_get_setting_connection (con); - g_assert (s_con != NULL); - - tmpl = nmc_fields_con_active_details_vpn; - tmpl_len = sizeof (nmc_fields_con_active_details_vpn); - nmc->print_fields.indices = parse_output_fields (group_fld ? group_fld : NMC_FIELDS_CON_ACTIVE_DETAILS_VPN_ALL, - tmpl, FALSE, NULL, NULL); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - s_vpn = nm_connection_get_setting_vpn (con); - if (s_vpn) { - items_num = nm_setting_vpn_get_num_data_items (s_vpn); - if (items_num > 0) { - FillVPNDataInfo info; - - vpn_data_array = g_new (char *, items_num + 1); - info.array = vpn_data_array; - info.idx = 0; - nm_setting_vpn_foreach_data_item (s_vpn, &fill_vpn_data_item, &info); - vpn_data_array[items_num] = NULL; - } - username = nm_setting_vpn_get_user_name (s_vpn); - } - - type_str = get_vpn_connection_type (con); - banner_str = g_strescape (nm_vpn_connection_get_banner (NM_VPN_CONNECTION (acon)), ""); - vpn_state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (acon)); - vpn_state_str = g_strdup_printf ("%d - %s", vpn_state, vpn_connection_state_to_string (vpn_state)); - - /* Add values */ - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); - set_val_strc (arr, 0, nmc_fields_con_active_details_groups[5].name); - set_val_str (arr, 1, type_str); - set_val_strc (arr, 2, username ? username : get_vpn_data_item (con, VPN_DATA_ITEM_USERNAME)); - set_val_strc (arr, 3, get_vpn_data_item (con, VPN_DATA_ITEM_GATEWAY)); - set_val_str (arr, 4, banner_str); - set_val_str (arr, 5, vpn_state_str); - set_val_arr (arr, 6, vpn_data_array); - g_ptr_array_add (nmc->output_data, arr); - - print_data (nmc); /* Print all data */ - was_output = TRUE; - } - } - - g_array_free (print_groups, TRUE); - if (group_fields) - g_ptr_array_free (group_fields, TRUE); - - return TRUE; -} - -static gboolean -split_required_fields_for_con_show (const char *input, - char **profile_flds, - char **active_flds, - GError **error) -{ - char **fields, **iter; - char *dot; - GString *str1, *str2; - gboolean found; - gboolean group_profile = FALSE; - gboolean group_active = FALSE; - gboolean success = TRUE; - gboolean is_all, is_common; - int i; - - if (!input) { - *profile_flds = NULL; - *active_flds = NULL; - return TRUE; - } - - str1 = g_string_new (NULL); - str2 = g_string_new (NULL); - - /* Split supplied fields string */ - fields = g_strsplit_set (input, ",", -1); - for (iter = fields; iter && *iter; iter++) { - g_strstrip (*iter); - dot = strchr (*iter, '.'); - if (dot) - *dot = '\0'; - - is_all = !dot && strcasecmp (*iter, "all") == 0; - is_common = !dot && strcasecmp (*iter, "common") == 0; - - found = FALSE; - - for (i = 0; nmc_fields_settings_names[i].name; i++) { - if ( is_all || is_common - || !strcasecmp (*iter, nmc_fields_settings_names[i].name)) { - if (dot) - *dot = '.'; - g_string_append (str1, *iter); - g_string_append_c (str1, ','); - found = TRUE; - break; - } - } - if (found) - continue; - for (i = 0; nmc_fields_con_active_details_groups[i].name; i++) { - if ( is_all || is_common - || !strcasecmp (*iter, nmc_fields_con_active_details_groups[i].name)) { - if (dot) - *dot = '.'; - g_string_append (str2, *iter); - g_string_append_c (str2, ','); - found = TRUE; - break; - } - } - if (!found) { - if (dot) - *dot = '.'; - if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_PROFILE)) - group_profile = TRUE; - else if (!strcasecmp (*iter, CON_SHOW_DETAIL_GROUP_ACTIVE)) - group_active = TRUE; - else { - char *allowed1 = nmc_get_allowed_fields (nmc_fields_settings_names, -1); - char *allowed2 = nmc_get_allowed_fields (nmc_fields_con_active_details_groups, -1); - g_set_error (error, NMCLI_ERROR, 0, _("invalid field '%s'; allowed fields: %s and %s, or %s,%s"), - *iter, allowed1, allowed2, CON_SHOW_DETAIL_GROUP_PROFILE, CON_SHOW_DETAIL_GROUP_ACTIVE); - g_free (allowed1); - g_free (allowed2); - success = FALSE; - break; - } - } - } - if (fields) - g_strfreev (fields); - - /* Handle pseudo groups: profile, active */ - if (success && group_profile) { - if (str1->len > 0) { - g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), - CON_SHOW_DETAIL_GROUP_PROFILE); - success = FALSE; - } else - g_string_assign (str1, "all,"); - } - if (success && group_active) { - if (str2->len > 0) { - g_set_error (error, NMCLI_ERROR, 0, _("'%s' has to be alone"), - CON_SHOW_DETAIL_GROUP_ACTIVE); - success = FALSE; - } else - g_string_assign (str2, "all,"); - } - - if (success) { - if (str1->len > 0) - g_string_truncate (str1, str1->len - 1); - if (str2->len > 0) - g_string_truncate (str2, str2->len - 1); - *profile_flds = g_string_free (str1, str1->len == 0); - *active_flds = g_string_free (str2, str2->len == 0); - } else { - g_string_free (str1, TRUE); - g_string_free (str2, TRUE); - } - return success; -} - -static NMCResultCode -do_connections_show (NmCli *nmc, gboolean active_only, int argc, char **argv) -{ - GError *err = NULL; - char *profile_flds = NULL, *active_flds = NULL; - - nmc->should_wait = FALSE; - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto finish; - } - - if (argc == 0) { - char *fields_str; - char *fields_all = NMC_FIELDS_CON_SHOW_ALL; - char *fields_common = NMC_FIELDS_CON_SHOW_COMMON; - NmcOutputField *tmpl, *arr; - size_t tmpl_len; - GSList *iter; - - if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) - fields_str = fields_common; - else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) - fields_str = fields_all; - else - fields_str = nmc->required_fields; - - tmpl = nmc_fields_con_show; - tmpl_len = sizeof (nmc_fields_con_show); - nmc->print_fields.indices = parse_output_fields (fields_str, tmpl, FALSE, NULL, &err); - if (err) { - goto finish; - } - if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &err)) - goto finish; - - /* Add headers */ - nmc->print_fields.header_name = active_only ? _("NetworkManager active profiles") : - _("NetworkManager connection profiles"); - arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_MAIN_HEADER_ADD | NMC_OF_FLAG_FIELD_NAMES); - g_ptr_array_add (nmc->output_data, arr); - - /* Add values */ - for (iter = nmc->system_connections; iter; iter = g_slist_next (iter)) { - NMConnection *con = NM_CONNECTION (iter->data); - fill_output_connection (con, nmc, active_only); - } - print_data (nmc); /* Print all data */ - } else { - gboolean new_line = FALSE; - gboolean without_fields = (nmc->required_fields == NULL); - const GPtrArray *active_cons = nm_client_get_active_connections (nmc->client); - GSList *pos = NULL; - - /* multiline mode is default for 'connection show ' */ - if (!nmc->mode_specified) - nmc->multiline_output = TRUE; - - /* Split required fields into the settings and active ones. */ - if (!split_required_fields_for_con_show (nmc->required_fields, &profile_flds, &active_flds, &err)) - goto finish; - g_free (nmc->required_fields); - nmc->required_fields = NULL; - - while (argc > 0) { - NMConnection *con; - NMActiveConnection *acon = NULL; - const char *selector = NULL; - - if ( strcmp (*argv, "id") == 0 - || strcmp (*argv, "uuid") == 0 - || strcmp (*argv, "path") == 0 - || strcmp (*argv, "apath") == 0) { - selector = *argv; - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto finish; - } - } - - /* Find connection by id, uuid, path or apath */ - con = nmc_find_connection (nmc->system_connections, selector, *argv, &pos); - if (!con) { - acon = find_active_connection (active_cons, nmc->system_connections, selector, *argv, NULL); - if (acon) - con = get_connection_for_active (nmc->system_connections, acon); - } - - /* Print connection details */ - if (con) { - gboolean res; - - /* Filter only active connections */ - if (!acon) - acon = get_ac_for_connection (active_cons, con); - if (active_only && !acon) { - next_arg (&argc, &argv); - continue; - } - - /* Show an empty line between connections */ - if (new_line) - printf ("\n"); - - /* Show profile configuration */ - if (without_fields || profile_flds) { - nmc->required_fields = profile_flds; - res = nmc_connection_profile_details (con, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; - } - - /* If the profile is active, print also active details */ - if (without_fields || active_flds) { - if (acon) { - nmc->required_fields = active_flds; - res = nmc_active_connection_details (acon, nmc); - nmc->required_fields = NULL; - if (!res) - goto finish; - } - } - new_line = TRUE; - } else { - g_string_printf (nmc->return_text, _("Error: %s - no such connection profile."), *argv); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto finish; - } - - /* Take next argument. - * But for pos != NULL we have more connections of the same name, - * so process the same argument again. - */ - if (!pos) - next_arg (&argc, &argv); - } - } - -finish: - if (err) { - g_string_printf (nmc->return_text, _("Error: %s."), err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_error_free (err); - } - g_free (profile_flds); - g_free (active_flds); - return nmc->return_value; -} - -static NMActiveConnection * -get_default_active_connection (NmCli *nmc, NMDevice **device) -{ - NMActiveConnection *default_ac = NULL; - NMDevice *non_default_device = NULL; - NMActiveConnection *non_default_ac = NULL; - const GPtrArray *connections; - int i; - - g_return_val_if_fail (nmc != NULL, NULL); - g_return_val_if_fail (device != NULL, NULL); - g_return_val_if_fail (*device == NULL, NULL); - - connections = nm_client_get_active_connections (nmc->client); - for (i = 0; connections && (i < connections->len); i++) { - NMActiveConnection *candidate = g_ptr_array_index (connections, i); - const GPtrArray *devices; - - devices = nm_active_connection_get_devices (candidate); - if (!devices || !devices->len) - continue; - - if (nm_active_connection_get_default (candidate)) { - if (!default_ac) { - *device = g_ptr_array_index (devices, 0); - default_ac = candidate; - } - } else { - if (!non_default_ac) { - non_default_device = g_ptr_array_index (devices, 0); - non_default_ac = candidate; - } - } - } - - /* Prefer the default connection if one exists, otherwise return the first - * non-default connection. - */ - if (!default_ac && non_default_ac) { - default_ac = non_default_ac; - *device = non_default_device; - } - return default_ac; -} - -/* Find a device to activate the connection on. - * IN: connection: connection to activate - * iface: device interface name to use (optional) - * ap: access point to use (optional; valid just for 802-11-wireless) - * nsp: Network Service Provider to use (option; valid only for wimax) - * OUT: device: found device - * spec_object: specific_object path of NMAccessPoint - * RETURNS: TRUE when a device is found, FALSE otherwise. - */ -static gboolean -find_device_for_connection (NmCli *nmc, - NMConnection *connection, - const char *iface, - const char *ap, - const char *nsp, - NMDevice **device, - const char **spec_object, - GError **error) -{ - NMSettingConnection *s_con; - const char *con_type; - int i, j; - - g_return_val_if_fail (nmc != NULL, FALSE); - g_return_val_if_fail (device != NULL && *device == NULL, FALSE); - g_return_val_if_fail (spec_object != NULL && *spec_object == NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - - if (strcmp (con_type, NM_SETTING_VPN_SETTING_NAME) == 0) { - /* VPN connections */ - NMActiveConnection *active = NULL; - if (iface) { - *device = nm_client_get_device_by_iface (nmc->client, iface); - if (*device) - active = nm_device_get_active_connection (*device); - - if (!active) { - g_set_error (error, NMCLI_ERROR, 0, _("no active connection on device '%s'"), iface); - return FALSE; - } - *spec_object = nm_object_get_path (NM_OBJECT (active)); - return TRUE; - } else { - active = get_default_active_connection (nmc, device); - if (!active) { - g_set_error_literal (error, NMCLI_ERROR, 0, _("no active connection or device")); - return FALSE; - } - *spec_object = nm_object_get_path (NM_OBJECT (active)); - return TRUE; - } - } else { - /* Other connections */ - NMDevice *found_device = NULL; - const GPtrArray *devices = nm_client_get_devices (nmc->client); - - for (i = 0; devices && (i < devices->len) && !found_device; i++) { - NMDevice *dev = g_ptr_array_index (devices, i); - - if (iface) { - const char *dev_iface = nm_device_get_iface (dev); - if ( !g_strcmp0 (dev_iface, iface) - && nm_device_connection_compatible (dev, connection, NULL)) { - found_device = dev; - } - } else { - if (nm_device_connection_compatible (dev, connection, NULL)) { - found_device = dev; - } - } - - if (found_device && ap && !strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME) && NM_IS_DEVICE_WIFI (dev)) { - char *bssid_up = g_ascii_strup (ap, -1); - const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev)); - found_device = NULL; /* Mark as not found; set to the device again later, only if AP matches */ - - for (j = 0; aps && (j < aps->len); j++) { - NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j); - const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap); - - if (!strcmp (bssid_up, candidate_bssid)) { - found_device = dev; - *spec_object = nm_object_get_path (NM_OBJECT (candidate_ap)); - break; - } - } - g_free (bssid_up); - } - -#if WITH_WIMAX - if ( found_device - && nsp - && !strcmp (con_type, NM_SETTING_WIMAX_SETTING_NAME) - && NM_IS_DEVICE_WIMAX (dev)) { - const GPtrArray *nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (dev)); - found_device = NULL; /* Mark as not found; set to the device again later, only if NSP matches */ - - for (j = 0; nsps && (j < nsps->len); j++) { - NMWimaxNsp *candidate_nsp = g_ptr_array_index (nsps, j); - const char *candidate_name = nm_wimax_nsp_get_name (candidate_nsp); - - if (!strcmp (nsp, candidate_name)) { - found_device = dev; - *spec_object = nm_object_get_path (NM_OBJECT (candidate_nsp)); - break; - } - } - } -#endif - } - - if (found_device) { - *device = found_device; - return TRUE; - } else { - if (iface) - g_set_error (error, NMCLI_ERROR, 0, _("device '%s' not compatible with connection '%s'"), - iface, nm_setting_connection_get_id (s_con)); - else - g_set_error (error, NMCLI_ERROR, 0, _("no device found for connection '%s'"), - nm_setting_connection_get_id (s_con)); - return FALSE; - } - } -} - -static const char * -vpn_connection_state_reason_to_string (NMVPNConnectionStateReason reason) -{ - switch (reason) { - case NM_VPN_CONNECTION_STATE_REASON_UNKNOWN: - return _("unknown reason"); - case NM_VPN_CONNECTION_STATE_REASON_NONE: - return _("none"); - case NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED: - return _("the user was disconnected"); - case NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: - return _("the base network connection was interrupted"); - case NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED: - return _("the VPN service stopped unexpectedly"); - case NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: - return _("the VPN service returned invalid configuration"); - case NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: - return _("the connection attempt timed out"); - case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: - return _("the VPN service did not start in time"); - case NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED: - return _("the VPN service failed to start"); - case NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS: - return _("no valid VPN secrets"); - case NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED: - return _("invalid VPN secrets"); - case NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED: - return _("the connection was removed"); - default: - return _("unknown"); - } -} - -static void -active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data) -{ - NmCli *nmc = (NmCli *) user_data; - NMActiveConnectionState state; - - state = nm_active_connection_get_state (active); - - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("Connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (active))); - quit (); - } else if ( state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED - || state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { - g_string_printf (nmc->return_text, _("Error: Connection activation failed.")); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - quit (); - } -} - -static void -vpn_connection_state_cb (NMVPNConnection *vpn, - NMVPNConnectionState state, - NMVPNConnectionStateReason reason, - gpointer user_data) -{ - NmCli *nmc = (NmCli *) user_data; - - switch (state) { - case NM_VPN_CONNECTION_STATE_PREPARE: - case NM_VPN_CONNECTION_STATE_NEED_AUTH: - case NM_VPN_CONNECTION_STATE_CONNECT: - case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: - /* no operation */ - break; - - case NM_VPN_CONNECTION_STATE_ACTIVATED: - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("VPN connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (vpn))); - quit (); - break; - - case NM_VPN_CONNECTION_STATE_FAILED: - case NM_VPN_CONNECTION_STATE_DISCONNECTED: - g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s."), - vpn_connection_state_reason_to_string (reason)); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - quit (); - break; - - default: - break; - } -} - -static gboolean -timeout_cb (gpointer user_data) -{ - /* Time expired -> exit nmcli */ - - NmCli *nmc = (NmCli *) user_data; - - g_string_printf (nmc->return_text, _("Error: Timeout %d sec expired."), nmc->timeout); - nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED; - quit (); - return FALSE; -} - -static gboolean -progress_cb (gpointer user_data) -{ - const char *str = (const char *) user_data; - - nmc_terminal_show_progress (str); - - return TRUE; -} - -static gboolean -progress_device_cb (gpointer user_data) -{ - NMDevice *device = (NMDevice *) user_data; - - nmc_terminal_show_progress (device ? nmc_device_state_to_string (nm_device_get_state (device)) : ""); - - return TRUE; -} - -static gboolean -progress_vpn_cb (gpointer user_data) -{ - NMVPNConnection *vpn = (NMVPNConnection *) user_data; - const char *str; - - str = NM_IS_VPN_CONNECTION (vpn) ? - vpn_connection_state_to_string (nm_vpn_connection_get_vpn_state (vpn)) : - ""; - - nmc_terminal_show_progress (str); - - return TRUE; -} - -typedef struct { - NmCli *nmc; - NMDevice *device; -} ActivateConnectionInfo; - -static gboolean -master_iface_slaves_check (gpointer user_data) -{ - ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - NMDevice *device = info->device; - const GPtrArray *slaves = NULL; - - if (NM_IS_DEVICE_BOND (device)) - slaves = nm_device_bond_get_slaves (NM_DEVICE_BOND (device)); - else if (NM_IS_DEVICE_TEAM (device)) - slaves = nm_device_team_get_slaves (NM_DEVICE_TEAM (device)); - else if (NM_IS_DEVICE_BRIDGE (device)) - slaves = nm_device_bridge_get_slaves (NM_DEVICE_BRIDGE (device)); - else - g_warning ("%s: should not be reached.", __func__); - - if (!slaves) { - g_string_printf (nmc->return_text, - _("Error: Device '%s' is waiting for slaves before proceeding with activation."), - nm_device_get_iface (device)); - nmc->return_value = NMC_RESULT_ERROR_TIMEOUT_EXPIRED; - quit (); - } - - g_free (info); - return FALSE; -} - -static void -activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *error, gpointer user_data) -{ - ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - NMDevice *device = info->device; - NMActiveConnectionState state; - const GPtrArray *ac_devs; - - if (error) { - g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s"), error->message); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - quit (); - } else { - state = nm_active_connection_get_state (active); - if (!device) { - /* device could be NULL for virtual devices. Fill it here. */ - ac_devs = nm_active_connection_get_devices (active); - info->device = device = ac_devs && ac_devs->len > 0 ? g_ptr_array_index (ac_devs, 0) : NULL; - } - - if (nmc->nowait_flag || state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - /* User doesn't want to wait or already activated */ - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - if (nmc->print_output == NMC_PRINT_PRETTY) - nmc_terminal_erase_line (); - printf (_("Connection successfully activated (D-Bus active path: %s)\n"), - nm_object_get_path (NM_OBJECT (active))); - } - quit (); - } else { - if (NM_IS_VPN_CONNECTION (active)) { - /* Monitor VPN state */ - g_signal_connect (G_OBJECT (active), "vpn-state-changed", G_CALLBACK (vpn_connection_state_cb), nmc); - - /* Start progress indication showing VPN states */ - if (nmc->print_output == NMC_PRINT_PRETTY) { - if (progress_id) - g_source_remove (progress_id); - progress_id = g_timeout_add (120, progress_vpn_cb, NM_VPN_CONNECTION (active)); - } - } else { - g_signal_connect (active, "notify::state", G_CALLBACK (active_connection_state_cb), nmc); - - /* Start progress indication showing device states */ - if (nmc->print_output == NMC_PRINT_PRETTY) { - if (progress_id) - g_source_remove (progress_id); - progress_id = g_timeout_add (120, progress_device_cb, device); - } - } - - /* Start timer not to loop forever when signals are not emitted */ - g_timeout_add_seconds (nmc->timeout, timeout_cb, nmc); - - /* Check for bond or team or bridge slaves */ - if ( NM_IS_DEVICE_BOND (device) - || NM_IS_DEVICE_TEAM (device) - || NM_IS_DEVICE_BRIDGE (device)) { - g_timeout_add_seconds (SLAVES_UP_TIMEOUT, master_iface_slaves_check, info); - return; /* info will be freed in master_iface_slaves_check () */ - } - } - } - g_free (info); -} - -/* We were using nm_connection_get_virtual_iface_name() to determine whether the - * connection is virtual or not. But it did't work for VLANs without - * vlan.interface-name. nm_connection_get_virtual_iface_name() returns NULL for those. - * So we need to use our own implementation for now. - */ -static gboolean -is_connection_virtual (NMConnection *connection) -{ - if ( nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) - return TRUE; - if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { - NMSettingInfiniband *s_infi = nm_connection_get_setting_infiniband (connection); - int p_key = nm_setting_infiniband_get_p_key (s_infi); - const char *parent = nm_setting_infiniband_get_parent (s_infi); - - if (p_key != -1 && parent) - return TRUE; - } - return FALSE; -} - -static gboolean -nmc_activate_connection (NmCli *nmc, - NMConnection *connection, - const char *ifname, - const char *ap, - const char *nsp, - NMClientActivateFn callback, - GError **error) -{ - ActivateConnectionInfo *info; - NMDevice *device = NULL; - const char *spec_object = NULL; - gboolean device_found; - GError *local = NULL; - - g_return_val_if_fail (nmc != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (connection) { - device_found = find_device_for_connection (nmc, connection, ifname, ap, nsp, &device, &spec_object, &local); - - /* Virtual connection may not have their interfaces created yet */ - if (!device_found && !is_connection_virtual (connection)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_CON_ACTIVATION, - "%s", local && local->message ? local->message : _("unknown error")); - g_clear_error (&local); - return FALSE; - } - } else if (ifname) { - device = nm_client_get_device_by_iface (nmc->client, ifname); - if (!device) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND, - _("unknown device '%s'."), ifname); - return FALSE; - } - } else { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND, - _("neither a valid connection nor device given")); - return FALSE; - } - - info = g_malloc0 (sizeof (ActivateConnectionInfo)); - info->nmc = nmc; - info->device = device; - - nm_client_activate_connection (nmc->client, - connection, - device, - spec_object, - callback, - info); - return TRUE; -} - -static NMCResultCode -do_connection_up (NmCli *nmc, int argc, char **argv) -{ - NMConnection *connection = NULL; - const char *ifname = NULL; - const char *ap = NULL; - const char *nsp = NULL; - GError *error = NULL; - const char *selector = NULL; - const char *name = NULL; - char *line = NULL; - - /* - * Set default timeout for connection activation. - * Activation can take quite a long time, use 90 seconds. - */ - if (nmc->timeout == -1) - nmc->timeout = 90; - - if (argc == 0) { - if (nmc->ask) { - line = nmc_readline (PROMPT_CONNECTION); - name = line ? line : ""; - } - } else if (strcmp (*argv, "ifname") != 0) { - if ( strcmp (*argv, "id") == 0 - || strcmp (*argv, "uuid") == 0 - || strcmp (*argv, "path") == 0) { - - selector = *argv; - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - name = *argv; - } - name = *argv; - next_arg (&argc, &argv); - } - - if (name) - connection = nmc_find_connection (nmc->system_connections, selector, name, NULL); - - while (argc > 0) { - if (strcmp (*argv, "ifname") == 0) { - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - ifname = *argv; - } - else if (strcmp (*argv, "ap") == 0) { - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - ap = *argv; - } -#if WITH_WIMAX - else if (strcmp (*argv, "nsp") == 0) { - if (next_arg (&argc, &argv) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *(argv-1)); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - - nsp = *argv; - } -#endif - else { - fprintf (stderr, _("Unknown parameter: %s\n"), *argv); - } - - argc--; - argv++; - } - - /* create NMClient */ - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto error; - } - - /* Use nowait_flag instead of should_wait because exiting has to be postponed till - * active_connection_state_cb() is called. That gives NM time to check our permissions - * and we can follow activation progress. - */ - nmc->nowait_flag = (nmc->timeout == 0); - nmc->should_wait = TRUE; - - if (!nmc_activate_connection (nmc, connection, ifname, ap, nsp, activate_connection_cb, &error)) { - g_string_printf (nmc->return_text, _("Error: %s."), - error ? error->message : _("unknown error")); - nmc->return_value = error ? error->code : NMC_RESULT_ERROR_CON_ACTIVATION; - g_clear_error (&error); - goto error; - } - - /* Start progress indication */ - if (nmc->print_output == NMC_PRINT_PRETTY) - progress_id = g_timeout_add (120, progress_cb, _("preparing")); - - g_free (line); - return nmc->return_value; -error: - nmc->should_wait = FALSE; - g_free (line); - return nmc->return_value; -} - -static NMCResultCode -do_connection_down (NmCli *nmc, int argc, char **argv) -{ - NMActiveConnection *active; - const GPtrArray *active_cons; - char *line = NULL; - char **arg_arr = NULL; - char **arg_ptr = argv; - int arg_num = argc; - int idx = 0; - - if (argc == 0) { - if (nmc->ask) { - line = nmc_readline (PROMPT_CONNECTION); - nmc_string_to_arg_array (line, "", &arg_arr, &arg_num); - arg_ptr = arg_arr; - } - if (arg_num == 0) { - g_string_printf (nmc->return_text, _("Error: No connection specified.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - } - - /* create NMClient */ - nmc->get_client (nmc); - - if (!nm_client_get_manager_running (nmc->client)) { - g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); - nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; - goto error; - } - - /* Get active connections */ - active_cons = nm_client_get_active_connections (nmc->client); - while (arg_num > 0) { - const char *selector = NULL; - - if ( strcmp (*arg_ptr, "id") == 0 - || strcmp (*arg_ptr, "uuid") == 0 - || strcmp (*arg_ptr, "path") == 0 - || strcmp (*arg_ptr, "apath") == 0) { - - selector = *arg_ptr; - if (next_arg (&arg_num, &arg_ptr) != 0) { - g_string_printf (nmc->return_text, _("Error: %s argument is missing."), selector); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - } - - active = find_active_connection (active_cons, nmc->system_connections, selector, *arg_ptr, &idx); - if (active) { - nm_client_deactivate_connection (nmc->client, active); - } else { - g_string_printf (nmc->return_text, _("Error: '%s' is not an active connection."), *arg_ptr); - nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; - goto error; - } - - if (idx == 0) - next_arg (&arg_num, &arg_ptr); - } - - // FIXME: do something better then sleep() - /* Don't quit immediatelly and give NM time to check our permissions */ - sleep (1); - -error: - nmc->should_wait = FALSE; - g_strfreev (arg_arr); - return nmc->return_value; -} - -/*----------------------------------------------------------------------------*/ - -typedef struct NameItem { - const char *name; - const char *alias; - const struct NameItem *settings; - gboolean mandatory; -} NameItem; - -static const NameItem nmc_generic_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_ethernet_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_DCB_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_infiniband_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_wifi_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", NULL, TRUE }, - { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-sec", NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_wimax_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_gsm_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_cdma_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_mobile_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_SERIAL_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_GSM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bluetooth_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_adsl_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -/* PPPoE is a base connection type from historical reasons. - * See libnm-util/nm-setting.c:_nm_setting_is_base_type() - */ -static const NameItem nmc_pppoe_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_PPP_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_olpc_mesh_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_vpn_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_VPN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_vlan_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bond_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BOND_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_team_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bridge_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, - { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bond_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_team_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_TEAM_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - -static const NameItem nmc_bridge_slave_settings [] = { - { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_BRIDGE_PORT_SETTING_NAME, NULL, NULL, TRUE }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, TRUE }, - { NM_SETTING_802_1X_SETTING_NAME, NULL, NULL, FALSE }, - { NULL, NULL, NULL, FALSE } -}; - - -/* Available connection types */ -static const NameItem nmc_valid_connection_types[] = { - { NM_SETTING_GENERIC_SETTING_NAME, NULL, nmc_generic_settings }, - { NM_SETTING_WIRED_SETTING_NAME, "ethernet", nmc_ethernet_settings }, - { NM_SETTING_PPPOE_SETTING_NAME, NULL, nmc_pppoe_settings }, - { NM_SETTING_WIRELESS_SETTING_NAME, "wifi", nmc_wifi_settings }, - { NM_SETTING_WIMAX_SETTING_NAME, NULL, nmc_wimax_settings }, - { NM_SETTING_GSM_SETTING_NAME, NULL, nmc_gsm_settings }, - { NM_SETTING_CDMA_SETTING_NAME, NULL, nmc_cdma_settings }, - { NM_SETTING_INFINIBAND_SETTING_NAME, NULL, nmc_infiniband_settings }, - { NM_SETTING_ADSL_SETTING_NAME, NULL, nmc_adsl_settings }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, NULL, nmc_bluetooth_settings }, - { NM_SETTING_VPN_SETTING_NAME, NULL, nmc_vpn_settings }, - { NM_SETTING_OLPC_MESH_SETTING_NAME, "olpc-mesh", nmc_olpc_mesh_settings }, - { NM_SETTING_VLAN_SETTING_NAME, NULL, nmc_vlan_settings }, - { NM_SETTING_BOND_SETTING_NAME, NULL, nmc_bond_settings }, - { NM_SETTING_TEAM_SETTING_NAME, NULL, nmc_team_settings }, - { NM_SETTING_BRIDGE_SETTING_NAME, NULL, nmc_bridge_settings }, - { "bond-slave", NULL, nmc_bond_slave_settings }, - { "team-slave", NULL, nmc_team_slave_settings }, - { "bridge-slave", NULL, nmc_bridge_slave_settings }, - { NULL, NULL, NULL } -}; - -/* - * Return an alias for the 'name' if exists, else return the 'name'. - * The returned string must not be freed. - */ -static const char * -get_name_alias (const char *name, const NameItem array[]) -{ - const NameItem *iter = &array[0]; - - if (!name) - return NULL; - - while (iter && iter->name) { - if (!strcmp (name, iter->name)) { - if (iter->alias) - return iter->alias; - else - return iter->name; - } - iter++; - } - return name; -} - -/* - * Construct a string with names and aliases from the array formatted as: - * "name (alias), name, name (alias), name, name" - * - * Returns: string; the caller is responsible for freeing it. - */ -static char * -get_valid_options_string (const NameItem array[]) -{ - const NameItem *iter = &array[0]; - GString *str; - - str = g_string_sized_new (150); - while (iter && iter->name) { - if (str->len) - g_string_append (str, ", "); - if (iter->alias) - g_string_append_printf (str, "%s (%s)", iter->name, iter->alias); - else - g_string_append (str, iter->name); - iter++; - } - return g_string_free (str, FALSE); -} - -/* - * Check if 'val' is valid string in either array->name or array->alias. - * It accepts shorter string provided they are not ambiguous. - * 'val' == NULL doesn't hurt. - * - * Returns: pointer to array->name string or NULL on failure. - * The returned string must not be freed. - */ -static const char * -check_valid_name (const char *val, const NameItem array[], GError **error) -{ - const NameItem *iter; - GPtrArray *tmp_arr; - const char *str; - GError *tmp_err = NULL; - - /* Create a temporary array that can be used in nmc_string_is_valid() */ - tmp_arr = g_ptr_array_sized_new (30); - iter = &array[0]; - while (iter && iter->name) { - g_ptr_array_add (tmp_arr, (gpointer) iter->name); - if (iter->alias) - g_ptr_array_add (tmp_arr, (gpointer) iter->alias); - iter++; - } - g_ptr_array_add (tmp_arr, (gpointer) NULL); - - /* Check string validity */ - str = nmc_string_is_valid (val, (const char **) tmp_arr->pdata, &tmp_err); - if (!str) { - if (tmp_err->code == 1) - g_propagate_error (error, tmp_err); - else { - /* We want to handle aliases, so construct own error message */ - char *err_str = get_valid_options_string (array); - g_set_error (error, 1, 0, _("'%s' not among [%s]"), - val ? val : "", err_str); - g_free (err_str); - g_clear_error (&tmp_err); - } - g_ptr_array_free (tmp_arr, TRUE); - return NULL; - } - - /* Return a pointer to the found string in passed 'array' */ - iter = &array[0]; - while (iter && iter->name) { - if ( (iter->name && g_strcmp0 (iter->name, str) == 0) - || (iter->alias && g_strcmp0 (iter->alias, str) == 0)) { - g_ptr_array_free (tmp_arr, TRUE); - return iter->name; - } - iter++; - } - /* We should not really come here */ - g_ptr_array_free (tmp_arr, TRUE); - g_set_error (error, 1, 0, _("Unknown error")); - return NULL; -} - -static const NameItem * -get_valid_settings_array (const char *con_type) -{ - guint i, num; - - if (!con_type) - return NULL; - - num = G_N_ELEMENTS (nmc_valid_connection_types); - for (i = 0; i < num; i++) { - if (!g_strcmp0 (con_type, nmc_valid_connection_types[i].name)) - return nmc_valid_connection_types[i].settings; - } - return NULL; -} - -static gboolean -is_setting_mandatory (NMConnection *connection, NMSetting *setting) -{ - NMSettingConnection *s_con; - const char *c_type; - const NameItem *item; - const char *name; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - c_type = nm_setting_connection_get_connection_type (s_con); - - name = nm_setting_get_name (setting); - - item = get_valid_settings_array (c_type); - while (item && item->name) { - if (!strcmp (name, item->name)) - return item->mandatory; - item++; - } - return FALSE; -} - -/*----------------------------------------------------------------------------*/ - -static gboolean -check_and_convert_mac (const char *mac, - GByteArray **mac_array, - int type, - const char *keyword, - GError **error) -{ - GByteArray *local_mac_array = NULL; - g_return_val_if_fail (mac_array == NULL || *mac_array == NULL, FALSE); - - if (!mac) - return TRUE; - - local_mac_array = nm_utils_hwaddr_atoba (mac, type); - if (!local_mac_array) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not a valid %s MAC address."), - keyword, mac, type == ARPHRD_INFINIBAND ? _("InfiniBand") : _("Ethernet")); - return FALSE; - } - - if (mac_array) - *mac_array = local_mac_array; - else - if (local_mac_array) - g_byte_array_free (local_mac_array, TRUE); - - return TRUE; -} - -static gboolean -check_and_convert_mtu (const char *mtu, guint32 *mtu_int, GError **error) -{ - unsigned long local_mtu_int; - - if (!mtu) - return TRUE; - - if (!nmc_string_to_uint (mtu, TRUE, 0, G_MAXUINT32, &local_mtu_int)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mtu': '%s' is not a valid MTU."), mtu); - return FALSE; - } - if (mtu_int) - *mtu_int = (guint32) local_mtu_int; - return TRUE; -} - -static gboolean -check_infiniband_parent (const char *parent, GError **error) -{ - if (!parent) - return TRUE; - - if (!nm_utils_iface_valid_name (parent)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'parent': '%s' is not a valid interface name."), parent); - return FALSE; - } - return TRUE; -} - - -static gboolean -check_infiniband_p_key (const char *p_key, guint32 *p_key_int, GError **error) -{ - unsigned long local_p_key_int; - gboolean p_key_valid = FALSE; - if (!p_key) - return TRUE; - - if (!strncmp (p_key, "0x", 2)) - p_key_valid = nmc_string_to_uint_base (p_key + 2, 16, TRUE, 0, G_MAXUINT16, &local_p_key_int); - else - p_key_valid = nmc_string_to_uint (p_key, TRUE, 0, G_MAXUINT16, &local_p_key_int); - if (!p_key_valid) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'p-key': '%s' is not a valid InfiniBand P_KEY."), p_key); - return FALSE; - } - if (p_key_int) - *p_key_int = (guint32) local_p_key_int; - return TRUE; -} - -/* Checks InfiniBand mode. - * It accepts shortcuts and normalizes them ('mode' argument is modified on success). - */ -static gboolean -check_infiniband_mode (char **mode, GError **error) -{ - char *tmp; - const char *checked_mode; - const char *modes[] = { "datagram", "connected", NULL }; - - if (!mode || !*mode) - return TRUE; - - tmp = g_strstrip (g_strdup (*mode)); - checked_mode = nmc_string_is_valid (tmp, modes, NULL); - g_free (tmp); - if (checked_mode) { - g_free (*mode); - *mode = g_strdup (checked_mode); - } else - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': '%s' is not a valid InfiniBand transport mode [datagram, connected]."), *mode); - return !!checked_mode; -} - -static gboolean -check_and_convert_vlan_flags (const char *flags, guint32 *flags_int, GError **error) -{ - unsigned long local_flags_int; - - if (!flags) - return TRUE; - - if (!nmc_string_to_uint (flags, TRUE, 0, 7, &local_flags_int)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'flags': '%s' is not valid; use <0-7>."), flags); - return FALSE; - } - if (flags_int) - *flags_int = (guint32) local_flags_int; - return TRUE; -} - -static gboolean -check_and_convert_vlan_prio_maps (const char *prio_map, - NMVlanPriorityMap type, - char ***prio_map_arr, - GError **error) -{ - char **local_prio_map_arr; - GError *local_err = NULL; - - if (!prio_map) - return TRUE; - - if (!(local_prio_map_arr = nmc_vlan_parse_priority_maps (prio_map, type, &local_err))) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not valid; %s "), - type == NM_VLAN_INGRESS_MAP ? "ingress" : "egress", - prio_map, local_err->message); - return FALSE; - } - - if (prio_map_arr) - *prio_map_arr = local_prio_map_arr; - return TRUE; -} - -static gboolean -add_ip4_address_to_connection (NMIP4Address *ip4addr, NMConnection *connection) -{ - NMSettingIP4Config *s_ip4; - gboolean ret; - - if (!ip4addr) - return TRUE; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!s_ip4) { - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - 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); - } - ret = nm_setting_ip4_config_add_address (s_ip4, ip4addr); - nm_ip4_address_unref (ip4addr); - - return ret; -} - -static gboolean -add_ip6_address_to_connection (NMIP6Address *ip6addr, NMConnection *connection) -{ - NMSettingIP6Config *s_ip6; - gboolean ret; - - if (!ip6addr) - return TRUE; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!s_ip6) { - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - 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); - } - ret = nm_setting_ip6_config_add_address (s_ip6, ip6addr); - nm_ip6_address_unref (ip6addr); - - return ret; -} - -static char * -unique_master_iface_ifname (GSList *list, - const char *type, - const char *ifname_property, - const char *try_name) -{ - NMConnection *connection; - NMSetting *setting; - char *new_name; - unsigned int num = 1; - GSList *iterator = list; - char *ifname_val = NULL; - - new_name = g_strdup (try_name); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - setting = nm_connection_get_setting_by_name (connection, type); - if (!setting) { - iterator = g_slist_next (iterator); - continue; - } - - g_object_get (setting, ifname_property, &ifname_val, NULL); - if (g_strcmp0 (new_name, ifname_val) == 0) { - g_free (new_name); - new_name = g_strdup_printf ("%s%d", try_name, num++); - iterator = list; - } else - iterator = g_slist_next (iterator); - g_free (ifname_val); - } - return new_name; -} - -static const char * -_strip_master_prefix (const char *master, const char *(**func)(NMConnection *)) -{ - if (!master) - return NULL; - - if (g_str_has_prefix (master, "ifname/")) { - master = master + strlen ("ifname/"); - if (func) - *func = nm_connection_get_virtual_iface_name; - } else if (g_str_has_prefix (master, "uuid/")) { - master = master + strlen ("uuid/"); - if (func) - *func = nm_connection_get_uuid; - } else if (g_str_has_prefix (master, "id/")) { - master = master + strlen ("id/"); - if (func) - *func = nm_connection_get_id; - } - return master; -} - -/* verify_master_for_slave: - * @connections: list af all connections - * @master: UUID, ifname or ID of the master connection - * @type: virtual connection type (bond, team, bridge, ...) - * - * Check whether master is a valid interface name, UUID or ID of some @type connection. - * First UUID and ifname are checked. If they don't match, ID is checked - * and replaced by UUID on a match. - * - * Returns: identifier of master connection if found, %NULL otherwise - */ -static const char * -verify_master_for_slave (GSList *connections, - const char *master, - const char *type) -{ - NMConnection *connection; - NMSettingConnection *s_con; - const char *con_type, *id, *uuid, *ifname; - GSList *iterator = connections; - const char *found_by_id = NULL; - const char *out_master = NULL; - const char *(*func) (NMConnection *) = NULL; - - if (!master) - return NULL; - - master = _strip_master_prefix (master, &func); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (con_type, type) != 0) { - iterator = g_slist_next (iterator); - continue; - } - if (func) { - /* There was a prefix; only compare to that type. */ - if (g_strcmp0 (master, func (connection)) == 0) { - if (func == nm_connection_get_id) - out_master = nm_connection_get_uuid (connection); - else - out_master = master; - break; - } - } else { - id = nm_connection_get_id (connection); - uuid = nm_connection_get_uuid (connection); - ifname = nm_connection_get_virtual_iface_name (connection); - if ( g_strcmp0 (master, uuid) == 0 - || g_strcmp0 (master, ifname) == 0) { - out_master = master; - break; - } - if (!found_by_id && g_strcmp0 (master, id) == 0) - found_by_id = uuid; - } - - iterator = g_slist_next (iterator); - } - return out_master ? out_master : found_by_id; -} - -static gboolean -bridge_prop_string_to_uint (const char *str, - const char *nmc_arg, - GType bridge_type, - const char *propname, - unsigned long *out_val, - GError **error) -{ - GParamSpecUInt *pspec; - - pspec = (GParamSpecUInt *) g_object_class_find_property (g_type_class_peek (bridge_type), - propname); - g_assert (G_IS_PARAM_SPEC_UINT (pspec)); - - if (!nmc_string_to_uint (str, TRUE, pspec->minimum, pspec->maximum, out_val)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s': '%s' is not valid; use <%u-%u>."), - nmc_arg, str, pspec->minimum, pspec->maximum); - return FALSE; - } - return TRUE; -} - -#define WORD_YES "yes" -#define WORD_NO "no" -#define WORD_LOC_YES _("yes") -#define WORD_LOC_NO _("no") -static const char * -prompt_yes_no (gboolean default_yes, char *delim) -{ - static char prompt[128] = { 0 }; - - if (!delim) - delim = ""; - - snprintf (prompt, sizeof (prompt), "(%s/%s) [%s]%s ", - WORD_LOC_YES, WORD_LOC_NO, - default_yes ? WORD_LOC_YES : WORD_LOC_NO, delim); - - return prompt; -} - -static gboolean -normalize_yes_no (char **yes_no) -{ - char *tmp; - const char *checked_yes_no; - const char *strv[] = { WORD_LOC_YES, WORD_LOC_NO, NULL }; - - if (!yes_no || !*yes_no) - return FALSE; - - tmp = g_strstrip (g_strdup (*yes_no)); - checked_yes_no = nmc_string_is_valid (tmp, strv, NULL); - g_free (tmp); - if (g_strcmp0 (checked_yes_no, WORD_LOC_YES) == 0) { - g_free (*yes_no); - *yes_no = g_strdup (WORD_YES); - } else if (g_strcmp0 (checked_yes_no, WORD_LOC_NO) == 0) { - g_free (*yes_no); - *yes_no = g_strdup (WORD_NO); - } - return !!checked_yes_no; -} - -static gboolean -want_provide_opt_args (const char *type, int num) -{ - char *answer; - gboolean ret = TRUE; - - /* Ask for optional arguments. */ - printf (ngettext ("There is %d optional argument for '%s' connection type.\n", - "There are %d optional arguments for '%s' connection type.\n", num), - num, type); - answer = nmc_readline (ngettext ("Do you want to provide it? %s", - "Do you want to provide them? %s", num), - prompt_yes_no (TRUE, NULL)); - answer = answer ? g_strstrip (answer) : NULL; - if (answer && matches (answer, WORD_LOC_YES) != 0) - ret = FALSE; - g_free (answer); - return ret; -} - -static void -do_questionnaire_ethernet (gboolean ethernet, char **mtu, char **mac, char **cloned_mac) -{ - gboolean once_more; - GError *error = NULL; - const char *type = ethernet ? _("ethernet") : _("Wi-Fi"); - - /* Ask for optional arguments */ - if (!want_provide_opt_args (type, 3)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } - if (!*cloned_mac) { - do { - *cloned_mac = nmc_readline (_("Cloned MAC [none]: ")); - once_more = !check_and_convert_mac (*cloned_mac, NULL, ARPHRD_ETHER, "cloned-mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*cloned_mac); - } - } while (once_more); - } -} - -#define WORD_DATAGRAM "datagram" -#define WORD_CONNECTED "connected" -#define PROMPT_IB_MODE "(" WORD_DATAGRAM "/" WORD_CONNECTED ") [" WORD_DATAGRAM "]: " -static void -do_questionnaire_infiniband (char **mtu, char **mac, char **mode, char **parent, char **p_key) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional arguments */ - if (!want_provide_opt_args (_("InfiniBand"), 5)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_INFINIBAND, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } - if (!*mode) { - do { - *mode = nmc_readline (_("Transport mode %s"), PROMPT_IB_MODE); - if (!*mode) - *mode = g_strdup ("datagram"); - once_more = !check_infiniband_mode (mode, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mode); - } - } while (once_more); - } - if (!*parent) { - do { - *parent = nmc_readline (_("Parent interface [none]: ")); - once_more = !check_infiniband_parent (*parent, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*parent); - } - } while (once_more); - } - if (!*p_key) { - do { - *p_key = nmc_readline (_("P_KEY [none]: ")); - once_more = !check_infiniband_p_key (*p_key, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*p_key); - } - /* If parent is specified, so has to be P_KEY */ - if (!once_more && *parent && !*p_key) { - once_more = TRUE; - printf (_("Error: 'p-key' is mandatory when 'parent' is specified.\n")); - } - } while (once_more); - } -} - -static void -do_questionnaire_wifi (char **mtu, char **mac, char **cloned_mac) -{ - /* At present, the optional Wi-Fi arguments are the same as for ethernet. */ - return do_questionnaire_ethernet (FALSE, mtu, mac, cloned_mac); -} - -static void -do_questionnaire_wimax (char **mac) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'wimax' arguments. */ - if (!want_provide_opt_args (_("WiMAX"), 1)) - return; - - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_pppoe (char **password, char **service, char **mtu, char **mac) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'pppoe' arguments. */ - if (!want_provide_opt_args (_("PPPoE"), 4)) - return; - - if (!*password) - *password = nmc_readline (_("Password [none]: ")); - if (!*service) - *service = nmc_readline (_("Service [none]: ")); - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_readline (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_mobile (char **user, char **password) -{ - /* Ask for optional 'gsm' or 'cdma' arguments. */ - if (!want_provide_opt_args (_("mobile broadband"), 2)) - return; - - if (!*user) - *user = nmc_readline (_("Username [none]: ")); - if (!*password) - *password = nmc_readline (_("Password [none]: ")); -} - -#define WORD_PANU "panu" -#define WORD_DUN_GSM "dun-gsm" -#define WORD_DUN_CDMA "dun-cdma" -#define PROMPT_BT_TYPE "(" WORD_PANU "/" WORD_DUN_GSM "/" WORD_DUN_CDMA ") [" WORD_PANU "]: " -static void -do_questionnaire_bluetooth (char **bt_type) -{ - gboolean once_more; - - /* Ask for optional 'bluetooth' arguments. */ - if (!want_provide_opt_args (_("bluetooth"), 1)) - return; - - if (!*bt_type) { - const char *types[] = { "dun", "dun-gsm", "dun-cdma", "panu", NULL }; - const char *tmp; - do { - *bt_type = nmc_readline (_("Bluetooth type %s"), PROMPT_BT_TYPE); - if (!*bt_type) - *bt_type = g_strdup ("panu"); - tmp = nmc_string_is_valid (*bt_type, types, NULL); - once_more = !tmp; - if (once_more) { - printf (_("Error: 'bt-type': '%s' is not a valid bluetooth type.\n"), *bt_type); - g_free (*bt_type); - } - } while (once_more); - g_free (*bt_type); - *bt_type = g_strdup (tmp); - } -} - -static void -do_questionnaire_vlan (char **mtu, char **flags, char **ingress, char **egress) -{ - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'vlan' arguments. */ - if (!want_provide_opt_args (_("VLAN"), 4)) - return; - - if (!*mtu) { - do { - *mtu = nmc_readline (_("MTU [auto]: ")); - once_more = !check_and_convert_mtu (*mtu, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mtu); - } - } while (once_more); - } - if (!*flags) { - do { - *flags = nmc_readline (_("VLAN flags (<0-7>) [none]: ")); - once_more = !check_and_convert_vlan_flags (*flags, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*flags); - } - } while (once_more); - } - if (!*ingress) { - do { - *ingress = nmc_readline (_("Ingress priority maps [none]: ")); - once_more = !check_and_convert_vlan_prio_maps (*ingress, NM_VLAN_INGRESS_MAP, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*ingress); - } - } while (once_more); - } - if (!*egress) { - do { - *egress = nmc_readline (_("Egress priority maps [none]: ")); - once_more = !check_and_convert_vlan_prio_maps (*egress, NM_VLAN_EGRESS_MAP, NULL, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*egress); - } - } while (once_more); - } -} - -#define PROMPT_BOND_MODE _("Bonding mode [balance-rr]: ") -#define WORD_MIIMON "miimon" -#define WORD_ARP "arp" -#define PROMPT_BOND_MON_MODE "(" WORD_MIIMON "/" WORD_ARP ") [" WORD_MIIMON "]: " -static void -do_questionnaire_bond (char **mode, char **primary, char **miimon, - char **downdelay, char **updelay, - char **arpinterval, char **arpiptarget) -{ - char *monitor_mode; - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bond' arguments. */ - if (!want_provide_opt_args (_("bond"), 7)) - return; - - if (!*mode) { - const char *mode_tmp; - do { - *mode = nmc_readline (PROMPT_BOND_MODE); - if (!*mode) - *mode = g_strdup ("balance-rr"); - mode_tmp = nmc_bond_validate_mode (*mode, &error); - g_free (*mode); - if (mode_tmp) { - *mode = g_strdup (mode_tmp); - } else { - printf ("%s\n", error->message); - g_clear_error (&error); - } - } while (!mode_tmp); - } - - if (g_strcmp0 (*mode, "active-backup") == 0 && !*primary) { - do { - *primary = nmc_readline (_("Bonding primary interface [none]: ")); - once_more = *primary && !nm_utils_iface_valid_name (*primary); - if (once_more) { - printf (_("Error: 'primary': '%s' is not a valid interface name.\n"), - *primary); - g_free (*primary); - } - } while (once_more); - } - - do { - monitor_mode = nmc_readline (_("Bonding monitoring mode %s"), PROMPT_BOND_MON_MODE); - if (!monitor_mode) - monitor_mode = g_strdup (WORD_MIIMON); - g_strstrip (monitor_mode); - once_more = matches (monitor_mode, WORD_MIIMON) != 0 && matches (monitor_mode, WORD_ARP) != 0; - if (once_more) { - printf (_("Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n"), - monitor_mode, WORD_MIIMON, WORD_ARP); - g_free (monitor_mode); - } - } while (once_more); - - if (matches (monitor_mode, WORD_MIIMON) == 0) { - if (!*miimon) { - do { - *miimon = nmc_readline (_("Bonding miimon [100]: ")); - once_more = *miimon && !nmc_string_to_uint (*miimon, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'miimon': '%s' is not a valid number <0-%u>.\n"), - *miimon, G_MAXUINT32); - g_free (*miimon); - } - } while (once_more); - } - if (!*downdelay) { - do { - *downdelay = nmc_readline (_("Bonding downdelay [0]: ")); - once_more = *downdelay && !nmc_string_to_uint (*downdelay, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'downdelay': '%s' is not a valid number <0-%u>.\n"), - *downdelay, G_MAXUINT32); - g_free (*downdelay); - } - } while (once_more); - } - if (!*updelay) { - do { - *updelay = nmc_readline (_("Bonding updelay [0]: ")); - once_more = *updelay && !nmc_string_to_uint (*updelay, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'updelay': '%s' is not a valid number <0-%u>.\n"), - *updelay, G_MAXUINT32); - g_free (*updelay); - } - } while (once_more); - } - } else { - if (!*arpinterval) { - do { - *arpinterval = nmc_readline (_("Bonding arp-interval [0]: ")); - once_more = *arpinterval && !nmc_string_to_uint (*arpinterval, TRUE, 0, G_MAXUINT32, &tmp); - if (once_more) { - printf (_("Error: 'arp-interval': '%s' is not a valid number <0-%u>.\n"), - *arpinterval, G_MAXUINT32); - g_free (*arpinterval); - } - } while (once_more); - } - if (!*arpiptarget) { - //FIXME: verify the string - *arpiptarget = nmc_readline (_("Bonding arp-ip-target [none]: ")); - } - } - - g_free (monitor_mode); -} - -static void -do_questionnaire_team_common (const char *type_name, char **config) -{ - gboolean once_more; - char *json = NULL; - GError *error = NULL; - - /* Ask for optional arguments. */ - if (!want_provide_opt_args (type_name, 1)) - return; - - if (!*config) { - do { - *config = nmc_readline (_("Team JSON configuration [none]: ")); - once_more = !nmc_team_check_config (*config, &json, &error); - if (once_more) { - printf ("Error: %s\n", error->message); - g_clear_error (&error); - g_free (*config); - } - } while (once_more); - } - - *config = json; -} - -/* Both team and team-slave curently have just ithe same one optional argument */ -static void -do_questionnaire_team (char **config) -{ - do_questionnaire_team_common (_("team"), config); -} - -static void -do_questionnaire_team_slave (char **config) -{ - do_questionnaire_team_common (_("team-slave"), config); -} - -static void -do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay, char **hello_time, - char **max_age, char **ageing_time, char **mac) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bridge' arguments. */ - if (!want_provide_opt_args (_("bridge"), 7)) - return; - - if (!*stp) { - gboolean stp_bool; - do { - *stp = nmc_readline (_("Enable STP %s"), prompt_yes_no (TRUE, ":")); - *stp = *stp ? *stp : g_strdup ("yes"); - normalize_yes_no (stp); - once_more = !nmc_string_to_bool (*stp, &stp_bool, &error); - if (once_more) { - printf (_("Error: 'stp': %s.\n"), error->message); - g_clear_error (&error); - g_free (*stp); - } - } while (once_more); - } - if (!*priority) { - do { - *priority = nmc_readline (_("STP priority [32768]: ")); - *priority = *priority ? *priority : g_strdup ("32768"); - once_more = !nmc_string_to_uint (*priority, TRUE, 0, G_MAXUINT16, &tmp); - if (once_more) { - printf (_("Error: 'priority': '%s' is not a valid number <0-%d>.\n"), - *priority, G_MAXUINT16); - g_free (*priority); - } - } while (once_more); - } - if (!*fwd_delay) { - do { - *fwd_delay = nmc_readline (_("Forward delay [15]: ")); - *fwd_delay = *fwd_delay ? *fwd_delay : g_strdup ("15"); - once_more = !nmc_string_to_uint (*fwd_delay, TRUE, 2, 30, &tmp); - if (once_more) { - printf (_("Error: 'forward-delay': '%s' is not a valid number <2-30>.\n"), - *fwd_delay); - g_free (*fwd_delay); - } - } while (once_more); - } - - if (!*hello_time) { - do { - *hello_time = nmc_readline (_("Hello time [2]: ")); - *hello_time = *hello_time ? *hello_time : g_strdup ("2"); - once_more = !nmc_string_to_uint (*hello_time, TRUE, 1, 10, &tmp); - if (once_more) { - printf (_("Error: 'hello-time': '%s' is not a valid number <1-10>.\n"), - *hello_time); - g_free (*hello_time); - } - } while (once_more); - } - if (!*max_age) { - do { - *max_age = nmc_readline (_("Max age [20]: ")); - *max_age = *max_age ? *max_age : g_strdup ("20"); - once_more = !nmc_string_to_uint (*max_age, TRUE, 6, 40, &tmp); - if (once_more) { - printf (_("Error: 'max-age': '%s' is not a valid number <6-40>.\n"), - *max_age); - g_free (*max_age); - } - } while (once_more); - } - if (!*ageing_time) { - do { - *ageing_time = nmc_readline (_("MAC address ageing time [300]: ")); - *ageing_time = *ageing_time ? *ageing_time : g_strdup ("300"); - once_more = !nmc_string_to_uint (*ageing_time, TRUE, 0, 1000000, &tmp); - if (once_more) { - printf (_("Error: 'ageing-time': '%s' is not a valid number <0-1000000>.\n"), - *ageing_time); - g_free (*ageing_time); - } - } while (once_more); - } - if (!*mac) { - do { - *mac = nmc_get_user_input (_("MAC [none]: ")); - once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*mac); - } - } while (once_more); - } -} - -static void -do_questionnaire_bridge_slave (char **priority, char **path_cost, char **hairpin) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'bridge-slave' arguments. */ - if (!want_provide_opt_args (_("bridge-slave"), 3)) - return; - - if (!*priority) { - do { - *priority = nmc_readline (_("Bridge port priority [32]: ")); - *priority = *priority ? *priority : g_strdup ("32"); - once_more = !bridge_prop_string_to_uint (*priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PRIORITY, &tmp, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*priority); - } - } while (once_more); - } - if (!*path_cost) { - do { - *path_cost = nmc_readline (_("Bridge port STP path cost [100]: ")); - *path_cost = *path_cost ? *path_cost : g_strdup ("100"); - once_more = !bridge_prop_string_to_uint (*path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PATH_COST, &tmp, &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*path_cost); - } - } while (once_more); - } - if (!*hairpin) { - gboolean hairpin_bool; - do { - *hairpin = nmc_readline (_("Hairpin %s"), prompt_yes_no (TRUE, ":")); - *hairpin = *hairpin ? *hairpin : g_strdup ("yes"); - normalize_yes_no (hairpin); - once_more = !nmc_string_to_bool (*hairpin, &hairpin_bool, &error); - if (once_more) { - printf (_("Error: 'hairpin': %s.\n"), error->message); - g_clear_error (&error); - g_free (*hairpin); - } - } while (once_more); - } -} - -static void -do_questionnaire_vpn (char **user) -{ - /* Ask for optional 'vpn' arguments. */ - if (!want_provide_opt_args (_("VPN"), 1)) - return; - - if (!*user) - *user = nmc_readline (_("Username [none]: ")); -} - -static void -do_questionnaire_olpc (char **channel, char **dhcp_anycast) -{ - unsigned long tmp; - gboolean once_more; - GError *error = NULL; - - /* Ask for optional 'olpc' arguments. */ - if (!want_provide_opt_args (_("OLPC Mesh"), 2)) - return; - - if (!*channel) { - do { - *channel = nmc_readline (_("OLPC Mesh channel [1]: ")); - once_more = *channel && !nmc_string_to_uint (*channel, TRUE, 1, 13, &tmp); - if (once_more) { - printf (_("Error: 'channel': '%s' is not a valid number <1-13>.\n"), - *channel); - g_free (*channel); - } - } while (once_more); - } - if (!*dhcp_anycast) { - do { - *dhcp_anycast = nmc_readline (_("DHCP anycast MAC address [none]: ")); - once_more = !check_and_convert_mac (*dhcp_anycast, NULL, ARPHRD_ETHER, "dhcp-anycast", &error); - if (once_more) { - printf ("%s\n", error->message); - g_clear_error (&error); - g_free (*dhcp_anycast); - } - } while (once_more); - } -} - -static gboolean -split_address (char* str, char **ip, char **gw, char **rest) -{ - size_t n1, n2, n3, n4, n5; - - *ip = *gw = *rest = NULL; - if (!str) - return FALSE; - - n1 = strspn (str, " \t"); - n2 = strcspn (str+n1, " \t\0") + n1; - n3 = strspn (str+n2, " \t") + n2; - n4 = strcspn (str+n3, " \t\0") + n3; - n5 = strspn (str+n4, " \t") + n4; - - str[n2] = str[n4] = '\0'; - *ip = str[n1] ? str + n1 : NULL; - *gw = str[n3] ? str + n3 : NULL; - *rest = str[n5] ? str + n5 : NULL; - - return TRUE; -} - -static void -ask_for_ip_addresses (NMConnection *connection, int family) -{ - gboolean ip_loop; - GError *error = NULL; - char *str, *ip, *gw, *rest; - const char *prompt; - gboolean added; - gpointer ipaddr; - - if (family == 4) - prompt =_("IPv4 address (IP[/plen] [gateway]) [none]: "); - else - prompt =_("IPv6 address (IP[/plen] [gateway]) [none]: "); - - ip_loop = TRUE; - do { - str = nmc_readline ("%s", prompt); - split_address (str, &ip, &gw, &rest); - if (ip) { - if (family == 4) - ipaddr = nmc_parse_and_build_ip4_address (ip, gw, &error); - else - ipaddr = nmc_parse_and_build_ip6_address (ip, gw, &error); - if (ipaddr) { - if (family == 4) - added = add_ip4_address_to_connection ((NMIP4Address *) ipaddr, connection); - else - added = add_ip6_address_to_connection ((NMIP6Address *) ipaddr, connection); - gw = gw ? gw : (family == 4) ? "0.0.0.0" : "::"; - if (added) - printf (_(" Address successfully added: %s %s\n"), ip, gw); - else - printf (_(" Warning: address already present: %s %s\n"), ip, gw); - if (rest) - printf (_(" Warning: ignoring garbage at the end: '%s'\n"), rest); - } else { - g_prefix_error (&error, _("Error: ")); - printf ("%s\n", error->message); - g_clear_error (&error); - } - } else - ip_loop = FALSE; - - g_free (str); - } while (ip_loop); -} - -static void -do_questionnaire_ip (NMConnection *connection) -{ - char *answer; - - /* Ask for IP addresses */ - answer = nmc_readline (_("Do you want to add IP addresses? %s"), prompt_yes_no (TRUE, NULL)); - answer = answer ? g_strstrip (answer) : NULL; - if (answer && matches (answer, WORD_LOC_YES) != 0) { - g_free (answer); - return; - } - - printf (_("Press to finish adding addresses.\n")); - - ask_for_ip_addresses (connection, 4); - ask_for_ip_addresses (connection, 6); - - g_free (answer); - return; -} - -static gboolean -complete_connection_by_type (NMConnection *connection, - const char *con_type, - GSList *all_connections, - gboolean ask, - int argc, - char **argv, - GError **error) -{ - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingInfiniband *s_infiniband; - NMSettingWireless *s_wifi; - NMSettingWimax *s_wimax; - NMSettingPPPOE *s_pppoe; - NMSettingGsm *s_gsm; - NMSettingCdma *s_cdma; - NMSettingBluetooth *s_bt; - NMSettingVlan *s_vlan; - NMSettingBond *s_bond; - NMSettingTeam *s_team; - NMSettingTeamPort *s_team_port; - NMSettingBridge *s_bridge; - NMSettingBridgePort *s_bridge_port; - NMSettingVPN *s_vpn; - NMSettingOlpcMesh *s_olpc_mesh; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - if (!strcmp (con_type, NM_SETTING_WIRED_SETTING_NAME)) { - /* Build up the settings required for 'ethernet' */ - gboolean success = FALSE; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - const char *cloned_mac_c = NULL; - char *cloned_mac = NULL; - GByteArray *array = NULL; - GByteArray *cloned_array = NULL; - nmc_arg_t exp_args[] = { {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; - if (ask) - do_questionnaire_ethernet (TRUE, &mtu, &mac, &cloned_mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_wired; - if (!check_and_convert_mac (mac, &array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wired; - if (!check_and_convert_mac (cloned_mac, &cloned_array, ARPHRD_ETHER, "cloned-mac", error)) - goto cleanup_wired; - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, array, NULL); - if (cloned_array) - g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_array, NULL); - - success = TRUE; -cleanup_wired: - g_free (mtu); - g_free (mac); - g_free (cloned_mac); - if (array) - g_byte_array_free (array, TRUE); - if (cloned_array) - g_byte_array_free (cloned_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_INFINIBAND_SETTING_NAME)) { - /* Build up the settings required for 'infiniband' */ - gboolean success = FALSE; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *array = NULL; - const char *mode_c = NULL; - char *mode = NULL; - const char *parent_c = NULL; - char *parent = NULL; - const char *p_key_c = NULL; - char *p_key = NULL; - guint32 p_key_int = 0; - nmc_arg_t exp_args[] = { {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"transport-mode", TRUE, &mode_c, FALSE}, - {"parent", TRUE, &parent_c, FALSE}, - {"p-key", TRUE, &p_key_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - mode = mode_c ? g_strdup (mode_c) : NULL; - parent = parent_c ? g_strdup (parent_c) : NULL; - p_key = p_key_c ? g_strdup (p_key_c) : NULL; - if (ask) - do_questionnaire_infiniband (&mtu, &mac, &mode, &parent, &p_key); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_ib; - if (!check_and_convert_mac (mac, &array, ARPHRD_INFINIBAND, "mac", error)) - goto cleanup_ib; - if (!check_infiniband_mode (&mode, error)) - goto cleanup_ib; - if (p_key) { - if (!check_infiniband_p_key (p_key, &p_key_int, error)) - goto cleanup_ib; - if (!check_infiniband_parent (parent, error)) - goto cleanup_ib; - } else if (parent) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'parent': not valid without 'p-key'.")); - goto cleanup_ib; - } - - /* Add 'infiniband' setting */ - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); - nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, mode ? mode : "datagram", NULL); - if (mtu) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MTU, mtu_int, NULL); - if (array) { - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - if (p_key) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_P_KEY, p_key_int, NULL); - if (parent) - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_PARENT, parent, NULL); - - - success = TRUE; -cleanup_ib: - g_free (mtu); - g_free (mac); - g_free (mode); - g_free (parent); - g_free (p_key); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME)) { - /* Build up the settings required for 'wifi' */ - gboolean success = FALSE; - char *ssid_ask = NULL; - const char *ssid = NULL; - GByteArray *ssid_arr = NULL; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - const char *cloned_mac_c = NULL; - char *cloned_mac = NULL; - GByteArray *cloned_mac_array = NULL; - nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, - {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {"cloned-mac", TRUE, &cloned_mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!ssid && ask) - ssid = ssid_ask = nmc_readline (_("SSID: ")); - if (!ssid) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'ssid' is required.")); - return FALSE; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - mac = mac_c ? g_strdup (mac_c) : NULL; - cloned_mac = cloned_mac_c ? g_strdup (cloned_mac_c) : NULL; - if (ask) - do_questionnaire_wifi (&mtu, &mac, &cloned_mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_wifi; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wifi; - if (!check_and_convert_mac (cloned_mac, &cloned_mac_array, ARPHRD_ETHER, "cloned-mac", error)) - goto cleanup_wifi; - - /* Add wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid_arr = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (ssid_arr, (const guint8 *) ssid, strlen (ssid)); - g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid_arr, NULL); - - if (mtu) - g_object_set (s_wifi, NM_SETTING_WIRELESS_MTU, mtu_int, NULL); - if (mac_array) - g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_array, NULL); - if (cloned_mac_array) - g_object_set (s_wifi, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac_array, NULL); - - success = TRUE; -cleanup_wifi: - g_free (ssid_ask); - g_free (mtu); - g_free (mac); - g_free (cloned_mac); - if (ssid_arr) - g_byte_array_free (ssid_arr, TRUE); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (cloned_mac_array) - g_byte_array_free (cloned_mac_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_WIMAX_SETTING_NAME)) { - /* Build up the settings required for 'wimax' */ - gboolean success = FALSE; - const char *nsp_name = NULL; - char *nsp_name_ask = NULL; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"nsp", TRUE, &nsp_name, !ask}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!nsp_name && ask) - nsp_name = nsp_name_ask = nmc_readline (_("WiMAX NSP name: ")); - if (!nsp_name) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'nsp' is required.")); - goto cleanup_wimax; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mac = mac_c ? g_strdup (mac_c) : NULL; - if (ask) - do_questionnaire_wimax (&mac); - - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_wimax; - - /* Add 'wimax' setting */ - s_wimax = (NMSettingWimax *) nm_setting_wimax_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wimax)); - g_object_set (s_wimax, NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); - - if (mac_array) { - g_object_set (s_wimax, NM_SETTING_WIMAX_MAC_ADDRESS, mac_array, NULL); - g_byte_array_free (mac_array, TRUE); - } - - success = TRUE; -cleanup_wimax: - g_free (nsp_name_ask); - g_free (mac); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_PPPOE_SETTING_NAME)) { - /* Build up the settings required for 'pppoe' */ - gboolean success = FALSE; - const char *username = NULL; - char *username_ask = NULL; - const char *password_c = NULL; - char *password = NULL; - const char *service_c = NULL; - char *service = NULL; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int = 0; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"username", TRUE, &username, !ask}, - {"password", TRUE, &password_c, FALSE}, - {"service", TRUE, &service_c, FALSE}, - {"mtu", TRUE, &mtu_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!username && ask) - username = username_ask = nmc_readline (_("PPPoE username: ")); - if (!username) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'username' is required.")); - goto cleanup_pppoe; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - password = g_strdup (password_c); - service = g_strdup (service_c); - mtu = g_strdup (mtu_c); - mac = g_strdup (mac_c); - if (ask) - do_questionnaire_pppoe (&password, &service, &mtu, &mac); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_pppoe; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_pppoe; - - /* Add 'pppoe' setting */ - s_pppoe = (NMSettingPPPOE *) nm_setting_pppoe_new (); - nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); - g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, username, NULL); - g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, password, NULL); - g_object_set (s_pppoe, NM_SETTING_PPPOE_SERVICE, service, NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (mac_array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_array, NULL); - - success = TRUE; -cleanup_pppoe: - g_free (username_ask); - g_free (password); - g_free (service); - g_free (mtu); - g_free (mac); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (!success) - return FALSE; - - } else if ( !strcmp (con_type, NM_SETTING_GSM_SETTING_NAME) - || !strcmp (con_type, NM_SETTING_CDMA_SETTING_NAME)) { - /* Build up the settings required for 'gsm' or 'cdma' mobile broadband */ - gboolean success = FALSE; - const char *apn = NULL; - char *apn_ask = NULL; - const char *user_c = NULL; - char *user = NULL; - const char *password_c = NULL; - char *password = NULL; - gboolean is_gsm; - int i = 0; - nmc_arg_t gsm_args[] = { {NULL}, {NULL}, {NULL}, /* placeholders */ - {NULL} }; - - is_gsm = !strcmp (con_type, NM_SETTING_GSM_SETTING_NAME); - - if (is_gsm) - gsm_args[i++] = (nmc_arg_t) {"apn", TRUE, &apn, !ask}; - gsm_args[i++] = (nmc_arg_t) {"user", TRUE, &user_c, FALSE}; - gsm_args[i++] = (nmc_arg_t) {"password", TRUE, &password_c, FALSE}; - gsm_args[i++] = (nmc_arg_t) {NULL}; - - if (!nmc_parse_args (gsm_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!apn && ask && is_gsm) - apn = apn_ask = nmc_readline (_("APN: ")); - if (!apn && is_gsm) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'apn' is required.")); - goto cleanup_mobile; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - user = user_c ? g_strdup (user_c) : NULL; - password = password_c ? g_strdup (password_c) : NULL; - if (ask) - do_questionnaire_mobile (&user, &password); - - if (is_gsm) { - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, NULL); - - /* Add 'gsm' setting */ - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - g_object_set (s_gsm, - NM_SETTING_GSM_NUMBER, "*99#", - NM_SETTING_GSM_APN, apn, - NM_SETTING_GSM_USERNAME, user, - NM_SETTING_GSM_PASSWORD, password, - NULL); - g_free (apn_ask); - } else { - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_CDMA_SETTING_NAME, NULL); - - /* Add 'cdma' setting */ - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - g_object_set (s_cdma, - NM_SETTING_CDMA_NUMBER, "#777", - NM_SETTING_CDMA_USERNAME, user, - NM_SETTING_CDMA_PASSWORD, password, - NULL); - } - - success = TRUE; -cleanup_mobile: - g_free (user); - g_free (password); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BLUETOOTH_SETTING_NAME)) { - /* Build up the settings required for 'bluetooth' */ - gboolean success = FALSE; - const char *addr = NULL; - char *addr_ask = NULL; - const char *bt_type_c = NULL; - char *bt_type = NULL; - GByteArray *array = NULL; - nmc_arg_t exp_args[] = { {"addr", TRUE, &addr, !ask}, - {"bt-type", TRUE, &bt_type_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!addr && ask) - addr = addr_ask = nmc_readline (_("Bluetooth device address: ")); - if (!addr) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'addr' is required.")); - return FALSE; - } - if (!check_and_convert_mac (addr, &array, ARPHRD_ETHER, "addr", error)) - goto cleanup_bt; - - /* Also ask for all optional arguments if '--ask' is specified. */ - bt_type = bt_type_c ? g_strdup (bt_type_c) : NULL; - if (ask) - do_questionnaire_bluetooth (&bt_type); - - /* Default to 'panu' if bt-type is not provided. */ - if (!bt_type) - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_PANU); - - /* Add 'bluetooth' setting */ - s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bt)); - - if (array) { - g_object_set (s_bt, NM_SETTING_BLUETOOTH_BDADDR, array, NULL); - g_byte_array_free (array, TRUE); - } - - /* 'dun' type requires adding 'gsm' or 'cdma' setting */ - if ( !strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN) - || !strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm")) { - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_DUN); - s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); - nm_connection_add_setting (connection, NM_SETTING (s_gsm)); - g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); -// g_object_set (s_gsm, NM_SETTING_GSM_APN, "FIXME", NULL; - - } else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma")) { - bt_type = g_strdup (NM_SETTING_BLUETOOTH_TYPE_DUN); - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL); - - } else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { - /* no op */ - } else { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]."), - bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU, NM_SETTING_BLUETOOTH_TYPE_DUN, - NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm", NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma"); - goto cleanup_bt; - } - g_object_set (s_bt, NM_SETTING_BLUETOOTH_TYPE, bt_type, NULL); - - success = TRUE; -cleanup_bt: - g_free (addr_ask); - g_free (bt_type); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_VLAN_SETTING_NAME)) { - /* Build up the settings required for 'vlan' */ - gboolean success = FALSE; - const char *ifname = NULL; - const char *parent = NULL; - char *parent_ask = NULL; - const char *vlan_id = NULL; - char *vlan_id_ask = NULL; - unsigned long id = 0; - const char *flags_c = NULL; - char *flags = NULL; - guint32 flags_int = 0; - const char *ingress_c = NULL, *egress_c = NULL; - char *ingress = NULL, *egress = NULL; - char **ingress_arr = NULL, **egress_arr = NULL, **p; - const char *mtu_c = NULL; - char *mtu = NULL; - guint32 mtu_int; - GByteArray *addr_array = NULL; - nmc_arg_t exp_args[] = { {"dev", TRUE, &parent, !ask}, - {"id", TRUE, &vlan_id, !ask}, - {"flags", TRUE, &flags_c, FALSE}, - {"ingress", TRUE, &ingress_c, FALSE}, - {"egress", TRUE, &egress_c, FALSE}, - {"mtu", TRUE, &mtu_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!parent && ask) - parent = parent_ask = nmc_readline (_("VLAN parent device or connection UUID: ")); - if (!parent) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'dev' is required.")); - return FALSE; - } - if (!vlan_id && ask) - vlan_id = vlan_id_ask = nmc_readline (_("VLAN ID <0-4095>: ")); - if (!vlan_id) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'id' is required.")); - goto cleanup_vlan; - } - if (vlan_id) { - if (!nmc_string_to_uint (vlan_id, TRUE, 0, 4095, &id)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'id': '%s' is not valid; use <0-4095>."), - vlan_id); - goto cleanup_vlan; - } - } - - if ( !(addr_array = nm_utils_hwaddr_atoba (parent, ARPHRD_ETHER)) - && !nm_utils_is_uuid (parent) - && !nm_utils_iface_valid_name (parent)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'dev': '%s' is neither UUID, interface name, nor MAC."), - parent); - goto cleanup_vlan; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - mtu = mtu_c ? g_strdup (mtu_c) : NULL; - flags = flags_c ? g_strdup (flags_c) : NULL; - ingress = ingress_c ? g_strdup (ingress_c) : NULL; - egress = egress_c ? g_strdup (egress_c) : NULL; - if (ask) - do_questionnaire_vlan (&mtu, &flags, &ingress, &egress); - - /* ifname is taken from connection's ifname */ - ifname = nm_setting_connection_get_interface_name (s_con); - - if (!check_and_convert_mtu (mtu, &mtu_int, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_flags (flags, &flags_int, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_prio_maps (ingress, NM_VLAN_INGRESS_MAP, &ingress_arr, error)) - goto cleanup_vlan; - if (!check_and_convert_vlan_prio_maps (egress, NM_VLAN_EGRESS_MAP, &egress_arr, error)) - goto cleanup_vlan; - - /* Add 'vlan' setting */ - s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vlan)); - - /* Add 'wired' setting if necessary */ - if (mtu || addr_array) { - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (mtu) - g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu_int, NULL); - if (addr_array) - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, addr_array, NULL); - } - - /* Set 'vlan' properties */ - if (!addr_array) - g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, parent, NULL); - - if (ifname) - g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, ifname, NULL); - g_object_set (s_vlan, NM_SETTING_VLAN_ID, id, NULL); - - if (flags) - g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, flags_int, NULL); - for (p = ingress_arr; p && *p; p++) - nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_INGRESS_MAP, *p); - for (p = egress_arr; p && *p; p++) - nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_EGRESS_MAP, *p); - - success = TRUE; -cleanup_vlan: - g_free (mtu); - g_free (flags); - g_free (ingress); - g_free (egress); - if (addr_array) - g_byte_array_free (addr_array, TRUE); - g_free (parent_ask); - g_free (vlan_id_ask); - g_strfreev (ingress_arr); - g_strfreev (egress_arr); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BOND_SETTING_NAME)) { - /* Build up the settings required for 'bond' */ - gboolean success = FALSE; - char *bond_ifname = NULL; - const char *ifname = NULL; - const char *bond_mode_c = NULL; - char *bond_mode = NULL; - const char *bond_primary_c = NULL; - char *bond_primary = NULL; - const char *bond_miimon_c = NULL; - char *bond_miimon = NULL; - const char *bond_downdelay_c = NULL; - char *bond_downdelay = NULL; - const char *bond_updelay_c = NULL; - char *bond_updelay = NULL; - const char *bond_arpinterval_c = NULL; - char *bond_arpinterval = NULL; - const char *bond_arpiptarget_c = NULL; - char *bond_arpiptarget = NULL; - nmc_arg_t exp_args[] = { {"mode", TRUE, &bond_mode_c, FALSE}, - {"primary", TRUE, &bond_primary_c, FALSE}, - {"miimon", TRUE, &bond_miimon_c, FALSE}, - {"downdelay", TRUE, &bond_downdelay_c, FALSE}, - {"updelay", TRUE, &bond_updelay_c, FALSE}, - {"arp-interval", TRUE, &bond_arpinterval_c, FALSE}, - {"arp-ip-target", TRUE, &bond_arpiptarget_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - bond_mode = bond_mode_c ? g_strdup (bond_mode_c) : NULL; - bond_primary = bond_primary_c ? g_strdup (bond_primary_c) : NULL; - bond_miimon = bond_miimon_c ? g_strdup (bond_miimon_c) : NULL; - bond_downdelay = bond_downdelay_c ? g_strdup (bond_downdelay_c) : NULL; - bond_updelay = bond_updelay_c ? g_strdup (bond_updelay_c) : NULL; - bond_arpinterval = bond_arpinterval_c ? g_strdup (bond_arpinterval_c) : NULL; - bond_arpiptarget = bond_arpiptarget_c ? g_strdup (bond_arpiptarget_c) : NULL; - if (ask) - do_questionnaire_bond (&bond_mode, &bond_primary, &bond_miimon, - &bond_downdelay, &bond_updelay, - &bond_arpinterval, &bond_arpiptarget); - - /* Use connection's ifname as 'bond' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - bond_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_BOND_SETTING_NAME, - NM_SETTING_BOND_INTERFACE_NAME, - "nm-bond"); - else - bond_ifname = g_strdup (ifname); - - /* Add 'bond' setting */ - s_bond = (NMSettingBond *) nm_setting_bond_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bond)); - - /* Set bond options */ - g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, bond_ifname, NULL); - if (bond_mode) { - GError *err = NULL; - const char *bm; - if (!(bm = nmc_bond_validate_mode (bond_mode, &err))) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'mode': %s."), err->message); - g_clear_error (&err); - goto cleanup_bond; - } - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MODE, bm); - } - if (bond_primary) { - if (!nm_utils_iface_valid_name (bond_primary)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'primary': '%s' is not a valid interface name."), - bond_primary); - goto cleanup_bond; - } - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_PRIMARY, bond_primary); - } - if (bond_miimon) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON, bond_miimon); - if (bond_downdelay && strcmp (bond_downdelay, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, bond_downdelay); - if (bond_updelay && strcmp (bond_updelay, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY, bond_updelay); - if (bond_arpinterval && strcmp (bond_arpinterval, "0") != 0) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL, bond_arpinterval); - if (bond_arpiptarget) - nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, bond_arpiptarget); - - success = TRUE; -cleanup_bond: - g_free (bond_ifname); - g_free (bond_mode); - g_free (bond_primary); - g_free (bond_miimon); - g_free (bond_downdelay); - g_free (bond_updelay); - g_free (bond_arpinterval); - g_free (bond_arpiptarget); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "bond-slave")) { - /* Build up the settings required for 'bond-slave' */ - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_BOND_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_BOND_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_BOND_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - g_free (master_ask); - - } else if (!strcmp (con_type, NM_SETTING_TEAM_SETTING_NAME)) { - /* Build up the settings required for 'team' */ - gboolean success = FALSE; - char *team_ifname = NULL; - const char *ifname = NULL; - const char *config_c = NULL; - char *config = NULL; - char *json = NULL; - nmc_arg_t exp_args[] = { {"config", TRUE, &config_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - config = g_strdup (config_c); - if (ask) - do_questionnaire_team (&config); - - /* Use connection's ifname as 'team' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - team_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_TEAM_SETTING_NAME, - NM_SETTING_TEAM_INTERFACE_NAME, - "nm-team"); - else - team_ifname = g_strdup (ifname); - - /* Add 'team' setting */ - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team)); - - if (!nmc_team_check_config (config, &json, error)) { - g_prefix_error (error, _("Error: ")); - goto cleanup_team; - } - - /* Set team options */ - g_object_set (s_team, NM_SETTING_TEAM_INTERFACE_NAME, team_ifname, NULL); - g_object_set (s_team, NM_SETTING_TEAM_CONFIG, json, NULL); - - success = TRUE; -cleanup_team: - g_free (team_ifname); - g_free (config); - g_free (json); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "team-slave")) { - /* Build up the settings required for 'team-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - const char *config_c = NULL; - char *config = NULL; - char *json = NULL; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {"config", TRUE, &config_c, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_TEAM_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_TEAM_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_TEAM_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - /* Also ask for all optional arguments if '--ask' is specified. */ - config = g_strdup (config_c); - if (ask) - do_questionnaire_team_slave (&config); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Add 'team-port' setting */ - s_team_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team_port)); - - if (!nmc_team_check_config (config, &json, error)) { - g_prefix_error (error, _("Error: ")); - goto cleanup_team_slave; - } - - /* Set team-port options */ - g_object_set (s_team_port, NM_SETTING_TEAM_PORT_CONFIG, json, NULL); - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - success = TRUE; -cleanup_team_slave: - g_free (master_ask); - g_free (config); - g_free (json); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_BRIDGE_SETTING_NAME)) { - /* Build up the settings required for 'bridge' */ - gboolean success = FALSE; - char *bridge_ifname = NULL; - const char *ifname = NULL; - const char *stp_c = NULL; - char *stp = NULL; - const char *priority_c = NULL; - char *priority = NULL; - const char *fwd_delay_c = NULL; - char *fwd_delay = NULL; - const char *hello_time_c = NULL; - char *hello_time = NULL; - const char *max_age_c = NULL; - char *max_age = NULL; - const char *ageing_time_c = NULL; - char *ageing_time = NULL; - gboolean stp_bool; - unsigned long stp_prio_int, fwd_delay_int, hello_time_int, - max_age_int, ageing_time_int; - const char *mac_c = NULL; - char *mac = NULL; - GByteArray *mac_array = NULL; - nmc_arg_t exp_args[] = { {"stp", TRUE, &stp_c, FALSE}, - {"priority", TRUE, &priority_c, FALSE}, - {"forward-delay", TRUE, &fwd_delay_c, FALSE}, - {"hello-time", TRUE, &hello_time_c, FALSE}, - {"max-age", TRUE, &max_age_c, FALSE}, - {"ageing-time", TRUE, &ageing_time_c, FALSE}, - {"mac", TRUE, &mac_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - /* Also ask for all optional arguments if '--ask' is specified. */ - stp = stp_c ? g_strdup (stp_c) : NULL; - priority = priority_c ? g_strdup (priority_c) : NULL; - fwd_delay = fwd_delay_c ? g_strdup (fwd_delay_c) : NULL; - hello_time = hello_time_c ? g_strdup (hello_time_c) : NULL; - max_age = max_age_c ? g_strdup (max_age_c) : NULL; - ageing_time = ageing_time_c ? g_strdup (ageing_time_c) : NULL; - mac = g_strdup (mac_c); - if (ask) - do_questionnaire_bridge (&stp, &priority, &fwd_delay, &hello_time, - &max_age, &ageing_time, &mac); - - /* Use connection's ifname as 'bridge' ifname if exists, else generate one */ - ifname = nm_setting_connection_get_interface_name (s_con); - if (!ifname) - bridge_ifname = unique_master_iface_ifname (all_connections, - NM_SETTING_BRIDGE_SETTING_NAME, - NM_SETTING_BRIDGE_INTERFACE_NAME, - "nm-bridge"); - else - bridge_ifname = g_strdup (ifname); - - if (stp) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (stp, &stp_bool, &tmp_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'stp': %s."), tmp_err->message); - g_clear_error (&tmp_err); - goto cleanup_bridge; - } - } - - /* Add 'bond' setting */ - /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ - s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - - if (priority) - if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_PRIORITY, &stp_prio_int, error)) - goto cleanup_bridge; - if (fwd_delay) - if (!bridge_prop_string_to_uint (fwd_delay, "forward-delay", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_FORWARD_DELAY, &fwd_delay_int, error)) - goto cleanup_bridge; - if (hello_time) - if (!bridge_prop_string_to_uint (hello_time, "hello-time", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_HELLO_TIME, &hello_time_int, error)) - goto cleanup_bridge; - if (max_age) - if (!bridge_prop_string_to_uint (max_age, "max-age", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_MAX_AGE, &max_age_int, error)) - goto cleanup_bridge; - if (ageing_time) - if (!bridge_prop_string_to_uint (ageing_time, "ageing-time", NM_TYPE_SETTING_BRIDGE, - NM_SETTING_BRIDGE_AGEING_TIME, &ageing_time_int, error)) - goto cleanup_bridge; - if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error)) - goto cleanup_bridge; - - /* Set bridge options */ - g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, bridge_ifname, NULL); - if (stp) - g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, stp_bool, NULL); - if (priority) - g_object_set (s_bridge, NM_SETTING_BRIDGE_PRIORITY, stp_prio_int, NULL); - if (fwd_delay) - g_object_set (s_bridge, NM_SETTING_BRIDGE_FORWARD_DELAY, fwd_delay_int, NULL); - if (hello_time) - g_object_set (s_bridge, NM_SETTING_BRIDGE_HELLO_TIME, hello_time_int, NULL); - if (max_age) - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAX_AGE, max_age_int, NULL); - if (ageing_time) - g_object_set (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME, ageing_time_int, NULL); - if (mac_array) - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, mac_array, NULL); - - success = TRUE; -cleanup_bridge: - g_free (bridge_ifname); - g_free (stp); - g_free (priority); - g_free (fwd_delay); - g_free (hello_time); - g_free (max_age); - g_free (ageing_time); - g_free (mac); - if (mac_array) - g_byte_array_free (mac_array, TRUE); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, "bridge-slave")) { - /* Build up the settings required for 'bridge-slave' */ - gboolean success = FALSE; - const char *master = NULL; - char *master_ask = NULL; - const char *checked_master = NULL; - const char *type = NULL; - const char *priority_c = NULL; - char *priority = NULL; - const char *path_cost_c = NULL; - char *path_cost = NULL; - const char *hairpin_c = NULL; - char *hairpin = NULL; - unsigned long prio_int, path_cost_int; - gboolean hairpin_bool; - nmc_arg_t exp_args[] = { {"master", TRUE, &master, !ask}, - {"type", TRUE, &type, FALSE}, - {"priority", TRUE, &priority_c, FALSE}, - {"path-cost", TRUE, &path_cost_c, FALSE}, - {"hairpin", TRUE, &hairpin_c, FALSE}, - {NULL} }; - - /* Set global variables for use in TAB completion */ - nmc_tab_completion.con_type = NM_SETTING_BRIDGE_SETTING_NAME; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - if (!master && ask) - master = master_ask = nmc_readline (PROMPT_BRIDGE_MASTER); - if (!master) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'master' is required.")); - return FALSE; - } - /* Verify master argument */ - checked_master = verify_master_for_slave (all_connections, master, NM_SETTING_BRIDGE_SETTING_NAME); - if (!checked_master) - printf (_("Warning: master='%s' doesn't refer to any existing profile.\n"), master); - - if (type) - printf (_("Warning: 'type' is currently ignored. " - "We only support ethernet slaves for now.\n")); - - /* Add 'bridge-port' setting */ - /* Must be done *before* bridge_prop_string_to_uint() so that the type is known */ - s_bridge_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_bridge_port)); - - /* Also ask for all optional arguments if '--ask' is specified. */ - priority = priority_c ? g_strdup (priority_c) : NULL; - path_cost = path_cost_c ? g_strdup (path_cost_c) : NULL; - hairpin = hairpin_c ? g_strdup (hairpin_c) : NULL; - if (ask) - do_questionnaire_bridge_slave (&priority, &path_cost, &hairpin); - - if (priority) - if (!bridge_prop_string_to_uint (priority, "priority", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PRIORITY, &prio_int, error)) - goto cleanup_bridge_slave; - if (path_cost) - if (!bridge_prop_string_to_uint (path_cost, "path-cost", NM_TYPE_SETTING_BRIDGE_PORT, - NM_SETTING_BRIDGE_PORT_PATH_COST, &path_cost_int, error)) - goto cleanup_bridge_slave; - if (hairpin) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (hairpin, &hairpin_bool, &tmp_err)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'hairpin': %s."), tmp_err->message); - g_clear_error (&tmp_err); - goto cleanup_bridge_slave; - } - } - - /* Change properties in 'connection' setting */ - g_object_set (s_con, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_MASTER, checked_master ? checked_master : _strip_master_prefix (master, NULL), - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, - NULL); - - /* Add ethernet setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - if (priority) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PRIORITY, prio_int, NULL); - if (path_cost) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_PATH_COST, path_cost_int, NULL); - if (hairpin) - g_object_set (s_bridge_port, NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, hairpin_bool, NULL); - - success = TRUE; -cleanup_bridge_slave: - g_free (master_ask); - g_free (priority); - g_free (path_cost); - g_free (hairpin); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_VPN_SETTING_NAME)) { - /* Build up the settings required for 'vpn' */ - gboolean success = FALSE; - const char *vpn_type = NULL; - char *vpn_type_ask = NULL; - const char *user_c = NULL; - char *user = NULL; - const char *st; - char *service_type = NULL; - nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask}, - {"user", TRUE, &user_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!vpn_type && ask) - vpn_type = vpn_type_ask = nmc_readline (PROMPT_VPN_TYPE); - if (!vpn_type) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'vpn-type' is required.")); - goto cleanup_vpn; - } - if (vpn_type_ask) - vpn_type = g_strstrip (vpn_type_ask); - - if (!(st = nmc_string_is_valid (vpn_type, nmc_known_vpns, NULL))) { - printf (_("Warning: 'vpn-type': %s not known.\n"), vpn_type); - st = vpn_type; - } - service_type = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, st); - - /* Also ask for all optional arguments if '--ask' is specified. */ - user = user_c ? g_strdup (user_c) : NULL; - if (ask) - do_questionnaire_vpn (&user); - - /* Add 'vpn' setting */ - s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); - nm_connection_add_setting (connection, NM_SETTING (s_vpn)); - - g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL); - g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user, NULL); - - success = TRUE; -cleanup_vpn: - g_free (vpn_type_ask); - g_free (service_type); - g_free (user); - if (!success) - return FALSE; - - } else if (!strcmp (con_type, NM_SETTING_OLPC_MESH_SETTING_NAME)) { - /* Build up the settings required for 'olpc' */ - gboolean success = FALSE; - char *ssid_ask = NULL; - const char *ssid = NULL; - GByteArray *ssid_arr; - const char *channel_c = NULL; - char *channel = NULL; - unsigned long chan; - const char *dhcp_anycast_c = NULL; - char *dhcp_anycast = NULL; - GByteArray *array = NULL; - nmc_arg_t exp_args[] = { {"ssid", TRUE, &ssid, !ask}, - {"channel", TRUE, &channel_c, FALSE}, - {"dhcp-anycast", TRUE, &dhcp_anycast_c, FALSE}, - {NULL} }; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error)) - return FALSE; - - if (!ssid && ask) - ssid = ssid_ask = nmc_readline (_("SSID: ")); - if (!ssid) { - g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'ssid' is required.")); - goto cleanup_olpc; - } - - /* Also ask for all optional arguments if '--ask' is specified. */ - channel = channel_c ? g_strdup (channel_c) : NULL; - dhcp_anycast = dhcp_anycast_c ? g_strdup (dhcp_anycast_c) : NULL; - if (ask) - do_questionnaire_olpc (&channel, &dhcp_anycast); - - if (channel) { - if (!nmc_string_to_uint (channel, TRUE, 1, 13, &chan)) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'channel': '%s' is not valid; use <1-13>."), - channel); - goto cleanup_olpc; - } - } - if (!check_and_convert_mac (dhcp_anycast, &array, ARPHRD_ETHER, "dhcp-anycast", error)) - goto cleanup_olpc; - - /* Add OLPC mesh setting */ - s_olpc_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new (); - nm_connection_add_setting (connection, NM_SETTING (s_olpc_mesh)); - - ssid_arr = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (ssid_arr, (const guint8 *) ssid, strlen (ssid)); - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_SSID, ssid_arr, NULL); - if (channel) - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_CHANNEL, chan, NULL); - else - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_CHANNEL, 1, NULL); - if (array) { - g_object_set (s_olpc_mesh, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - g_byte_array_free (ssid_arr, TRUE); - - success = TRUE; -cleanup_olpc: - g_free (ssid_ask); - g_free (channel); - g_free (dhcp_anycast); - if (!success) - return FALSE; - - } else { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s' is not a valid connection type."), - con_type); - return FALSE; - } - - /* Read and add IP configuration */ - if ( strcmp (con_type, "bond-slave") != 0 - && strcmp (con_type, "team-slave") != 0 - && strcmp (con_type, "bridge-slave") != 0) { - - NMIP4Address *ip4addr = NULL; - NMIP6Address *ip6addr = NULL; - const char *ip4 = NULL, *gw4 = NULL, *ip6 = NULL, *gw6 = NULL; - nmc_arg_t exp_args[] = { {"ip4", TRUE, &ip4, FALSE}, {"gw4", TRUE, &gw4, FALSE}, - {"ip6", TRUE, &ip6, FALSE}, {"gw6", TRUE, &gw6, FALSE}, - {NULL} }; - - while (argc) { - nmc_arg_t *p; - - /* reset 'found' flag */ - for (p = exp_args; p->name; p++) - p->found = FALSE; - - ip4 = gw4 = ip6 = gw6 = NULL; - - if (!nmc_parse_args (exp_args, TRUE, &argc, &argv, error)) - return FALSE; - - /* coverity[dead_error_begin] */ - if (ip4) { - ip4addr = nmc_parse_and_build_ip4_address (ip4, gw4, error); - if (!ip4addr) { - g_prefix_error (error, _("Error: ")); - return FALSE; - } - add_ip4_address_to_connection (ip4addr, connection); - } - - /* coverity[dead_error_begin] */ - if (ip6) { - ip6addr = nmc_parse_and_build_ip6_address (ip6, gw6, error); - if (!ip6addr) { - g_prefix_error (error, _("Error: ")); - return FALSE; - } - add_ip6_address_to_connection (ip6addr, connection); - } - } - - /* Ask for addresses if '--ask' is specified. */ - if (ask) - do_questionnaire_ip (connection); - } - - return TRUE; -} - -static char * -unique_connection_name (GSList *list, const char *try_name) -{ - NMConnection *connection; - const char *name; - char *new_name; - unsigned int num = 1; - GSList *iterator = list; - - new_name = g_strdup (try_name); - while (iterator) { - connection = NM_CONNECTION (iterator->data); - - name = nm_connection_get_id (connection); - if (g_strcmp0 (new_name, name) == 0) { - g_free (new_name); - new_name = g_strdup_printf ("%s-%d", try_name, num++); - iterator = list; - } - iterator = g_slist_next (iterator); - } - return new_name; -} - -typedef struct { - NmCli *nmc; - char *con_name; -} AddConnectionInfo; - -static void -add_connection_cb (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, - gpointer user_data) -{ - AddConnectionInfo *info = (AddConnectionInfo *) user_data; - NmCli *nmc = info->nmc; - - if (error) { - g_string_printf (nmc->return_text, - _("Error: Failed to add '%s' connection: (%d) %s"), - info->con_name, error->code, error->message); - nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; - } else { - printf (_("Connection '%s' (%s) successfully added.\n"), - nm_connection_get_id (NM_CONNECTION (connection)), - nm_connection_get_uuid (NM_CONNECTION (connection))); - } - - g_free (info->con_name); - g_free (info); - quit (); -} - -static gboolean -add_new_connection (gboolean persistent, - NMRemoteSettings *settings, - NMConnection *connection, - NMRemoteSettingsAddConnectionFunc callback, - gpointer user_data) -{ - if (persistent) - return nm_remote_settings_add_connection (settings, connection, callback, user_data); - else - return nm_remote_settings_add_connection_unsaved (settings, connection, callback, user_data); -} - -static void -update_connection (gboolean persistent, - NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, - gpointer user_data) -{ - if (persistent) - nm_remote_connection_commit_changes (connection, callback, user_data); - else - nm_remote_connection_commit_changes_unsaved (connection, callback, user_data); -} - -static char * -gen_func_vpn_types (const char *text, int state) -{ - return nmc_rl_gen_func_basic (text, state, nmc_known_vpns); -} - -static char * -gen_func_bool_values_l10n (const char *text, int state) -{ - const char *words[] = { WORD_LOC_YES, WORD_LOC_NO, NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_ib_type (const char *text, int state) -{ - const char *words[] = { "datagram", "connected", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bt_type (const char *text, int state) -{ - const char *words[] = { "panu", "dun-gsm", "dun-cdma", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bond_mode (const char *text, int state) -{ - const char *words[] = { "balance-rr", "active-backup", "balance-xor", "broadcast", - "802.3ad", "balance-tlb", "balance-alb", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} -static char * -gen_func_bond_mon_mode (const char *text, int state) -{ - const char *words[] = { "miimon", "arp", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_master_ifnames (const char *text, int state) -{ - GSList *iter; - GPtrArray *ifnames; - char *ret; - NMConnection *con; - NMSettingConnection *s_con; - const char *con_type, *ifname; - - if (!nm_cli.system_connections) - return NULL; - - /* Disable appending space after completion */ - rl_completion_append_character = '\0'; - - ifnames = g_ptr_array_sized_new (20); - for (iter = nm_cli.system_connections; iter; iter = g_slist_next (iter)) { - con = NM_CONNECTION (iter->data); - s_con = nm_connection_get_setting_connection (con); - g_assert (s_con); - con_type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0) - continue; - ifname = nm_connection_get_virtual_iface_name (con); - g_ptr_array_add (ifnames, (gpointer) ifname); - } - g_ptr_array_add (ifnames, (gpointer) NULL); - - ret = nmc_rl_gen_func_basic (text, state, (const char **) ifnames->pdata); - - g_ptr_array_free (ifnames, TRUE); - return ret; -} - -static gboolean -is_single_word (const char* line) -{ - size_t n1, n2, n3; - - n1 = strspn (line, " \t"); - n2 = strcspn (line+n1, " \t\0") + n1; - n3 = strspn (line+n2, " \t"); - - if (n3 == 0) - return TRUE; - else - return FALSE; -} - -static char ** -nmcli_con_add_tab_completion (const char *text, int start, int end) -{ - char **match_array = NULL; - rl_compentry_func_t *generator_func = NULL; - - /* Disable readline's default filename completion */ - rl_attempted_completion_over = 1; - - /* Restore standard append character to space */ - rl_completion_append_character = ' '; - - if (!is_single_word (rl_line_buffer)) - return NULL; - - if (g_strcmp0 (rl_prompt, PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; - else if (g_strcmp0 (rl_prompt, PROMPT_VPN_TYPE) == 0) - generator_func = gen_func_vpn_types; - else if ( g_strcmp0 (rl_prompt, PROMPT_BOND_MASTER) == 0 - || g_strcmp0 (rl_prompt, PROMPT_TEAM_MASTER) == 0 - || g_strcmp0 (rl_prompt, PROMPT_BRIDGE_MASTER) == 0) - generator_func = gen_func_master_ifnames; - else if ( g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, ":")) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, ":"))) - generator_func = gen_func_bool_values_l10n; - else if (g_str_has_suffix (rl_prompt, PROMPT_IB_MODE)) - generator_func = gen_func_ib_type; - else if (g_str_has_suffix (rl_prompt, PROMPT_BT_TYPE)) - generator_func = gen_func_bt_type; - else if (g_str_has_prefix (rl_prompt, PROMPT_BOND_MODE)) - generator_func = gen_func_bond_mode; - else if (g_str_has_suffix (rl_prompt, PROMPT_BOND_MON_MODE)) - generator_func = gen_func_bond_mon_mode; - - if (generator_func) - match_array = rl_completion_matches (text, generator_func); - - return match_array; -} - -static NMCResultCode -do_connection_add (NmCli *nmc, int argc, char **argv) -{ - NMConnection *connection = NULL; - NMSettingConnection *s_con; - char *uuid; - char *default_name = NULL; - const char *type = NULL; - char *type_ask = NULL; - const char *con_name = NULL; - const char *autoconnect = NULL; - gboolean auto_bool = TRUE; - const char *ifname = NULL; - char *ifname_ask = NULL; - gboolean ifname_mandatory = TRUE; - const char *save = NULL; - gboolean save_bool = TRUE; - AddConnectionInfo *info = NULL; - const char *setting_name; - GError *error = NULL; - nmc_arg_t exp_args[] = { {"type", TRUE, &type, !nmc->ask}, - {"con-name", TRUE, &con_name, FALSE}, - {"autoconnect", TRUE, &autoconnect, FALSE}, - {"ifname", TRUE, &ifname, FALSE}, - {"save", TRUE, &save, FALSE}, - {NULL} }; - - rl_attempted_completion_function = (rl_completion_func_t *) nmcli_con_add_tab_completion; - - nmc->return_value = NMC_RESULT_SUCCESS; - - if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, &error)) { - g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto error; - } - - if (!type && nmc->ask) { - char *types_tmp = get_valid_options_string (nmc_valid_connection_types); - printf ("Valid types: [%s]\n", types_tmp); - type = type_ask = nmc_readline (PROMPT_CON_TYPE); - g_free (types_tmp); - } - if (!type) { - g_string_printf (nmc->return_text, _("Error: 'type' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - if (type_ask) - type = g_strstrip (type_ask); - - if (!(setting_name = check_valid_name (type, nmc_valid_connection_types, &error))) { - g_string_printf (nmc->return_text, _("Error: invalid connection type; %s."), - error->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&error); - goto error; - } - if (autoconnect) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (autoconnect, &auto_bool, &tmp_err)) { - g_string_printf (nmc->return_text, _("Error: 'autoconnect': %s."), - tmp_err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&tmp_err); - goto error; - } - } - if (save) { - GError *tmp_err = NULL; - if (!nmc_string_to_bool (save, &save_bool, &tmp_err)) { - g_string_printf (nmc->return_text, _("Error: 'save': %s."), - tmp_err->message); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - g_clear_error (&tmp_err); - goto error; - } - } - - /* ifname is mandatory for all connection types except virtual ones (bond, team, bridge, vlan) */ - if ( strcmp (type, NM_SETTING_BOND_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_TEAM_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME) == 0 - || strcmp (type, NM_SETTING_VLAN_SETTING_NAME) == 0) - ifname_mandatory = FALSE; - - if (!ifname && ifname_mandatory && nmc->ask) { - ifname = ifname_ask = nmc_readline (_("Interface name [*]: ")); - if (!ifname) - ifname = ifname_ask = g_strdup ("*"); - } - if (!ifname && ifname_mandatory) { - g_string_printf (nmc->return_text, _("Error: 'ifname' argument is required.")); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - if (ifname) { - if (!nm_utils_iface_valid_name (ifname) && strcmp (ifname, "*") != 0) { - g_string_printf (nmc->return_text, - _("Error: 'ifname': '%s' is not a valid interface nor '*'."), - ifname); - nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; - goto error; - } - /* Special value of '*' means no specific interface name */ - if (strcmp (ifname, "*") == 0) - ifname = NULL; - } - - /* Create a new connection object */ - connection = nm_connection_new (); - - /* Build up the 'connection' setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - uuid = nm_utils_uuid_generate (); - if (con_name) - default_name = g_strdup (con_name); - else { - char *try_name = ifname ? - g_strdup_printf ("%s-%s", get_name_alias (setting_name, nmc_valid_connection_types), ifname) - : g_strdup (get_name_alias (setting_name, nmc_valid_connection_types)); - default_name = unique_connection_name (nmc->system_connections, try_name); - g_free (try_name); - } - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, default_name, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, setting_name, - NM_SETTING_CONNECTION_AUTOCONNECT, auto_bool, - NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, - NULL); - g_free (uuid); - g_free (default_name); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - if (!complete_connection_by_type (connection, - setting_name, - nmc->system_connections, - nmc->ask, - argc, - argv, - &error)) { - g_string_assign (nmc->return_text, error->message); - nmc->return_value = error->code; - g_clear_error (&error); - goto error; - } - - nmc->should_wait = TRUE; - - info = g_malloc0 (sizeof (AddConnectionInfo)); - info->nmc = nmc; - info->con_name = g_strdup (nm_connection_get_id (connection)); - - /* Tell the settings service to add the new connection */ - add_new_connection (save_bool, - nmc->system_settings, - connection, - add_connection_cb, - info); - - if (connection) - g_object_unref (connection); - - return nmc->return_value; - -error: - if (connection) - g_object_unref (connection); - g_free (type_ask); - g_free (ifname_ask); - - nmc->should_wait = FALSE; - return nmc->return_value; -} - - -/*----------------------------------------------------------------------------*/ -/* Functions for readline TAB completion in editor */ - -static void -uuid_display_hook (char **array, int len, int max_len) -{ - NMConnection *con; - int i, max = 0; - char *tmp; - const char *id; - - for (i = 1; i <= len; i++) { - con = nmc_find_connection (nmc_tab_completion.nmc->system_connections, "uuid", array[i], NULL); - id = con ? nm_connection_get_id (con) : NULL; - if (id) { - tmp = g_strdup_printf ("%s (%s)", array[i], id); - g_free (array[i]); - array[i] = tmp; - if (max < strlen (id)) - max = strlen (id); - } - } - rl_display_match_list (array, len, max_len + max + 3); - rl_forced_update_display (); -} - -static char *pre_input_deftext; -static int -set_deftext (void) -{ - if (pre_input_deftext && rl_startup_hook) { - rl_insert_text (pre_input_deftext); - g_free (pre_input_deftext); - pre_input_deftext = NULL; - rl_startup_hook = NULL; - } - return 0; -} - -static char * -gen_nmcli_cmds_menu (const char *text, int state) -{ - const char *words[] = { "goto", "set", "remove", "describe", "print", "verify", - "save", "activate", "back", "help", "quit", "nmcli", - NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_nmcli_cmds_submenu (const char *text, int state) -{ - const char *words[] = { "set", "add", "change", "remove", "describe", - "print", "back", "help", "quit", - NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_nmcli (const char *text, int state) -{ - const char *words[] = { "status-line", "save-confirmation", "prompt-color", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_nmcli_prompt_color (const char *text, int state) -{ - const char *words[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_func_bool_values (const char *text, int state) -{ - const char *words[] = { "yes", "no", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_verify0 (const char *text, int state) -{ - const char *words[] = { "all", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_print0 (const char *text, int state) -{ - static char **words = NULL; - char *ret = NULL; - - if (!state) { - GHashTable *settings; - GHashTableIter iter; - const char *setting_name; - int i = 0; - - settings = nm_connection_to_hash (nmc_tab_completion.connection, NM_SETTING_HASH_FLAG_NO_SECRETS); - words = g_new (char *, g_hash_table_size (settings) + 2); - g_hash_table_iter_init (&iter, settings); - while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, NULL)) - words [i++] = g_strdup (setting_name); - words[i++] = g_strdup ("all"); - words[i] = NULL; - g_hash_table_unref (settings); - } - - if (words) { - ret = nmc_rl_gen_func_basic (text, state, (const char **) words); - if (ret == NULL) { - g_strfreev (words); - words = NULL; - } - } - return ret; -} - -static char * -gen_cmd_print2 (const char *text, int state) -{ - const char *words[] = { "setting", "connection", "all", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_cmd_save (const char *text, int state) -{ - const char *words[] = { "persistent", "temporary", NULL }; - return nmc_rl_gen_func_basic (text, state, words); -} - -static char * -gen_connection_types (const char *text, int state) -{ - static int list_idx, len; - const char *c_type, *a_type; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - while (nmc_valid_connection_types[list_idx].name) { - a_type = nmc_valid_connection_types[list_idx].alias; - c_type = nmc_valid_connection_types[list_idx].name; - list_idx++; - if (a_type && !strncmp (text, a_type, len)) - return g_strdup (a_type); - if (c_type && !strncmp (text, c_type, len)) - return g_strdup (c_type); - } - - return NULL; -} - -static char * -gen_setting_names (const char *text, int state) -{ - static int list_idx, len; - const char *s_name, *a_name; - const NameItem *valid_settings_arr; - - if (!state) { - list_idx = 0; - len = strlen (text); - } - - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - if (!valid_settings_arr) - return NULL; - while (valid_settings_arr[list_idx].name) { - a_name = valid_settings_arr[list_idx].alias; - s_name = valid_settings_arr[list_idx].name; - list_idx++; - if (len == 0 && a_name) - return g_strdup_printf ("%s (%s)", s_name, a_name); - if (a_name && !strncmp (text, a_name, len)) - return g_strdup (a_name); - if (s_name && !strncmp (text, s_name, len)) - return g_strdup (s_name); - } - return NULL; -} - -static char * -gen_property_names (const char *text, int state) -{ - NMSetting *setting = NULL; - char **valid_props = NULL; - char *ret = NULL; - const char *line = rl_line_buffer; - const char *setting_name; - char **strv = NULL; - const NameItem *valid_settings_arr; - const char *p1; - - /* Try to get the setting from 'line' - setting_name.property */ - p1 = strchr (line, '.'); - if (p1) { - while (p1 > line && !g_ascii_isspace (*p1)) - p1--; - - strv = g_strsplit (p1+1, ".", 2); - - valid_settings_arr = get_valid_settings_array (nmc_tab_completion.con_type); - setting_name = check_valid_name (strv[0], valid_settings_arr, NULL); - setting = nmc_setting_new_for_name (setting_name); - } else { - /* Else take the current setting, if any */ - setting = nmc_tab_completion.setting ? g_object_ref (nmc_tab_completion.setting) : NULL; - } - - if (setting) { - valid_props = nmc_setting_get_valid_properties (setting); - ret = nmc_rl_gen_func_basic (text, state, (const char **) valid_props); - } - - g_strfreev (strv); - g_strfreev (valid_props); - if (setting) - g_object_unref (setting); - return ret; -} - -static char * -gen_compat_devices (const char *text, int state) -{ - int i, j = 0; - const GPtrArray *devices; - const char **compatible_devices; - char *ret; - - devices = nm_client_get_devices (nmc_tab_completion.nmc->client); - if (!devices || devices->len < 1) - return NULL; - - compatible_devices = g_new (const char *, devices->len + 1); - for (i = 0; i < devices->len; i++) { - NMDevice *dev = g_ptr_array_index (devices, i); - const char *ifname = nm_device_get_iface (dev); - NMDevice *device = NULL; - const char *spec_object = NULL; - - if (find_device_for_connection (nmc_tab_completion.nmc, nmc_tab_completion.connection, - ifname, NULL, NULL, &device, &spec_object, NULL)) { - compatible_devices[j++] = ifname; - } - } - compatible_devices[j] = NULL; - - ret = nmc_rl_gen_func_basic (text, state, compatible_devices); - - g_free (compatible_devices); - return ret; -} - -static char * -gen_vpn_uuids (const char *text, int state) -{ - GSList *iter; - guint len; - int i = 0; - const char **uuids; - char *ret; - - len = g_slist_length (nmc_tab_completion.nmc->system_connections); - if (len < 1) - return NULL; - - uuids = g_new (const char *, len + 1); - for (iter = nmc_tab_completion.nmc->system_connections; iter; iter = g_slist_next (iter)) { - const char *type = nm_connection_get_connection_type (NM_CONNECTION (iter->data)); - - if (g_strcmp0 (type, NM_SETTING_VPN_SETTING_NAME) == 0) - uuids[i++] = nm_connection_get_uuid (NM_CONNECTION (iter->data)); - } - uuids[i] = NULL; - - ret = nmc_rl_gen_func_basic (text, state, uuids); - - g_free (uuids); - return ret; -} - -static rl_compentry_func_t * -get_gen_func_cmd_nmcli (const char *str) -{ - if (!str) - return NULL; - if (matches (str, "status-line") == 0) - return gen_func_bool_values; - if (matches (str, "save-confirmation") == 0) - return gen_func_bool_values; - if (matches (str, "prompt-color") == 0) - return gen_cmd_nmcli_prompt_color; - return NULL; -} - -/* - * Helper function parsing line for completion. - * IN: - * line : the whole line to be parsed - * end : the position of cursor in the line - * cmd : command to match - * OUT: - * cw_num : is set to the word number being completed (1, 2, 3, 4). - * prev_word : returns the previous word (so that we have some context). - * - * Returns TRUE when the first word of the 'line' matches 'cmd'. - * - * Examples: - * line="rem" cmd="remove" -> TRUE cw_num=1 - * line="set con" cmd="set" -> TRUE cw_num=2 - * line="go ipv4.method" cmd="goto" -> TRUE cw_num=2 - * line=" des eth.mtu " cmd="describe" -> TRUE cw_num=3 - * line=" bla ipv4.method" cmd="goto" -> FALSE - */ -static gboolean -should_complete_cmd (const char *line, int end, const char *cmd, - int *cw_num, char **prev_word) -{ - char *tmp; - const char *word1, *word2, *word3; - size_t n1, n2, n3, n4, n5, n6; - gboolean word1_done, word2_done, word3_done; - gboolean ret = FALSE; - - if (!line) - return FALSE; - - tmp = g_strdup (line); - - n1 = strspn (tmp, " \t"); - n2 = strcspn (tmp+n1, " \t\0") + n1; - n3 = strspn (tmp+n2, " \t") + n2; - n4 = strcspn (tmp+n3, " \t\0") + n3; - n5 = strspn (tmp+n4, " \t") + n4; - n6 = strcspn (tmp+n5, " \t\0") + n5; - - word1_done = end > n2; - word2_done = end > n4; - word3_done = end > n6; - tmp[n2] = tmp[n4] = tmp[n6] = '\0'; - - word1 = tmp[n1] ? tmp + n1 : NULL; - word2 = tmp[n3] ? tmp + n3 : NULL; - word3 = tmp[n5] ? tmp + n5 : NULL; - - if (!word1_done) { - if (cw_num) - *cw_num = 1; - if (prev_word) - *prev_word = NULL; - } else if (!word2_done) { - if (cw_num) - *cw_num = 2; - if (prev_word) - *prev_word = g_strdup (word1); - } else if (!word3_done) { - if (cw_num) - *cw_num = 3; - if (prev_word) - *prev_word = g_strdup (word2); - } else { - if (cw_num) - *cw_num = 4; - if (prev_word) - *prev_word = g_strdup (word3); - } - - if (word1 && matches (word1, cmd) == 0) - ret = TRUE; - - g_free (tmp); - return ret; -} - -static char * -extract_property_name (const char *prompt, const char *line) -{ - char *prop = NULL; - - /* If prompt is set take the property name from it, else extract it from line */ - if (!prompt) { - const char *p1; - size_t num; - p1 = strchr (line, '.'); - if (p1) { - p1++; - } else { - size_t n1, n2, n3; - n1 = strspn (line, " \t"); - n2 = strcspn (line+n1, " \t\0") + n1; - n3 = strspn (line+n2, " \t") + n2; - p1 = line + n3; - } - num = strcspn (p1, " \t\0"); - prop = g_strndup (p1, num); - } else { - const char *p1, *dot; - size_t num; - p1 = strchr (prompt, ' '); - /* prompt looks like this: "nmcli 802-1x>" or "nmcli 802-1x.pac-file>" */ - if (p1) { - dot = strchr (p1 + 1, '.'); - p1 = dot ? dot + 1 : p1; - num = strcspn (p1, ">"); - prop = g_strndup (p1, num); - } - } - - return prop; -} - -static gboolean -should_complete_files (const char *prompt, const char *line) -{ - char *prop; - gboolean found = FALSE; - const char *file_properties[] = { - /* '802-1x' properties */ - "ca-cert", - "ca-path", - "client-cert", - "pac-file", - "phase2-ca-cert", - "phase2-ca-path", - "phase2-client-cert", - "private-key", - "phase2-private-key", - /* 'team' and 'team-port' properties */ - "config", - NULL - }; - - prop = extract_property_name (prompt, line); - if (prop) { - found = !!nmc_string_is_valid (prop, file_properties, NULL); - g_free (prop); - } - return found; -} - -static gboolean -should_complete_vpn_uuids (const char *prompt, const char *line) -{ - char *prop; - gboolean found = FALSE; - const char *uuid_properties[] = { - /* 'connection' properties */ - "secondaries", - NULL - }; - - prop = extract_property_name (prompt, line); - if (prop) { - found = !!nmc_string_is_valid (prop, uuid_properties, NULL); - g_free (prop); - } - return found; -} - -/* from readline */ -extern int rl_complete_with_tilde_expansion; - -/* - * Attempt to complete on the contents of TEXT. START and END show the - * region of TEXT that contains the word to complete. We can use the - * entire line in case we want to do some simple parsing. Return the - * array of matches, or NULL if there aren't any. - */ -static char ** -nmcli_editor_tab_completion (const char *text, int start, int end) -{ - char **match_array = NULL; - const char *line = rl_line_buffer; - const char *prompt = rl_prompt; - rl_compentry_func_t *generator_func = NULL; - gboolean copy_char; - const char *p1; - char *p2, *prompt_tmp; - char *word = NULL; - size_t n1; - int num; - - /* Restore standard append character to space */ - rl_completion_append_character = ' '; - - /* Restore standard function for displaying matches */ - rl_completion_display_matches_hook = NULL; - - /* Disable default filename completion */ - rl_attempted_completion_over = 1; - - /* Enable tilde expansion when filenames are completed */ - rl_complete_with_tilde_expansion = 1; - - /* Filter out possible ANSI color escape sequences */ - p1 = prompt; - p2 = prompt_tmp = g_strdup (prompt); - copy_char = TRUE; - while (*p1) { - if (*p1 == '\33') - copy_char = FALSE; - if (copy_char) - *p2++ = *p1; - if (!copy_char && *p1 == 'm') - copy_char = TRUE; - p1++; - } - *p2 = '\0'; - - /* Find the first non-space character */ - n1 = strspn (line, " \t"); - - /* Choose the right generator function */ - if (strcmp (prompt_tmp, EDITOR_PROMPT_CON_TYPE) == 0) - generator_func = gen_connection_types; - else if (strcmp (prompt_tmp, EDITOR_PROMPT_SETTING) == 0) - generator_func = gen_setting_names; - else if (strcmp (prompt_tmp, EDITOR_PROMPT_PROPERTY) == 0) - generator_func = gen_property_names; - else if ( g_str_has_suffix (rl_prompt, prompt_yes_no (TRUE, NULL)) - || g_str_has_suffix (rl_prompt, prompt_yes_no (FALSE, NULL))) - generator_func = gen_func_bool_values_l10n; - else if (g_str_has_prefix (prompt_tmp, "nmcli")) { - if (!strchr (prompt_tmp, '.')) { - int level = g_str_has_prefix (prompt_tmp, "nmcli>") ? 0 : 1; - const char *dot = strchr (line, '.'); - - /* Main menu - level 0,1 */ - if (start == n1) - generator_func = gen_nmcli_cmds_menu; - else { - if (should_complete_cmd (line, end, "goto", &num, NULL) && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) - generator_func = gen_setting_names; - else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "set", &num, NULL)) { - if (num < 3) { - if (level == 0 && (!dot || dot >= line + end)) { - generator_func = gen_setting_names; - rl_completion_append_character = '.'; - } else - generator_func = gen_property_names; - } else if (num >= 3) { - if (num == 3 && should_complete_files (NULL, line)) - rl_attempted_completion_over = 0; - if (should_complete_vpn_uuids (NULL, line)) { - rl_completion_display_matches_hook = uuid_display_hook; - generator_func = gen_vpn_uuids; - } - } - } else if ( ( should_complete_cmd (line, end, "remove", &num, NULL) - || should_complete_cmd (line, end, "describe", &num, NULL)) - && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) { - generator_func = gen_setting_names; - rl_completion_append_character = '.'; - } else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "nmcli", &num, &word)) { - if (num < 3) - generator_func = gen_cmd_nmcli; - else if (num == 3) - generator_func = get_gen_func_cmd_nmcli (word); - } else if (should_complete_cmd (line, end, "print", &num, NULL) && num <= 2) { - if (level == 0 && (!dot || dot >= line + end)) - generator_func = gen_cmd_print0; - else - generator_func = gen_property_names; - } else if (should_complete_cmd (line, end, "verify", &num, NULL) && num <= 2) { - generator_func = gen_cmd_verify0; - } else if (should_complete_cmd (line, end, "activate", &num, NULL) && num <= 2) { - generator_func = gen_compat_devices; - } else if (should_complete_cmd (line, end, "save", &num, NULL) && num <= 2) { - generator_func = gen_cmd_save; - } else if (should_complete_cmd (line, end, "help", &num, NULL) && num <= 2) - generator_func = gen_nmcli_cmds_menu; - } - } else { - /* Submenu - level 2 */ - if (start == n1) - generator_func = gen_nmcli_cmds_submenu; - else { - if ( should_complete_cmd (line, end, "add", &num, NULL) - || should_complete_cmd (line, end, "set", &num, NULL)) { - if (num <= 2 && should_complete_files (prompt_tmp, line)) - rl_attempted_completion_over = 0; - else if (should_complete_vpn_uuids (prompt_tmp, line)) { - rl_completion_display_matches_hook = uuid_display_hook; - generator_func = gen_vpn_uuids; - } - } - if (should_complete_cmd (line, end, "print", &num, NULL) && num <= 2) - generator_func = gen_cmd_print2; - else if (should_complete_cmd (line, end, "help", &num, NULL) && num <= 2) - generator_func = gen_nmcli_cmds_submenu; - } - } - } - - if (generator_func) - match_array = rl_completion_matches (text, generator_func); - - g_free (prompt_tmp); - g_free (word); - return match_array; -} - -#define NMCLI_EDITOR_HISTORY ".nmcli-history" - -static void -load_history_cmds (const char *uuid) -{ - GKeyFile *kf; - char *filename; - char **keys; - char *line; - size_t i; - GError *err = NULL; - - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if (err->code == G_KEY_FILE_ERROR_PARSE) - printf ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - return; - } - keys = g_key_file_get_keys (kf, uuid, NULL, NULL); - for (i = 0; keys && keys[i]; i++) { - line = g_key_file_get_string (kf, uuid, keys[i], NULL); - if (line && *line) - add_history (line); - g_free (line); - } - g_strfreev (keys); - g_key_file_free (kf); - g_free (filename); -} - -static void -save_history_cmds (const char *uuid) -{ - HIST_ENTRY **hist = NULL; - GKeyFile *kf; - char *filename; - size_t i; - char *key; - char *data; - gsize len = 0; - GError *err = NULL; - - hist = history_list (); - if (hist) { - filename = g_build_filename (g_get_home_dir (), NMCLI_EDITOR_HISTORY, NULL); - kf = g_key_file_new (); - if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { - if ( err->code != G_FILE_ERROR_NOENT - && err->code != G_KEY_FILE_ERROR_NOT_FOUND) { - printf ("Warning: %s parse error: %s\n", filename, err->message); - g_key_file_free (kf); - g_free (filename); - g_clear_error (&err); - return; - } - g_clear_error (&err); - } - - /* Remove previous history group and save new history entries */ - g_key_file_remove_group (kf, uuid, NULL); - for (i = 0; hist[i]; i++) - { - key = g_strdup_printf ("%zd", i); - g_key_file_set_string (kf, uuid, key, hist[i]->line); - g_free (key); - } - - /* Write history to file */ - data = g_key_file_to_data (kf, &len, NULL); - if (data) { - g_file_set_contents (filename, data, len, NULL); - g_free (data); - } - g_key_file_free (kf); - g_free (filename); - } -} - -/*----------------------------------------------------------------------------*/ - -static void -editor_show_connection (NMConnection *connection, NmCli *nmc) -{ - nmc->print_output = NMC_PRINT_PRETTY; - nmc->multiline_output = TRUE; - nmc->escape_values = 0; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - nmc_connection_profile_details (connection, nmc); -} - -static void -editor_show_setting (NMSetting *setting, NmCli *nmc) -{ - printf (_("['%s' setting values]\n"), - nm_setting_get_name (setting)); - - nmc->print_output = NMC_PRINT_NORMAL; - nmc->multiline_output = TRUE; - nmc->escape_values = 0; - - /* Remove any previous data */ - nmc_empty_output_fields (nmc); - - setting_details (setting, nmc, NULL); -} - -typedef enum { - NMC_EDITOR_MAIN_CMD_UNKNOWN = 0, - NMC_EDITOR_MAIN_CMD_GOTO, - NMC_EDITOR_MAIN_CMD_REMOVE, - NMC_EDITOR_MAIN_CMD_SET, - NMC_EDITOR_MAIN_CMD_DESCRIBE, - NMC_EDITOR_MAIN_CMD_PRINT, - NMC_EDITOR_MAIN_CMD_VERIFY, - NMC_EDITOR_MAIN_CMD_SAVE, - NMC_EDITOR_MAIN_CMD_ACTIVATE, - NMC_EDITOR_MAIN_CMD_BACK, - NMC_EDITOR_MAIN_CMD_HELP, - NMC_EDITOR_MAIN_CMD_NMCLI, - NMC_EDITOR_MAIN_CMD_QUIT, -} NmcEditorMainCmd; - -static NmcEditorMainCmd -parse_editor_main_cmd (const char *cmd, char **cmd_arg) -{ - NmcEditorMainCmd editor_cmd = NMC_EDITOR_MAIN_CMD_UNKNOWN; - char **vec; - - vec = nmc_strsplit_set (cmd, " \t", 2); - if (g_strv_length (vec) < 1) { - if (cmd_arg) - *cmd_arg = NULL; - return NMC_EDITOR_MAIN_CMD_UNKNOWN; - } - - if (matches (vec[0], "goto") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_GOTO; - else if (matches (vec[0], "remove") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_REMOVE; - else if (matches (vec[0], "set") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_SET; - else if (matches (vec[0], "describe") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_DESCRIBE; - else if (matches (vec[0], "print") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_PRINT; - else if (matches (vec[0], "verify") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_VERIFY; - else if (matches (vec[0], "save") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_SAVE; - else if (matches (vec[0], "activate") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_ACTIVATE; - else if (matches (vec[0], "back") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_BACK; - else if (matches (vec[0], "help") == 0 || strcmp (vec[0], "?") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_HELP; - else if (matches (vec[0], "quit") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_QUIT; - else if (matches (vec[0], "nmcli") == 0) - editor_cmd = NMC_EDITOR_MAIN_CMD_NMCLI; - - /* set pointer to command argument */ - if (cmd_arg) - *cmd_arg = vec[1] ? g_strstrip (g_strdup (vec[1])) : NULL; - - g_strfreev (vec); - return editor_cmd; -} - -static void -editor_main_usage (void) -{ - printf ("------------------------------------------------------------------------------\n"); - /* TRANSLATORS: do not translate command names and keywords before :: - * However, you should translate terms enclosed in <>. - */ - printf (_("---[ Main menu ]---\n" - "goto [ | ] :: go to a setting or property\n" - "remove [.] | :: remove setting or reset property value\n" - "set [. ] :: set property value\n" - "describe [.] :: describe property\n" - "print [all | [.]] :: print the connection\n" - "verify [all] :: verify the connection\n" - "save [persistent|temporary] :: save the connection\n" - "activate [] [/|] :: activate the connection\n" - "back :: go one level up (back)\n" - "help/? [] :: print this help\n" - "nmcli :: nmcli configuration\n" - "quit :: exit nmcli\n")); - printf ("------------------------------------------------------------------------------\n"); -} - -static void -editor_main_help (const char *command) -{ - if (!command) - editor_main_usage (); - else { - /* detailed command descriptions */ - NmcEditorMainCmd cmd = parse_editor_main_cmd (command, NULL); - - switch (cmd) { - case NMC_EDITOR_MAIN_CMD_GOTO: - printf (_("goto [.] | :: enter setting/property for editing\n\n" - "This command enters into a setting or property for editing it.\n\n" - "Examples: nmcli> goto connection\n" - " nmcli connection> goto secondaries\n" - " nmcli> goto ipv4.addresses\n")); - break; - case NMC_EDITOR_MAIN_CMD_REMOVE: - printf (_("remove [.] :: remove setting or reset property value\n\n" - "This command removes an entire setting from the connection, or if a property\n" - "is given, resets that property to the default value.\n\n" - "Examples: nmcli> remove wifi-sec\n" - " nmcli> remove eth.mtu\n")); - break; - case NMC_EDITOR_MAIN_CMD_SET: - printf (_("set [. ] :: set property value\n\n" - "This command sets property value.\n\n" - "Example: nmcli> set con.id My connection\n")); - break; - case NMC_EDITOR_MAIN_CMD_DESCRIBE: - printf (_("describe [.] :: describe property\n\n" - "Shows property description. You can consult nm-settings(5) " - "manual page to see all NM settings and properties.\n")); - break; - case NMC_EDITOR_MAIN_CMD_PRINT: - printf (_("print [all] :: print setting or connection values\n\n" - "Shows current property or the whole connection.\n\n" - "Example: nmcli ipv4> print all\n")); - break; - case NMC_EDITOR_MAIN_CMD_VERIFY: - printf (_("verify [all] :: verify setting or connection validity\n\n" - "Verifies whether the setting or connection is valid and can " - "be saved later. It indicates invalid values on error.\n\n" - "Examples: nmcli> verify\n" - " nmcli bond> verify\n")); - break; - case NMC_EDITOR_MAIN_CMD_SAVE: - printf (_("save [persistent|temporary] :: save the connection\n\n" - "Sends the connection profile to NetworkManager that either will save it\n" - "persistently, or will only keep it in memory. 'save' without an argument\n" - "means 'save persistent'.\n" - "Note that once you save the profile persistently those settings are saved\n" - "across reboot or restart. Subsequent changes can also be temporary or\n" - "persistent, but any temporary changes will not persist across reboot or\n" - "restart. If you want to fully remove the persistent connection, the connection\n" - "profile must be deleted.\n")); - break; - case NMC_EDITOR_MAIN_CMD_ACTIVATE: - printf (_("activate [] [/|] :: activate the connection\n\n" - "Activates the connection.\n\n" - "Available options:\n" - " - device the connection will be activated on\n" - "/| - AP (Wi-Fi) or NSP (WiMAX) (prepend with / when is not specified)\n")); - break; - case NMC_EDITOR_MAIN_CMD_BACK: - printf (_("back :: go to upper menu level\n\n")); - break; - case NMC_EDITOR_MAIN_CMD_HELP: - printf (_("help/? [] :: help for the nmcli commands\n\n")); - break; - case NMC_EDITOR_MAIN_CMD_NMCLI: - printf (_("nmcli [ ] :: nmcli configuration\n\n" - "Configures nmcli. The following options are available:\n" - "status-line yes | no [default: no]\n" - "save-confirmation yes | no [default: yes]\n" - "prompt-color <0-8> [default: 0]\n" - " 0 = normal\n" - " 1 = \33[30mblack\33[0m\n" - " 2 = \33[31mred\33[0m\n" - " 3 = \33[32mgreen\33[0m\n" - " 4 = \33[33myellow\33[0m\n" - " 5 = \33[34mblue\33[0m\n" - " 6 = \33[35mmagenta\33[0m\n" - " 7 = \33[36mcyan\33[0m\n" - " 8 = \33[37mwhite\33[0m\n" - "\n" - "Examples: nmcli> nmcli status-line yes\n" - " nmcli> nmcli save-confirmation no\n" - " nmcli> nmcli prompt-color 3\n")); - break; - case NMC_EDITOR_MAIN_CMD_QUIT: - printf (_("quit :: exit nmcli\n\n" - "This command exits nmcli. When the connection being edited " - "is not saved, the user is asked to confirm the action.\n")); - break; - default: - printf (_("Unknown command: '%s'\n"), command); - break; - } - } -} - -typedef enum { - NMC_EDITOR_SUB_CMD_UNKNOWN = 0, - NMC_EDITOR_SUB_CMD_SET, - NMC_EDITOR_SUB_CMD_ADD, - NMC_EDITOR_SUB_CMD_CHANGE, - NMC_EDITOR_SUB_CMD_REMOVE, - NMC_EDITOR_SUB_CMD_DESCRIBE, - NMC_EDITOR_SUB_CMD_PRINT, - NMC_EDITOR_SUB_CMD_BACK, - NMC_EDITOR_SUB_CMD_HELP, - NMC_EDITOR_SUB_CMD_QUIT -} NmcEditorSubCmd; - -static NmcEditorSubCmd -parse_editor_sub_cmd (const char *cmd, char **cmd_arg) -{ - NmcEditorSubCmd editor_cmd = NMC_EDITOR_SUB_CMD_UNKNOWN; - char **vec; - - vec = nmc_strsplit_set (cmd, " \t", 2); - if (g_strv_length (vec) < 1) { - if (cmd_arg) - *cmd_arg = NULL; - return NMC_EDITOR_SUB_CMD_UNKNOWN; - } - - if (matches (vec[0], "set") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_SET; - else if (matches (vec[0], "add") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_ADD; - else if (matches (vec[0], "change") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_CHANGE; - else if (matches (vec[0], "remove") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_REMOVE; - else if (matches (vec[0], "describe") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_DESCRIBE; - else if (matches (vec[0], "print") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_PRINT; - else if (matches (vec[0], "back") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_BACK; - else if (matches (vec[0], "help") == 0 || strcmp (vec[0], "?") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_HELP; - else if (matches (vec[0], "quit") == 0) - editor_cmd = NMC_EDITOR_SUB_CMD_QUIT; - - /* set pointer to command argument */ - if (cmd_arg) - *cmd_arg = g_strdup (vec[1]); - - g_strfreev (vec); - return editor_cmd; -} - -static void -editor_sub_help (void) -{ - printf ("------------------------------------------------------------------------------\n"); - /* TRANSLATORS: do not translate command names and keywords before :: - * However, you should translate terms enclosed in <>. - */ - printf (_("---[ Property menu ]---\n" - "set [] :: set new value\n" - "add [] :: add new option to the property\n" - "change :: change current value\n" - "remove [ | + + + + + Deletes a software device from NetworkManager and removes the interface from the system. + The method returns an error when called for a hardware device. + + + diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml index 6a8750b7..98076534 100644 --- a/introspection/nm-ip4-config.xml +++ b/introspection/nm-ip4-config.xml @@ -2,20 +2,42 @@ + + + Array of arrays of IPv4 address/prefix/gateway. All 3 + elements of each array are in network byte order. Essentially: + [(addr, prefix, gateway), (addr, prefix, gateway), ...] + + Deprecated: use AddressData and Gateway + + + + + Array of IP address data objects. All addresses will include + "address" (an IP address string), and "prefix" (a uint). Some + addresses may include additional attributes. + + The gateway in use. - - Array of tuples of IPv4 address/prefix/gateway. All 3 - elements of each tuple are in network byte order. Essentially: - [(addr, prefix, gateway), (addr, prefix, gateway), ...] + + + Arrays of IPv4 route/prefix/next-hop/metric. All 4 elements of + each tuple are in network byte order. 'route' and 'next hop' + are IPv4 addresses, while prefix and metric are simple + unsigned integers. Essentially: [(route, prefix, next-hop, + metric), (route, prefix, next-hop, metric), ...] + + Deprecated: use RouteData - - Tuples of IPv4 route/prefix/next-hop/metric. All 4 elements - of each tuple are in network byte order. 'route' and 'next hop' are IPv4 - addresses, while prefix and metric are simple unsigned integers. Essentially: - [(route, prefix, next-hop, metric), (route, prefix, next-hop, metric), ...] + + + Array of IP route data objects. All routes will include "dest" + (an IP address string) and "prefix" (a uint). Some routes may + include "next-hop" (an IP address string), "metric" (a uint), + and additional attributes. diff --git a/introspection/nm-ip6-config.xml b/introspection/nm-ip6-config.xml index 55c519e7..985dd2e3 100644 --- a/introspection/nm-ip6-config.xml +++ b/introspection/nm-ip6-config.xml @@ -2,14 +2,37 @@ + + + Array of tuples of IPv6 address/prefix/gateway. + + Deprecated: use AddressData and Gateway. + + + + + Array of IP address data objects. All addresses will include + "address" (an IP address string), and "prefix" (a uint). Some + addresses may include additional attributes. + + The gateway in use. - - Tuples of IPv6 address/prefix/gateway. - - Tuples of IPv6 route/prefix/next-hop/metric. + + Tuples of IPv6 route/prefix/next-hop/metric. + + Deprecated: use RouteData + + + + + Array of IP route data objects. All routes will include "dest" + (an IP address string) and "prefix" (a uint). Some routes may + include "next-hop" (an IP address string), "metric" (a uint), + and additional attributes. + The nameservers in use. diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 6af2be30..a9bb6dcf 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -2,6 +2,8 @@ + + Get the list of network devices. @@ -71,16 +73,6 @@ The path of the active connection object representing this active connection. - - - - - Another connection is already activating or the same connection is already active. FIXME: check if the error name is correct. FIXME: split into 2 errors? - - - The connection is invalid for this device. - - @@ -123,13 +115,6 @@ The path of the active connection object representing this active connection. - - - - - The connection is invalid for this device. - - @@ -215,7 +200,7 @@ - One of [ERR, WARN, INFO, DEBUG]. + One of [ERR, WARN, INFO, DEBUG, TRACE]. @@ -244,7 +229,7 @@ - One of [ERR, WARN, INFO, DEBUG]. + One of [ERR, WARN, INFO, DEBUG, TRACE]. @@ -342,6 +327,14 @@ + + + The connection type of the "primary" active connection being + used to access the network. This is the same as the Type + property on the object indicated by PrimaryConnection. + + + The object path of an active connection that is currently diff --git a/introspection/nm-ppp-manager.xml b/introspection/nm-ppp-manager.xml index 9e2dfdb1..5ea1e8b1 100644 --- a/introspection/nm-ppp-manager.xml +++ b/introspection/nm-ppp-manager.xml @@ -2,6 +2,8 @@ + + @@ -14,6 +16,11 @@ + + + + + diff --git a/introspection/nm-settings-connection.xml b/introspection/nm-settings-connection.xml index b5bd2cd0..b02762d6 100644 --- a/introspection/nm-settings-connection.xml +++ b/introspection/nm-settings-connection.xml @@ -93,6 +93,14 @@ + + + Clear the secrets belonging to this network connection profile. + + + + + Saves a "dirty" connection (that had previously been diff --git a/introspection/nm-vpn-connection.xml b/introspection/nm-vpn-connection.xml index 65b91785..03bbbe98 100644 --- a/introspection/nm-vpn-connection.xml +++ b/introspection/nm-vpn-connection.xml @@ -2,6 +2,8 @@ + + Represents an active connection to a Virtual Private Network. diff --git a/introspection/nm-vpn-plugin.xml b/introspection/nm-vpn-plugin.xml index 07397c2b..adb6a085 100644 --- a/introspection/nm-vpn-plugin.xml +++ b/introspection/nm-vpn-plugin.xml @@ -2,6 +2,8 @@ + + This interface is provided by plugins providing VPN services to the NetworkManager daemon. @@ -137,7 +139,7 @@ - + The state of the plugin. @@ -147,7 +149,7 @@ Emitted when the plugin state changes. - + The new state of the plugin. @@ -251,6 +253,44 @@ + + + + The state of the VPN plugin is unknown. + + + + + The VPN plugin is initialized. + + + + + (Not used.) + + + + + The plugin is attempting to connect to a VPN server. + + + + + The plugin has connected to a VPN server. + + + + + The plugin is disconnecting from the VPN server. + + + + + The plugin has disconnected from the VPN server. + + + + diff --git a/libgsystem/COPYING b/libgsystem/COPYING deleted file mode 100644 index 5bc8fb2c..00000000 --- a/libgsystem/COPYING +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library 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 - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/libgsystem/Makefile-libgsystem.am b/libgsystem/Makefile-libgsystem.am deleted file mode 100644 index 092522c7..00000000 --- a/libgsystem/Makefile-libgsystem.am +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2012 Colin Walters -# -# 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -EXTRA_DIST += $(libgsystem_srcpath)/README $(libgsystem_srcpath)/COPYING - -libgsystem_la_SOURCES = \ - $(libgsystem_srcpath)/gsystem-local-alloc.h \ - $(libgsystem_srcpath)/gsystem-local-alloc.c \ - $(libgsystem_srcpath)/gsystem-console.h \ - $(libgsystem_srcpath)/gsystem-console.c \ - $(libgsystem_srcpath)/gsystem-file-utils.h \ - $(libgsystem_srcpath)/gsystem-file-utils.c \ - $(libgsystem_srcpath)/gsystem-glib-compat.h \ - $(libgsystem_srcpath)/gsystem-shutil.h \ - $(libgsystem_srcpath)/gsystem-shutil.c \ - $(libgsystem_srcpath)/gsystem-log.h \ - $(libgsystem_srcpath)/gsystem-log.c \ - $(libgsystem_srcpath)/gsystem-subprocess-context.h \ - $(libgsystem_srcpath)/gsystem-subprocess-context-private.h \ - $(libgsystem_srcpath)/gsystem-subprocess-context.c \ - $(libgsystem_srcpath)/gsystem-subprocess.h \ - $(libgsystem_srcpath)/gsystem-subprocess.c \ - $(libgsystem_srcpath)/libgsystem.h \ - $(NULL) - -libgsystem_la_CFLAGS = $(AM_CFLAGS) $(libgsystem_cflags) -libgsystem_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^gs_" -no-undefined -export-dynamic -libgsystem_la_LIBADD = $(libgsystem_libs) diff --git a/libgsystem/README b/libgsystem/README deleted file mode 100644 index 13fa05f2..00000000 --- a/libgsystem/README +++ /dev/null @@ -1,10 +0,0 @@ -libgsystem is intended to be used as a git external for components -that depend on GLib, but accept a hard dependency on things which are -difficult to do in GLib itself. For example, the local-alloc API -depends on GCC/clang. - -It will also be a useful place to evolve new APIs (e.g. logging) -before their eventual inclusion in GLib (if ever). - -There's no bugzilla component currently, please mail -patches to: walters@verbum.org diff --git a/libgsystem/gsystem-console.c b/libgsystem/gsystem-console.c deleted file mode 100644 index 35477eba..00000000 --- a/libgsystem/gsystem-console.c +++ /dev/null @@ -1,443 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2013 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#define _GSYSTEM_NO_LOCAL_ALLOC -#include "libgsystem.h" - -/** - * SECTION:gsconsole - * @title: GSConsole - * @short_description: Interact with standard input/output as well as terminal - * - * First, this class offers API to access the standard input and - * output/error, streams as #GInputStream and #GOutputStream - * respectively. - * - * In the case where the process is connected to a controlling - * terminal, the gs_console_get() API is available, which exposes a - * number of additional features such as no-echo password reading. - * - * Since: 2.36 - */ - -#include "config.h" - -#include "gsystem-console.h" - -#include -#ifdef G_OS_UNIX -#include -#include -#include -#include -#include -#include -#endif -#include - -typedef GObjectClass GSConsoleClass; - -struct _GSConsole -{ - GObject parent; - - gboolean in_status_line; - gssize last_line_written; -}; - -G_DEFINE_TYPE (GSConsole, gs_console, G_TYPE_OBJECT); - -static void -gs_console_init (GSConsole *self) -{ - self->last_line_written = -1; -} - -static void -gs_console_class_init (GSConsoleClass *class) -{ -} - -/** - * gs_console_get: - * - * If the current process has an interactive console, return the - * singleton #GSConsole instance. On Unix, this is equivalent to - * isatty(). For all other cases, such as pipes, sockets, /dev/null, - * this function will return %NULL. - * - * Returns: (transfer none): The console instance, or %NULL if not interactive - * - * Since: 2.36 - */ -GSConsole * -gs_console_get (void) -{ - static gsize checked = 0; - static GSConsole *instance = NULL; - - if (g_once_init_enter (&checked)) - { -#ifdef G_OS_UNIX - if (isatty (0) && isatty (1)) - instance = g_object_new (GS_TYPE_CONSOLE, NULL); -#endif - g_once_init_leave (&checked, 1); - } - - return (GSConsole*) instance; -} - -/** - * gs_console_get_stdin: - * - * Returns: (transfer none): The singleton stream connected to standard input - */ -GInputStream * -gs_console_get_stdin (void) -{ -#ifdef G_OS_UNIX - static gsize instance = 0; - - if (g_once_init_enter (&instance)) - g_once_init_leave (&instance, (gsize) g_unix_input_stream_new (0, FALSE)); - - return (GInputStream*) instance; -#else - g_error ("not implemented"); -#endif -} - -/** - * gs_console_get_stdout: - * - * Returns: (transfer none): The singleton stream connected to standard output - */ -GOutputStream * -gs_console_get_stdout (void) -{ -#ifdef G_OS_UNIX - static gsize instance = 0; - - if (g_once_init_enter (&instance)) - g_once_init_leave (&instance, (gsize) g_unix_output_stream_new (1, FALSE)); - - return (GOutputStream*) instance; -#else - g_error ("not implemented"); -#endif -} - -/** - * gs_console_get_stderr: - * - * Returns: (transfer none): The singleton stream connected to standard error - */ -GOutputStream * -gs_console_get_stderr (void) -{ -#ifdef G_OS_UNIX - static gsize instance = 0; - - if (g_once_init_enter (&instance)) - g_once_init_leave (&instance, (gsize) g_unix_output_stream_new (2, FALSE)); - - return (GOutputStream*) instance; -#else - g_error ("not implemented"); -#endif -} - -#ifdef G_OS_UNIX -static inline void -_set_error_from_errno (GError **error) -{ - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); -} -#endif - -/** - * gs_console_read_password: - * @console: the #GSConsole - * @prompt: A string to output before reading the password - * @error: a #GError - * - * Write @prompt to standard output, then switch output echo off, read - * a result string, then switch output echo back on. - * - * Returns: A string, or %NULL on error - */ -char * -gs_console_read_password (GSConsole *console, - const char *prompt, - GCancellable *cancellable, - GError **error) -{ -#ifdef G_OS_UNIX - gboolean ret = FALSE; - /* This code is modified from that found in - * polkit/src/polkittextagentlistener.c, reused under the LGPL v2.1 - */ - int res; - struct termios ts, ots; - GInputStream *in; - GOutputStream *out; - GString *str = NULL; - gsize bytes_written; - gboolean reset_terminal = FALSE; - - in = gs_console_get_stdin (); - out = gs_console_get_stdout (); - - if (!g_output_stream_write_all (out, prompt, strlen (prompt), &bytes_written, - cancellable, error)) - goto out; - if (!g_output_stream_flush (out, cancellable, error)) - goto out; - - /* TODO: We really ought to block SIGINT and STGSTP (and probably - * other signals too) so we can restore the terminal (since we - * turn off echoing). See e.g. Advanced Programming in the - * UNIX Environment 2nd edition (Steves and Rago) section - * 18.10, pg 660 where this is suggested. See also various - * getpass(3) implementations - * - * However, since we are a library routine the user could have - * multiple threads - in fact, typical usage of - * PolkitAgentTextListener is to run it in a thread. And - * unfortunately threads and POSIX signals is a royal PITA. - * - * Maybe we could fork(2) and ask for the password in the - * child and send it back to the parent over a pipe? (we are - * guaranteed that there is only one thread in the child - * process). - * - * (Side benefit of doing this in a child process is that we - * could avoid blocking the thread where the - * PolkitAgentTextListener object is being serviced from. But - * since this class is normally used in a dedicated thread - * it doesn't really matter *anyway*.) - * - * Anyway, On modern Linux not doing this doesn't seem to be a - * problem - looks like modern shells restore echoing anyway - * on the first input. So maybe it's not even worth solving - * the problem. - */ - - do - res = tcgetattr (1, &ts); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - if (res == -1) - { - _set_error_from_errno (error); - goto out; - } - ots = ts; - ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); - do - res = tcsetattr (1, TCSAFLUSH, &ts); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - if (res == -1) - { - _set_error_from_errno (error); - goto out; - } - - /* After this point, we'll need to clean up the terminal in case of - * error. - */ - reset_terminal = TRUE; - - str = g_string_new (NULL); - while (TRUE) - { - gssize bytes_read; - guint8 buf[1]; - - /* FIXME - we should probably be converting from the system - * codeset, in case it's not UTF-8. - */ - bytes_read = g_input_stream_read (in, buf, sizeof (buf), - cancellable, error); - if (bytes_read < 0) - goto out; - else if (bytes_read == 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED, - "End of stream while reading password"); - goto out; - } - else if (buf[0] == '\n') - { - break; - } - else - { - g_string_append_c (str, buf[0]); - } - } - - ret = TRUE; - out: - if (reset_terminal) - { - do - res = tcsetattr (1, TCSAFLUSH, &ots); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - if (res == -1) - { - _set_error_from_errno (error); - g_string_free (str, TRUE); - return NULL; - } - } - - if (!ret) - { - g_string_free (str, TRUE); - return NULL; - } - else - { - return g_string_free (str, FALSE); - } -#else - g_error ("not implemented"); -#endif -} - -/** - * gs_console_begin_status_line: - * @console: the #GSConsole - * @line: String to output - * - * The primary use case for this function is to output periodic - * "status" or "progress" information. The first time this function - * is called, @line will be output normally. Subsequent invocations - * will overwrite the previous. - * - * You must invoke gs_console_end_status_line() to return the console - * to normal mode. In particular, concurrent use of this function and - * the stream returned by gs_console_get_stdout() results in undefined - * behavior. - */ -gboolean -gs_console_begin_status_line (GSConsole *console, - const char *line, - GCancellable *cancellable, - GError **error) -{ -#ifdef G_OS_UNIX - gboolean ret = FALSE; - gsize linelen; - GOutputStream *out; - gsize bytes_written; - - out = gs_console_get_stdout (); - - if (!console->in_status_line) - { - guint8 buf[3] = { (guint8)'\n', 0x1B, 0x37 }; - if (!g_output_stream_write_all (out, buf, sizeof (buf), &bytes_written, - cancellable, error)) - goto out; - console->in_status_line = TRUE; - console->last_line_written = -1; - } - - { - guint8 buf[2] = { 0x1B, 0x38 }; - if (!g_output_stream_write_all (out, buf, sizeof (buf), &bytes_written, - cancellable, error)) - goto out; - } - - linelen = strlen (line); - if (!g_output_stream_write_all (out, line, linelen, &bytes_written, - cancellable, error)) - goto out; - - /* Now we need to pad with spaces enough to overwrite our last line - */ - if (console->last_line_written >= 0 - && linelen < (gsize) console->last_line_written) - { - gsize towrite = console->last_line_written - linelen; - const char c = ' '; - while (towrite > 0) - { - if (!g_output_stream_write_all (out, &c, 1, &bytes_written, - cancellable, error)) - goto out; - towrite--; - } - } - - console->last_line_written = linelen; - - ret = TRUE; - out: - return ret; -#else - g_error ("not implemented"); -#endif -} - -/** - * gs_console_end_status_line: - * @console: the #GSConsole - * - * Complete a series of invocations of gs_console_begin_status_line(), - * returning the stream to normal mode. The last printed status line - * remains on the console; if this is not desired, print an empty - * string to clear it before invoking this function. - */ -gboolean -gs_console_end_status_line (GSConsole *console, - GCancellable *cancellable, - GError **error) -{ -#ifdef G_OS_UNIX - gboolean ret = FALSE; - GOutputStream *out; - gsize bytes_written; - char c = '\n'; - - g_return_val_if_fail (console->in_status_line, FALSE); - - out = gs_console_get_stdout (); - - if (!g_output_stream_write_all (out, &c, 1, &bytes_written, - cancellable, error)) - goto out; - - console->in_status_line = FALSE; - - ret = TRUE; - out: - return ret; -#else - g_error ("not implemented"); -#endif -} diff --git a/libgsystem/gsystem-console.h b/libgsystem/gsystem-console.h deleted file mode 100644 index a22b2d45..00000000 --- a/libgsystem/gsystem-console.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2013 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_CONSOLE_H__ -#define __GSYSTEM_CONSOLE_H__ - -#include - -G_BEGIN_DECLS - -#define GS_TYPE_CONSOLE (gs_console_get_type ()) -#define GS_CONSOLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_CONSOLE, GSConsole)) -#define GS_IS_CONSOLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_CONSOLE)) - -typedef struct _GSConsole GSConsole; - -GType gs_console_get_type (void) G_GNUC_CONST; - -GInputStream * gs_console_get_stdin (void); -GOutputStream * gs_console_get_stdout (void); -GOutputStream * gs_console_get_stderr (void); - -GSConsole * gs_console_get (void); - -char * gs_console_read_password (GSConsole *console, - const char *prompt, - GCancellable *cancellable, - GError **error); - -gboolean gs_console_begin_status_line (GSConsole *console, - const char *line, - GCancellable *cancellable, - GError **error); - -gboolean gs_console_end_status_line (GSConsole *console, - GCancellable *cancellable, - GError **error); - - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-file-utils.c b/libgsystem/gsystem-file-utils.c deleted file mode 100644 index 02606035..00000000 --- a/libgsystem/gsystem-file-utils.c +++ /dev/null @@ -1,1644 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 William Jon McCann - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include - -#define _GSYSTEM_NO_LOCAL_ALLOC -#include "libgsystem.h" -#include "gsystem-glib-compat.h" -#include -#include -#include -#include -#include -#include -#include -#ifdef GSYSTEM_CONFIG_XATTRS -#include -#endif - -static int -close_nointr (int fd) -{ - int res; - /* Note this is NOT actually a retry loop. - * See: https://bugzilla.gnome.org/show_bug.cgi?id=682819 - */ - res = close (fd); - /* Just ignore EINTR...on Linux, retrying is wrong. */ - if (res == EINTR) - res = 0; - return res; -} - -static void -close_nointr_noerror (int fd) -{ - (void) close_nointr (fd); -} - -static int -open_nointr (const char *path, int flags, mode_t mode) -{ - int res; - do - res = open (path, flags, mode); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - return res; -} - -static inline void -_set_error_from_errno (GError **error) -{ - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); -} - -/** - * gs_file_openat_noatime: - * @dfd: File descriptor for directory - * @name: Pathname, relative to @dfd - * @ret_fd: (out): Returned file descriptor - * @cancellable: Cancellable - * @error: Error - * - * Wrapper for openat() using %O_RDONLY with %O_NOATIME if available. - */ -gboolean -gs_file_openat_noatime (int dfd, - const char *name, - int *ret_fd, - GCancellable *cancellable, - GError **error) -{ - int fd; - -#ifdef O_NOATIME - do - fd = openat (dfd, name, O_RDONLY | O_NOATIME, 0); - while (G_UNLIKELY (fd == -1 && errno == EINTR)); - /* Only the owner or superuser may use O_NOATIME; so we may get - * EPERM. EINVAL may happen if the kernel is really old... - */ - if (fd == -1 && (errno == EPERM || errno == EINVAL)) -#endif - do - fd = openat (dfd, name, O_RDONLY, 0); - while (G_UNLIKELY (fd == -1 && errno == EINTR)); - - if (fd == -1) - { - _set_error_from_errno (error); - return FALSE; - } - else - { - *ret_fd = fd; - return TRUE; - } -} - -/** - * gs_file_read_noatime: - * @file: a #GFile - * @cancellable: a #GCancellable - * @error: a #GError - * - * Like g_file_read(), but try to avoid updating the file's - * access time. This should be used by background scanning - * components such as search indexers, antivirus programs, etc. - * - * Returns: (transfer full): A new input stream, or %NULL on error - */ -GInputStream * -gs_file_read_noatime (GFile *file, - GCancellable *cancellable, - GError **error) -{ - const char *path = NULL; - int fd; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return NULL; - - path = gs_file_get_path_cached (file); - if (path == NULL) - { - char *uri; - uri = g_file_get_uri (file); - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, - "%s has no associated path", uri); - g_free (uri); - return NULL; - } - - if (!gs_file_openat_noatime (AT_FDCWD, path, &fd, cancellable, error)) - return NULL; - - return g_unix_input_stream_new (fd, TRUE); -} - -/** - * gs_stream_fstat: - * @stream: A stream containing a Unix file descriptor - * @stbuf: Memory location to write stat buffer - * @cancellable: - * @error: - * - * Some streams created via libgsystem are #GUnixInputStream; these do - * not support e.g. g_file_input_stream_query_info(). This function - * allows dropping to the raw unix fstat() call for these types of - * streams, while still conveniently wrapped with the normal GLib - * handling of @cancellable and @error. - */ -gboolean -gs_stream_fstat (GFileDescriptorBased *stream, - struct stat *stbuf, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int fd; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - goto out; - - fd = g_file_descriptor_based_get_fd (stream); - - if (fstat (fd, stbuf) == -1) - { - _set_error_from_errno (error); - goto out; - } - - ret = TRUE; - out: - return ret; -} - -/** - * gs_file_map_noatime: (skip) - * @file: a #GFile - * @cancellable: a #GCancellable - * @error: a #GError - * - * Like g_mapped_file_new(), but try to avoid updating the file's - * access time. This should be used by background scanning - * components such as search indexers, antivirus programs, etc. - * - * Returns: (transfer full): A new mapped file, or %NULL on error - */ -GMappedFile * -gs_file_map_noatime (GFile *file, - GCancellable *cancellable, - GError **error) -{ - const char *path; - int fd; - GMappedFile *ret; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return NULL; - - path = gs_file_get_path_cached (file); - if (path == NULL) - return NULL; - - if (!gs_file_openat_noatime (AT_FDCWD, path, &fd, cancellable, error)) - return NULL; - - ret = g_mapped_file_new_from_fd (fd, FALSE, error); - close_nointr_noerror (fd); /* Ignore errors - we always want to close */ - - return ret; -} - -#if GLIB_CHECK_VERSION(2,34,0) -/** - * gs_file_map_readonly: - * @file: a #GFile - * @cancellable: - * @error: - * - * Return a #GBytes which references a readonly view of the contents of - * @file. This function uses #GMappedFile internally. - * - * Returns: (transfer full): a newly referenced #GBytes - */ -GBytes * -gs_file_map_readonly (GFile *file, - GCancellable *cancellable, - GError **error) -{ - GMappedFile *mfile; - GBytes *ret; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return NULL; - - mfile = g_mapped_file_new (gs_file_get_path_cached (file), FALSE, error); - if (!mfile) - return NULL; - - ret = g_mapped_file_get_bytes (mfile); - g_mapped_file_unref (mfile); - return ret; -} -#endif - -/** - * gs_file_sync_data: - * @file: a #GFile - * @cancellable: - * @error: - * - * Wraps the UNIX fsync() function (or fdatasync(), if available), which - * ensures that the data in @file is on non-volatile storage. - */ -gboolean -gs_file_sync_data (GFile *file, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int res; - int fd = -1; - - if (!gs_file_openat_noatime (AT_FDCWD, gs_file_get_path_cached (file), &fd, - cancellable, error)) - goto out; - - do - { -#ifdef __linux - res = fdatasync (fd); -#else - res = fsync (fd); -#endif - } - while (G_UNLIKELY (res != 0 && errno == EINTR)); - if (res != 0) - { - _set_error_from_errno (error); - goto out; - } - - res = close_nointr (fd); - if (res != 0) - { - _set_error_from_errno (error); - goto out; - } - fd = -1; - - ret = TRUE; - out: - if (fd != -1) - close_nointr_noerror (fd); - return ret; -} - -/** - * gs_file_create: - * @file: Path to non-existent file - * @mode: Unix access permissions - * @out_stream: (out) (transfer full) (allow-none): Newly created output, or %NULL - * @cancellable: a #GCancellable - * @error: a #GError - * - * Like g_file_create(), except this function allows specifying the - * access mode. This allows atomically creating private files. - */ -gboolean -gs_file_create (GFile *file, - int mode, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int fd; - GOutputStream *ret_stream = NULL; - - fd = open_nointr (gs_file_get_path_cached (file), O_WRONLY | O_CREAT | O_EXCL, mode); - if (fd < 0) - { - _set_error_from_errno (error); - goto out; - } - - if (fchmod (fd, mode) < 0) - { - close (fd); - _set_error_from_errno (error); - goto out; - } - - ret_stream = g_unix_output_stream_new (fd, TRUE); - - ret = TRUE; - gs_transfer_out_value (out_stream, &ret_stream); - out: - g_clear_object (&ret_stream); - return ret; -} - -static const char * -get_default_tmp_prefix (void) -{ - static char *tmpprefix = NULL; - - if (g_once_init_enter (&tmpprefix)) - { - const char *prgname = g_get_prgname (); - const char *p; - char *prefix; - char *iter; - - if (prgname) - { - p = strrchr (prgname, '/'); - if (p) - prgname = p + 1; - } - else - prgname = ""; - - prefix = g_strdup_printf ("tmp-%s%u-", prgname, getuid ()); - for (iter = prefix; *iter; iter++) - { - char c = *iter; - if (c == ' ') - *iter = '_'; - } - - g_once_init_leave (&tmpprefix, prefix); - } - - return tmpprefix; -} - -/** - * gs_fileutil_gen_tmp_name: - * @prefix: (allow-none): String prepended to the result - * @suffix: (allow-none): String suffixed to the result - * - * Generate a name suitable for use as a temporary file. This - * function does no I/O; it is not guaranteed that a file with that - * name does not exist. - */ -char * -gs_fileutil_gen_tmp_name (const char *prefix, - const char *suffix) -{ - static const char table[] = "ABCEDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz0123456789"; - GString *str = g_string_new (""); - guint i; - - if (!prefix) - prefix = get_default_tmp_prefix (); - if (!suffix) - suffix = "tmp"; - - g_string_append (str, prefix); - for (i = 0; i < 8; i++) - { - int offset = g_random_int_range (0, sizeof (table) - 1); - g_string_append_c (str, (guint8)table[offset]); - } - g_string_append_c (str, '.'); - g_string_append (str, suffix); - - return g_string_free (str, FALSE); -} - -/** - * gs_file_open_dir_fd: - * @path: Directory name - * @out_fd: (out): File descriptor for directory - * @cancellable: Cancellable - * @error: Error - * - * On success, sets @out_fd to a file descriptor for the directory - * that can be used with UNIX functions such as openat(). - */ -gboolean -gs_file_open_dir_fd (GFile *path, - int *out_fd, - GCancellable *cancellable, - GError **error) -{ - /* Linux specific probably */ - *out_fd = open (gs_file_get_path_cached (path), O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC); - if (*out_fd == -1) - { - _set_error_from_errno (error); - return FALSE; - } - return TRUE; -} - -/** - * gs_file_open_in_tmpdir_at: - * @tmpdir_fd: Directory to place temporary file - * @mode: Default mode (will be affected by umask) - * @out_name: (out) (transfer full): Newly created file name - * @out_stream: (out) (transfer full) (allow-none): Newly created output stream - * @cancellable: - * @error: - * - * Like g_file_open_tmp(), except the file will be created in the - * provided @tmpdir, and allows specification of the Unix @mode, which - * means private files may be created. Return values will be stored - * in @out_name, and optionally @out_stream. - */ -gboolean -gs_file_open_in_tmpdir_at (int tmpdir_fd, - int mode, - char **out_name, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - const int max_attempts = 128; - int i; - char *tmp_name = NULL; - int fd; - - /* 128 attempts seems reasonable... */ - for (i = 0; i < max_attempts; i++) - { - g_free (tmp_name); - tmp_name = gs_fileutil_gen_tmp_name (NULL, NULL); - - do - fd = openat (tmpdir_fd, tmp_name, O_WRONLY | O_CREAT | O_EXCL, mode); - while (fd == -1 && errno == EINTR); - if (fd < 0 && errno != EEXIST) - { - _set_error_from_errno (error); - goto out; - } - else if (fd != -1) - break; - } - if (i == max_attempts) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Exhausted attempts to open temporary file"); - goto out; - } - - ret = TRUE; - gs_transfer_out_value (out_name, &tmp_name); - if (out_stream) - *out_stream = g_unix_output_stream_new (fd, TRUE); - else - (void) close (fd); - out: - g_free (tmp_name); - return ret; -} - -/** - * gs_file_open_in_tmpdir: - * @tmpdir: Directory to place temporary file - * @mode: Default mode (will be affected by umask) - * @out_file: (out) (transfer full): Newly created file path - * @out_stream: (out) (transfer full) (allow-none): Newly created output stream - * @cancellable: - * @error: - * - * Like g_file_open_tmp(), except the file will be created in the - * provided @tmpdir, and allows specification of the Unix @mode, which - * means private files may be created. Return values will be stored - * in @out_file, and optionally @out_stream. - */ -gboolean -gs_file_open_in_tmpdir (GFile *tmpdir, - int mode, - GFile **out_file, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - DIR *d = NULL; - int dfd = -1; - char *tmp_name = NULL; - GOutputStream *ret_stream = NULL; - - d = opendir (gs_file_get_path_cached (tmpdir)); - if (!d) - { - _set_error_from_errno (error); - goto out; - } - dfd = dirfd (d); - - if (!gs_file_open_in_tmpdir_at (dfd, mode, &tmp_name, - out_stream ? &ret_stream : NULL, - cancellable, error)) - goto out; - - ret = TRUE; - *out_file = g_file_get_child (tmpdir, tmp_name); - gs_transfer_out_value (out_stream, &ret_stream); - out: - if (d) (void) closedir (d); - g_clear_object (&ret_stream); - g_free (tmp_name); - return ret; -} - -static gboolean -linkcopy_internal_attempt (GFile *src, - GFile *dest, - GFile *dest_parent, - GFileCopyFlags flags, - gboolean sync_data, - gboolean enable_guestfs_fuse_workaround, - gboolean *out_try_again, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int res; - char *tmp_name = NULL; - GFile *tmp_dest = NULL; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - goto out; - - tmp_name = gs_fileutil_gen_tmp_name (NULL, NULL); - tmp_dest = g_file_get_child (dest_parent, tmp_name); - - res = link (gs_file_get_path_cached (src), gs_file_get_path_cached (tmp_dest)); - if (res == -1) - { - if (errno == EEXIST) - { - /* Nothing, fall through */ - *out_try_again = TRUE; - ret = TRUE; - goto out; - } - else if (errno == EXDEV || errno == EMLINK || errno == EPERM - || (enable_guestfs_fuse_workaround && errno == ENOENT)) - { - if (!g_file_copy (src, tmp_dest, flags, - cancellable, NULL, NULL, error)) - goto out; - } - else - { - _set_error_from_errno (error); - goto out; - } - } - - if (sync_data) - { - /* Now, we need to fsync */ - if (!gs_file_sync_data (tmp_dest, cancellable, error)) - goto out; - } - - if (!gs_file_rename (tmp_dest, dest, cancellable, error)) - goto out; - - ret = TRUE; - *out_try_again = FALSE; - out: - g_clear_pointer (&tmp_name, g_free); - g_clear_object (&tmp_dest); - return ret; -} - -static gboolean -linkcopy_internal (GFile *src, - GFile *dest, - GFileCopyFlags flags, - gboolean sync_data, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - gboolean dest_exists; - int i; - gboolean enable_guestfs_fuse_workaround; - struct stat src_stat; - struct stat dest_stat; - GFile *dest_parent = NULL; - - flags |= G_FILE_COPY_NOFOLLOW_SYMLINKS; - - g_return_val_if_fail ((flags & (G_FILE_COPY_BACKUP | G_FILE_COPY_TARGET_DEFAULT_PERMS)) == 0, FALSE); - - dest_parent = g_file_get_parent (dest); - - if (lstat (gs_file_get_path_cached (src), &src_stat) == -1) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno), - g_strerror (errsv)); - goto out; - } - - if (lstat (gs_file_get_path_cached (dest), &dest_stat) == -1) - dest_exists = FALSE; - else - dest_exists = TRUE; - - if (((flags & G_FILE_COPY_OVERWRITE) == 0) && dest_exists) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "File exists"); - goto out; - } - - /* Work around the behavior of link() where it's a no-op if src and - * dest are the same. - */ - if (dest_exists && - src_stat.st_dev == dest_stat.st_dev && - src_stat.st_ino == dest_stat.st_ino) - { - ret = TRUE; - goto out; - } - - enable_guestfs_fuse_workaround = getenv ("LIBGSYSTEM_ENABLE_GUESTFS_FUSE_WORKAROUND") != NULL; - - /* 128 attempts seems reasonable... */ - for (i = 0; i < 128; i++) - { - gboolean tryagain = FALSE; - - if (!linkcopy_internal_attempt (src, dest, dest_parent, - flags, sync_data, - enable_guestfs_fuse_workaround, - &tryagain, - cancellable, error)) - goto out; - - if (!tryagain) - break; - } - - ret = TRUE; - out: - g_clear_object (&dest_parent); - return ret; - -} - -/** - * gs_file_linkcopy: - * @src: Source file - * @dest: Destination file - * @flags: flags - * @cancellable: - * @error: - * - * First tries to use the UNIX link() call, but if the files are on - * separate devices, fall back to copying via g_file_copy(). - * - * The given @flags have different semantics than those documented - * when hardlinking is used. Specifically, both - * #G_FILE_COPY_TARGET_DEFAULT_PERMS and #G_FILE_COPY_BACKUP are not - * supported. #G_FILE_COPY_NOFOLLOW_SYMLINKS treated as if it was - * always given - if you want to follow symbolic links, you will need - * to resolve them manually. - * - * Beware - do not use this function if @src may be modified, and it's - * undesirable for the changes to also be reflected in @dest. The - * best use of this function is in the case where @src and @dest are - * read-only, or where @src is a temporary file, and you want to put - * it in the final place. - */ -gboolean -gs_file_linkcopy (GFile *src, - GFile *dest, - GFileCopyFlags flags, - GCancellable *cancellable, - GError **error) -{ - return linkcopy_internal (src, dest, flags, FALSE, cancellable, error); -} - -/** - * gs_file_linkcopy_sync_data: - * @src: Source file - * @dest: Destination file - * @flags: flags - * @cancellable: - * @error: - * - * This function is similar to gs_file_linkcopy(), except it also uses - * gs_file_sync_data() to ensure that @dest is in stable storage - * before it is moved into place. - */ -gboolean -gs_file_linkcopy_sync_data (GFile *src, - GFile *dest, - GFileCopyFlags flags, - GCancellable *cancellable, - GError **error) -{ - return linkcopy_internal (src, dest, flags, TRUE, cancellable, error); -} - -static char * -gs_file_get_target_path (GFile *file) -{ - GFileInfo *info; - const char *target; - char *path; - - info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, G_FILE_QUERY_INFO_NONE, NULL, NULL); - if (info == NULL) - return NULL; - target = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); - path = g_filename_from_uri (target, NULL, NULL); - g_object_unref (info); - - return path; -} - -G_LOCK_DEFINE_STATIC (pathname_cache); - -/** - * gs_file_get_path_cached: - * - * Like g_file_get_path(), but returns a constant copy so callers - * don't need to free the result. - */ -const char * -gs_file_get_path_cached (GFile *file) -{ - const char *path; - static GQuark _file_path_quark = 0; - - if (G_UNLIKELY (_file_path_quark) == 0) - _file_path_quark = g_quark_from_static_string ("gsystem-file-path"); - - G_LOCK (pathname_cache); - - path = g_object_get_qdata ((GObject*)file, _file_path_quark); - if (!path) - { - if (g_file_has_uri_scheme (file, "trash") || - g_file_has_uri_scheme (file, "recent")) - path = gs_file_get_target_path (file); - else - path = g_file_get_path (file); - if (path == NULL) - { - G_UNLOCK (pathname_cache); - return NULL; - } - g_object_set_qdata_full ((GObject*)file, _file_path_quark, (char*)path, (GDestroyNotify)g_free); - } - - G_UNLOCK (pathname_cache); - - return path; -} - -/** - * gs_file_get_basename_cached: - * - * Like g_file_get_basename(), but returns a constant copy so callers - * don't need to free the result. - */ -const char * -gs_file_get_basename_cached (GFile *file) -{ - const char *name; - static GQuark _file_name_quark = 0; - - if (G_UNLIKELY (_file_name_quark) == 0) - _file_name_quark = g_quark_from_static_string ("gsystem-file-name"); - - G_LOCK (pathname_cache); - - name = g_object_get_qdata ((GObject*)file, _file_name_quark); - if (!name) - { - name = g_file_get_basename (file); - g_object_set_qdata_full ((GObject*)file, _file_name_quark, (char*)name, (GDestroyNotify)g_free); - } - - G_UNLOCK (pathname_cache); - - return name; -} - -/** - * gs_file_enumerator_iterate: - * @direnum: an open #GFileEnumerator - * @out_info: (out) (transfer none) (allow-none): Output location for the next #GFileInfo - * @out_child: (out) (transfer none) (allow-none): Output location for the next #GFile, or %NULL - * @cancellable: a #GCancellable - * @error: a #GError - * - * This is a version of g_file_enumerator_next_file() that's easier to - * use correctly from C programs. With g_file_enumerator_next_file(), - * the gboolean return value signifies "end of iteration or error", which - * requires allocation of a temporary #GError. - * - * In contrast, with this function, a %FALSE return from - * gs_file_enumerator_iterate() always means - * "error". End of iteration is signaled by @out_info being %NULL. - * - * Another crucial difference is that the references for @out_info and - * @out_child are owned by @direnum (they are cached as hidden - * properties). You must not unref them in your own code. This makes - * memory management significantly easier for C code in combination - * with loops. - * - * Finally, this function optionally allows retrieving a #GFile as - * well. - * - * The code pattern for correctly using gs_file_enumerator_iterate() from C - * is: - * - * |[ - * direnum = g_file_enumerate_children (file, ...); - * while (TRUE) - * { - * GFileInfo *info; - * if (!gs_file_enumerator_iterate (direnum, &info, NULL, cancellable, error)) - * goto out; - * if (!info) - * break; - * ... do stuff with "info"; do not unref it! ... - * } - * - * out: - * g_object_unref (direnum); // Note: frees the last @info - * ]| - */ -gboolean -gs_file_enumerator_iterate (GFileEnumerator *direnum, - GFileInfo **out_info, - GFile **out_child, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - GError *temp_error = NULL; - - static GQuark cached_info_quark; - static GQuark cached_child_quark; - static gsize quarks_initialized; - - g_return_val_if_fail (direnum != NULL, FALSE); - g_return_val_if_fail (out_info != NULL, FALSE); - - if (g_once_init_enter (&quarks_initialized)) - { - cached_info_quark = g_quark_from_static_string ("gsystem-cached-info"); - cached_child_quark = g_quark_from_static_string ("gsystem-cached-child"); - g_once_init_leave (&quarks_initialized, 1); - } - - - *out_info = g_file_enumerator_next_file (direnum, cancellable, &temp_error); - if (out_child) - *out_child = NULL; - if (temp_error != NULL) - { - g_propagate_error (error, temp_error); - goto out; - } - else if (*out_info != NULL) - { - g_object_set_qdata_full ((GObject*)direnum, cached_info_quark, *out_info, (GDestroyNotify)g_object_unref); - if (out_child != NULL) - { - const char *name = g_file_info_get_name (*out_info); - *out_child = g_file_get_child (g_file_enumerator_get_container (direnum), name); - g_object_set_qdata_full ((GObject*)direnum, cached_child_quark, *out_child, (GDestroyNotify)g_object_unref); - } - } - - ret = TRUE; - out: - return ret; -} - -/** - * gs_file_rename: - * @from: Current path - * @to: New path - * @cancellable: a #GCancellable - * @error: a #GError - * - * This function wraps the raw Unix function rename(). - * - * Returns: %TRUE on success, %FALSE on error - */ -gboolean -gs_file_rename (GFile *from, - GFile *to, - GCancellable *cancellable, - GError **error) -{ - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - if (rename (gs_file_get_path_cached (from), - gs_file_get_path_cached (to)) < 0) - { - _set_error_from_errno (error); - return FALSE; - } - return TRUE; -} - -/** - * gs_file_unlink: - * @path: Path to file - * @cancellable: a #GCancellable - * @error: a #GError - * - * Like g_file_delete(), except this function does not follow Unix - * symbolic links, and will delete a symbolic link even if it's - * pointing to a nonexistent file. In other words, this function - * merely wraps the raw Unix function unlink(). - * - * Returns: %TRUE on success, %FALSE on error - */ -gboolean -gs_file_unlink (GFile *path, - GCancellable *cancellable, - GError **error) -{ - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - if (unlink (gs_file_get_path_cached (path)) < 0) - { - _set_error_from_errno (error); - return FALSE; - } - return TRUE; -} - -static gboolean -chown_internal (GFile *path, - gboolean dereference_links, - guint32 owner, - guint32 group, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int res; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - do - if (dereference_links) - res = chown (gs_file_get_path_cached (path), owner, group); - else - res = lchown (gs_file_get_path_cached (path), owner, group); - while (G_UNLIKELY (res != 0 && errno == EINTR)); - - if (res < 0) - { - _set_error_from_errno (error); - goto out; - } - - ret = TRUE; - out: - return ret; -} - -/** - * gs_file_chown: - * @path: Path to file - * @owner: UNIX owner - * @group: UNIX group - * @cancellable: a #GCancellable - * @error: a #GError - * - * Merely wraps UNIX chown(). - * - * Returns: %TRUE on success, %FALSE on error - */ -gboolean -gs_file_chown (GFile *path, - guint32 owner, - guint32 group, - GCancellable *cancellable, - GError **error) -{ - return chown_internal (path, TRUE, owner, group, cancellable, error); -} - -/** - * gs_file_lchown: - * @path: Path to file - * @owner: UNIX owner - * @group: UNIX group - * @cancellable: a #GCancellable - * @error: a #GError - * - * Merely wraps UNIX lchown(). - * - * Returns: %TRUE on success, %FALSE on error - */ -gboolean -gs_file_lchown (GFile *path, - guint32 owner, - guint32 group, - GCancellable *cancellable, - GError **error) -{ - return chown_internal (path, FALSE, owner, group, cancellable, error); -} - -/** - * gs_file_chmod: - * @path: Path to file - * @mode: UNIX mode - * @cancellable: a #GCancellable - * @error: a #GError - * - * Merely wraps UNIX chmod(). - * - * Returns: %TRUE on success, %FALSE on error - */ -gboolean -gs_file_chmod (GFile *path, - guint mode, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int res; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - do - res = chmod (gs_file_get_path_cached (path), mode); - while (G_UNLIKELY (res != 0 && errno == EINTR)); - - if (res < 0) - { - _set_error_from_errno (error); - goto out; - } - - ret = TRUE; - out: - return ret; -} - -/** - * gs_file_ensure_directory: - * @dir: Path to create as directory - * @with_parents: Also create parent directories - * @cancellable: a #GCancellable - * @error: a #GError - * - * Like g_file_make_directory(), except does not throw an error if the - * directory already exists. - */ -gboolean -gs_file_ensure_directory (GFile *dir, - gboolean with_parents, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - GError *temp_error = NULL; - GFile *parent = NULL; - - if (!g_file_make_directory (dir, cancellable, &temp_error)) - { - if (with_parents && - g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - g_clear_error (&temp_error); - - parent = g_file_get_parent (dir); - if (parent) - { - if (!gs_file_ensure_directory (parent, TRUE, cancellable, error)) - goto out; - } - if (!gs_file_ensure_directory (dir, FALSE, cancellable, error)) - goto out; - } - else if (!g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) - { - g_propagate_error (error, temp_error); - goto out; - } - else - g_clear_error (&temp_error); - } - - ret = TRUE; - out: - g_clear_object (&parent); - return ret; -} - -/** - * gs_file_ensure_directory_mode: - * @dir: Path to create as directory - * @mode: Create directory with these permissions - * @cancellable: a #GCancellable - * @error: a #GError - * - * Wraps UNIX mkdir() function with support for @cancellable, and - * uses @error instead of errno. - */ -gboolean -gs_file_ensure_directory_mode (GFile *dir, - guint mode, - GCancellable *cancellable, - GError **error) -{ - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - if (mkdir (gs_file_get_path_cached (dir), mode) == -1 && errno != EEXIST) - { - _set_error_from_errno (error); - return FALSE; - } - return TRUE; -} - -/** - * gs_file_load_contents_utf8: - * @file: Path to file whose contents must be UTF-8 - * @cancellable: - * @error: - * - * Like g_file_load_contents(), except validates the contents are - * UTF-8. - */ -gchar * -gs_file_load_contents_utf8 (GFile *file, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - gsize len; - char *ret_contents = NULL; - - if (!g_file_load_contents (file, cancellable, &ret_contents, &len, - NULL, error)) - goto out; - if (!g_utf8_validate (ret_contents, len, NULL)) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_DATA, - "Invalid UTF-8"); - goto out; - } - - ret = TRUE; - out: - if (!ret) - { - g_free (ret_contents); - return NULL; - } - return ret_contents; -} - -static int -path_common_directory (char *one, - char *two) -{ - int dir_index = 0; - int i = 0; - - while (*one && *two) - { - if (*one != *two) - break; - if (*one == '/') - dir_index = i + 1; - - one++; - two++; - i++; - } - - return dir_index; -} - -/** - * gs_file_get_relpath: - * @one: The first #GFile - * @two: The second #GFile - * - * Like gs_file_get_relative_path(), but does not mandate that - * the two files have any parent in common. This function will - * instead insert "../" where appropriate. - * - * Returns: (transfer full): The relative path between the two. - */ -gchar * -gs_file_get_relpath (GFile *one, - GFile *two) -{ - gchar *simple_path; - gchar *one_path, *one_suffix; - gchar *two_path, *two_suffix; - GString *path; - int i; - - simple_path = g_file_get_relative_path (one, two); - if (simple_path) - return simple_path; - - one_path = g_file_get_path (one); - two_path = g_file_get_path (two); - - i = path_common_directory (one_path, two_path); - one_suffix = one_path + i; - two_suffix = two_path + i; - - path = g_string_new (""); - - /* For every leftover path segment one has, append "../" so - * that we reach the same directory. */ - while (*one_suffix) - { - g_string_append (path, "../"); - one_suffix = strchr (one_suffix, '/'); - if (one_suffix == NULL) - break; - one_suffix++; - } - - /* And now append the leftover stuff on two's side. */ - g_string_append (path, two_suffix); - - g_free (one_path); - g_free (two_path); - - return g_string_free (path, FALSE); -} - -/** - * gs_file_realpath: - * @file: A #GFile - * - * Return a #GFile that contains the same path with symlinks - * followed. That is, it's a #GFile whose path is the result - * of calling realpath() on @file. - * - * Returns: (allow-none) (transfer full): A new #GFile or %NULL if @file is invalid - */ -GFile * -gs_file_realpath (GFile *file) -{ - gchar *path; - gchar path_real[PATH_MAX]; - - path = g_file_get_path (file); - - if (realpath ((const char *) path, path_real) == NULL) - { - g_free (path); - return NULL; - } - - g_free (path); - return g_file_new_for_path (path_real); -} - -#ifdef GSYSTEM_CONFIG_XATTRS -static char * -canonicalize_xattrs (char *xattr_string, - size_t len) -{ - char *p; - GSList *xattrs = NULL; - GSList *iter; - GString *result; - - result = g_string_new (0); - - p = xattr_string; - while (p < xattr_string+len) - { - xattrs = g_slist_prepend (xattrs, p); - p += strlen (p) + 1; - } - - xattrs = g_slist_sort (xattrs, (GCompareFunc) strcmp); - for (iter = xattrs; iter; iter = iter->next) { - g_string_append (result, iter->data); - g_string_append_c (result, '\0'); - } - - g_slist_free (xattrs); - return g_string_free (result, FALSE); -} - -static GVariant * -variant_new_ay_bytes (GBytes *bytes) -{ - gsize size; - gconstpointer data; - data = g_bytes_get_data (bytes, &size); - g_bytes_ref (bytes); - return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, size, - TRUE, (GDestroyNotify)g_bytes_unref, bytes); -} - -static gboolean -read_xattr_name_array (const char *path, - const char *xattrs, - size_t len, - GVariantBuilder *builder, - GError **error) -{ - gboolean ret = FALSE; - const char *p; - - p = xattrs; - while (p < xattrs+len) - { - ssize_t bytes_read; - char *buf; - GBytes *bytes = NULL; - - bytes_read = lgetxattr (path, p, NULL, 0); - if (bytes_read < 0) - { - _set_error_from_errno (error); - g_prefix_error (error, "lgetxattr (%s, %s) failed: ", path, p); - goto out; - } - if (bytes_read == 0) - continue; - - buf = g_malloc (bytes_read); - bytes = g_bytes_new_take (buf, bytes_read); - if (lgetxattr (path, p, buf, bytes_read) < 0) - { - g_bytes_unref (bytes); - _set_error_from_errno (error); - g_prefix_error (error, "lgetxattr (%s, %s) failed: ", path, p); - goto out; - } - - g_variant_builder_add (builder, "(@ay@ay)", - g_variant_new_bytestring (p), - variant_new_ay_bytes (bytes)); - - p = p + strlen (p) + 1; - g_bytes_unref (bytes); - } - - ret = TRUE; - out: - return ret; -} -#endif - -static gboolean -get_xattrs_impl (GFile *f, - GVariantBuilder *builder, - GCancellable *cancellable, - GError **error) -{ -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - const char *path; - ssize_t bytes_read; - char *xattr_names = NULL; - char *xattr_names_canonical = NULL; - - path = gs_file_get_path_cached (f); - - bytes_read = llistxattr (path, NULL, 0); - - if (bytes_read < 0) - { - if (errno != ENOTSUP) - { - _set_error_from_errno (error); - g_prefix_error (error, "llistxattr (%s) failed: ", path); - goto out; - } - } - else if (bytes_read > 0) - { - xattr_names = g_malloc (bytes_read); - if (llistxattr (path, xattr_names, bytes_read) < 0) - { - _set_error_from_errno (error); - g_prefix_error (error, "llistxattr (%s) failed: ", path); - goto out; - } - xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read); - - if (!read_xattr_name_array (path, xattr_names_canonical, bytes_read, builder, error)) - goto out; - } - - ret = TRUE; - out: - g_clear_pointer (&xattr_names, g_free); - g_clear_pointer (&xattr_names_canonical, g_free); - return ret; -#else - return TRUE; -#endif -} - -/** - * gs_file_get_all_xattrs: - * @f: a #GFile - * @out_xattrs: (out): A new #GVariant containing the extended attributes - * @cancellable: Cancellable - * @error: Error - * - * Read all extended attributes of @f in a canonical sorted order, and - * set @out_xattrs with the result. - * - * If the filesystem does not support extended attributes, @out_xattrs - * will have 0 elements, and this function will return successfully. - */ -gboolean -gs_file_get_all_xattrs (GFile *f, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - GVariantBuilder builder; - gboolean builder_initialized = FALSE; - GVariant *ret_xattrs = NULL; - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); - builder_initialized = TRUE; - - if (!get_xattrs_impl (f, &builder, - cancellable, error)) - goto out; - - ret_xattrs = g_variant_builder_end (&builder); - builder_initialized = FALSE; - g_variant_ref_sink (ret_xattrs); - - ret = TRUE; - gs_transfer_out_value (out_xattrs, &ret_xattrs); - out: - g_clear_pointer (&ret_xattrs, g_variant_unref); - if (!builder_initialized) - g_variant_builder_clear (&builder); - return ret; -} - -/** - * gs_fd_set_all_xattrs: - * @fd: File descriptor - * @xattrs: Extended attributes - * @cancellable: Cancellable - * @error: Error - * - * For each attribute in @xattrs, set its value on the file or - * directory referred to by @fd. This function does not remove any - * attributes not in @xattrs. - */ -gboolean -gs_fd_set_all_xattrs (int fd, - GVariant *xattrs, - GCancellable *cancellable, - GError **error) -{ -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - int i, n; - - n = g_variant_n_children (xattrs); - for (i = 0; i < n; i++) - { - const guint8* name; - const guint8* value_data; - GVariant *value = NULL; - gsize value_len; - int res; - - g_variant_get_child (xattrs, i, "(^&ay@ay)", - &name, &value); - value_data = g_variant_get_fixed_array (value, &value_len, 1); - - do - res = fsetxattr (fd, (char*)name, (char*)value_data, value_len, 0); - while (G_UNLIKELY (res == -1 && errno == EINTR)); - g_variant_unref (value); - if (G_UNLIKELY (res == -1)) - { - _set_error_from_errno (error); - goto out; - } - } - - ret = TRUE; - out: - return ret; -#else - return TRUE; -#endif -} - -/** - * gs_file_set_all_xattrs: - * @file: File descriptor - * @xattrs: Extended attributes - * @cancellable: Cancellable - * @error: Error - * - * For each attribute in @xattrs, set its value on the file or - * directory referred to by @file. This function does not remove any - * attributes not in @xattrs. - */ -gboolean -gs_file_set_all_xattrs (GFile *file, - GVariant *xattrs, - GCancellable *cancellable, - GError **error) -{ -#ifdef GSYSTEM_CONFIG_XATTRS - gboolean ret = FALSE; - const char *path; - int i, n; - - path = gs_file_get_path_cached (file); - - n = g_variant_n_children (xattrs); - for (i = 0; i < n; i++) - { - const guint8* name; - GVariant *value; - const guint8* value_data; - gsize value_len; - gboolean loop_err; - - g_variant_get_child (xattrs, i, "(^&ay@ay)", - &name, &value); - value_data = g_variant_get_fixed_array (value, &value_len, 1); - - loop_err = lsetxattr (path, (char*)name, (char*)value_data, value_len, 0) < 0; - g_clear_pointer (&value, (GDestroyNotify) g_variant_unref); - if (loop_err) - { - _set_error_from_errno (error); - g_prefix_error (error, "lsetxattr (%s, %s) failed: ", path, name); - goto out; - } - } - - ret = TRUE; - out: - return ret; -#else - return TRUE; -#endif -} diff --git a/libgsystem/gsystem-file-utils.h b/libgsystem/gsystem-file-utils.h deleted file mode 100644 index 021aebb7..00000000 --- a/libgsystem/gsystem-file-utils.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_FILE_UTILS_H__ -#define __GSYSTEM_FILE_UTILS_H__ - -#include -#include - -G_BEGIN_DECLS - -const char *gs_file_get_path_cached (GFile *file); - -const char *gs_file_get_basename_cached (GFile *file); - -gboolean gs_file_enumerator_iterate (GFileEnumerator *direnum, - GFileInfo **out_info, - GFile **out_child, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_openat_noatime (int dfd, - const char *name, - int *ret_fd, - GCancellable *cancellable, - GError **error); - -GInputStream *gs_file_read_noatime (GFile *file, - GCancellable *cancellable, - GError **error); -GMappedFile *gs_file_map_noatime (GFile *file, - GCancellable *cancellable, - GError **error); - -#ifndef __GI_SCANNER__ -gboolean gs_stream_fstat (GFileDescriptorBased *stream, - struct stat *out_stbuf, - GCancellable *cancellable, - GError **error); - -#endif - -#if GLIB_CHECK_VERSION(2,34,0) -GBytes *gs_file_map_readonly (GFile *file, - GCancellable *cancellable, - GError **error); -#endif - -gboolean gs_file_sync_data (GFile *file, - GCancellable *cancellable, - GError **error); - -char * gs_fileutil_gen_tmp_name (const char *prefix, - const char *suffix); - -gboolean gs_file_open_dir_fd (GFile *path, - int *out_fd, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_open_in_tmpdir_at (int tmpdir_fd, - int mode, - char **out_name, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_open_in_tmpdir (GFile *tmpdir, - int mode, - GFile **out_file, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_create (GFile *file, - int mode, - GOutputStream **out_stream, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_linkcopy (GFile *src, - GFile *dest, - GFileCopyFlags flags, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_linkcopy_sync_data (GFile *src, - GFile *dest, - GFileCopyFlags flags, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_rename (GFile *from, - GFile *to, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_unlink (GFile *path, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_chown (GFile *path, - guint32 owner, - guint32 group, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_lchown (GFile *path, - guint32 owner, - guint32 group, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_chmod (GFile *path, - guint mode, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_ensure_directory (GFile *dir, - gboolean with_parents, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_ensure_directory_mode (GFile *dir, - guint mode, - GCancellable *cancellable, - GError **error); - -gchar *gs_file_load_contents_utf8 (GFile *file, - GCancellable *cancellable, - GError **error); - -gchar *gs_file_get_relpath (GFile *one, - GFile *two); - -GFile * gs_file_realpath (GFile *file); - -gboolean gs_file_get_all_xattrs (GFile *f, - GVariant **out_xattrs, - GCancellable *cancellable, - GError **error); - -gboolean gs_fd_set_all_xattrs (int fd, - GVariant *xattrs, - GCancellable *cancellable, - GError **error); - -gboolean gs_file_set_all_xattrs (GFile *file, - GVariant *xattrs, - GCancellable *cancellable, - GError **error); - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-glib-compat.h b/libgsystem/gsystem-glib-compat.h deleted file mode 100644 index 6fd59c65..00000000 --- a/libgsystem/gsystem-glib-compat.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012,2013 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __LIBGSYSTEM_GLIB_COMPAT__ -#define __LIBGSYSTEM_GLIB_COMPAT__ - -#include - -#if !GLIB_CHECK_VERSION(2,34,0) -static inline void -g_type_ensure (GType type) -{ - if (G_UNLIKELY (type == (GType)-1)) - g_error ("can't happen"); -} - -#define g_clear_pointer(pp, destroy) \ - G_STMT_START { \ - G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \ - /* Only one access, please */ \ - gpointer *_pp = (gpointer *) (pp); \ - gpointer _p; \ - /* This assignment is needed to avoid a gcc warning */ \ - GDestroyNotify _destroy = (GDestroyNotify) (destroy); \ - \ - (void) (0 ? (gpointer) *(pp) : 0); \ - do \ - _p = g_atomic_pointer_get (_pp); \ - while G_UNLIKELY (!g_atomic_pointer_compare_and_exchange (_pp, _p, NULL)); \ - \ - if (_p) \ - _destroy (_p); \ - } G_STMT_END - -#endif - -#endif diff --git a/libgsystem/gsystem-local-alloc.c b/libgsystem/gsystem-local-alloc.c deleted file mode 100644 index add3fcb3..00000000 --- a/libgsystem/gsystem-local-alloc.c +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include "gsystem-local-alloc.h" - -/** - * SECTION:gslocalalloc - * @title: GSystem local allocation - * @short_description: Release local variables automatically when they go out of scope - * - * These macros leverage the GCC extension __attribute__ ((cleanup)) - * to allow calling a cleanup function such as g_free() when a - * variable goes out of scope. See - * for more information on the attribute. - * - * The provided macros make it easy to use the cleanup attribute for - * types that come with GLib. The primary two are #gs_free and - * #gs_unref_object, which correspond to g_free() and - * g_object_unref(), respectively. - * - * The rationale behind this is that particularly when handling error - * paths, it can be very tricky to ensure the right variables are - * freed. With this, one simply applies gs_lobj to a - * locally-allocated #GFile for example, and it will be automatically - * unreferenced when it goes out of scope. - * - * Note - you should only use these macros for stack - * allocated variables. They don't provide garbage - * collection or let you avoid freeing things. They're simply a - * compiler assisted deterministic mechanism for calling a cleanup - * function when a stack frame ends. - * - * Calling g_free automatically - * - * - * GFile * - * create_file (GError **error) - * { - * gs_free char *random_id = NULL; - * - * if (!prepare_file (error)) - * return NULL; - * - * random_id = alloc_random_id (); - * - * return create_file_real (error); - * // Note that random_id is freed here automatically - * } - * - * - * - */ diff --git a/libgsystem/gsystem-local-alloc.h b/libgsystem/gsystem-local-alloc.h deleted file mode 100644 index 34db2979..00000000 --- a/libgsystem/gsystem-local-alloc.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_LOCAL_ALLOC_H__ -#define __GSYSTEM_LOCAL_ALLOC_H__ - -#include - -G_BEGIN_DECLS - -#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \ - static inline void name (void *v) \ - { \ - func (*(Type*)v); \ - } - -#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \ - static inline void name (void *v) \ - { \ - if (*(Type*)v) \ - func (*(Type*)v); \ - } - -/* These functions shouldn't be invoked directly; - * they are stubs that: - * 1) Take a pointer to the location (typically itself a pointer). - * 2) Provide %NULL-safety where it doesn't exist already (e.g. g_object_unref) - */ -GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free) -GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free) -GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref) -GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free) - -GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev) -GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free) - -/** - * gs_free: - * - * Call g_free() on a variable location when it goes out of scope. - */ -#define gs_free __attribute__ ((cleanup(gs_local_free))) - -/** - * gs_unref_object: - * - * Call g_object_unref() on a variable location when it goes out of - * scope. Note that unlike g_object_unref(), the variable may be - * %NULL. - */ -#define gs_unref_object __attribute__ ((cleanup(gs_local_obj_unref))) - -/** - * gs_unref_variant: - * - * Call g_variant_unref() on a variable location when it goes out of - * scope. Note that unlike g_variant_unref(), the variable may be - * %NULL. - */ -#define gs_unref_variant __attribute__ ((cleanup(gs_local_variant_unref))) - -/** - * gs_free_variant_iter: - * - * Call g_variant_iter_free() on a variable location when it goes out of - * scope. - */ -#define gs_free_variant_iter __attribute__ ((cleanup(gs_local_variant_iter_free))) - -/** - * gs_free_variant_builder: - * - * Call g_variant_builder_unref() on a variable location when it goes out of - * scope. - */ -#define gs_unref_variant_builder __attribute__ ((cleanup(gs_local_variant_builder_unref))) - -/** - * gs_unref_array: - * - * Call g_array_unref() on a variable location when it goes out of - * scope. Note that unlike g_array_unref(), the variable may be - * %NULL. - - */ -#define gs_unref_array __attribute__ ((cleanup(gs_local_array_unref))) - -/** - * gs_unref_ptrarray: - * - * Call g_ptr_array_unref() on a variable location when it goes out of - * scope. Note that unlike g_ptr_array_unref(), the variable may be - * %NULL. - - */ -#define gs_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref))) - -/** - * gs_unref_hashtable: - * - * Call g_hash_table_unref() on a variable location when it goes out - * of scope. Note that unlike g_hash_table_unref(), the variable may - * be %NULL. - */ -#define gs_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref))) - -/** - * gs_free_checksum: - * - * Call g_checksum_free() on a variable location when it goes out - * of scope. Note that unlike g_checksum_free(), the variable may - * be %NULL. - */ -#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free))) - -/** - * gs_unref_bytes: - * - * Call g_bytes_unref() on a variable location when it goes out - * of scope. Note that unlike g_bytes_unref(), the variable may - * be %NULL. - */ -#define gs_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref))) - -/** - * gs_strfreev: - * - * Call g_strfreev() on a variable location when it goes out of scope. - */ -#define gs_strfreev __attribute__ ((cleanup(gs_local_strfreev))) - -/** - * gs_free_error: - * - * Call g_error_free() on a variable location when it goes out of scope. - */ -#define gs_free_error __attribute__ ((cleanup(gs_local_free_error))) - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-log.c b/libgsystem/gsystem-log.c deleted file mode 100644 index 7b031453..00000000 --- a/libgsystem/gsystem-log.c +++ /dev/null @@ -1,167 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 William Jon McCann - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#ifdef ENABLE_SYSTEMD_JOURNAL -#define SD_JOURNAL_SUPPRESS_LOCATION -#include -#endif -#include - -#define _GSYSTEM_NO_LOCAL_ALLOC -#include "libgsystem.h" - -/** - * gs_log_structured: - * @message: Text message to send - * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data - * - * Log structured data in an operating-system specific fashion. The - * parameter @opts should be an array of UTF-8 KEY=VALUE strings. - * This function does not support binary data. See - * http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html - * for more information about fields that can be used on a systemd - * system. - */ -void -gs_log_structured (const char *message, - const char *const *keys) -{ -#ifdef ENABLE_SYSTEMD_JOURNAL - const char *const*iter; - char *msgkey; - guint i, n_opts; - struct iovec *iovs; - - for (n_opts = 0, iter = keys; *iter; iter++, n_opts++) - ; - - n_opts++; /* Add one for MESSAGE= */ - iovs = g_alloca (sizeof (struct iovec) * n_opts); - - for (i = 0, iter = keys; *iter; iter++, i++) { - iovs[i].iov_base = (char*)keys[i]; - iovs[i].iov_len = strlen (keys[i]); - } - g_assert(i == n_opts-1); - msgkey = g_strconcat ("MESSAGE=", message, NULL); - iovs[i].iov_base = msgkey; - iovs[i].iov_len = strlen (msgkey); - - // The code location isn't useful since we're wrapping - sd_journal_sendv (iovs, n_opts); - - g_free (msgkey); -#else - g_print ("%s\n", message); -#endif -} - -/** - * gs_stdout_is_journal: - * - * Use this function when you want your code to behave differently - * depeneding on whether your program was started as a systemd unit, - * or e.g. interactively at a terminal. - * - * Returns: %TRUE if stdout is (probably) connnected to the systemd journal - */ -gboolean -gs_stdout_is_journal (void) -{ - static gsize initialized; - static gboolean stdout_is_socket; - - if (g_once_init_enter (&initialized)) - { - guint64 pid = (guint64) getpid (); - char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid); - char buf[1024]; - ssize_t bytes_read; - - if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1) - { - buf[bytes_read] = '\0'; - stdout_is_socket = g_str_has_prefix (buf, "socket:"); - } - else - stdout_is_socket = FALSE; - - g_free (fdpath); - g_once_init_leave (&initialized, TRUE); - } - - return stdout_is_socket; -} - -/** - * gs_log_structured_print: - * @message: A message to log - * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data - * - * Like gs_log_structured(), but also print to standard output (if it - * is not already connected to the system log). - */ -void -gs_log_structured_print (const char *message, - const char *const *keys) -{ - gs_log_structured (message, keys); - -#ifdef ENABLE_SYSTEMD_JOURNAL - if (!gs_stdout_is_journal ()) - g_print ("%s\n", message); -#endif -} - -/** - * gs_log_structured_print_id_v: - * @message_id: A unique MESSAGE_ID - * @format: A format string - * - * The provided @message_id is a unique MESSAGE_ID (see for more information). - * - * This function otherwise acts as gs_log_structured_print(), taking - * @format as a format string. - */ -void -gs_log_structured_print_id_v (const char *message_id, - const char *format, - ...) -{ - char *keys[] = { NULL, NULL }; - char *msg; - va_list args; - - va_start (args, format); - msg = g_strdup_vprintf (format, args); - va_end (args); - - keys[0] = g_strconcat ("MESSAGE_ID=", message_id, NULL); - gs_log_structured_print (msg, (const char *const *)keys); - g_free (keys[0]); - g_free (msg); -} diff --git a/libgsystem/gsystem-log.h b/libgsystem/gsystem-log.h deleted file mode 100644 index 80cfc341..00000000 --- a/libgsystem/gsystem-log.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2013 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_LOG_H__ -#define __GSYSTEM_LOG_H__ - -#include - -G_BEGIN_DECLS - -gboolean gs_stdout_is_journal (void); - -void gs_log_structured (const char *message, - const char *const *keys); - -void gs_log_structured_print (const char *message, - const char *const *keys); - -void gs_log_structured_print_id_v (const char *message_id, - const char *format, - ...) G_GNUC_PRINTF (2, 3); - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-shutil.c b/libgsystem/gsystem-shutil.c deleted file mode 100644 index 8029dd9c..00000000 --- a/libgsystem/gsystem-shutil.c +++ /dev/null @@ -1,460 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 William Jon McCann - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#define _GSYSTEM_NO_LOCAL_ALLOC -#include "libgsystem.h" -#include "gsystem-glib-compat.h" -#include -#include -#include -#include -#include - -/* Taken from systemd/src/shared/util.h */ -union dirent_storage { - struct dirent dent; - guint8 storage[offsetof(struct dirent, d_name) + - ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))]; -}; - -static inline void -_set_error_from_errno (GError **error) -{ - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); -} - -static gboolean -copy_xattrs_from_file_to_fd (GFile *src, - int dest_fd, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - GVariant *src_xattrs = NULL; - - if (!gs_file_get_all_xattrs (src, &src_xattrs, cancellable, error)) - goto out; - - if (src_xattrs) - { - if (!gs_fd_set_all_xattrs (dest_fd, src_xattrs, cancellable, error)) - goto out; - } - - ret = TRUE; - out: - g_clear_pointer (&src_xattrs, g_variant_unref); - return ret; -} - -typedef enum { - GS_CP_MODE_NONE, - GS_CP_MODE_HARDLINK, - GS_CP_MODE_COPY_ALL -} GsCpMode; - -static gboolean -cp_internal (GFile *src, - GFile *dest, - GsCpMode mode, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - GFileEnumerator *enumerator = NULL; - GFileInfo *src_info = NULL; - GFile *dest_child = NULL; - int dest_dfd = -1; - int r; - - enumerator = g_file_enumerate_children (src, "standard::type,standard::name,unix::uid,unix::gid,unix::mode", - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); - if (!enumerator) - goto out; - - src_info = g_file_query_info (src, "standard::name,unix::mode,unix::uid,unix::gid," \ - "time::modified,time::modified-usec,time::access,time::access-usec", - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); - if (!src_info) - goto out; - - do - r = mkdir (gs_file_get_path_cached (dest), 0755); - while (G_UNLIKELY (r == -1 && errno == EINTR)); - if (r == -1) - { - _set_error_from_errno (error); - goto out; - } - - if (mode != GS_CP_MODE_NONE) - { - if (!gs_file_open_dir_fd (dest, &dest_dfd, - cancellable, error)) - goto out; - - do - r = fchown (dest_dfd, - g_file_info_get_attribute_uint32 (src_info, "unix::uid"), - g_file_info_get_attribute_uint32 (src_info, "unix::gid")); - while (G_UNLIKELY (r == -1 && errno == EINTR)); - if (r == -1) - { - _set_error_from_errno (error); - goto out; - } - - do - r = fchmod (dest_dfd, g_file_info_get_attribute_uint32 (src_info, "unix::mode")); - while (G_UNLIKELY (r == -1 && errno == EINTR)); - - if (!copy_xattrs_from_file_to_fd (src, dest_dfd, cancellable, error)) - goto out; - - if (dest_dfd != -1) - { - (void) close (dest_dfd); - dest_dfd = -1; - } - } - - while (TRUE) - { - GFileInfo *file_info = NULL; - GFile *src_child = NULL; - - if (!gs_file_enumerator_iterate (enumerator, &file_info, &src_child, - cancellable, error)) - goto out; - if (!file_info) - break; - - if (dest_child) g_object_unref (dest_child); - dest_child = g_file_get_child (dest, g_file_info_get_name (file_info)); - - if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) - { - if (!cp_internal (src_child, dest_child, mode, - cancellable, error)) - goto out; - } - else - { - gboolean did_link = FALSE; - (void) unlink (gs_file_get_path_cached (dest_child)); - if (mode == GS_CP_MODE_HARDLINK) - { - if (link (gs_file_get_path_cached (src_child), gs_file_get_path_cached (dest_child)) == -1) - { - if (!(errno == EMLINK || errno == EXDEV)) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - /* We failed to hardlink; fall back to copying all; this will - * affect subsequent directory copies too. - */ - mode = GS_CP_MODE_COPY_ALL; - } - else - did_link = TRUE; - } - if (!did_link) - { - GFileCopyFlags copyflags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS; - if (mode == GS_CP_MODE_COPY_ALL) - copyflags |= G_FILE_COPY_ALL_METADATA; - if (!g_file_copy (src_child, dest_child, copyflags, - cancellable, NULL, NULL, error)) - goto out; - } - } - } - - ret = TRUE; - out: - if (dest_dfd != -1) - (void) close (dest_dfd); - g_clear_object (&src_info); - g_clear_object (&enumerator); - g_clear_object (&dest_child); - return ret; -} - -/** - * gs_shutil_cp_al_or_fallback: - * @src: Source path - * @dest: Destination path - * @cancellable: - * @error: - * - * Recursively copy path @src (which must be a directory) to the - * target @dest. If possible, hardlinks are used; if a hardlink is - * not possible, a regular copy is created. Any existing files are - * overwritten. - * - * Returns: %TRUE on success - */ -gboolean -gs_shutil_cp_al_or_fallback (GFile *src, - GFile *dest, - GCancellable *cancellable, - GError **error) -{ - return cp_internal (src, dest, GS_CP_MODE_HARDLINK, - cancellable, error); -} - -/** - * gs_shutil_cp_a: - * @src: Source path - * @dest: Destination path - * @cancellable: - * @error: - * - * Recursively copy path @src (which must be a directory) to the - * target @dest. Any existing files are overwritten. - * - * Returns: %TRUE on success - */ -gboolean -gs_shutil_cp_a (GFile *src, - GFile *dest, - GCancellable *cancellable, - GError **error) -{ - return cp_internal (src, dest, GS_CP_MODE_COPY_ALL, - cancellable, error); -} - -static unsigned char -struct_stat_to_dt (struct stat *stbuf) -{ - if (S_ISDIR (stbuf->st_mode)) - return DT_DIR; - if (S_ISREG (stbuf->st_mode)) - return DT_REG; - if (S_ISCHR (stbuf->st_mode)) - return DT_CHR; - if (S_ISBLK (stbuf->st_mode)) - return DT_BLK; - if (S_ISFIFO (stbuf->st_mode)) - return DT_FIFO; - if (S_ISLNK (stbuf->st_mode)) - return DT_LNK; - if (S_ISSOCK (stbuf->st_mode)) - return DT_SOCK; - return DT_UNKNOWN; -} - -static gboolean -gs_shutil_rm_rf_children (DIR *dir, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int dfd; - DIR *child_dir = NULL; - struct dirent *dent; - union dirent_storage buf; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - goto out; - - dfd = dirfd (dir); - - while (readdir_r (dir, &buf.dent, &dent) == 0) - { - if (dent == NULL) - break; - if (dent->d_type == DT_UNKNOWN) - { - struct stat stbuf; - if (fstatat (dfd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1) - { - int errsv = errno; - if (errsv == ENOENT) - continue; - else - { - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - } - dent->d_type = struct_stat_to_dt (&stbuf); - /* Assume unknown types are just treated like regular files */ - if (dent->d_type == DT_UNKNOWN) - dent->d_type = DT_REG; - } - - if (strcmp (dent->d_name, ".") == 0 || strcmp (dent->d_name, "..") == 0) - continue; - - if (dent->d_type == DT_DIR) - { - int child_dfd = openat (dfd, dent->d_name, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); - - if (child_dfd == -1) - { - if (errno == ENOENT) - continue; - else - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - } - - child_dir = fdopendir (child_dfd); - if (!child_dir) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - - if (!gs_shutil_rm_rf_children (child_dir, cancellable, error)) - goto out; - - if (unlinkat (dfd, dent->d_name, AT_REMOVEDIR) == -1) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - - (void) closedir (child_dir); - child_dir = NULL; - } - else - { - if (unlinkat (dfd, dent->d_name, 0) == -1) - { - int errsv = errno; - if (errno != ENOENT) - { - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - } - } - } - /* Ignore error result from readdir_r, that's what others - * seem to do =( - */ - - ret = TRUE; - out: - if (child_dir) (void) closedir (child_dir); - return ret; -} - -/** - * gs_shutil_rm_rf: - * @path: A file or directory - * @cancellable: - * @error: - * - * Recursively delete the filename referenced by @path; it may be a - * file or directory. No error is thrown if @path does not exist. - */ -gboolean -gs_shutil_rm_rf (GFile *path, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int dfd = -1; - DIR *d = NULL; - - /* With O_NOFOLLOW first */ - dfd = openat (AT_FDCWD, gs_file_get_path_cached (path), - O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); - - if (dfd == -1) - { - int errsv = errno; - if (errsv == ENOENT) - { - ; - } - else if (errsv == ENOTDIR || errsv == ELOOP) - { - if (!gs_file_unlink (path, cancellable, error)) - goto out; - } - else - { - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - } - else - { - d = fdopendir (dfd); - if (!d) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - - if (!gs_shutil_rm_rf_children (d, cancellable, error)) - goto out; - - if (rmdir (gs_file_get_path_cached (path)) == -1) - { - int errsv = errno; - if (errsv != ENOENT) - { - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - } - } - - ret = TRUE; - out: - if (d) (void) closedir (d); - return ret; -} - diff --git a/libgsystem/gsystem-shutil.h b/libgsystem/gsystem-shutil.h deleted file mode 100644 index 3cdea778..00000000 --- a/libgsystem/gsystem-shutil.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_SHUTIL_H__ -#define __GSYSTEM_SHUTIL_H__ - -#include - -G_BEGIN_DECLS - -gboolean -gs_shutil_cp_al_or_fallback (GFile *src, - GFile *dest, - GCancellable *cancellable, - GError **error); - -gboolean -gs_shutil_cp_a (GFile *src, - GFile *dest, - GCancellable *cancellable, - GError **error); - -gboolean -gs_shutil_rm_rf (GFile *path, - GCancellable *cancellable, - GError **error); - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-subprocess-context-private.h b/libgsystem/gsystem-subprocess-context-private.h deleted file mode 100644 index 719df451..00000000 --- a/libgsystem/gsystem-subprocess-context-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* GIO - GLib Input, Output and Streaming Library - * - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GS_SUBPROCESS_CONTEXT_PRIVATE_H__ -#define __GS_SUBPROCESS_CONTEXT_PRIVATE_H__ - -#include "gsystem-subprocess-context.h" - -G_BEGIN_DECLS - -struct _GSSubprocessContext -{ - GObject parent; - - GSpawnFlags flags; - gchar **argv; - gboolean has_argv0; - char **envp; - char *cwd; - - GSSubprocessStreamDisposition stdin_disposition; - GSSubprocessStreamDisposition stdout_disposition; - GSSubprocessStreamDisposition stderr_disposition; - - guint keep_descriptors : 1; - guint search_path : 1; - guint search_path_from_envp : 1; - guint unused_flags : 29; - - gint stdin_fd; - gchar *stdin_path; - - gint stdout_fd; - gchar *stdout_path; - - gint stderr_fd; - gchar *stderr_path; - - GArray *postfork_close_fds; - GArray *inherit_fds; - - GSpawnChildSetupFunc child_setup_func; - gpointer child_setup_data; -}; - -G_END_DECLS - -#endif diff --git a/libgsystem/gsystem-subprocess-context.c b/libgsystem/gsystem-subprocess-context.c deleted file mode 100644 index 90ca7167..00000000 --- a/libgsystem/gsystem-subprocess-context.c +++ /dev/null @@ -1,501 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" - -#include "libgsystem.h" - -#if GLIB_CHECK_VERSION(2,34,0) - -#ifdef G_OS_UNIX -#include -#include -#include -#include -#endif - -/** - * SECTION:gssubprocesscontext - * @title: GSSubprocess Context - * @short_description: Environment options for launching a child process - * - * This class contains a set of options for launching child processes, - * such as where its standard input and output will be directed, the - * argument list, the environment, and more. - * - * While the #GSSubprocess class has high level functions covering - * popular cases, use of this class allows access to more advanced - * options. It can also be used to launch multiple subprocesses with - * a similar configuration. - * - * Since: 2.36 - */ - -#include "config.h" - -#include "gsystem-subprocess-context-private.h" -#include "gsystem-subprocess.h" - -#include - -typedef GObjectClass GSSubprocessContextClass; - -G_DEFINE_TYPE (GSSubprocessContext, gs_subprocess_context, G_TYPE_OBJECT); - -enum -{ - PROP_0, - PROP_ARGV, - N_PROPS -}; - -static GParamSpec *gs_subprocess_context_pspecs[N_PROPS]; - -/** - * gs_subprocess_context_new: - * @argv: Argument list - * - * Returns: (transfer full): A new instance of a #GSSubprocessContext. - */ -GSSubprocessContext * -gs_subprocess_context_new (gchar **argv) -{ - g_return_val_if_fail (argv != NULL && argv[0] != NULL, NULL); - - return g_object_new (GS_TYPE_SUBPROCESS_CONTEXT, - "argv", argv, - NULL); -} - -GSSubprocessContext * -gs_subprocess_context_newv (const gchar *first_arg, - ...) -{ - GSSubprocessContext *result; - va_list args; - - g_return_val_if_fail (first_arg != NULL, NULL); - - va_start (args, first_arg); - result = gs_subprocess_context_newa (first_arg, args); - va_end (args); - - return result; -} - -/** - * gs_subprocess_context_newa: - * @first_arg: First argument - * @args: a va_list - * - * Returns: (transfer full): A new instance of a #GSSubprocessContext. - */ -GSSubprocessContext * -gs_subprocess_context_newa (const gchar *first_arg, - va_list args) -{ - GSSubprocessContext *result; - GPtrArray *argv; - - g_return_val_if_fail (first_arg != NULL, NULL); - - argv = g_ptr_array_new (); - do - g_ptr_array_add (argv, (gchar*)first_arg); - while ((first_arg = va_arg (args, const gchar *)) != NULL); - g_ptr_array_add (argv, NULL); - - result = gs_subprocess_context_new ((gchar**)argv->pdata); - - return result; -} - -#ifdef G_OS_UNIX -GSSubprocessContext * -gs_subprocess_context_new_argv0 (const gchar *argv0, - gchar **argv) -{ - GSSubprocessContext *result; - GPtrArray *real_argv; - gchar **iter; - - g_return_val_if_fail (argv0 != NULL, NULL); - g_return_val_if_fail (argv != NULL && argv[0] != NULL, NULL); - - real_argv = g_ptr_array_new (); - g_ptr_array_add (real_argv, (gchar*)argv0); - for (iter = argv; *iter; iter++) - g_ptr_array_add (real_argv, (gchar*) *iter); - g_ptr_array_add (real_argv, NULL); - - result = g_object_new (GS_TYPE_SUBPROCESS_CONTEXT, - "argv", real_argv->pdata, - NULL); - result->has_argv0 = TRUE; - - return result; -} -#endif - -static void -gs_subprocess_context_init (GSSubprocessContext *self) -{ - self->stdin_fd = -1; - self->stdout_fd = -1; - self->stderr_fd = -1; - self->stdout_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT; - self->stderr_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT; - self->postfork_close_fds = g_array_new (FALSE, FALSE, sizeof (int)); - self->inherit_fds = g_array_new (FALSE, FALSE, sizeof (int)); -} - -static void -gs_subprocess_context_finalize (GObject *object) -{ - GSSubprocessContext *self = GS_SUBPROCESS_CONTEXT (object); - - g_strfreev (self->argv); - g_strfreev (self->envp); - g_free (self->cwd); - - g_free (self->stdin_path); - g_free (self->stdout_path); - g_free (self->stderr_path); - - g_array_unref (self->postfork_close_fds); - g_array_unref (self->inherit_fds); - - if (G_OBJECT_CLASS (gs_subprocess_context_parent_class)->finalize != NULL) - G_OBJECT_CLASS (gs_subprocess_context_parent_class)->finalize (object); -} - -static void -gs_subprocess_context_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GSSubprocessContext *self = GS_SUBPROCESS_CONTEXT (object); - - switch (prop_id) - { - case PROP_ARGV: - self->argv = (gchar**) g_value_dup_boxed (value); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gs_subprocess_context_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GSSubprocessContext *self = GS_SUBPROCESS_CONTEXT (object); - - switch (prop_id) - { - case PROP_ARGV: - g_value_set_boxed (value, self->argv); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gs_subprocess_context_class_init (GSSubprocessContextClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - - gobject_class->finalize = gs_subprocess_context_finalize; - gobject_class->get_property = gs_subprocess_context_get_property; - gobject_class->set_property = gs_subprocess_context_set_property; - - /** - * GSSubprocessContext:argv: - * - * Array of arguments passed to child process; must have at least - * one element. The first element has special handling - if it is - * an not absolute path ( as determined by g_path_is_absolute() ), - * then the system search path will be used. See - * %G_SPAWN_SEARCH_PATH. - * - * Note that in order to use the Unix-specific argv0 functionality, - * you must use the setter function - * gs_subprocess_context_set_args_and_argv0(). For more information - * about this, see %G_SPAWN_FILE_AND_ARGV_ZERO. - * - * Since: 2.36 - */ - gs_subprocess_context_pspecs[PROP_ARGV] = g_param_spec_boxed ("argv", "Arguments", "Arguments for child process", G_TYPE_STRV, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, N_PROPS, gs_subprocess_context_pspecs); -} - -/** - * gs_subprocess_context_argv_append: - * @self: - * @arg: An argument - * - * Append an argument to the child's argument vector. - */ -void -gs_subprocess_context_argv_append (GSSubprocessContext *self, - const gchar *arg) -{ - GPtrArray *new_argv = g_ptr_array_new (); - gchar **iter; - - for (iter = self->argv; *iter; iter++) - g_ptr_array_add (new_argv, *iter); - g_ptr_array_add (new_argv, g_strdup (arg)); - g_ptr_array_add (new_argv, NULL); - - /* Don't free elements */ - g_free (self->argv); - self->argv = (char**)g_ptr_array_free (new_argv, FALSE); -} - -/* Environment */ - -/** - * gs_subprocess_context_set_environment: - * @self: - * @environ: (array zero-terminated=1) (element-type utf8): Environment KEY=VALUE pairs - * - * Replace the environment that will be used for the child process. - * The default is to inherit the current process. - */ -void -gs_subprocess_context_set_environment (GSSubprocessContext *self, - gchar **env) -{ - g_strfreev (self->envp); - self->envp = g_strdupv (env); -} - -void -gs_subprocess_context_set_cwd (GSSubprocessContext *self, - const gchar *cwd) -{ - g_free (self->cwd); - self->cwd = g_strdup (cwd); -} - -void -gs_subprocess_context_set_keep_descriptors (GSSubprocessContext *self, - gboolean keep_descriptors) - -{ - self->keep_descriptors = keep_descriptors ? 1 : 0; -} - -void -gs_subprocess_context_set_search_path (GSSubprocessContext *self, - gboolean search_path, - gboolean search_path_from_envp) -{ - self->search_path = search_path ? 1 : 0; - self->search_path_from_envp = search_path_from_envp ? 1 : 0; -} - -void -gs_subprocess_context_set_stdin_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition) -{ - g_return_if_fail (disposition != GS_SUBPROCESS_STREAM_DISPOSITION_STDERR_MERGE); - self->stdin_disposition = disposition; -} - -void -gs_subprocess_context_set_stdout_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition) -{ - g_return_if_fail (disposition != GS_SUBPROCESS_STREAM_DISPOSITION_STDERR_MERGE); - self->stdout_disposition = disposition; -} - -void -gs_subprocess_context_set_stderr_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition) -{ - self->stderr_disposition = disposition; -} - -#ifdef G_OS_UNIX -void -gs_subprocess_context_set_stdin_file_path (GSSubprocessContext *self, - const gchar *path) -{ - self->stdin_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - g_free (self->stdin_path); - self->stdin_path = g_strdup (path); -} - -void -gs_subprocess_context_set_stdin_fd (GSSubprocessContext *self, - gint fd) -{ - self->stdin_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - self->stdin_fd = fd; -} - -void -gs_subprocess_context_set_stdout_file_path (GSSubprocessContext *self, - const gchar *path) -{ - self->stdout_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - g_free (self->stdout_path); - self->stdout_path = g_strdup (path); -} - -void -gs_subprocess_context_set_stdout_fd (GSSubprocessContext *self, - gint fd) -{ - self->stdout_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - self->stdout_fd = fd; -} - -void -gs_subprocess_context_set_stderr_file_path (GSSubprocessContext *self, - const gchar *path) -{ - self->stderr_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - g_free (self->stderr_path); - self->stderr_path = g_strdup (path); -} - -void -gs_subprocess_context_set_stderr_fd (GSSubprocessContext *self, - gint fd) -{ - self->stderr_disposition = GS_SUBPROCESS_STREAM_DISPOSITION_NULL; - self->stderr_fd = fd; -} -#endif - -#ifdef G_OS_UNIX -/** - * gs_subprocess_context_set_child_setup: (skip) - * @self: - * @child_setup: Function to call in the newly forked child, before execve() - * @user_data: Data passed to child - * - * FIXME - note extensive restricitons on GSpawnChildSetupFunc here - */ -void -gs_subprocess_context_set_child_setup (GSSubprocessContext *self, - GSpawnChildSetupFunc child_setup, - gpointer user_data) -{ - self->child_setup_func = child_setup; - self->child_setup_data = user_data; -} - -static gboolean -open_pipe_internal (GSSubprocessContext *self, - gboolean for_read, - void **out_stream, - gint *out_fdno, - GError **error) -{ - int pipefds[2]; - - g_return_val_if_fail (out_stream != NULL, FALSE); - g_return_val_if_fail (out_fdno != NULL, FALSE); - - if (!g_unix_open_pipe (pipefds, FD_CLOEXEC, error)) - return FALSE; - - if (for_read) - { - *out_stream = g_unix_input_stream_new (pipefds[0], TRUE); - *out_fdno = pipefds[1]; - } - else - { - *out_stream = g_unix_output_stream_new (pipefds[1], TRUE); - *out_fdno = pipefds[0]; - } - g_array_append_val (self->inherit_fds, *out_fdno); - g_array_append_val (self->postfork_close_fds, *out_fdno); - - return TRUE; -} - -/** - * gs_subprocess_context_open_pipe_read: - * @self: - * @out_stream: (out) (transfer full): A newly referenced output stream - * @out_fdno: (out): File descriptor number for the subprocess side of the pipe - * - * This allows you to open a pipe between the parent and child - * processes, independent of the standard streams. For this function, - * the pipe is set up so that the parent can read, and the child can - * write. For the opposite version, see - * gs_subprocess_context_open_pipe_write(). - * - * The returned @out_fdno is the file descriptor number that the child - * will see; you need to communicate this number via a separate - * channel, such as the argument list. For example, if you're using - * this pipe to send a password, provide - * --password-fd=<fdno string>. - * - * Returns: %TRUE on success, %FALSE on error (and @error will be set) - */ -gboolean -gs_subprocess_context_open_pipe_read (GSSubprocessContext *self, - GInputStream **out_stream, - gint *out_fdno, - GError **error) -{ - return open_pipe_internal (self, TRUE, (void**)out_stream, out_fdno, error); -} - -/** - * gs_subprocess_context_open_pipe_write: - * @self: - * @out_stream: (out) (transfer full): A newly referenced stream - * @out_fdno: (out): File descriptor number for the subprocess side of the pipe - * - * Like gs_subprocess_context_open_pipe_read(), but returns a writable - * channel from which the child process can read. - * - * Returns: %TRUE on success, %FALSE on error (and @error will be set) - */ -gboolean -gs_subprocess_context_open_pipe_write (GSSubprocessContext *self, - GOutputStream **out_stream, - gint *out_fdno, - GError **error) -{ - return open_pipe_internal (self, FALSE, (void**)out_stream, out_fdno, error); -} - -#endif - -#endif diff --git a/libgsystem/gsystem-subprocess-context.h b/libgsystem/gsystem-subprocess-context.h deleted file mode 100644 index b8a24012..00000000 --- a/libgsystem/gsystem-subprocess-context.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_SUBPROCESS_CONTEXT_H__ -#define __GSYSTEM_SUBPROCESS_CONTEXT_H__ - -#include - -#if GLIB_CHECK_VERSION(2,34,0) - -G_BEGIN_DECLS - -#define GS_TYPE_SUBPROCESS_CONTEXT (gs_subprocess_context_get_type ()) -#define GS_SUBPROCESS_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_SUBPROCESS_CONTEXT, GSSubprocessContext)) -#define GS_IS_SUBPROCESS_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_SUBPROCESS_CONTEXT)) - -typedef struct _GSSubprocessContext GSSubprocessContext; - -/** - * GSSubprocessStreamDisposition: - * @GS_SUBPROCESS_STREAM_DISPOSITION_NULL: Redirect to operating system's null output stream - * @GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT: Keep the stream from the parent process - * @GS_SUBPROCESS_STREAM_DISPOSITION_PIPE: Open a private unidirectional channel between the processes - * @GS_SUBPROCESS_STREAM_DISPOSITION_STDERR_MERGE: Only applicable to standard error; causes it to be merged with standard output - * - * Flags to define the behaviour of the standard input/output/error of - * a #GSSubprocess. - * - * Since: 2.36 - **/ -typedef enum { - GS_SUBPROCESS_STREAM_DISPOSITION_NULL, - GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT, - GS_SUBPROCESS_STREAM_DISPOSITION_PIPE, - GS_SUBPROCESS_STREAM_DISPOSITION_STDERR_MERGE -} GSSubprocessStreamDisposition; - -GType gs_subprocess_context_get_type (void) G_GNUC_CONST; - -GSSubprocessContext * gs_subprocess_context_new (gchar **argv); -GSSubprocessContext * gs_subprocess_context_newv (const gchar *first_arg, - ...); -GSSubprocessContext * gs_subprocess_context_newa (const gchar *first_arg, - va_list args); - -#ifdef G_OS_UNIX -GSSubprocessContext * gs_subprocess_context_new_argv0 (const gchar *argv0, - gchar **argv); -#endif - -void gs_subprocess_context_argv_append (GSSubprocessContext *self, - const gchar *arg); - -/* Environment */ - -void gs_subprocess_context_set_environment (GSSubprocessContext *self, - gchar **environ); -void gs_subprocess_context_set_cwd (GSSubprocessContext *self, - const gchar *cwd); -void gs_subprocess_context_set_keep_descriptors (GSSubprocessContext *self, - gboolean keep_descriptors); -void gs_subprocess_context_set_search_path (GSSubprocessContext *self, - gboolean search_path, - gboolean search_path_from_envp); - -/* Basic I/O control */ - -void gs_subprocess_context_set_stdin_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition); -void gs_subprocess_context_set_stdout_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition); -void gs_subprocess_context_set_stderr_disposition (GSSubprocessContext *self, - GSSubprocessStreamDisposition disposition); - -/* Extended I/O control, only available on UNIX */ - -#ifdef G_OS_UNIX -void gs_subprocess_context_set_stdin_file_path (GSSubprocessContext *self, - const gchar *path); -void gs_subprocess_context_set_stdin_fd (GSSubprocessContext *self, - gint fd); -void gs_subprocess_context_set_stdout_file_path (GSSubprocessContext *self, - const gchar *path); -void gs_subprocess_context_set_stdout_fd (GSSubprocessContext *self, - gint fd); -void gs_subprocess_context_set_stderr_file_path (GSSubprocessContext *self, - const gchar *path); -void gs_subprocess_context_set_stderr_fd (GSSubprocessContext *self, - gint fd); - -gboolean gs_subprocess_context_open_pipe_read (GSSubprocessContext *self, - GInputStream **out_stream, - gint *out_fdno, - GError **error); -gboolean gs_subprocess_context_open_pipe_write (GSSubprocessContext *self, - GOutputStream **out_stream, - gint *out_fdno, - GError **error); -#endif - -/* Child setup, only available on UNIX */ -#ifdef G_OS_UNIX -void gs_subprocess_context_set_child_setup (GSSubprocessContext *self, - GSpawnChildSetupFunc child_setup, - gpointer user_data); -#endif - -G_END_DECLS - -#endif -#endif diff --git a/libgsystem/gsystem-subprocess.c b/libgsystem/gsystem-subprocess.c deleted file mode 100644 index 4ec680f8..00000000 --- a/libgsystem/gsystem-subprocess.c +++ /dev/null @@ -1,966 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* GIO - GLib Input, Output and Streaming Library - * - * Copyright © 2012 Red Hat, Inc. - * Copyright © 2012 Canonical Limited - * - * This program 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 licence or (at - * your option) any later version. - * - * See the included COPYING file for more information. - * - * Authors: Colin Walters - * Ryan Lortie - */ - -#include "config.h" - -#define _GSYSTEM_NO_LOCAL_ALLOC -#include "libgsystem.h" - -#if GLIB_CHECK_VERSION(2,34,0) - -/** - * SECTION:gssubprocess - * @title: GSSubprocess - * @short_description: Create child processes and monitor their status - * - * This class wraps the lower-level g_spawn_async_with_pipes() API, - * providing a more modern GIO-style API, such as returning - * #GInputStream objects for child output pipes. - * - * One major advantage that GIO brings over the core GLib library is - * comprehensive API for asynchronous I/O, such - * g_output_stream_splice_async(). This makes GSubprocess - * significantly more powerful and flexible than equivalent APIs in - * some other languages such as the subprocess.py - * included with Python. For example, using #GSubprocess one could - * create two child processes, reading standard output from the first, - * processing it, and writing to the input stream of the second, all - * without blocking the main loop. - * - * Since: 2.36 - */ - -#include "config.h" - -#include "gsystem-subprocess.h" -#include "gsystem-subprocess-context-private.h" - -#include -#ifdef G_OS_UNIX -#include -#include -#include -#include -#endif -#include -#ifdef G_OS_WIN32 -#define _WIN32_WINNT 0x0500 -#include -#include "giowin32-priv.h" -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -static void initable_iface_init (GInitableIface *initable_iface); - -typedef GObjectClass GSSubprocessClass; - -#ifdef G_OS_UNIX -static void -gs_subprocess_unix_queue_waitpid (GSSubprocess *self); -#endif - -struct _GSSubprocess -{ - GObject parent; - - GSSubprocessContext *context; - GPid pid; - - guint pid_valid : 1; - guint reaped_child : 1; - guint unused : 30; - - /* These are the streams created if a pipe is requested via flags. */ - GOutputStream *stdin_pipe; - GInputStream *stdout_pipe; - GInputStream *stderr_pipe; -}; - -G_DEFINE_TYPE_WITH_CODE (GSSubprocess, gs_subprocess, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)); - -enum -{ - PROP_0, - PROP_CONTEXT, - N_PROPS -}; - -static GParamSpec *gs_subprocess_pspecs[N_PROPS]; - -static void -gs_subprocess_init (GSSubprocess *self) -{ -} - -static void -gs_subprocess_finalize (GObject *object) -{ - GSSubprocess *self = GS_SUBPROCESS (object); - - if (self->pid_valid) - { -#ifdef G_OS_UNIX - /* Here we need to actually call waitpid() to clean up the - * zombie. In case the child hasn't actually exited, defer this - * cleanup to the worker thread. - */ - if (!self->reaped_child) - gs_subprocess_unix_queue_waitpid (self); -#endif - g_spawn_close_pid (self->pid); - } - - g_clear_object (&self->stdin_pipe); - g_clear_object (&self->stdout_pipe); - g_clear_object (&self->stderr_pipe); - - if (G_OBJECT_CLASS (gs_subprocess_parent_class)->finalize != NULL) - G_OBJECT_CLASS (gs_subprocess_parent_class)->finalize (object); -} - -static void -gs_subprocess_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GSSubprocess *self = GS_SUBPROCESS (object); - - switch (prop_id) - { - case PROP_CONTEXT: - self->context = g_value_dup_object (value); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gs_subprocess_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GSSubprocess *self = GS_SUBPROCESS (object); - - switch (prop_id) - { - case PROP_CONTEXT: - g_value_set_object (value, self->context); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gs_subprocess_class_init (GSSubprocessClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - - gobject_class->finalize = gs_subprocess_finalize; - gobject_class->get_property = gs_subprocess_get_property; - gobject_class->set_property = gs_subprocess_set_property; - - /** - * GSSubprocess:context: - * - * - * Since: 2.36 - */ - gs_subprocess_pspecs[PROP_CONTEXT] = g_param_spec_object ("context", "Context", "Subprocess options", GS_TYPE_SUBPROCESS_CONTEXT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (gobject_class, N_PROPS, gs_subprocess_pspecs); -} - -#ifdef G_OS_UNIX - -static gboolean -gs_subprocess_unix_waitpid_dummy (gpointer data) -{ - return FALSE; -} - -static void -gs_subprocess_unix_queue_waitpid (GSSubprocess *self) -{ - GMainContext *worker_context; - GSource *waitpid_source; - -#ifdef GLIB_COMPILATION - worker_context = GLIB_PRIVATE_CALL (g_get_worker_context) (); -#else - worker_context = g_main_context_get_thread_default (); -#endif - waitpid_source = g_child_watch_source_new (self->pid); - g_source_set_callback (waitpid_source, gs_subprocess_unix_waitpid_dummy, NULL, NULL); - g_source_attach (waitpid_source, worker_context); - g_source_unref (waitpid_source); -} - -#endif - -static GInputStream * -platform_input_stream_from_spawn_fd (gint fd) -{ - if (fd < 0) - return NULL; - -#ifdef G_OS_UNIX - return g_unix_input_stream_new (fd, TRUE); -#else - return g_win32_input_stream_new_from_fd (fd, TRUE); -#endif -} - -static GOutputStream * -platform_output_stream_from_spawn_fd (gint fd) -{ - if (fd < 0) - return NULL; - -#ifdef G_OS_UNIX - return g_unix_output_stream_new (fd, TRUE); -#else - return g_win32_output_stream_new_from_fd (fd, TRUE); -#endif -} - -#ifdef G_OS_UNIX -static gint -unix_open_file (const char *filename, - gint mode, - GError **error) -{ - gint my_fd; - - do - my_fd = open (filename, mode | O_BINARY | O_CLOEXEC, 0666); - while (my_fd == -1 && errno == EINTR); - - /* If we return -1 we should also set the error */ - if (my_fd < 0) - { - gint saved_errno = errno; - char *display_name; - - display_name = g_filename_display_name (filename); - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno), - "Error opening file '%s': %s", display_name, - g_strerror (saved_errno)); - g_free (display_name); - /* fall through... */ - } - - return my_fd; -} -#endif - -typedef struct -{ - gint fds[3]; - GArray *inherit_fds; - GSpawnChildSetupFunc child_setup_func; - gpointer child_setup_data; -} ChildData; - -static void -child_setup (gpointer user_data) -{ - ChildData *child_data = user_data; - guint i; - gint result; - - /* We're on the child side now. "Rename" the file descriptors in - * child_data.fds[] to stdin/stdout/stderr. - * - * We don't close the originals. It's possible that the originals - * should not be closed and if they should be closed then they should - * have been created O_CLOEXEC. - */ - for (i = 0; i < 3; i++) - { - if (child_data->fds[i] != -1 && child_data->fds[i] != (int) i) - { - do - result = dup2 (child_data->fds[i], i); - while (G_UNLIKELY (result == -1 && errno == EINTR)); - } - } - - /* Unset the CLOEXEC flag for the child *should* inherit */ - for (i = 0; i < child_data->inherit_fds->len; i++) - { - int fd = g_array_index (child_data->inherit_fds, int, i); - int flags; - - do - flags = fcntl (fd, F_GETFL); - while (G_UNLIKELY (flags == -1 && errno == EINTR)); - - flags &= ~FD_CLOEXEC; - - do - result = fcntl (fd, F_SETFD, flags); - while (G_UNLIKELY (result == -1 && errno == EINTR)); - } - - if (child_data->child_setup_func) - child_data->child_setup_func (child_data->child_setup_data); -} - -static gboolean -initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - GSSubprocess *self = GS_SUBPROCESS (initable); - ChildData child_data = { { -1, -1, -1 } }; - gint *pipe_ptrs[3] = { NULL, NULL, NULL }; - gint pipe_fds[3] = { -1, -1, -1 }; - gint close_fds[3] = { -1, -1, -1 }; - GSpawnFlags spawn_flags = 0; - gboolean success = FALSE; - guint i; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - /* We must setup the three fds that will end up in the child as stdin, - * stdout and stderr. - * - * First, stdin. - */ -#ifdef G_OS_UNIX - if (self->context->stdin_fd != -1) - child_data.fds[0] = self->context->stdin_fd; - else if (self->context->stdin_path != NULL) - { - child_data.fds[0] = close_fds[0] = unix_open_file (self->context->stdin_path, - O_RDONLY, error); - if (child_data.fds[0] == -1) - goto out; - } - else -#endif - if (self->context->stdin_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_NULL) - ; /* nothing */ - else if (self->context->stdin_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT) - spawn_flags |= G_SPAWN_CHILD_INHERITS_STDIN; - else if (self->context->stdin_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_PIPE) - pipe_ptrs[0] = &pipe_fds[0]; - else - g_assert_not_reached (); - - /* Next, stdout. */ -#ifdef G_OS_UNIX - if (self->context->stdout_fd != -1) - child_data.fds[1] = self->context->stdout_fd; - else if (self->context->stdout_path != NULL) - { - child_data.fds[1] = close_fds[1] = unix_open_file (self->context->stdout_path, - O_CREAT | O_WRONLY, error); - if (child_data.fds[1] == -1) - goto out; - } - else -#endif - if (self->context->stdout_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_NULL) - spawn_flags |= G_SPAWN_STDOUT_TO_DEV_NULL; - else if (self->context->stdout_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT) - ; /* Nothing */ - else if (self->context->stdout_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_PIPE) - pipe_ptrs[1] = &pipe_fds[1]; - else - g_assert_not_reached (); - - /* Finally, stderr. */ -#ifdef G_OS_UNIX - if (self->context->stderr_fd != -1) - child_data.fds[2] = self->context->stderr_fd; - else if (self->context->stderr_path != NULL) - { - child_data.fds[2] = close_fds[2] = unix_open_file (self->context->stderr_path, - O_CREAT | O_WRONLY, error); - if (child_data.fds[2] == -1) - goto out; - } - else -#endif - if (self->context->stderr_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_NULL) - spawn_flags |= G_SPAWN_STDERR_TO_DEV_NULL; - else if (self->context->stderr_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT) - ; /* Nothing */ - else if (self->context->stderr_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_PIPE) - pipe_ptrs[2] = &pipe_fds[2]; - else if (self->context->stderr_disposition == GS_SUBPROCESS_STREAM_DISPOSITION_STDERR_MERGE) - /* This will work because stderr gets setup after stdout. */ - child_data.fds[2] = 1; - else - g_assert_not_reached (); - - child_data.inherit_fds = self->context->inherit_fds; - - if (self->context->keep_descriptors) - spawn_flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN; - - if (self->context->search_path) - spawn_flags |= G_SPAWN_SEARCH_PATH; - else if (self->context->search_path_from_envp) - spawn_flags |= G_SPAWN_SEARCH_PATH_FROM_ENVP; - else if (!g_path_is_absolute (((gchar**)self->context->argv)[0])) - spawn_flags |= G_SPAWN_SEARCH_PATH; - - if (self->context->has_argv0) - spawn_flags |= G_SPAWN_FILE_AND_ARGV_ZERO; - - spawn_flags |= G_SPAWN_DO_NOT_REAP_CHILD; -#ifdef GLIB_COMPILATION - spawn_flags |= G_SPAWN_CLOEXEC_PIPES; -#endif - - child_data.child_setup_func = self->context->child_setup_func; - child_data.child_setup_data = self->context->child_setup_data; - success = g_spawn_async_with_pipes (self->context->cwd, - (char**)self->context->argv, - self->context->envp, - spawn_flags, - child_setup, &child_data, - &self->pid, - pipe_ptrs[0], pipe_ptrs[1], pipe_ptrs[2], - error); - if (success) - self->pid_valid = TRUE; - -out: - for (i = 0; i < 3; i++) - if (close_fds[i] != -1) - close (close_fds[i]); - - for (i = 0; i < self->context->postfork_close_fds->len; i++) - (void) close (g_array_index (self->context->postfork_close_fds, int, i)); - - self->stdin_pipe = platform_output_stream_from_spawn_fd (pipe_fds[0]); - self->stdout_pipe = platform_input_stream_from_spawn_fd (pipe_fds[1]); - self->stderr_pipe = platform_input_stream_from_spawn_fd (pipe_fds[2]); - - return success; -} - -static void -initable_iface_init (GInitableIface *initable_iface) -{ - initable_iface->init = initable_init; -} - -/** - * gs_subprocess_new: - * - * Create a new process, using the parameters specified by - * GSSubprocessContext. - * - * Returns: (transfer full): A newly created %GSSubprocess, or %NULL on error (and @error will be set) - * - * Since: 2.36 - */ -GSSubprocess * -gs_subprocess_new (GSSubprocessContext *context, - GCancellable *cancellable, - GError **error) -{ - return g_initable_new (GS_TYPE_SUBPROCESS, - cancellable, error, - "context", context, - NULL); -} - -/** - * gs_subprocess_get_pid: - * @self: a #GSSubprocess - * - * The identifier for this child process; it is valid as long as the - * process @self is referenced. In particular, do - * not call g_spawn_close_pid() on this value; - * that is handled internally. - * - * On some Unix versions, it is possible for there to be a race - * condition where waitpid() may have been called to collect the child - * before any watches (such as that installed by - * gs_subprocess_add_watch()) have fired. If you are planning to use - * native functions such as kill() on the pid, your program should - * gracefully handle an %ESRCH result to mitigate this. - * - * If you want to request process termination, using the high level - * gs_subprocess_request_exit() and gs_subprocess_force_exit() API is - * recommended. - * - * Returns: Operating-system specific identifier for child process - * - * Since: 2.36 - */ -GPid -gs_subprocess_get_pid (GSSubprocess *self) -{ - g_return_val_if_fail (GS_IS_SUBPROCESS (self), 0); - - return self->pid; -} - -/** - * gs_subprocess_get_stdin_pipe: - * - * Returns: (transfer none): Pipe - */ -GOutputStream * -gs_subprocess_get_stdin_pipe (GSSubprocess *self) -{ - g_return_val_if_fail (GS_IS_SUBPROCESS (self), NULL); - g_return_val_if_fail (self->stdin_pipe, NULL); - - return self->stdin_pipe; -} - -/** - * gs_subprocess_get_stdout_pipe: - * - * Returns: (transfer none): Pipe - */ -GInputStream * -gs_subprocess_get_stdout_pipe (GSSubprocess *self) -{ - g_return_val_if_fail (GS_IS_SUBPROCESS (self), NULL); - g_return_val_if_fail (self->stdout_pipe, NULL); - - return self->stdout_pipe; -} - -/** - * gs_subprocess_get_stderr_pipe: - * - * Returns: (transfer none): Pipe - */ -GInputStream * -gs_subprocess_get_stderr_pipe (GSSubprocess *self) -{ - g_return_val_if_fail (GS_IS_SUBPROCESS (self), NULL); - g_return_val_if_fail (self->stderr_pipe, NULL); - - return self->stderr_pipe; -} - -typedef struct { - GSSubprocess *self; - GCancellable *cancellable; - GSimpleAsyncResult *result; -} GSSubprocessWatchData; - -static gboolean -gs_subprocess_on_child_exited (GPid pid, - gint status_code, - gpointer user_data) -{ - GSSubprocessWatchData *data = user_data; - GError *error = NULL; - - if (g_cancellable_set_error_if_cancelled (data->cancellable, &error)) - { - g_simple_async_result_take_error (data->result, error); - } - else - { - data->self->reaped_child = TRUE; - - g_simple_async_result_set_op_res_gssize (data->result, status_code); - } - - g_simple_async_result_complete (data->result); - - g_object_unref (data->result); - g_object_unref (data->self); - g_free (data); - - return FALSE; -} - -/** - * gs_subprocess_wait: - * @self: a #GSSubprocess - * @cancellable: a #GCancellable - * @callback: Invoked when process exits, or @cancellable is cancelled - * @user_data: Data for @callback - * - * Start an asynchronous wait for the subprocess @self to exit. - * - * Since: 2.36 - */ -void -gs_subprocess_wait (GSSubprocess *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSource *source; - GSSubprocessWatchData *data; - - data = g_new0 (GSSubprocessWatchData, 1); - - data->self = g_object_ref (self); - data->result = g_simple_async_result_new ((GObject*)self, callback, user_data, - gs_subprocess_wait); - - source = g_child_watch_source_new (self->pid); - - g_source_set_callback (source, (GSourceFunc)gs_subprocess_on_child_exited, - data, NULL); - if (cancellable) - { - GSource *cancellable_source; - - data->cancellable = g_object_ref (cancellable); - - cancellable_source = g_cancellable_source_new (cancellable); - g_source_add_child_source (source, cancellable_source); - g_source_unref (cancellable_source); - } - - g_source_attach (source, g_main_context_get_thread_default ()); - g_source_unref (source); -} - -/** - * gs_subprocess_wait_finish: - * @self: a #GSSubprocess - * @result: a #GAsyncResult - * @out_exit_status: (out): Exit status of the process encoded in platform-specific way - * @error: a #GError - * - * The exit status of the process will be stored in @out_exit_status. - * See the documentation of g_spawn_check_exit_status() for more - * details. - * - * Note that @error is not set if the process exits abnormally; you - * must use g_spawn_check_exit_status() for that. - * - * Since: 2.36 - */ -gboolean -gs_subprocess_wait_finish (GSSubprocess *self, - GAsyncResult *result, - int *out_exit_status, - GError **error) -{ - GSimpleAsyncResult *simple; - - simple = G_SIMPLE_ASYNC_RESULT (result); - - if (g_simple_async_result_propagate_error (simple, error)) - return FALSE; - - *out_exit_status = g_simple_async_result_get_op_res_gssize (simple); - - return TRUE; -} - -typedef struct { - GMainLoop *loop; - gint *exit_status_ptr; - gboolean caught_error; - GError **error; -} GSSubprocessSyncWaitData; - -static void -gs_subprocess_on_sync_wait_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - GSSubprocessSyncWaitData *data = user_data; - - if (!gs_subprocess_wait_finish ((GSSubprocess*)object, result, - data->exit_status_ptr, data->error)) - data->caught_error = TRUE; - - g_main_loop_quit (data->loop); -} - -/** - * gs_subprocess_wait_sync: - * @self: a #GSSubprocess - * @out_exit_status: (out): Platform-specific exit code - * @cancellable: a #GCancellable - * @error: a #GError - * - * Synchronously wait for the subprocess to terminate, returning the - * status code in @out_exit_status. See the documentation of - * g_spawn_check_exit_status() for how to interpret it. Note that if - * @error is set, then @out_exit_status will be left uninitialized. - * - * Returns: %TRUE on success, %FALSE if @cancellable was cancelled - * - * Since: 2.36 - */ -gboolean -gs_subprocess_wait_sync (GSSubprocess *self, - int *out_exit_status, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - gboolean pushed_thread_default = FALSE; - GMainContext *context = NULL; - GSSubprocessSyncWaitData data; - - memset (&data, 0, sizeof (data)); - - g_return_val_if_fail (GS_IS_SUBPROCESS (self), FALSE); - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - context = g_main_context_new (); - g_main_context_push_thread_default (context); - pushed_thread_default = TRUE; - - data.exit_status_ptr = out_exit_status; - data.loop = g_main_loop_new (context, TRUE); - data.error = error; - - gs_subprocess_wait (self, cancellable, - gs_subprocess_on_sync_wait_complete, &data); - - g_main_loop_run (data.loop); - - if (data.caught_error) - goto out; - - ret = TRUE; - out: - if (pushed_thread_default) - g_main_context_pop_thread_default (context); - if (context) - g_main_context_unref (context); - if (data.loop) - g_main_loop_unref (data.loop); - - return ret; -} - -/** - * gs_subprocess_wait_sync_check: - * @self: a #GSSubprocess - * @cancellable: a #GCancellable - * @error: a #GError - * - * Combines gs_subprocess_wait_sync() with g_spawn_check_exit_status(). - * - * Returns: %TRUE on success, %FALSE if process exited abnormally, or @cancellable was cancelled - * - * Since: 2.36 - */ -gboolean -gs_subprocess_wait_sync_check (GSSubprocess *self, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - int exit_status; - - if (!gs_subprocess_wait_sync (self, &exit_status, cancellable, error)) - goto out; - - if (!g_spawn_check_exit_status (exit_status, error)) - goto out; - - ret = TRUE; - out: - return ret; -} - -/** - * gs_subprocess_request_exit: - * @self: a #GSSubprocess - * - * This API uses an operating-system specific mechanism to request - * that the subprocess gracefully exit. This API is not available on - * all operating systems; for those not supported, it will do nothing - * and return %FALSE. Portable code should handle this situation - * gracefully. For example, if you are communicating via input or - * output pipe with the child, many programs will automatically exit - * when one of their standard input or output are closed. - * - * On Unix, this API sends %SIGTERM. - * - * A %TRUE return value does not mean the - * subprocess has exited, merely that an exit request was initiated. - * You can use gs_subprocess_add_watch() to monitor the status of the - * process after calling this function. - * - * This function returns %TRUE if the process has already exited. - * - * Returns: %TRUE if the operation is supported, %FALSE otherwise. - * - * Since: 2.36 - */ -gboolean -gs_subprocess_request_exit (GSSubprocess *self) -{ - g_return_val_if_fail (GS_IS_SUBPROCESS (self), FALSE); - -#ifdef G_OS_UNIX - (void) kill (self->pid, SIGTERM); - return TRUE; -#else - return FALSE; -#endif -} - -/** - * gs_subprocess_force_exit: - * @self: a #GSSubprocess - * - * Use an operating-system specific method to attempt an immediate, - * forceful termination of the process. There is no mechanism to - * determine whether or not the request itself was successful; - * however, you can use gs_subprocess_wait() to monitor the status of - * the process after calling this function. - * - * On Unix, this function sends %SIGKILL. - */ -void -gs_subprocess_force_exit (GSSubprocess *self) -{ - g_return_if_fail (GS_IS_SUBPROCESS (self)); - -#if !defined(GLIB_COMPIATION) - { - int ret; - do - ret = kill (self->pid, SIGKILL); - while (ret == -1 && errno == EINTR); - } -#elif defined(G_OS_UNIX) - GLIB_PRIVATE_CALL (g_main_send_signal) (self->pid, SIGKILL); -#else - TerminateProcess (self->pid, 1); -#endif -} - -GSSubprocess * -gs_subprocess_new_simple_argl (GSSubprocessStreamDisposition stdout_disposition, - GSSubprocessStreamDisposition stderr_disposition, - GCancellable *cancellable, - GError **error, - const gchar *first_arg, - ...) -{ - va_list args; - GSSubprocess *result; - GSSubprocessContext *context; - - va_start (args, first_arg); - context = gs_subprocess_context_newa (first_arg, args); - va_end (args); - result = gs_subprocess_new (context, cancellable, error); - g_object_unref (context); - - return result; -} - -/** - * gs_subprocess_new_simple_argv: - * @argv: (array zero-terminated=1) (element-type utf8): Argument array - * @stdout_disposition: Where to redirect stdout - * @stderr_disposition: Where to redirect stdout - * @error: a #GError - * - * Create a new subprocess using the provided argument array and - * stream dispositions. - */ -GSSubprocess * -gs_subprocess_new_simple_argv (gchar **argv, - GSSubprocessStreamDisposition stdout_disposition, - GSSubprocessStreamDisposition stderr_disposition, - GCancellable *cancellable, - GError **error) -{ - GSSubprocessContext *context; - GSSubprocess *result; - - context = gs_subprocess_context_new (argv); - gs_subprocess_context_set_stdout_disposition (context, stdout_disposition); - gs_subprocess_context_set_stderr_disposition (context, stderr_disposition); - - result = gs_subprocess_new (context, cancellable, error); - g_object_unref (context); - - return result; -} - -/** - * gs_subprocess_simple_run_sync: - * @cwd: Current working directory - * @stdin_disposition: What to do with standard input - * @cancellable: a #GCancellable - * @error: a #GError - * @first_arg: First argument - * @...: Remaining arguments, %NULL terminated - * - * Run a process synchronously, throw an error if it fails. - */ -gboolean -gs_subprocess_simple_run_sync (const char *cwd, - GSSubprocessStreamDisposition stdin_disposition, - GCancellable *cancellable, - GError **error, - const char *first_arg, - ...) -{ - gboolean ret = FALSE; - va_list args; - GSSubprocess *proc = NULL; - GSSubprocessContext *context = NULL; - - va_start (args, first_arg); - context = gs_subprocess_context_newa (first_arg, args); - va_end (args); - gs_subprocess_context_set_stdin_disposition (context, stdin_disposition); - gs_subprocess_context_set_cwd (context, cwd); - proc = gs_subprocess_new (context, cancellable, error); - if (!proc) - goto out; - - if (!gs_subprocess_wait_sync_check (proc, cancellable, error)) - goto out; - - ret = TRUE; - out: - g_object_unref (context); - if (proc) - g_object_unref (proc); - return ret; -} - -#endif diff --git a/libgsystem/gsystem-subprocess.h b/libgsystem/gsystem-subprocess.h deleted file mode 100644 index f248f7ba..00000000 --- a/libgsystem/gsystem-subprocess.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GSYSTEM_SUBPROCESS_H__ -#define __GSYSTEM_SUBPROCESS_H__ - -#include - -#if GLIB_CHECK_VERSION(2,34,0) - -#include "gsystem-subprocess-context.h" - -G_BEGIN_DECLS - -#define GS_TYPE_SUBPROCESS (gs_subprocess_get_type ()) -#define GS_SUBPROCESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_SUBPROCESS, GSSubprocess)) -#define GS_IS_SUBPROCESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_SUBPROCESS)) - -typedef struct _GSSubprocess GSSubprocess; - -GType gs_subprocess_get_type (void) G_GNUC_CONST; - -/**** Core API ****/ - -GSSubprocess * gs_subprocess_new (GSSubprocessContext *context, - GCancellable *cancellable, - GError **error); - -GOutputStream * gs_subprocess_get_stdin_pipe (GSSubprocess *self); - -GInputStream * gs_subprocess_get_stdout_pipe (GSSubprocess *self); - -GInputStream * gs_subprocess_get_stderr_pipe (GSSubprocess *self); - -void gs_subprocess_wait (GSSubprocess *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean gs_subprocess_wait_finish (GSSubprocess *self, - GAsyncResult *result, - int *out_exit_status, - GError **error); - -gboolean gs_subprocess_wait_sync (GSSubprocess *self, - int *out_exit_status, - GCancellable *cancellable, - GError **error); - -gboolean gs_subprocess_wait_sync_check (GSSubprocess *self, - GCancellable *cancellable, - GError **error); - -GPid gs_subprocess_get_pid (GSSubprocess *self); - -gboolean gs_subprocess_request_exit (GSSubprocess *self); - -void gs_subprocess_force_exit (GSSubprocess *self); - -/**** High level helpers ****/ - -GSSubprocess * gs_subprocess_new_simple_argl (GSSubprocessStreamDisposition stdout_disposition, - GSSubprocessStreamDisposition stderr_disposition, - GCancellable *cancellable, - GError **error, - const char *first_arg, - ...) G_GNUC_NULL_TERMINATED; -GSSubprocess * gs_subprocess_new_simple_argv (char **argv, - GSSubprocessStreamDisposition stdout_disposition, - GSSubprocessStreamDisposition stderr_disposition, - GCancellable *cancellable, - GError **error); - -gboolean gs_subprocess_simple_run_sync (const char *cwd, - GSSubprocessStreamDisposition stdin_disposition, - GCancellable *cancellable, - GError **error, - const char *first_arg, - ...) G_GNUC_NULL_TERMINATED; - -G_END_DECLS - -#endif -#endif diff --git a/libgsystem/libgsystem.h b/libgsystem/libgsystem.h deleted file mode 100644 index 60884b65..00000000 --- a/libgsystem/libgsystem.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2012,2013 Colin Walters . - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __LIBGSYSTEM__ -#define __LIBGSYSTEM__ - -#include - -G_BEGIN_DECLS - -#define gs_transfer_out_value(outp, srcp) G_STMT_START { \ - if (outp) \ - { \ - *(outp) = *(srcp); \ - *(srcp) = NULL; \ - } \ - } G_STMT_END; - -#include -#include -#include -#if GLIB_CHECK_VERSION(2,34,0) -#include -#endif -#include -#ifndef _GSYSTEM_NO_LOCAL_ALLOC -#include -#endif - -G_END_DECLS - -#endif diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am new file mode 100644 index 00000000..8fab84bc --- /dev/null +++ b/libnm-core/Makefile.am @@ -0,0 +1,48 @@ +include $(GLIB_MAKEFILE) + +SUBDIRS = . tests + +AM_CPPFLAGS = \ + -I${top_srcdir}/include \ + -DG_LOG_DOMAIN=\""libnm"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) + +noinst_LTLIBRARIES = libnm-core.la + +# header/source defines are in Makefile.libnm-core, so they can be shared +# with libnm/Makefile.am +include Makefile.libnm-core + +libnmincludedir = $(includedir)/libnm + +libnminclude_HEADERS = $(libnm_core_headers) +libnm_core_la_SOURCES = \ + $(libnm_core_sources) \ + $(libnm_core_private_headers) + +GLIB_GENERATED = nm-core-enum-types.h nm-core-enum-types.c +nm_core_enum_types_sources = $(notdir $(libnminclude_HEADERS)) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM + +libnm_core_la_LIBADD = \ + $(GLIB_LIBS) \ + $(UUID_LIBS) + +if WITH_GNUTLS +AM_CPPFLAGS += $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +libnm_core_la_SOURCES += crypto_gnutls.c +libnm_core_la_LIBADD += $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) +endif + +if WITH_NSS +AM_CPPFLAGS += $(NSS_CFLAGS) +libnm_core_la_SOURCES += crypto_nss.c +libnm_core_la_LIBADD += $(NSS_LIBS) +endif + +BUILT_SOURCES = $(GLIB_GENERATED) +CLEANFILES = $(BUILT_SOURCES) diff --git a/libnm-core/Makefile.in b/libnm-core/Makefile.in new file mode 100644 index 00000000..8ec1414e --- /dev/null +++ b/libnm-core/Makefile.in @@ -0,0 +1,1350 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ + +# In order for this to work correctly from both libnm-core/ and libnm/, +# we have to specify full pathnames. (We can't just use $(addprefix) from +# libnm/, because that's incompatible with the Makefile.introspection rules.) + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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@ +DIST_COMMON = $(srcdir)/Makefile.libnm-core $(srcdir)/Makefile.in \ + $(srcdir)/Makefile.am $(srcdir)/nm-version.h.in \ + $(top_srcdir)/build-aux/depcomp $(libnminclude_HEADERS) +@WITH_GNUTLS_TRUE@am__append_1 = $(LIBGCRYPT_CFLAGS) $(GNUTLS_CFLAGS) +@WITH_GNUTLS_TRUE@am__append_2 = crypto_gnutls.c +@WITH_GNUTLS_TRUE@am__append_3 = $(LIBGCRYPT_LIBS) $(GNUTLS_LIBS) +@WITH_NSS_TRUE@am__append_4 = $(NSS_CFLAGS) +@WITH_NSS_TRUE@am__append_5 = crypto_nss.c +@WITH_NSS_TRUE@am__append_6 = $(NSS_LIBS) +subdir = libnm-core +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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 = nm-version.h +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +@WITH_GNUTLS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \ +@WITH_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) +@WITH_NSS_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) +libnm_core_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) +am__libnm_core_la_SOURCES_DIST = $(core_build)/nm-core-enum-types.c \ + $(core)/crypto.c $(core)/nm-connection.c $(core)/nm-errors.c \ + $(core)/nm-property-compare.c $(core)/nm-setting-8021x.c \ + $(core)/nm-setting-adsl.c $(core)/nm-setting-bluetooth.c \ + $(core)/nm-setting-bond.c $(core)/nm-setting-bridge-port.c \ + $(core)/nm-setting-bridge.c $(core)/nm-setting-cdma.c \ + $(core)/nm-setting-connection.c $(core)/nm-setting-dcb.c \ + $(core)/nm-setting-generic.c $(core)/nm-setting-gsm.c \ + $(core)/nm-setting-infiniband.c $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip4-config.c \ + $(core)/nm-setting-ip6-config.c $(core)/nm-setting-olpc-mesh.c \ + $(core)/nm-setting-ppp.c $(core)/nm-setting-pppoe.c \ + $(core)/nm-setting-serial.c $(core)/nm-setting-team-port.c \ + $(core)/nm-setting-team.c $(core)/nm-setting-vlan.c \ + $(core)/nm-setting-vpn.c $(core)/nm-setting-wimax.c \ + $(core)/nm-setting-wired.c \ + $(core)/nm-setting-wireless-security.c \ + $(core)/nm-setting-wireless.c $(core)/nm-setting.c \ + $(core)/nm-simple-connection.c $(core)/nm-utils.c \ + $(core)/crypto.h $(core)/nm-connection-private.h \ + $(core)/nm-core-internal.h $(core)/nm-property-compare.h \ + $(core)/nm-setting-private.h $(core)/nm-utils-private.h \ + crypto_gnutls.c crypto_nss.c +am__objects_1 = nm-core-enum-types.lo crypto.lo nm-connection.lo \ + nm-errors.lo nm-property-compare.lo nm-setting-8021x.lo \ + nm-setting-adsl.lo nm-setting-bluetooth.lo nm-setting-bond.lo \ + nm-setting-bridge-port.lo nm-setting-bridge.lo \ + nm-setting-cdma.lo nm-setting-connection.lo nm-setting-dcb.lo \ + nm-setting-generic.lo nm-setting-gsm.lo \ + nm-setting-infiniband.lo nm-setting-ip-config.lo \ + nm-setting-ip4-config.lo nm-setting-ip6-config.lo \ + nm-setting-olpc-mesh.lo nm-setting-ppp.lo nm-setting-pppoe.lo \ + nm-setting-serial.lo nm-setting-team-port.lo \ + nm-setting-team.lo nm-setting-vlan.lo nm-setting-vpn.lo \ + nm-setting-wimax.lo nm-setting-wired.lo \ + nm-setting-wireless-security.lo nm-setting-wireless.lo \ + nm-setting.lo nm-simple-connection.lo nm-utils.lo +am__objects_2 = +@WITH_GNUTLS_TRUE@am__objects_3 = crypto_gnutls.lo +@WITH_NSS_TRUE@am__objects_4 = crypto_nss.lo +am_libnm_core_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) +libnm_core_la_OBJECTS = $(am_libnm_core_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libnm_core_la_SOURCES) +DIST_SOURCES = $(am__libnm_core_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +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__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libnmincludedir)" +HEADERS = $(libnminclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +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@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +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@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +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@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +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@ +PERL = @PERL@ +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_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +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_CXX = @ac_ct_CXX@ +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@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +SUBDIRS = . tests +AM_CPPFLAGS = -I${top_srcdir}/include -DG_LOG_DOMAIN=\""libnm"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(GLIB_CFLAGS) \ + $(am__append_1) $(am__append_4) +noinst_LTLIBRARIES = libnm-core.la +core = $(top_srcdir)/libnm-core +core_build = $(top_builddir)/libnm-core +libnm_core_headers = \ + $(core_build)/nm-core-enum-types.h \ + $(core_build)/nm-version.h \ + $(core)/nm-connection.h \ + $(core)/nm-core-types.h \ + $(core)/nm-dbus-interface.h \ + $(core)/nm-errors.h \ + $(core)/nm-setting-8021x.h \ + $(core)/nm-setting-adsl.h \ + $(core)/nm-setting-bluetooth.h \ + $(core)/nm-setting-bond.h \ + $(core)/nm-setting-bridge-port.h \ + $(core)/nm-setting-bridge.h \ + $(core)/nm-setting-cdma.h \ + $(core)/nm-setting-connection.h \ + $(core)/nm-setting-dcb.h \ + $(core)/nm-setting-generic.h \ + $(core)/nm-setting-gsm.h \ + $(core)/nm-setting-infiniband.h \ + $(core)/nm-setting-ip-config.h \ + $(core)/nm-setting-ip4-config.h \ + $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-olpc-mesh.h \ + $(core)/nm-setting-ppp.h \ + $(core)/nm-setting-pppoe.h \ + $(core)/nm-setting-serial.h \ + $(core)/nm-setting-team-port.h \ + $(core)/nm-setting-team.h \ + $(core)/nm-setting-vlan.h \ + $(core)/nm-setting-vpn.h \ + $(core)/nm-setting-wimax.h \ + $(core)/nm-setting-wired.h \ + $(core)/nm-setting-wireless-security.h \ + $(core)/nm-setting-wireless.h \ + $(core)/nm-setting.h \ + $(core)/nm-simple-connection.h \ + $(core)/nm-utils.h \ + $(core)/nm-vpn-dbus-interface.h + +libnm_core_private_headers = \ + $(core)/crypto.h \ + $(core)/nm-connection-private.h \ + $(core)/nm-core-internal.h \ + $(core)/nm-property-compare.h \ + $(core)/nm-setting-private.h \ + $(core)/nm-utils-private.h + +libnm_core_sources = \ + $(core_build)/nm-core-enum-types.c \ + $(core)/crypto.c \ + $(core)/nm-connection.c \ + $(core)/nm-errors.c \ + $(core)/nm-property-compare.c \ + $(core)/nm-setting-8021x.c \ + $(core)/nm-setting-adsl.c \ + $(core)/nm-setting-bluetooth.c \ + $(core)/nm-setting-bond.c \ + $(core)/nm-setting-bridge-port.c \ + $(core)/nm-setting-bridge.c \ + $(core)/nm-setting-cdma.c \ + $(core)/nm-setting-connection.c \ + $(core)/nm-setting-dcb.c \ + $(core)/nm-setting-generic.c \ + $(core)/nm-setting-gsm.c \ + $(core)/nm-setting-infiniband.c \ + $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip4-config.c \ + $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-olpc-mesh.c \ + $(core)/nm-setting-ppp.c \ + $(core)/nm-setting-pppoe.c \ + $(core)/nm-setting-serial.c \ + $(core)/nm-setting-team-port.c \ + $(core)/nm-setting-team.c \ + $(core)/nm-setting-vlan.c \ + $(core)/nm-setting-vpn.c \ + $(core)/nm-setting-wimax.c \ + $(core)/nm-setting-wired.c \ + $(core)/nm-setting-wireless-security.c \ + $(core)/nm-setting-wireless.c \ + $(core)/nm-setting.c \ + $(core)/nm-simple-connection.c \ + $(core)/nm-utils.c + + +# header/source defines are in Makefile.libnm-core, so they can be shared +# with libnm/Makefile.am +libnmincludedir = $(includedir)/libnm +libnminclude_HEADERS = $(libnm_core_headers) +libnm_core_la_SOURCES = $(libnm_core_sources) \ + $(libnm_core_private_headers) $(am__append_2) $(am__append_5) +GLIB_GENERATED = nm-core-enum-types.h nm-core-enum-types.c +nm_core_enum_types_sources = $(notdir $(libnminclude_HEADERS)) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +libnm_core_la_LIBADD = $(GLIB_LIBS) $(UUID_LIBS) $(am__append_3) \ + $(am__append_6) +BUILT_SOURCES = $(GLIB_GENERATED) +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 $(srcdir)/Makefile.libnm-core $(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 libnm-core/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libnm-core/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; +$(srcdir)/Makefile.libnm-core: + +$(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): +nm-version.h: $(top_builddir)/config.status $(srcdir)/nm-version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libnm-core.la: $(libnm_core_la_OBJECTS) $(libnm_core_la_DEPENDENCIES) $(EXTRA_libnm_core_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libnm_core_la_OBJECTS) $(libnm_core_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_gnutls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_nss.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-core-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-errors.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-property-compare.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-8021x.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-adsl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-bluetooth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-bond.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-bridge-port.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-bridge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-cdma.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-dcb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-generic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-gsm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-infiniband.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip4-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ip6-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-olpc-mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-ppp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-pppoe.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-serial.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-team-port.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-vlan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-vpn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wimax.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wired.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wireless-security.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting-wireless.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-setting.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-simple-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-utils.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +nm-core-enum-types.lo: $(core_build)/nm-core-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-core-enum-types.lo -MD -MP -MF $(DEPDIR)/nm-core-enum-types.Tpo -c -o nm-core-enum-types.lo `test -f '$(core_build)/nm-core-enum-types.c' || echo '$(srcdir)/'`$(core_build)/nm-core-enum-types.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-core-enum-types.Tpo $(DEPDIR)/nm-core-enum-types.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core_build)/nm-core-enum-types.c' object='nm-core-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-core-enum-types.lo `test -f '$(core_build)/nm-core-enum-types.c' || echo '$(srcdir)/'`$(core_build)/nm-core-enum-types.c + +crypto.lo: $(core)/crypto.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto.lo -MD -MP -MF $(DEPDIR)/crypto.Tpo -c -o crypto.lo `test -f '$(core)/crypto.c' || echo '$(srcdir)/'`$(core)/crypto.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/crypto.Tpo $(DEPDIR)/crypto.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/crypto.c' object='crypto.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto.lo `test -f '$(core)/crypto.c' || echo '$(srcdir)/'`$(core)/crypto.c + +nm-connection.lo: $(core)/nm-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-connection.lo -MD -MP -MF $(DEPDIR)/nm-connection.Tpo -c -o nm-connection.lo `test -f '$(core)/nm-connection.c' || echo '$(srcdir)/'`$(core)/nm-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-connection.Tpo $(DEPDIR)/nm-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-connection.c' object='nm-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-connection.lo `test -f '$(core)/nm-connection.c' || echo '$(srcdir)/'`$(core)/nm-connection.c + +nm-errors.lo: $(core)/nm-errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-errors.lo -MD -MP -MF $(DEPDIR)/nm-errors.Tpo -c -o nm-errors.lo `test -f '$(core)/nm-errors.c' || echo '$(srcdir)/'`$(core)/nm-errors.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-errors.Tpo $(DEPDIR)/nm-errors.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-errors.c' object='nm-errors.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-errors.lo `test -f '$(core)/nm-errors.c' || echo '$(srcdir)/'`$(core)/nm-errors.c + +nm-property-compare.lo: $(core)/nm-property-compare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-property-compare.lo -MD -MP -MF $(DEPDIR)/nm-property-compare.Tpo -c -o nm-property-compare.lo `test -f '$(core)/nm-property-compare.c' || echo '$(srcdir)/'`$(core)/nm-property-compare.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-property-compare.Tpo $(DEPDIR)/nm-property-compare.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-property-compare.c' object='nm-property-compare.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-property-compare.lo `test -f '$(core)/nm-property-compare.c' || echo '$(srcdir)/'`$(core)/nm-property-compare.c + +nm-setting-8021x.lo: $(core)/nm-setting-8021x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-8021x.lo -MD -MP -MF $(DEPDIR)/nm-setting-8021x.Tpo -c -o nm-setting-8021x.lo `test -f '$(core)/nm-setting-8021x.c' || echo '$(srcdir)/'`$(core)/nm-setting-8021x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-8021x.Tpo $(DEPDIR)/nm-setting-8021x.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-8021x.c' object='nm-setting-8021x.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-8021x.lo `test -f '$(core)/nm-setting-8021x.c' || echo '$(srcdir)/'`$(core)/nm-setting-8021x.c + +nm-setting-adsl.lo: $(core)/nm-setting-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-adsl.lo -MD -MP -MF $(DEPDIR)/nm-setting-adsl.Tpo -c -o nm-setting-adsl.lo `test -f '$(core)/nm-setting-adsl.c' || echo '$(srcdir)/'`$(core)/nm-setting-adsl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-adsl.Tpo $(DEPDIR)/nm-setting-adsl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-adsl.c' object='nm-setting-adsl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-adsl.lo `test -f '$(core)/nm-setting-adsl.c' || echo '$(srcdir)/'`$(core)/nm-setting-adsl.c + +nm-setting-bluetooth.lo: $(core)/nm-setting-bluetooth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-bluetooth.lo -MD -MP -MF $(DEPDIR)/nm-setting-bluetooth.Tpo -c -o nm-setting-bluetooth.lo `test -f '$(core)/nm-setting-bluetooth.c' || echo '$(srcdir)/'`$(core)/nm-setting-bluetooth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-bluetooth.Tpo $(DEPDIR)/nm-setting-bluetooth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-bluetooth.c' object='nm-setting-bluetooth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-bluetooth.lo `test -f '$(core)/nm-setting-bluetooth.c' || echo '$(srcdir)/'`$(core)/nm-setting-bluetooth.c + +nm-setting-bond.lo: $(core)/nm-setting-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-bond.lo -MD -MP -MF $(DEPDIR)/nm-setting-bond.Tpo -c -o nm-setting-bond.lo `test -f '$(core)/nm-setting-bond.c' || echo '$(srcdir)/'`$(core)/nm-setting-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-bond.Tpo $(DEPDIR)/nm-setting-bond.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-bond.c' object='nm-setting-bond.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-bond.lo `test -f '$(core)/nm-setting-bond.c' || echo '$(srcdir)/'`$(core)/nm-setting-bond.c + +nm-setting-bridge-port.lo: $(core)/nm-setting-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-bridge-port.lo -MD -MP -MF $(DEPDIR)/nm-setting-bridge-port.Tpo -c -o nm-setting-bridge-port.lo `test -f '$(core)/nm-setting-bridge-port.c' || echo '$(srcdir)/'`$(core)/nm-setting-bridge-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-bridge-port.Tpo $(DEPDIR)/nm-setting-bridge-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-bridge-port.c' object='nm-setting-bridge-port.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-bridge-port.lo `test -f '$(core)/nm-setting-bridge-port.c' || echo '$(srcdir)/'`$(core)/nm-setting-bridge-port.c + +nm-setting-bridge.lo: $(core)/nm-setting-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-bridge.lo -MD -MP -MF $(DEPDIR)/nm-setting-bridge.Tpo -c -o nm-setting-bridge.lo `test -f '$(core)/nm-setting-bridge.c' || echo '$(srcdir)/'`$(core)/nm-setting-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-bridge.Tpo $(DEPDIR)/nm-setting-bridge.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-bridge.c' object='nm-setting-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-bridge.lo `test -f '$(core)/nm-setting-bridge.c' || echo '$(srcdir)/'`$(core)/nm-setting-bridge.c + +nm-setting-cdma.lo: $(core)/nm-setting-cdma.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-cdma.lo -MD -MP -MF $(DEPDIR)/nm-setting-cdma.Tpo -c -o nm-setting-cdma.lo `test -f '$(core)/nm-setting-cdma.c' || echo '$(srcdir)/'`$(core)/nm-setting-cdma.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-cdma.Tpo $(DEPDIR)/nm-setting-cdma.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-cdma.c' object='nm-setting-cdma.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-cdma.lo `test -f '$(core)/nm-setting-cdma.c' || echo '$(srcdir)/'`$(core)/nm-setting-cdma.c + +nm-setting-connection.lo: $(core)/nm-setting-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-connection.lo -MD -MP -MF $(DEPDIR)/nm-setting-connection.Tpo -c -o nm-setting-connection.lo `test -f '$(core)/nm-setting-connection.c' || echo '$(srcdir)/'`$(core)/nm-setting-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-connection.Tpo $(DEPDIR)/nm-setting-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-connection.c' object='nm-setting-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-connection.lo `test -f '$(core)/nm-setting-connection.c' || echo '$(srcdir)/'`$(core)/nm-setting-connection.c + +nm-setting-dcb.lo: $(core)/nm-setting-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-dcb.lo -MD -MP -MF $(DEPDIR)/nm-setting-dcb.Tpo -c -o nm-setting-dcb.lo `test -f '$(core)/nm-setting-dcb.c' || echo '$(srcdir)/'`$(core)/nm-setting-dcb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-dcb.Tpo $(DEPDIR)/nm-setting-dcb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-dcb.c' object='nm-setting-dcb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-dcb.lo `test -f '$(core)/nm-setting-dcb.c' || echo '$(srcdir)/'`$(core)/nm-setting-dcb.c + +nm-setting-generic.lo: $(core)/nm-setting-generic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-generic.lo -MD -MP -MF $(DEPDIR)/nm-setting-generic.Tpo -c -o nm-setting-generic.lo `test -f '$(core)/nm-setting-generic.c' || echo '$(srcdir)/'`$(core)/nm-setting-generic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-generic.Tpo $(DEPDIR)/nm-setting-generic.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-generic.c' object='nm-setting-generic.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-generic.lo `test -f '$(core)/nm-setting-generic.c' || echo '$(srcdir)/'`$(core)/nm-setting-generic.c + +nm-setting-gsm.lo: $(core)/nm-setting-gsm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-gsm.lo -MD -MP -MF $(DEPDIR)/nm-setting-gsm.Tpo -c -o nm-setting-gsm.lo `test -f '$(core)/nm-setting-gsm.c' || echo '$(srcdir)/'`$(core)/nm-setting-gsm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-gsm.Tpo $(DEPDIR)/nm-setting-gsm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-gsm.c' object='nm-setting-gsm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-gsm.lo `test -f '$(core)/nm-setting-gsm.c' || echo '$(srcdir)/'`$(core)/nm-setting-gsm.c + +nm-setting-infiniband.lo: $(core)/nm-setting-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-infiniband.lo -MD -MP -MF $(DEPDIR)/nm-setting-infiniband.Tpo -c -o nm-setting-infiniband.lo `test -f '$(core)/nm-setting-infiniband.c' || echo '$(srcdir)/'`$(core)/nm-setting-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-infiniband.Tpo $(DEPDIR)/nm-setting-infiniband.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-infiniband.c' object='nm-setting-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-infiniband.lo `test -f '$(core)/nm-setting-infiniband.c' || echo '$(srcdir)/'`$(core)/nm-setting-infiniband.c + +nm-setting-ip-config.lo: $(core)/nm-setting-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-ip-config.lo -MD -MP -MF $(DEPDIR)/nm-setting-ip-config.Tpo -c -o nm-setting-ip-config.lo `test -f '$(core)/nm-setting-ip-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ip-config.Tpo $(DEPDIR)/nm-setting-ip-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-ip-config.c' object='nm-setting-ip-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-ip-config.lo `test -f '$(core)/nm-setting-ip-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip-config.c + +nm-setting-ip4-config.lo: $(core)/nm-setting-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-ip4-config.lo -MD -MP -MF $(DEPDIR)/nm-setting-ip4-config.Tpo -c -o nm-setting-ip4-config.lo `test -f '$(core)/nm-setting-ip4-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip4-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ip4-config.Tpo $(DEPDIR)/nm-setting-ip4-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-ip4-config.c' object='nm-setting-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-ip4-config.lo `test -f '$(core)/nm-setting-ip4-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip4-config.c + +nm-setting-ip6-config.lo: $(core)/nm-setting-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-ip6-config.lo -MD -MP -MF $(DEPDIR)/nm-setting-ip6-config.Tpo -c -o nm-setting-ip6-config.lo `test -f '$(core)/nm-setting-ip6-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip6-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ip6-config.Tpo $(DEPDIR)/nm-setting-ip6-config.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-ip6-config.c' object='nm-setting-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-ip6-config.lo `test -f '$(core)/nm-setting-ip6-config.c' || echo '$(srcdir)/'`$(core)/nm-setting-ip6-config.c + +nm-setting-olpc-mesh.lo: $(core)/nm-setting-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-olpc-mesh.lo -MD -MP -MF $(DEPDIR)/nm-setting-olpc-mesh.Tpo -c -o nm-setting-olpc-mesh.lo `test -f '$(core)/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`$(core)/nm-setting-olpc-mesh.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-olpc-mesh.Tpo $(DEPDIR)/nm-setting-olpc-mesh.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-olpc-mesh.c' object='nm-setting-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-olpc-mesh.lo `test -f '$(core)/nm-setting-olpc-mesh.c' || echo '$(srcdir)/'`$(core)/nm-setting-olpc-mesh.c + +nm-setting-ppp.lo: $(core)/nm-setting-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-ppp.lo -MD -MP -MF $(DEPDIR)/nm-setting-ppp.Tpo -c -o nm-setting-ppp.lo `test -f '$(core)/nm-setting-ppp.c' || echo '$(srcdir)/'`$(core)/nm-setting-ppp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-ppp.Tpo $(DEPDIR)/nm-setting-ppp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-ppp.c' object='nm-setting-ppp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-ppp.lo `test -f '$(core)/nm-setting-ppp.c' || echo '$(srcdir)/'`$(core)/nm-setting-ppp.c + +nm-setting-pppoe.lo: $(core)/nm-setting-pppoe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-pppoe.lo -MD -MP -MF $(DEPDIR)/nm-setting-pppoe.Tpo -c -o nm-setting-pppoe.lo `test -f '$(core)/nm-setting-pppoe.c' || echo '$(srcdir)/'`$(core)/nm-setting-pppoe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-pppoe.Tpo $(DEPDIR)/nm-setting-pppoe.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-pppoe.c' object='nm-setting-pppoe.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-pppoe.lo `test -f '$(core)/nm-setting-pppoe.c' || echo '$(srcdir)/'`$(core)/nm-setting-pppoe.c + +nm-setting-serial.lo: $(core)/nm-setting-serial.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-serial.lo -MD -MP -MF $(DEPDIR)/nm-setting-serial.Tpo -c -o nm-setting-serial.lo `test -f '$(core)/nm-setting-serial.c' || echo '$(srcdir)/'`$(core)/nm-setting-serial.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-serial.Tpo $(DEPDIR)/nm-setting-serial.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-serial.c' object='nm-setting-serial.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-serial.lo `test -f '$(core)/nm-setting-serial.c' || echo '$(srcdir)/'`$(core)/nm-setting-serial.c + +nm-setting-team-port.lo: $(core)/nm-setting-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-team-port.lo -MD -MP -MF $(DEPDIR)/nm-setting-team-port.Tpo -c -o nm-setting-team-port.lo `test -f '$(core)/nm-setting-team-port.c' || echo '$(srcdir)/'`$(core)/nm-setting-team-port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-team-port.Tpo $(DEPDIR)/nm-setting-team-port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-team-port.c' object='nm-setting-team-port.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-team-port.lo `test -f '$(core)/nm-setting-team-port.c' || echo '$(srcdir)/'`$(core)/nm-setting-team-port.c + +nm-setting-team.lo: $(core)/nm-setting-team.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-team.lo -MD -MP -MF $(DEPDIR)/nm-setting-team.Tpo -c -o nm-setting-team.lo `test -f '$(core)/nm-setting-team.c' || echo '$(srcdir)/'`$(core)/nm-setting-team.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-team.Tpo $(DEPDIR)/nm-setting-team.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-team.c' object='nm-setting-team.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-team.lo `test -f '$(core)/nm-setting-team.c' || echo '$(srcdir)/'`$(core)/nm-setting-team.c + +nm-setting-vlan.lo: $(core)/nm-setting-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-vlan.lo -MD -MP -MF $(DEPDIR)/nm-setting-vlan.Tpo -c -o nm-setting-vlan.lo `test -f '$(core)/nm-setting-vlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-vlan.Tpo $(DEPDIR)/nm-setting-vlan.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-vlan.c' object='nm-setting-vlan.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-vlan.lo `test -f '$(core)/nm-setting-vlan.c' || echo '$(srcdir)/'`$(core)/nm-setting-vlan.c + +nm-setting-vpn.lo: $(core)/nm-setting-vpn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-vpn.lo -MD -MP -MF $(DEPDIR)/nm-setting-vpn.Tpo -c -o nm-setting-vpn.lo `test -f '$(core)/nm-setting-vpn.c' || echo '$(srcdir)/'`$(core)/nm-setting-vpn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-vpn.Tpo $(DEPDIR)/nm-setting-vpn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-vpn.c' object='nm-setting-vpn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-vpn.lo `test -f '$(core)/nm-setting-vpn.c' || echo '$(srcdir)/'`$(core)/nm-setting-vpn.c + +nm-setting-wimax.lo: $(core)/nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-wimax.lo -MD -MP -MF $(DEPDIR)/nm-setting-wimax.Tpo -c -o nm-setting-wimax.lo `test -f '$(core)/nm-setting-wimax.c' || echo '$(srcdir)/'`$(core)/nm-setting-wimax.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-wimax.Tpo $(DEPDIR)/nm-setting-wimax.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-wimax.c' object='nm-setting-wimax.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-wimax.lo `test -f '$(core)/nm-setting-wimax.c' || echo '$(srcdir)/'`$(core)/nm-setting-wimax.c + +nm-setting-wired.lo: $(core)/nm-setting-wired.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-wired.lo -MD -MP -MF $(DEPDIR)/nm-setting-wired.Tpo -c -o nm-setting-wired.lo `test -f '$(core)/nm-setting-wired.c' || echo '$(srcdir)/'`$(core)/nm-setting-wired.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-wired.Tpo $(DEPDIR)/nm-setting-wired.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-wired.c' object='nm-setting-wired.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-wired.lo `test -f '$(core)/nm-setting-wired.c' || echo '$(srcdir)/'`$(core)/nm-setting-wired.c + +nm-setting-wireless-security.lo: $(core)/nm-setting-wireless-security.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-wireless-security.lo -MD -MP -MF $(DEPDIR)/nm-setting-wireless-security.Tpo -c -o nm-setting-wireless-security.lo `test -f '$(core)/nm-setting-wireless-security.c' || echo '$(srcdir)/'`$(core)/nm-setting-wireless-security.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-wireless-security.Tpo $(DEPDIR)/nm-setting-wireless-security.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-wireless-security.c' object='nm-setting-wireless-security.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-wireless-security.lo `test -f '$(core)/nm-setting-wireless-security.c' || echo '$(srcdir)/'`$(core)/nm-setting-wireless-security.c + +nm-setting-wireless.lo: $(core)/nm-setting-wireless.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting-wireless.lo -MD -MP -MF $(DEPDIR)/nm-setting-wireless.Tpo -c -o nm-setting-wireless.lo `test -f '$(core)/nm-setting-wireless.c' || echo '$(srcdir)/'`$(core)/nm-setting-wireless.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting-wireless.Tpo $(DEPDIR)/nm-setting-wireless.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting-wireless.c' object='nm-setting-wireless.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting-wireless.lo `test -f '$(core)/nm-setting-wireless.c' || echo '$(srcdir)/'`$(core)/nm-setting-wireless.c + +nm-setting.lo: $(core)/nm-setting.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-setting.lo -MD -MP -MF $(DEPDIR)/nm-setting.Tpo -c -o nm-setting.lo `test -f '$(core)/nm-setting.c' || echo '$(srcdir)/'`$(core)/nm-setting.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-setting.Tpo $(DEPDIR)/nm-setting.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-setting.c' object='nm-setting.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-setting.lo `test -f '$(core)/nm-setting.c' || echo '$(srcdir)/'`$(core)/nm-setting.c + +nm-simple-connection.lo: $(core)/nm-simple-connection.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-simple-connection.lo -MD -MP -MF $(DEPDIR)/nm-simple-connection.Tpo -c -o nm-simple-connection.lo `test -f '$(core)/nm-simple-connection.c' || echo '$(srcdir)/'`$(core)/nm-simple-connection.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-simple-connection.Tpo $(DEPDIR)/nm-simple-connection.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-simple-connection.c' object='nm-simple-connection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-simple-connection.lo `test -f '$(core)/nm-simple-connection.c' || echo '$(srcdir)/'`$(core)/nm-simple-connection.c + +nm-utils.lo: $(core)/nm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-utils.lo -MD -MP -MF $(DEPDIR)/nm-utils.Tpo -c -o nm-utils.lo `test -f '$(core)/nm-utils.c' || echo '$(srcdir)/'`$(core)/nm-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-utils.Tpo $(DEPDIR)/nm-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(core)/nm-utils.c' object='nm-utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-utils.lo `test -f '$(core)/nm-utils.c' || echo '$(srcdir)/'`$(core)/nm-utils.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-libnmincludeHEADERS: $(libnminclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libnminclude_HEADERS)'; test -n "$(libnmincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libnmincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libnmincludedir)" || exit 1; \ + fi; \ + 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_HEADER) $$files '$(DESTDIR)$(libnmincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libnmincludedir)" || exit $$?; \ + done + +uninstall-libnmincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libnminclude_HEADERS)'; test -n "$(libnmincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libnmincludedir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + 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-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libnmincludedir)"; 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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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-libnmincludeHEADERS + +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: uninstall-libnmincludeHEADERS + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am 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-libnmincludeHEADERS 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-am uninstall uninstall-am \ + uninstall-libnmincludeHEADERS + +include $(GLIB_MAKEFILE) + +# 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/libnm-core/Makefile.libnm-core b/libnm-core/Makefile.libnm-core new file mode 100644 index 00000000..fc6d779b --- /dev/null +++ b/libnm-core/Makefile.libnm-core @@ -0,0 +1,91 @@ +# In order for this to work correctly from both libnm-core/ and libnm/, +# we have to specify full pathnames. (We can't just use $(addprefix) from +# libnm/, because that's incompatible with the Makefile.introspection rules.) + +core = $(top_srcdir)/libnm-core +core_build = $(top_builddir)/libnm-core + +libnm_core_headers = \ + $(core_build)/nm-core-enum-types.h \ + $(core_build)/nm-version.h \ + $(core)/nm-connection.h \ + $(core)/nm-core-types.h \ + $(core)/nm-dbus-interface.h \ + $(core)/nm-errors.h \ + $(core)/nm-setting-8021x.h \ + $(core)/nm-setting-adsl.h \ + $(core)/nm-setting-bluetooth.h \ + $(core)/nm-setting-bond.h \ + $(core)/nm-setting-bridge-port.h \ + $(core)/nm-setting-bridge.h \ + $(core)/nm-setting-cdma.h \ + $(core)/nm-setting-connection.h \ + $(core)/nm-setting-dcb.h \ + $(core)/nm-setting-generic.h \ + $(core)/nm-setting-gsm.h \ + $(core)/nm-setting-infiniband.h \ + $(core)/nm-setting-ip-config.h \ + $(core)/nm-setting-ip4-config.h \ + $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-olpc-mesh.h \ + $(core)/nm-setting-ppp.h \ + $(core)/nm-setting-pppoe.h \ + $(core)/nm-setting-serial.h \ + $(core)/nm-setting-team-port.h \ + $(core)/nm-setting-team.h \ + $(core)/nm-setting-vlan.h \ + $(core)/nm-setting-vpn.h \ + $(core)/nm-setting-wimax.h \ + $(core)/nm-setting-wired.h \ + $(core)/nm-setting-wireless-security.h \ + $(core)/nm-setting-wireless.h \ + $(core)/nm-setting.h \ + $(core)/nm-simple-connection.h \ + $(core)/nm-utils.h \ + $(core)/nm-vpn-dbus-interface.h + +libnm_core_private_headers = \ + $(core)/crypto.h \ + $(core)/nm-connection-private.h \ + $(core)/nm-core-internal.h \ + $(core)/nm-property-compare.h \ + $(core)/nm-setting-private.h \ + $(core)/nm-utils-private.h + +libnm_core_sources = \ + $(core_build)/nm-core-enum-types.c \ + $(core)/crypto.c \ + $(core)/nm-connection.c \ + $(core)/nm-errors.c \ + $(core)/nm-property-compare.c \ + $(core)/nm-setting-8021x.c \ + $(core)/nm-setting-adsl.c \ + $(core)/nm-setting-bluetooth.c \ + $(core)/nm-setting-bond.c \ + $(core)/nm-setting-bridge-port.c \ + $(core)/nm-setting-bridge.c \ + $(core)/nm-setting-cdma.c \ + $(core)/nm-setting-connection.c \ + $(core)/nm-setting-dcb.c \ + $(core)/nm-setting-generic.c \ + $(core)/nm-setting-gsm.c \ + $(core)/nm-setting-infiniband.c \ + $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip4-config.c \ + $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-olpc-mesh.c \ + $(core)/nm-setting-ppp.c \ + $(core)/nm-setting-pppoe.c \ + $(core)/nm-setting-serial.c \ + $(core)/nm-setting-team-port.c \ + $(core)/nm-setting-team.c \ + $(core)/nm-setting-vlan.c \ + $(core)/nm-setting-vpn.c \ + $(core)/nm-setting-wimax.c \ + $(core)/nm-setting-wired.c \ + $(core)/nm-setting-wireless-security.c \ + $(core)/nm-setting-wireless.c \ + $(core)/nm-setting.c \ + $(core)/nm-simple-connection.c \ + $(core)/nm-utils.c + diff --git a/libnm-core/crypto.c b/libnm-core/crypto.c new file mode 100644 index 00000000..205d22c6 --- /dev/null +++ b/libnm-core/crypto.c @@ -0,0 +1,816 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * Dan Williams + * + * 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "nm-errors.h" + +#define PEM_RSA_KEY_BEGIN "-----BEGIN RSA PRIVATE KEY-----" +#define PEM_RSA_KEY_END "-----END RSA PRIVATE KEY-----" + +#define PEM_DSA_KEY_BEGIN "-----BEGIN DSA PRIVATE KEY-----" +#define PEM_DSA_KEY_END "-----END DSA PRIVATE KEY-----" + +#define PEM_CERT_BEGIN "-----BEGIN CERTIFICATE-----" +#define PEM_CERT_END "-----END CERTIFICATE-----" + +#define PEM_PKCS8_ENC_KEY_BEGIN "-----BEGIN ENCRYPTED PRIVATE KEY-----" +#define PEM_PKCS8_ENC_KEY_END "-----END ENCRYPTED PRIVATE KEY-----" + +#define PEM_PKCS8_DEC_KEY_BEGIN "-----BEGIN PRIVATE KEY-----" +#define PEM_PKCS8_DEC_KEY_END "-----END PRIVATE KEY-----" + +static gboolean +find_tag (const char *tag, + const guint8 *data, + gsize data_len, + gsize start_at, + gsize *out_pos) +{ + gsize i, taglen; + gsize len = data_len - start_at; + + g_return_val_if_fail (out_pos != NULL, FALSE); + + taglen = strlen (tag); + if (len >= taglen) { + for (i = 0; i < len - taglen + 1; i++) { + if (memcmp (data + start_at + i, tag, taglen) == 0) { + *out_pos = start_at + i; + return TRUE; + } + } + } + return FALSE; +} + +#define DEK_INFO_TAG "DEK-Info: " +#define PROC_TYPE_TAG "Proc-Type: " + +static GByteArray * +parse_old_openssl_key_file (const guint8 *data, + gsize data_len, + NMCryptoKeyType *out_key_type, + char **out_cipher, + char **out_iv, + GError **error) +{ + GByteArray *bindata = NULL; + char **lines = NULL; + char **ln = NULL; + gsize start = 0, end = 0; + GString *str = NULL; + int enc_tags = 0; + NMCryptoKeyType key_type; + char *iv = NULL; + char *cipher = NULL; + unsigned char *tmp = NULL; + gsize tmp_len = 0; + const char *start_tag; + const char *end_tag; + guint8 save_end = 0; + + *out_key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + *out_iv = NULL; + *out_cipher = NULL; + + if (find_tag (PEM_RSA_KEY_BEGIN, data, data_len, 0, &start)) { + key_type = NM_CRYPTO_KEY_TYPE_RSA; + start_tag = PEM_RSA_KEY_BEGIN; + end_tag = PEM_RSA_KEY_END; + } else if (find_tag (PEM_DSA_KEY_BEGIN, data, data_len, 0, &start)) { + key_type = NM_CRYPTO_KEY_TYPE_DSA; + start_tag = PEM_DSA_KEY_BEGIN; + end_tag = PEM_DSA_KEY_END; + } else + goto parse_error; + + start += strlen (start_tag); + if (!find_tag (end_tag, data, data_len, start, &end)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM key file had no end tag '%s'."), + end_tag); + goto parse_error; + } + + save_end = data[end]; + ((guint8 *)data)[end] = '\0'; + lines = g_strsplit ((const char *) (data + start), "\n", 0); + ((guint8 *)data)[end] = save_end; + + if (!lines || g_strv_length (lines) <= 1) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Doesn't look like a PEM private key file.")); + goto parse_error; + } + + str = g_string_new_len (NULL, end - start); + for (ln = lines; *ln; ln++) { + char *p = *ln; + + /* Chug leading spaces */ + p = g_strstrip (p); + if (!*p) + continue; + + if (!strncmp (p, PROC_TYPE_TAG, strlen (PROC_TYPE_TAG))) { + if (enc_tags++ != 0 || str->len != 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: Proc-Type was not first tag.")); + goto parse_error; + } + + p += strlen (PROC_TYPE_TAG); + if (strcmp (p, "4,ENCRYPTED")) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: unknown Proc-Type tag '%s'."), + p); + goto parse_error; + } + } else if (!strncmp (p, DEK_INFO_TAG, strlen (DEK_INFO_TAG))) { + char *comma; + + if (enc_tags++ != 1 || str->len != 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: DEK-Info was not the second tag.")); + goto parse_error; + } + + p += strlen (DEK_INFO_TAG); + + /* Grab the IV first */ + comma = strchr (p, ','); + if (!comma || (*(comma + 1) == '\0')) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: no IV found in DEK-Info tag.")); + goto parse_error; + } + *comma++ = '\0'; + if (!g_ascii_isxdigit (*comma)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: invalid format of IV in DEK-Info tag.")); + goto parse_error; + } + iv = g_strdup (comma); + + /* Get the private key cipher */ + if (!strcasecmp (p, "DES-EDE3-CBC")) { + cipher = g_strdup (p); + } else if (!strcasecmp (p, "DES-CBC")) { + cipher = g_strdup (p); + } else if (!strcasecmp (p, "AES-128-CBC")) { + cipher = g_strdup (p); + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Malformed PEM file: unknown private key cipher '%s'."), + p); + goto parse_error; + } + } else { + if (enc_tags == 1) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + "Malformed PEM file: both Proc-Type and DEK-Info tags are required."); + goto parse_error; + } + g_string_append (str, p); + } + } + + tmp = g_base64_decode (str->str, &tmp_len); + if (tmp == NULL || !tmp_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Could not decode private key.")); + goto parse_error; + } + g_string_free (str, TRUE); + + if (lines) + g_strfreev (lines); + + bindata = g_byte_array_sized_new (tmp_len); + g_byte_array_append (bindata, tmp, tmp_len); + g_free (tmp); + + *out_key_type = key_type; + *out_iv = iv; + *out_cipher = cipher; + return bindata; + +parse_error: + g_free (tmp); + g_free (cipher); + g_free (iv); + if (str) + g_string_free (str, TRUE); + if (lines) + g_strfreev (lines); + return NULL; +} + +static GByteArray * +parse_pkcs8_key_file (const guint8 *data, + gsize data_len, + gboolean *out_encrypted, + GError **error) +{ + GByteArray *key = NULL; + gsize start = 0, end = 0; + unsigned char *der = NULL; + guint8 save_end; + gsize length = 0; + const char *start_tag = NULL, *end_tag = NULL; + gboolean encrypted = FALSE; + + /* Try encrypted first, decrypted next */ + if (find_tag (PEM_PKCS8_ENC_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_PKCS8_ENC_KEY_BEGIN; + end_tag = PEM_PKCS8_ENC_KEY_END; + encrypted = TRUE; + } else if (find_tag (PEM_PKCS8_DEC_KEY_BEGIN, data, data_len, 0, &start)) { + start_tag = PEM_PKCS8_DEC_KEY_BEGIN; + end_tag = PEM_PKCS8_DEC_KEY_END; + encrypted = FALSE; + } else { + g_set_error_literal (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected PKCS#8 start tag.")); + return NULL; + } + + start += strlen (start_tag); + if (!find_tag (end_tag, data, data_len, start, &end)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to find expected PKCS#8 end tag '%s'."), + end_tag); + return NULL; + } + + /* g_base64_decode() wants a NULL-terminated string */ + save_end = data[end]; + ((guint8 *)data)[end] = '\0'; + der = g_base64_decode ((const char *) (data + start), &length); + ((guint8 *)data)[end] = save_end; + + if (der && length) { + key = g_byte_array_sized_new (length); + g_byte_array_append (key, der, length); + g_assert (key->len == length); + *out_encrypted = encrypted; + } else { + g_set_error_literal (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to decode PKCS#8 private key.")); + } + + g_free (der); + return key; +} + +static GByteArray * +file_to_g_byte_array (const char *filename, GError **error) +{ + char *contents; + GByteArray *array = NULL; + gsize length = 0; + + if (g_file_get_contents (filename, &contents, &length, error)) { + array = g_byte_array_sized_new (length); + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + g_free (contents); + } + return array; +} + +/* + * Convert a hex string into bytes. + */ +static char * +convert_iv (const char *src, + gsize *out_len, + GError **error) +{ + int num; + int i; + char conv[3]; + char *c; + + g_return_val_if_fail (src != NULL, NULL); + + num = strlen (src); + if (num % 2) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("IV must be an even number of bytes in length.")); + return NULL; + } + + num /= 2; + c = g_malloc0 (num + 1); + + conv[2] = '\0'; + for (i = 0; i < num; i++) { + conv[0] = src[(i * 2)]; + conv[1] = src[(i * 2) + 1]; + if (!g_ascii_isxdigit (conv[0]) || !g_ascii_isxdigit (conv[1])) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("IV contains non-hexadecimal digits.")); + goto error; + } + + c[i] = strtol(conv, NULL, 16); + } + *out_len = num; + return c; + +error: + g_free (c); + return NULL; +} + +char * +crypto_make_des_aes_key (const char *cipher, + const char *salt, + const gsize salt_len, + const char *password, + gsize *out_len, + GError **error) +{ + char *key; + guint32 digest_len; + + g_return_val_if_fail (cipher != NULL, NULL); + g_return_val_if_fail (salt != NULL, NULL); + g_return_val_if_fail (salt_len >= 8, NULL); + g_return_val_if_fail (password != NULL, NULL); + g_return_val_if_fail (out_len != NULL, NULL); + + if (!strcmp (cipher, "DES-EDE3-CBC")) + digest_len = 24; + else if (!strcmp (cipher, "DES-CBC")) + digest_len = 8; + else if (!strcmp (cipher, "AES-128-CBC")) + digest_len = 16; + else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Private key cipher '%s' was unknown."), + cipher); + return NULL; + } + + if (password[0] == '\0') + return NULL; + + key = g_malloc0 (digest_len + 1); + + crypto_md5_hash (salt, + 8, + password, + strlen (password), + key, + digest_len); + + *out_len = digest_len; + return key; +} + +static GByteArray * +decrypt_key (const char *cipher, + int key_type, + const guint8 *data, + gsize data_len, + const char *iv, + const char *password, + GError **error) +{ + char *bin_iv = NULL; + gsize bin_iv_len = 0; + char *key = NULL; + gsize key_len = 0; + char *output = NULL; + gsize decrypted_len = 0; + GByteArray *decrypted = NULL; + + g_return_val_if_fail (password != NULL, NULL); + + bin_iv = convert_iv (iv, &bin_iv_len, error); + if (!bin_iv) + return NULL; + + /* Convert the password and IV into a DES or AES key */ + key = crypto_make_des_aes_key (cipher, bin_iv, bin_iv_len, password, &key_len, error); + if (!key || !key_len) + goto out; + + output = crypto_decrypt (cipher, key_type, + data, data_len, + bin_iv, bin_iv_len, + key, key_len, + &decrypted_len, + error); + if (output && decrypted_len) { + decrypted = g_byte_array_sized_new (decrypted_len); + g_byte_array_append (decrypted, (guint8 *) output, decrypted_len); + } + +out: + /* Don't leak stale key material */ + if (key) + memset (key, 0, key_len); + g_free (output); + g_free (key); + g_free (bin_iv); + + return decrypted; +} + +GByteArray * +crypto_decrypt_openssl_private_key_data (const guint8 *data, + gsize data_len, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error) +{ + GByteArray *decrypted = NULL; + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + GByteArray *parsed; + char *iv = NULL; + char *cipher = NULL; + + g_return_val_if_fail (data != NULL, NULL); + if (out_key_type) + g_return_val_if_fail (*out_key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, NULL); + + if (!crypto_init (error)) + return NULL; + + parsed = parse_old_openssl_key_file (data, data_len, &key_type, &cipher, &iv, NULL); + /* return the key type even if decryption failed */ + if (out_key_type) + *out_key_type = key_type; + + if (!parsed) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Unable to determine private key type.")); + return NULL; + } + + if (password) { + if (!cipher || !iv) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + _("Password provided, but key was not encrypted.")); + } else { + decrypted = decrypt_key (cipher, + key_type, + parsed->data, + parsed->len, + iv, + password, + error); + } + } else if (!cipher && !iv) + decrypted = g_byte_array_ref (parsed); + + g_byte_array_unref (parsed); + g_free (cipher); + g_free (iv); + + return decrypted; +} + +GByteArray * +crypto_decrypt_openssl_private_key (const char *file, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error) +{ + GByteArray *contents; + GByteArray *key = NULL; + + if (!crypto_init (error)) + return NULL; + + contents = file_to_g_byte_array (file, error); + if (contents) { + key = crypto_decrypt_openssl_private_key_data (contents->data, contents->len, + password, out_key_type, error); + g_byte_array_free (contents, TRUE); + } + return key; +} + +static GByteArray * +extract_pem_cert_data (GByteArray *contents, GError **error) +{ + GByteArray *cert = NULL; + gsize start = 0, end = 0; + unsigned char *der = NULL; + guint8 save_end; + gsize length = 0; + + if (!find_tag (PEM_CERT_BEGIN, contents->data, contents->len, 0, &start)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM certificate had no start tag '%s'."), + PEM_CERT_BEGIN); + goto done; + } + + start += strlen (PEM_CERT_BEGIN); + if (!find_tag (PEM_CERT_END, contents->data, contents->len, start, &end)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("PEM certificate had no end tag '%s'."), + PEM_CERT_END); + goto done; + } + + /* g_base64_decode() wants a NULL-terminated string */ + save_end = contents->data[end]; + contents->data[end] = '\0'; + der = g_base64_decode ((const char *) (contents->data + start), &length); + contents->data[end] = save_end; + + if (der && length) { + cert = g_byte_array_sized_new (length); + g_byte_array_append (cert, der, length); + g_assert (cert->len == length); + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Failed to decode certificate.")); + } + +done: + g_free (der); + return cert; +} + +GByteArray * +crypto_load_and_verify_certificate (const char *file, + NMCryptoFileFormat *out_file_format, + GError **error) +{ + GByteArray *array, *contents; + + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (out_file_format != NULL, NULL); + g_return_val_if_fail (*out_file_format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, NULL); + + if (!crypto_init (error)) + return NULL; + + contents = file_to_g_byte_array (file, error); + if (!contents) + return NULL; + + /* Check for PKCS#12 */ + if (crypto_is_pkcs12_data (contents->data, contents->len, NULL)) { + *out_file_format = NM_CRYPTO_FILE_FORMAT_PKCS12; + return contents; + } + + /* Check for plain DER format */ + if (contents->len > 2 && contents->data[0] == 0x30 && contents->data[1] == 0x82) { + *out_file_format = crypto_verify_cert (contents->data, contents->len, error); + } else { + array = extract_pem_cert_data (contents, error); + if (!array) { + g_byte_array_free (contents, TRUE); + return NULL; + } + + *out_file_format = crypto_verify_cert (array->data, array->len, error); + g_byte_array_free (array, TRUE); + } + + if (*out_file_format != NM_CRYPTO_FILE_FORMAT_X509) { + g_byte_array_free (contents, TRUE); + contents = NULL; + } + + return contents; +} + +gboolean +crypto_is_pkcs12_data (const guint8 *data, + gsize data_len, + GError **error) +{ + GError *local = NULL; + gboolean success; + + g_return_val_if_fail (data != NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + success = crypto_verify_pkcs12 (data, data_len, NULL, &local); + if (success == FALSE) { + /* If the error was just a decryption error, then it's pkcs#12 */ + if (local) { + if (g_error_matches (local, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED)) { + success = TRUE; + g_error_free (local); + } else + g_propagate_error (error, local); + } + } + return success; +} + +gboolean +crypto_is_pkcs12_file (const char *file, GError **error) +{ + GByteArray *contents; + gboolean success = FALSE; + + g_return_val_if_fail (file != NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + contents = file_to_g_byte_array (file, error); + if (contents) { + success = crypto_is_pkcs12_data (contents->data, contents->len, error); + g_byte_array_free (contents, TRUE); + } + return success; +} + +/* Verifies that a private key can be read, and if a password is given, that + * the private key can be decrypted with that password. + */ +NMCryptoFileFormat +crypto_verify_private_key_data (const guint8 *data, + gsize data_len, + const char *password, + gboolean *out_is_encrypted, + GError **error) +{ + GByteArray *tmp; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + NMCryptoKeyType ktype = NM_CRYPTO_KEY_TYPE_UNKNOWN; + gboolean is_encrypted = FALSE; + + g_return_val_if_fail (data != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_return_val_if_fail (out_is_encrypted == NULL || *out_is_encrypted == FALSE, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + + if (!crypto_init (error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + /* Check for PKCS#12 first */ + if (crypto_is_pkcs12_data (data, data_len, NULL)) { + is_encrypted = TRUE; + if (!password || crypto_verify_pkcs12 (data, data_len, password, error)) + format = NM_CRYPTO_FILE_FORMAT_PKCS12; + } else { + /* Maybe it's PKCS#8 */ + tmp = parse_pkcs8_key_file (data, data_len, &is_encrypted, NULL); + if (tmp) { + if (crypto_verify_pkcs8 (tmp->data, tmp->len, is_encrypted, password, error)) + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + } else { + char *cipher, *iv; + + /* Or it's old-style OpenSSL */ + tmp = parse_old_openssl_key_file (data, data_len, &ktype, + &cipher, &iv, NULL); + if (tmp) { + format = NM_CRYPTO_FILE_FORMAT_RAW_KEY; + is_encrypted = (cipher && iv); + g_free (cipher); + g_free (iv); + } + } + + if (tmp) { + /* Don't leave key data around */ + memset (tmp->data, 0, tmp->len); + g_byte_array_free (tmp, TRUE); + } + } + + if (out_is_encrypted) + *out_is_encrypted = is_encrypted; + return format; +} + +NMCryptoFileFormat +crypto_verify_private_key (const char *filename, + const char *password, + gboolean *out_is_encrypted, + GError **error) +{ + GByteArray *contents; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + g_return_val_if_fail (filename != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + + if (!crypto_init (error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + contents = file_to_g_byte_array (filename, error); + if (contents) { + format = crypto_verify_private_key_data (contents->data, contents->len, password, out_is_encrypted, error); + g_byte_array_free (contents, TRUE); + } + return format; +} + +void +crypto_md5_hash (const char *salt, + gssize salt_len, + const char *password, + gssize password_len, + char *buffer, + gsize buflen) +{ + GChecksum *ctx; + int nkey = buflen; + gsize digest_len; + int count = 0; + char digest[16]; + char *p = buffer; + + g_assert_cmpint (g_checksum_type_get_length (G_CHECKSUM_MD5), ==, sizeof (digest)); + + g_return_if_fail (password_len == 0 || password); + g_return_if_fail (buffer != NULL); + g_return_if_fail (buflen > 0); + g_return_if_fail (salt_len == 0 || salt); + + ctx = g_checksum_new (G_CHECKSUM_MD5); + + if (salt_len < 0) + salt_len = strlen (salt); + if (password_len < 0) + password_len = strlen (password); + + while (nkey > 0) { + int i = 0; + + g_checksum_reset (ctx); + if (count++) + g_checksum_update (ctx, (const guchar *) digest, sizeof (digest)); + if (password_len > 0) + g_checksum_update (ctx, (const guchar *) password, password_len); + if (salt_len > 0) + g_checksum_update (ctx, (const guchar *) salt, salt_len); + + digest_len = sizeof (digest); + g_checksum_get_digest (ctx, (guchar *) digest, &digest_len); + g_assert (digest_len == sizeof (digest)); + + while (nkey && (i < sizeof (digest))) { + *(p++) = digest[i++]; + nkey--; + } + } + + memset (digest, 0, sizeof (digest)); + g_checksum_free (ctx); +} diff --git a/libnm-core/crypto.h b/libnm-core/crypto.h new file mode 100644 index 00000000..434f108d --- /dev/null +++ b/libnm-core/crypto.h @@ -0,0 +1,133 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * Dan Williams + * + * 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ + +#include + +#define MD5_HASH_LEN 20 +#define CIPHER_DES_EDE3_CBC "DES-EDE3-CBC" +#define CIPHER_DES_CBC "DES-CBC" +#define CIPHER_AES_CBC "AES-128-CBC" + +typedef enum { + NM_CRYPTO_KEY_TYPE_UNKNOWN = 0, + NM_CRYPTO_KEY_TYPE_RSA, + NM_CRYPTO_KEY_TYPE_DSA +} NMCryptoKeyType; + +typedef enum { + NM_CRYPTO_FILE_FORMAT_UNKNOWN = 0, + NM_CRYPTO_FILE_FORMAT_X509, + NM_CRYPTO_FILE_FORMAT_RAW_KEY, + NM_CRYPTO_FILE_FORMAT_PKCS12 +} NMCryptoFileFormat; + +gboolean crypto_init (GError **error); + +GByteArray *crypto_decrypt_openssl_private_key_data (const guint8 *data, + gsize data_len, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error); + +GByteArray *crypto_decrypt_openssl_private_key (const char *file, + const char *password, + NMCryptoKeyType *out_key_type, + GError **error); + +GByteArray *crypto_load_and_verify_certificate (const char *file, + NMCryptoFileFormat *out_file_format, + GError **error); + +gboolean crypto_is_pkcs12_file (const char *file, GError **error); + +gboolean crypto_is_pkcs12_data (const guint8 *data, gsize len, GError **error); + +NMCryptoFileFormat crypto_verify_private_key_data (const guint8 *data, + gsize data_len, + const char *password, + gboolean *out_is_encrypted, + GError **error); + +NMCryptoFileFormat crypto_verify_private_key (const char *file, + const char *password, + gboolean *out_is_encrypted, + GError **error); + +/* Internal utils API bits for crypto providers */ + +void crypto_md5_hash (const char *salt, + gssize salt_len, + const char *password, + gssize password_len, + char *buffer, + gsize buflen); + +char *crypto_make_des_aes_key (const char *cipher, + const char *salt, + const gsize salt_len, + const char *password, + gsize *out_len, + GError **error); + +char * crypto_decrypt (const char *cipher, + int key_type, + const guint8 *data, + gsize data_len, + const char *iv, + const gsize iv_len, + const char *key, + const gsize key_len, + gsize *out_len, + GError **error); + +char * crypto_encrypt (const char *cipher, + const guint8 *data, + gsize data_len, + const char *iv, + gsize iv_len, + const char *key, + gsize key_len, + gsize *out_len, + GError **error); + +gboolean crypto_randomize (void *buffer, gsize buffer_len, GError **error); + +NMCryptoFileFormat crypto_verify_cert (const guint8 *data, + gsize len, + GError **error); + +gboolean crypto_verify_pkcs12 (const guint8 *data, + gsize data_len, + const char *password, + GError **error); + +gboolean crypto_verify_pkcs8 (const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char *password, + GError **error); + +#endif /* __CRYPTO_H__ */ diff --git a/libnm-core/crypto_gnutls.c b/libnm-core/crypto_gnutls.c new file mode 100644 index 00000000..96dddb90 --- /dev/null +++ b/libnm-core/crypto_gnutls.c @@ -0,0 +1,454 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * 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. + * + * Copyright 2007 - 2009 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include + +#include "crypto.h" +#include "nm-errors.h" + +#define SALT_LEN 8 + +static gboolean initialized = FALSE; + +gboolean +crypto_init (GError **error) +{ + if (initialized) + return TRUE; + + if (gnutls_global_init() != 0) { + gnutls_global_deinit(); + g_set_error_literal (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the crypto engine.")); + return FALSE; + } + + initialized = TRUE; + return TRUE; +} + +char * +crypto_decrypt (const char *cipher, + int key_type, + const guint8 *data, + gsize data_len, + const char *iv, + const gsize iv_len, + const char *key, + const gsize key_len, + gsize *out_len, + GError **error) +{ + gcry_cipher_hd_t ctx; + gcry_error_t err; + int cipher_mech, i; + char *output = NULL; + gboolean success = FALSE; + gsize pad_len, real_iv_len; + + if (!crypto_init (error)) + return NULL; + + if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) { + cipher_mech = GCRY_CIPHER_3DES; + real_iv_len = SALT_LEN; + } else if (!strcmp (cipher, CIPHER_DES_CBC)) { + cipher_mech = GCRY_CIPHER_DES; + real_iv_len = SALT_LEN; + } else if (!strcmp (cipher, CIPHER_AES_CBC)) { + cipher_mech = GCRY_CIPHER_AES; + real_iv_len = 16; + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Private key cipher '%s' was unknown."), + cipher); + return NULL; + } + + if (iv_len < real_iv_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Invalid IV length (must be at least %zd)."), + real_iv_len); + return NULL; + } + + output = g_malloc0 (data_len); + + err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to initialize the decryption cipher context: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + err = gcry_cipher_setkey (ctx, key, key_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set symmetric key for decryption: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + err = gcry_cipher_setiv (ctx, iv, iv_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set IV for decryption: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + err = gcry_cipher_decrypt (ctx, output, data_len, data, data_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + pad_len = output[data_len - 1]; + + /* Check if the padding at the end of the decrypted data is valid */ + if (pad_len == 0 || pad_len > real_iv_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: unexpected padding length.")); + goto out; + } + + /* Validate tail padding; last byte is the padding size, and all pad bytes + * should contain the padding size. + */ + for (i = 1; i <= pad_len; ++i) { + if (output[data_len - i] != pad_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key.")); + goto out; + } + } + + *out_len = data_len - pad_len; + success = TRUE; + +out: + if (!success) { + if (output) { + /* Don't expose key material */ + memset (output, 0, data_len); + g_free (output); + output = NULL; + } + } + gcry_cipher_close (ctx); + return output; +} + +char * +crypto_encrypt (const char *cipher, + const guint8 *data, + gsize data_len, + const char *iv, + const gsize iv_len, + const char *key, + gsize key_len, + gsize *out_len, + GError **error) +{ + gcry_cipher_hd_t ctx; + gcry_error_t err; + int cipher_mech; + char *output = NULL; + gboolean success = FALSE; + gsize padded_buf_len, pad_len, output_len; + char *padded_buf = NULL; + guint32 i; + gsize salt_len; + + if (!crypto_init (error)) + return NULL; + + if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) { + cipher_mech = GCRY_CIPHER_3DES; + salt_len = SALT_LEN; + } else if (!strcmp (cipher, CIPHER_AES_CBC)) { + cipher_mech = GCRY_CIPHER_AES; + salt_len = iv_len; + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Private key cipher '%s' was unknown."), + cipher); + return NULL; + } + + /* If data_len % ivlen == 0, then we add another complete block + * onto the end so that the decrypter knows there's padding. + */ + pad_len = iv_len - (data_len % iv_len); + output_len = padded_buf_len = data_len + pad_len; + padded_buf = g_malloc0 (padded_buf_len); + + memcpy (padded_buf, data, data_len); + for (i = 0; i < pad_len; i++) + padded_buf[data_len + i] = (guint8) (pad_len & 0xFF); + + output = g_malloc0 (output_len); + + err = gcry_cipher_open (&ctx, cipher_mech, GCRY_CIPHER_MODE_CBC, 0); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to initialize the encryption cipher context: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + err = gcry_cipher_setkey (ctx, key, key_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set symmetric key for encryption: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + /* gcrypt only wants 8 bytes of the IV (same as the DES block length) */ + err = gcry_cipher_setiv (ctx, iv, salt_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set IV for encryption: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + err = gcry_cipher_encrypt (ctx, output, output_len, padded_buf, padded_buf_len); + if (err) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to encrypt the data: %s / %s."), + gcry_strsource (err), gcry_strerror (err)); + goto out; + } + + *out_len = output_len; + success = TRUE; + +out: + if (padded_buf) { + memset (padded_buf, 0, padded_buf_len); + g_free (padded_buf); + padded_buf = NULL; + } + + if (!success) { + if (output) { + /* Don't expose key material */ + memset (output, 0, output_len); + g_free (output); + output = NULL; + } + } + gcry_cipher_close (ctx); + return output; +} + +NMCryptoFileFormat +crypto_verify_cert (const unsigned char *data, + gsize len, + GError **error) +{ + gnutls_x509_crt_t der; + gnutls_datum_t dt; + int err; + + if (!crypto_init (error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + err = gnutls_x509_crt_init (&der); + if (err < 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Error initializing certificate data: %s"), + gnutls_strerror (err)); + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + } + + /* Try DER first */ + dt.data = (unsigned char *) data; + dt.size = len; + err = gnutls_x509_crt_import (der, &dt, GNUTLS_X509_FMT_DER); + if (err == GNUTLS_E_SUCCESS) { + gnutls_x509_crt_deinit (der); + return NM_CRYPTO_FILE_FORMAT_X509; + } + + /* And PEM next */ + err = gnutls_x509_crt_import (der, &dt, GNUTLS_X509_FMT_PEM); + gnutls_x509_crt_deinit (der); + if (err == GNUTLS_E_SUCCESS) + return NM_CRYPTO_FILE_FORMAT_X509; + + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode certificate: %s"), + gnutls_strerror (err)); + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; +} + +gboolean +crypto_verify_pkcs12 (const guint8 *data, + gsize data_len, + const char *password, + GError **error) +{ + gnutls_pkcs12_t p12; + gnutls_datum_t dt; + gboolean success = FALSE; + int err; + + g_return_val_if_fail (data != NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + dt.data = (unsigned char *) data; + dt.size = data_len; + + err = gnutls_pkcs12_init (&p12); + if (err < 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#12 decoder: %s"), + gnutls_strerror (err)); + return FALSE; + } + + /* DER first */ + err = gnutls_pkcs12_import (p12, &dt, GNUTLS_X509_FMT_DER, 0); + if (err < 0) { + /* PEM next */ + err = gnutls_pkcs12_import (p12, &dt, GNUTLS_X509_FMT_PEM, 0); + if (err < 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#12 file: %s"), + gnutls_strerror (err)); + goto out; + } + } + + err = gnutls_pkcs12_verify_mac (p12, password); + if (err == GNUTLS_E_SUCCESS) + success = TRUE; + else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Couldn't verify PKCS#12 file: %s"), + gnutls_strerror (err)); + } + +out: + gnutls_pkcs12_deinit (p12); + return success; +} + +gboolean +crypto_verify_pkcs8 (const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char *password, + GError **error) +{ + gnutls_x509_privkey_t p8; + gnutls_datum_t dt; + int err; + + g_return_val_if_fail (data != NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + dt.data = (unsigned char *) data; + dt.size = data_len; + + err = gnutls_x509_privkey_init (&p8); + if (err < 0) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#8 decoder: %s"), + gnutls_strerror (err)); + return FALSE; + } + + err = gnutls_x509_privkey_import_pkcs8 (p8, + &dt, + GNUTLS_X509_FMT_DER, + is_encrypted ? password : NULL, + is_encrypted ? 0 : GNUTLS_PKCS_PLAIN); + gnutls_x509_privkey_deinit (p8); + + if (err < 0) { + if (err == GNUTLS_E_UNKNOWN_CIPHER_TYPE) { + /* HACK: gnutls doesn't support all the cipher types that openssl + * can use with PKCS#8, so if we encounter one, we have to assume + * the given password works. gnutls needs to unsuckify, apparently. + * Specifically, by default openssl uses pbeWithMD5AndDES-CBC + * which gnutls does not support. + */ + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#8 file: %s"), + gnutls_strerror (err)); + return FALSE; + } + } + + return TRUE; +} + +gboolean +crypto_randomize (void *buffer, gsize buffer_len, GError **error) +{ + if (!crypto_init (error)) + return FALSE; + + gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM); + return TRUE; +} diff --git a/libnm-core/crypto_nss.c b/libnm-core/crypto_nss.c new file mode 100644 index 00000000..d0c3506b --- /dev/null +++ b/libnm-core/crypto_nss.c @@ -0,0 +1,526 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * Dan Williams + * + * 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. + * + * Copyright 2007 - 2009 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "nm-errors.h" + +static gboolean initialized = FALSE; + +gboolean +crypto_init (GError **error) +{ + SECStatus ret; + + if (initialized) + return TRUE; + + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 1); + ret = NSS_NoDB_Init (NULL); + if (ret != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the crypto engine: %d."), + PR_GetError ()); + PR_Cleanup (); + return FALSE; + } + + SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); + SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); + + initialized = TRUE; + return TRUE; +} + +char * +crypto_decrypt (const char *cipher, + int key_type, + const guint8 *data, + gsize data_len, + const char *iv, + const gsize iv_len, + const char *key, + const gsize key_len, + gsize *out_len, + GError **error) +{ + char *output = NULL; + int decrypted_len = 0; + CK_MECHANISM_TYPE cipher_mech; + PK11SlotInfo *slot = NULL; + SECItem key_item; + PK11SymKey *sym_key = NULL; + SECItem *sec_param = NULL; + PK11Context *ctx = NULL; + SECStatus s; + gboolean success = FALSE; + unsigned int pad_len = 0, extra = 0; + guint32 i, real_iv_len = 0; + + if (!crypto_init (error)) + return NULL; + + if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) { + cipher_mech = CKM_DES3_CBC_PAD; + real_iv_len = 8; + } else if (!strcmp (cipher, CIPHER_DES_CBC)) { + cipher_mech = CKM_DES_CBC_PAD; + real_iv_len = 8; + } else if (!strcmp (cipher, CIPHER_AES_CBC)) { + cipher_mech = CKM_AES_CBC_PAD; + real_iv_len = 16; + } else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Private key cipher '%s' was unknown."), + cipher); + return NULL; + } + + if (iv_len < real_iv_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Invalid IV length (must be at least %d)."), + real_iv_len); + return NULL; + } + + output = g_malloc0 (data_len); + + slot = PK11_GetBestSlot (cipher_mech, NULL); + if (!slot) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the decryption cipher slot.")); + goto out; + } + + key_item.data = (unsigned char *) key; + key_item.len = key_len; + sym_key = PK11_ImportSymKey (slot, cipher_mech, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL); + if (!sym_key) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set symmetric key for decryption.")); + goto out; + } + + key_item.data = (unsigned char *) iv; + key_item.len = real_iv_len; + sec_param = PK11_ParamFromIV (cipher_mech, &key_item); + if (!sec_param) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to set IV for decryption.")); + goto out; + } + + ctx = PK11_CreateContextBySymKey (cipher_mech, CKA_DECRYPT, sym_key, sec_param); + if (!ctx) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to initialize the decryption context.")); + goto out; + } + + s = PK11_CipherOp (ctx, + (unsigned char *) output, + &decrypted_len, + data_len, + data, + data_len); + if (s != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: %d."), + PORT_GetError ()); + goto out; + } + + if (decrypted_len > data_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: decrypted data too large.")); + goto out; + } + + s = PK11_DigestFinal (ctx, + (unsigned char *) (output + decrypted_len), + &extra, + data_len - decrypted_len); + if (s != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to finalize decryption of the private key: %d."), + PORT_GetError ()); + goto out; + } + decrypted_len += extra; + pad_len = data_len - decrypted_len; + + /* Check if the padding at the end of the decrypted data is valid */ + if (pad_len == 0 || pad_len > real_iv_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key: unexpected padding length.")); + goto out; + } + + /* Validate tail padding; last byte is the padding size, and all pad bytes + * should contain the padding size. + */ + for (i = pad_len; i > 0; i--) { + if (output[data_len - i] != pad_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Failed to decrypt the private key.")); + goto out; + } + } + + *out_len = decrypted_len; + success = TRUE; + +out: + if (ctx) + PK11_DestroyContext (ctx, PR_TRUE); + if (sym_key) + PK11_FreeSymKey (sym_key); + if (sec_param) + SECITEM_FreeItem (sec_param, PR_TRUE); + if (slot) + PK11_FreeSlot (slot); + + if (!success) { + if (output) { + /* Don't expose key material */ + memset (output, 0, data_len); + g_free (output); + output = NULL; + } + } + return output; +} + +char * +crypto_encrypt (const char *cipher, + const guint8 *data, + gsize data_len, + const char *iv, + gsize iv_len, + const char *key, + gsize key_len, + gsize *out_len, + GError **error) +{ + SECStatus ret; + CK_MECHANISM_TYPE cipher_mech = CKM_DES3_CBC_PAD; + PK11SlotInfo *slot = NULL; + SECItem key_item = { .data = (unsigned char *) key, .len = key_len }; + SECItem iv_item = { .data = (unsigned char *) iv, .len = iv_len }; + PK11SymKey *sym_key = NULL; + SECItem *sec_param = NULL; + PK11Context *ctx = NULL; + unsigned char *output, *padded_buf; + gsize output_len; + int encrypted_len = 0, i; + gboolean success = FALSE; + gsize padded_buf_len, pad_len; + + if (!crypto_init (error)) + return NULL; + + if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) + cipher_mech = CKM_DES3_CBC_PAD; + else if (!strcmp (cipher, CIPHER_AES_CBC)) + cipher_mech = CKM_AES_CBC_PAD; + else { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + _("Private key cipher '%s' was unknown."), + cipher); + return NULL; + } + + /* If data->len % ivlen == 0, then we add another complete block + * onto the end so that the decrypter knows there's padding. + */ + pad_len = iv_len - (data_len % iv_len); + output_len = padded_buf_len = data_len + pad_len; + padded_buf = g_malloc0 (padded_buf_len); + + memcpy (padded_buf, data, data_len); + for (i = 0; i < pad_len; i++) + padded_buf[data_len + i] = (guint8) (pad_len & 0xFF); + + output = g_malloc0 (output_len); + + slot = PK11_GetBestSlot (cipher_mech, NULL); + if (!slot) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Failed to initialize the encryption cipher slot.")); + goto out; + } + + sym_key = PK11_ImportSymKey (slot, cipher_mech, PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL); + if (!sym_key) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set symmetric key for encryption.")); + goto out; + } + + sec_param = PK11_ParamFromIV (cipher_mech, &iv_item); + if (!sec_param) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to set IV for encryption.")); + goto out; + } + + ctx = PK11_CreateContextBySymKey (cipher_mech, CKA_ENCRYPT, sym_key, sec_param); + if (!ctx) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to initialize the encryption context.")); + goto out; + } + + ret = PK11_CipherOp (ctx, output, &encrypted_len, output_len, padded_buf, padded_buf_len); + if (ret != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Failed to encrypt: %d."), + PORT_GetError ()); + goto out; + } + + if (encrypted_len != output_len) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, + _("Unexpected amount of data after encrypting.")); + goto out; + } + + *out_len = encrypted_len; + success = TRUE; + +out: + if (ctx) + PK11_DestroyContext (ctx, PR_TRUE); + if (sym_key) + PK11_FreeSymKey (sym_key); + if (sec_param) + SECITEM_FreeItem (sec_param, PR_TRUE); + if (slot) + PK11_FreeSlot (slot); + + memset (padded_buf, 0, padded_buf_len); + g_free (padded_buf); + + if (!success) { + memset (output, 0, output_len); + g_free (output); + output = NULL; + } + return (char *) output; +} + +NMCryptoFileFormat +crypto_verify_cert (const unsigned char *data, + gsize len, + GError **error) +{ + CERTCertificate *cert; + + if (!crypto_init (error)) + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + /* Try DER/PEM first */ + cert = CERT_DecodeCertFromPackage ((char *) data, len); + if (!cert) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode certificate: %d"), + PORT_GetError()); + return NM_CRYPTO_FILE_FORMAT_UNKNOWN; + } + + CERT_DestroyCertificate (cert); + return NM_CRYPTO_FILE_FORMAT_X509; +} + +gboolean +crypto_verify_pkcs12 (const guint8 *data, + gsize data_len, + const char *password, + GError **error) +{ + SEC_PKCS12DecoderContext *p12ctx = NULL; + SECItem pw = { 0 }; + PK11SlotInfo *slot = NULL; + SECStatus s; + gunichar2 *ucs2_password; + glong ucs2_chars = 0; +#ifndef WORDS_BIGENDIAN + guint16 *p; +#endif /* WORDS_BIGENDIAN */ + + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + /* PKCS#12 passwords are apparently UCS2 BIG ENDIAN, and NSS doesn't do + * any conversions for us. + */ + if (password && *password) { + if (!g_utf8_validate (password, -1, NULL)) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + _("Password must be UTF-8")); + return FALSE; + } + ucs2_password = g_utf8_to_utf16 (password, strlen (password), NULL, &ucs2_chars, NULL); + /* Can't fail if g_utf8_validate() succeeded */ + g_return_val_if_fail (ucs2_password != NULL && ucs2_chars != 0, FALSE); + + ucs2_chars *= 2; /* convert # UCS2 characters -> bytes */ + pw.data = PORT_ZAlloc(ucs2_chars + 2); + memcpy (pw.data, ucs2_password, ucs2_chars); + pw.len = ucs2_chars + 2; /* include terminating NULL */ + + memset (ucs2_password, 0, ucs2_chars); + g_free (ucs2_password); + +#ifndef WORDS_BIGENDIAN + for (p = (guint16 *) pw.data; p < (guint16 *) (pw.data + pw.len); p++) + *p = GUINT16_SWAP_LE_BE (*p); +#endif /* WORDS_BIGENDIAN */ + } else { + /* NULL password */ + pw.data = NULL; + pw.len = 0; + } + + slot = PK11_GetInternalKeySlot(); + p12ctx = SEC_PKCS12DecoderStart (&pw, slot, NULL, NULL, NULL, NULL, NULL, NULL); + if (!p12ctx) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Couldn't initialize PKCS#12 decoder: %d"), + PORT_GetError()); + goto error; + } + + s = SEC_PKCS12DecoderUpdate (p12ctx, (guint8 *)data, data_len); + if (s != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_INVALID_DATA, + _("Couldn't decode PKCS#12 file: %d"), + PORT_GetError()); + goto error; + } + + s = SEC_PKCS12DecoderVerify (p12ctx); + if (s != SECSuccess) { + g_set_error (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + _("Couldn't verify PKCS#12 file: %d"), + PORT_GetError()); + goto error; + } + + SEC_PKCS12DecoderFinish (p12ctx); + SECITEM_ZfreeItem (&pw, PR_FALSE); + return TRUE; + +error: + if (p12ctx) + SEC_PKCS12DecoderFinish (p12ctx); + + if (slot) + PK11_FreeSlot(slot); + + SECITEM_ZfreeItem (&pw, PR_FALSE); + return FALSE; +} + +gboolean +crypto_verify_pkcs8 (const guint8 *data, + gsize data_len, + gboolean is_encrypted, + const char *password, + GError **error) +{ + g_return_val_if_fail (data != NULL, FALSE); + + if (!crypto_init (error)) + return FALSE; + + /* NSS apparently doesn't do PKCS#8 natively, but you have to put the + * PKCS#8 key into a PKCS#12 file and import that?? So until we figure + * all that out, we can only assume the password is valid. + */ + return TRUE; +} + +gboolean +crypto_randomize (void *buffer, gsize buffer_len, GError **error) +{ + SECStatus s; + + if (!crypto_init (error)) + return FALSE; + + s = PK11_GenerateRandom (buffer, buffer_len); + if (s != SECSuccess) { + g_set_error_literal (error, NM_CRYPTO_ERROR, + NM_CRYPTO_ERROR_FAILED, + _("Could not generate random data.")); + return FALSE; + } + return TRUE; +} diff --git a/libnm-core/nm-connection-private.h b/libnm-core/nm-connection-private.h new file mode 100644 index 00000000..620e6a81 --- /dev/null +++ b/libnm-core/nm-connection-private.h @@ -0,0 +1,35 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NM_CONNECTION_PRIVATE_H__ +#define __NM_CONNECTION_PRIVATE_H__ + +#include "nm-setting.h" +#include "nm-connection.h" + +NMSetting *_nm_connection_find_base_type_setting (NMConnection *connection); + +const char *_nm_connection_detect_slave_type (NMConnection *connection, + NMSetting **out_s_port); + +gboolean _nm_connection_verify_required_interface_name (NMConnection *connection, + GError **error); + +#endif /* __NM_CONNECTION_PRIVATE_H__ */ diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c new file mode 100644 index 00000000..907713bd --- /dev/null +++ b/libnm-core/nm-connection.c @@ -0,0 +1,2077 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include "nm-connection.h" +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-core-internal.h" + +/** + * SECTION:nm-connection + * @short_description: Describes a connection to specific network or provider + * + * An #NMConnection describes all the settings and configuration values that + * are necessary to configure network devices for operation on a specific + * network. Connections are the fundamental operating object for + * NetworkManager; no device is connected without a #NMConnection, or + * disconnected without having been connected with a #NMConnection. + * + * Each #NMConnection contains a list of #NMSetting objects usually referenced + * by name (using nm_connection_get_setting_by_name()) or by type (with + * nm_connection_get_setting()). The settings describe the actual parameters + * with which the network devices are configured, including device-specific + * parameters (MTU, SSID, APN, channel, rate, etc) and IP-level parameters + * (addresses, routes, addressing methods, etc). + * + */ + +typedef struct { + NMConnection *self; + + GHashTable *settings; + + /* D-Bus path of the connection, if any */ + char *path; +} NMConnectionPrivate; + +static NMConnectionPrivate *nm_connection_get_private (NMConnection *connection); +#define NM_CONNECTION_GET_PRIVATE(o) (nm_connection_get_private ((NMConnection *)o)) + +G_DEFINE_INTERFACE (NMConnection, nm_connection, G_TYPE_OBJECT) + +enum { + SECRETS_UPDATED, + SECRETS_CLEARED, + CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +static NMSettingVerifyResult _nm_connection_verify (NMConnection *connection, GError **error); + + +/*************************************************************/ + +static void +setting_changed_cb (NMSetting *setting, + GParamSpec *pspec, + NMConnection *self) +{ + g_signal_emit (self, signals[CHANGED], 0); +} + +static gboolean +_setting_release (gpointer key, gpointer value, gpointer user_data) +{ + g_signal_handlers_disconnect_by_func (user_data, setting_changed_cb, value); + return TRUE; +} + +static void +_nm_connection_add_setting (NMConnection *connection, NMSetting *setting) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + const char *name = G_OBJECT_TYPE_NAME (setting); + NMSetting *s_old; + + if ((s_old = g_hash_table_lookup (priv->settings, (gpointer) name))) + g_signal_handlers_disconnect_by_func (s_old, setting_changed_cb, connection); + g_hash_table_insert (priv->settings, (gpointer) name, setting); + /* Listen for property changes so we can emit the 'changed' signal */ + g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection); +} + +/** + * nm_connection_add_setting: + * @connection: a #NMConnection + * @setting: (transfer full): the #NMSetting to add to the connection object + * + * Adds a #NMSetting to the connection, replacing any previous #NMSetting of the + * same name which has previously been added to the #NMConnection. The + * connection takes ownership of the #NMSetting object and does not increase + * the setting object's reference count. + **/ +void +nm_connection_add_setting (NMConnection *connection, NMSetting *setting) +{ + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (NM_IS_SETTING (setting)); + + _nm_connection_add_setting (connection, setting); + g_signal_emit (connection, signals[CHANGED], 0); +} + +/** + * nm_connection_remove_setting: + * @connection: a #NMConnection + * @setting_type: the #GType of the setting object to remove + * + * Removes the #NMSetting with the given #GType from the #NMConnection. This + * operation dereferences the #NMSetting object. + **/ +void +nm_connection_remove_setting (NMConnection *connection, GType setting_type) +{ + NMConnectionPrivate *priv; + NMSetting *setting; + const char *setting_name; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (g_type_is_a (setting_type, NM_TYPE_SETTING)); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + setting_name = g_type_name (setting_type); + setting = g_hash_table_lookup (priv->settings, setting_name); + if (setting) { + g_signal_handlers_disconnect_by_func (setting, setting_changed_cb, connection); + g_hash_table_remove (priv->settings, setting_name); + g_signal_emit (connection, signals[CHANGED], 0); + } +} + +/** + * nm_connection_get_setting: + * @connection: a #NMConnection + * @setting_type: the #GType of the setting object to return + * + * Gets the #NMSetting with the given #GType, if one has been previously added + * to the #NMConnection. + * + * Returns: (transfer none): the #NMSetting, or %NULL if no setting of that type was previously + * added to the #NMConnection + **/ +NMSetting * +nm_connection_get_setting (NMConnection *connection, GType setting_type) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (g_type_is_a (setting_type, NM_TYPE_SETTING), NULL); + + return (NMSetting *) g_hash_table_lookup (NM_CONNECTION_GET_PRIVATE (connection)->settings, + g_type_name (setting_type)); +} + +/** + * nm_connection_get_setting_by_name: + * @connection: a #NMConnection + * @name: a setting name + * + * Gets the #NMSetting with the given name, if one has been previously added + * the #NMConnection. + * + * Returns: (transfer none): the #NMSetting, or %NULL if no setting with that name was previously + * added to the #NMConnection + **/ +NMSetting * +nm_connection_get_setting_by_name (NMConnection *connection, const char *name) +{ + GType type; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (name != NULL, NULL); + + type = nm_setting_lookup_type (name); + + return type ? nm_connection_get_setting (connection, type) : NULL; +} + +static gboolean +validate_permissions_type (GVariant *variant, GError **error) +{ + GVariant *s_con; + GVariant *permissions; + gboolean valid = TRUE; + + /* Ensure the connection::permissions item (if present) is the correct + * type, otherwise the g_object_set() will throw a warning and ignore the + * error, leaving us with no permissions. + */ + s_con = g_variant_lookup_value (variant, NM_SETTING_CONNECTION_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!s_con) + return TRUE; + + permissions = g_variant_lookup_value (s_con, NM_SETTING_CONNECTION_PERMISSIONS, NULL); + if (permissions) { + if (!g_variant_is_of_type (permissions, G_VARIANT_TYPE_STRING_ARRAY)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("wrong type; should be a list of strings.")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_PERMISSIONS); + valid = FALSE; + } + g_variant_unref (permissions); + } + + g_variant_unref (s_con); + return valid; +} + +/** + * nm_connection_replace_settings: + * @connection: a #NMConnection + * @new_settings: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION, with the new settings + * @error: location to store error, or %NULL + * + * Replaces @connection's settings with @new_settings (which must be + * syntactically valid, and describe a known type of connection, but does not + * need to result in a connection that passes nm_connection_verify()). + * + * Returns: %TRUE if connection was updated, %FALSE if @new_settings could not + * be deserialized (in which case @connection will be unchanged). + **/ +gboolean +nm_connection_replace_settings (NMConnection *connection, + GVariant *new_settings, + GError **error) +{ + NMConnectionPrivate *priv; + GVariantIter iter; + const char *setting_name; + GVariant *setting_dict; + GSList *settings = NULL, *s; + gboolean changed; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (g_variant_is_of_type (new_settings, NM_VARIANT_TYPE_CONNECTION), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + + if (!validate_permissions_type (new_settings, error)) + return FALSE; + + g_variant_iter_init (&iter, new_settings); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) { + NMSetting *setting; + GType type; + + type = nm_setting_lookup_type (setting_name); + if (type == G_TYPE_INVALID) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("unknown setting name")); + g_prefix_error (error, "%s: ", setting_name); + g_variant_unref (setting_dict); + g_slist_free_full (settings, g_object_unref); + return FALSE; + } + + setting = _nm_setting_new_from_dbus (type, setting_dict, new_settings, error); + g_variant_unref (setting_dict); + + if (!setting) { + g_slist_free_full (settings, g_object_unref); + return FALSE; + } + + settings = g_slist_prepend (settings, setting); + } + + if (g_hash_table_size (priv->settings) > 0) { + g_hash_table_foreach_remove (priv->settings, _setting_release, connection); + changed = TRUE; + } else + changed = (settings != NULL); + + for (s = settings; s; s = s->next) + _nm_connection_add_setting (connection, s->data); + + if (changed) + g_signal_emit (connection, signals[CHANGED], 0); + return TRUE; +} + +/** + * nm_connection_replace_settings_from_connection: + * @connection: a #NMConnection + * @new_connection: a #NMConnection to replace the settings of @connection with + * + * Deep-copies the settings of @new_connection and replaces the settings of @connection + * with the copied settings. + **/ +void +nm_connection_replace_settings_from_connection (NMConnection *connection, + NMConnection *new_connection) +{ + NMConnectionPrivate *priv, *new_priv; + GHashTableIter iter; + NMSetting *setting; + gboolean changed; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (NM_IS_CONNECTION (new_connection)); + + /* When 'connection' and 'new_connection' are the same object simply return + * in order not to destroy 'connection'. + */ + if (connection == new_connection) + return; + + /* No need to validate permissions like nm_connection_replace_settings() + * since we're dealing with an NMConnection which has already done that. + */ + + priv = NM_CONNECTION_GET_PRIVATE (connection); + new_priv = NM_CONNECTION_GET_PRIVATE (new_connection); + + if ((changed = g_hash_table_size (priv->settings) > 0)) + g_hash_table_foreach_remove (priv->settings, _setting_release, connection); + + if (g_hash_table_size (new_priv->settings)) { + g_hash_table_iter_init (&iter, new_priv->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) + _nm_connection_add_setting (connection, nm_setting_duplicate (setting)); + changed = TRUE; + } + + if (changed) + g_signal_emit (connection, signals[CHANGED], 0); +} + +/** + * nm_connection_clear_settings: + * @connection: a #NMConnection + * + * Deletes all of @connection's settings. + **/ +void +nm_connection_clear_settings (NMConnection *connection) +{ + NMConnectionPrivate *priv; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + + if (g_hash_table_size (priv->settings) > 0) { + g_hash_table_foreach_remove (priv->settings, _setting_release, connection); + g_signal_emit (connection, signals[CHANGED], 0); + } +} + +/** + * nm_connection_compare: + * @a: a #NMConnection + * @b: a second #NMConnection to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * + * Compares two #NMConnection objects for similarity, with comparison behavior + * modified by a set of flags. See nm_setting_compare() for a description of + * each flag's behavior. + * + * Returns: %TRUE if the comparison succeeds, %FALSE if it does not + **/ +gboolean +nm_connection_compare (NMConnection *a, + NMConnection *b, + NMSettingCompareFlags flags) +{ + GHashTableIter iter; + NMSetting *src; + + if (a == b) + return TRUE; + if (!a || !b) + return FALSE; + + /* B / A: ensure settings in B that are not in A make the comparison fail */ + if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (a)->settings) != + g_hash_table_size (NM_CONNECTION_GET_PRIVATE (b)->settings)) + return FALSE; + + /* A / B: ensure all settings in A match corresponding ones in B */ + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (a)->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &src)) { + NMSetting *cmp = nm_connection_get_setting (b, G_OBJECT_TYPE (src)); + + if (!cmp || !nm_setting_compare (src, cmp, flags)) + return FALSE; + } + + return TRUE; +} + + +static void +diff_one_connection (NMConnection *a, + NMConnection *b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable *diffs) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (a); + GHashTableIter iter; + NMSetting *a_setting = NULL; + + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &a_setting)) { + NMSetting *b_setting = NULL; + const char *setting_name = nm_setting_get_name (a_setting); + GHashTable *results; + gboolean new_results = TRUE; + + if (b) + b_setting = nm_connection_get_setting (b, G_OBJECT_TYPE (a_setting)); + + results = g_hash_table_lookup (diffs, setting_name); + if (results) + new_results = FALSE; + + if (!nm_setting_diff (a_setting, b_setting, flags, invert_results, &results)) { + if (new_results) + g_hash_table_insert (diffs, g_strdup (setting_name), results); + } + } +} + +/** + * nm_connection_diff: + * @a: a #NMConnection + * @b: a second #NMConnection to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * @out_settings: (element-type utf8 GLib.HashTable): if the + * connections differ, on return a hash table mapping setting names to + * second-level GHashTable (utf8 to guint32), which contains the key names that + * differ mapped to one or more of %NMSettingDiffResult as a bitfield + * + * Compares two #NMConnection objects for similarity, with comparison behavior + * modified by a set of flags. See nm_setting_compare() for a description of + * each flag's behavior. If the connections differ, settings and keys within + * each setting that differ are added to the returned @out_settings hash table. + * No values are returned, only key names. + * + * Returns: %TRUE if the connections contain the same values, %FALSE if they do + * not + **/ +gboolean +nm_connection_diff (NMConnection *a, + NMConnection *b, + NMSettingCompareFlags flags, + GHashTable **out_settings) +{ + GHashTable *diffs; + + g_return_val_if_fail (NM_IS_CONNECTION (a), FALSE); + g_return_val_if_fail (out_settings != NULL, FALSE); + g_return_val_if_fail (*out_settings == NULL, FALSE); + if (b) + g_return_val_if_fail (NM_IS_CONNECTION (b), FALSE); + + if (a == b) + return TRUE; + + diffs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy); + + /* Diff A to B, then B to A to capture keys in B that aren't in A */ + diff_one_connection (a, b, flags, FALSE, diffs); + if (b) + diff_one_connection (b, a, flags, TRUE, diffs); + + if (g_hash_table_size (diffs) == 0) + g_hash_table_destroy (diffs); + else + *out_settings = diffs; + + return *out_settings ? FALSE : TRUE; +} + +NMSetting * +_nm_connection_find_base_type_setting (NMConnection *connection) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + GHashTableIter iter; + NMSetting *setting = NULL, *s_iter; + + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &s_iter)) { + if (!_nm_setting_is_base_type (s_iter)) + continue; + + if (setting) { + /* FIXME: currently, if there is more than one matching base type, + * we cannot detect the base setting. + * See: https://bugzilla.gnome.org/show_bug.cgi?id=696936#c8 */ + return NULL; + } + setting = s_iter; + } + return setting; +} + +static gboolean +_normalize_connection_uuid (NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + char *uuid; + + g_assert (s_con); + + if (nm_setting_connection_get_uuid (s_con)) + return FALSE; + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); + g_free (uuid); + + return TRUE; +} + +static gboolean +_normalize_connection_type (NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + NMSetting *s_base = NULL; + const char *type; + + type = nm_setting_connection_get_connection_type (s_con); + + if (type) { + s_base = nm_connection_get_setting_by_name (self, type); + + if (!s_base) { + GType base_type = nm_setting_lookup_type (type); + + g_return_val_if_fail (base_type, FALSE); + nm_connection_add_setting (self, g_object_new (base_type, NULL)); + return TRUE; + } + } else { + s_base = _nm_connection_find_base_type_setting (self); + g_return_val_if_fail (s_base, FALSE); + + type = nm_setting_get_name (s_base); + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + return TRUE; + } + + return FALSE; +} + +const char * +_nm_connection_detect_slave_type (NMConnection *connection, NMSetting **out_s_port) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + GHashTableIter iter; + const char *slave_type = NULL; + NMSetting *s_port = NULL, *s_iter; + + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &s_iter)) { + const char *name = nm_setting_get_name (s_iter); + const char *i_slave_type = NULL; + + if (!strcmp (name, NM_SETTING_BRIDGE_PORT_SETTING_NAME)) + i_slave_type = NM_SETTING_BRIDGE_SETTING_NAME; + else if (!strcmp (name, NM_SETTING_TEAM_PORT_SETTING_NAME)) + i_slave_type = NM_SETTING_TEAM_SETTING_NAME; + else + continue; + + if (slave_type) { + /* there are more then one matching port types, cannot detect the slave type. */ + slave_type = NULL; + s_port = NULL; + break; + } + slave_type = i_slave_type; + s_port = s_iter; + } + + if (out_s_port) + *out_s_port = s_port; + return slave_type; +} + +static gboolean +_normalize_connection_slave_type (NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + const char *slave_type, *port_type; + + if (!s_con) + return FALSE; + if (!nm_setting_connection_get_master (s_con)) + return FALSE; + + slave_type = nm_setting_connection_get_slave_type (s_con); + if (slave_type) { + if ( _nm_setting_slave_type_is_valid (slave_type, &port_type) + && port_type) { + NMSetting *s_port; + + s_port = nm_connection_get_setting_by_name (self, port_type); + if (!s_port) { + GType p_type = nm_setting_lookup_type (port_type); + + g_return_val_if_fail (p_type, FALSE); + nm_connection_add_setting (self, g_object_new (p_type, NULL)); + return TRUE; + } + } + } else { + if ((slave_type = _nm_connection_detect_slave_type (self, NULL))) { + g_object_set (s_con, NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, NULL); + return TRUE; + } + } + return FALSE; +} + +static gboolean +_normalize_ip_config (NMConnection *self, GHashTable *parameters) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + const char *default_ip6_method = NULL; + NMSettingIPConfig *s_ip4, *s_ip6; + NMSetting *setting; + + if (parameters) + default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD); + if (!default_ip6_method) + default_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + + s_ip4 = nm_connection_get_setting_ip4_config (self); + s_ip6 = nm_connection_get_setting_ip6_config (self); + + if (nm_setting_connection_get_master (s_con)) { + /* Slave connections don't have IP configuration. */ + + if (s_ip4) + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP4_CONFIG); + + if (s_ip6) + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP6_CONFIG); + + return s_ip4 || s_ip6; + } else { + /* Ensure all non-slave connections have IP4 and IP6 settings objects. If no + * IP6 setting was specified, then assume that means IP6 config is allowed + * to fail. But if no IP4 setting was specified, assume the caller was just + * being lazy. + */ + if (!s_ip4) { + setting = nm_setting_ip4_config_new (); + + g_object_set (setting, + NM_SETTING_IP_CONFIG_METHOD, default_ip4_method, + NULL); + nm_connection_add_setting (self, setting); + } + if (!s_ip6) { + setting = nm_setting_ip6_config_new (); + + g_object_set (setting, + NM_SETTING_IP_CONFIG_METHOD, default_ip6_method, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NULL); + nm_connection_add_setting (self, setting); + } + return !s_ip4 || !s_ip6; + } +} + +static gboolean +_normalize_infiniband_mtu (NMConnection *self, GHashTable *parameters) +{ + NMSettingInfiniband *s_infini = nm_connection_get_setting_infiniband (self); + + if (s_infini) { + const char *transport_mode = nm_setting_infiniband_get_transport_mode (s_infini); + guint32 max_mtu = 0; + + if (transport_mode) { + if (!strcmp (transport_mode, "datagram")) + max_mtu = 2044; + else if (!strcmp (transport_mode, "connected")) + max_mtu = 65520; + + if (max_mtu && nm_setting_infiniband_get_mtu (s_infini) > max_mtu) { + g_object_set (s_infini, NM_SETTING_INFINIBAND_MTU, max_mtu, NULL); + return TRUE; + } + } + } + return FALSE; +} + +/** + * nm_connection_verify: + * @connection: the #NMConnection to verify + * @error: location to store error, or %NULL + * + * Validates the connection and all its settings. Each setting's properties + * have allowed values, and some values are dependent on other values. For + * example, if a Wi-Fi connection is security enabled, the #NMSettingWireless + * setting object's 'security' property must contain the setting name of the + * #NMSettingWirelessSecurity object, which must also be present in the + * connection for the connection to be valid. As another example, the + * #NMSettingWired object's 'mac-address' property must be a validly formatted + * MAC address. The returned #GError contains information about which + * setting and which property failed validation, and how it failed validation. + * + * Returns: %TRUE if the connection is valid, %FALSE if it is not + **/ +gboolean +nm_connection_verify (NMConnection *connection, GError **error) +{ + NMSettingVerifyResult result; + + result = _nm_connection_verify (connection, error); + + /* we treat normalizable connections as valid. */ + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error (error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +static NMSettingVerifyResult +_nm_connection_verify (NMConnection *connection, GError **error) +{ + NMConnectionPrivate *priv; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip4, *s_ip6; + GHashTableIter iter; + gpointer value; + GSList *all_settings = NULL, *setting_i; + NMSettingVerifyResult success = NM_SETTING_VERIFY_ERROR; + GError *normalizable_error = NULL; + NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!error || !*error, NM_SETTING_VERIFY_ERROR); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + + /* First, make sure there's at least 'connection' setting */ + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting not found")); + g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + goto EXIT; + } + + /* Build up the list of settings */ + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + /* Order NMSettingConnection so that it will be verified first. + * The reason is, that errors in this setting might be more fundamental + * and should be checked and reported with higher priority. + */ + if (value == s_con) + all_settings = g_slist_append (all_settings, value); + else + all_settings = g_slist_prepend (all_settings, value); + } + all_settings = g_slist_reverse (all_settings); + + /* Now, run the verify function of each setting */ + for (setting_i = all_settings; setting_i; setting_i = setting_i->next) { + GError *verify_error = NULL; + NMSettingVerifyResult verify_result; + + /* verify all settings. We stop if we find the first non-normalizable + * @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue + * but remember the error to return it to the user. + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR has a higher priority then + * @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type, + * we remember it instead (to return it as output). + **/ + verify_result = _nm_setting_verify (NM_SETTING (setting_i->data), connection, &verify_error); + if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE || + verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) { + if ( verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR + && normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE) { + /* NORMALIZABLE_ERROR has higher priority. */ + g_clear_error (&normalizable_error); + } + if (!normalizable_error) { + g_propagate_error (&normalizable_error, verify_error); + verify_error = NULL; + normalizable_error_type = verify_result; + } + } else if (verify_result != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error (error, verify_error); + g_slist_free (all_settings); + g_return_val_if_fail (verify_result == NM_SETTING_VERIFY_ERROR, success); + goto EXIT; + } + g_clear_error (&verify_error); + } + g_slist_free (all_settings); + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + + if (nm_setting_connection_get_master (s_con)) { + if ((normalizable_error_type == NM_SETTING_VERIFY_SUCCESS || + (normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE)) && (s_ip4 || s_ip6)) { + g_clear_error (&normalizable_error); + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error (&normalizable_error, "%s: ", + s_ip4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME : NM_SETTING_IP6_CONFIG_SETTING_NAME); + /* having a slave with IP config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } else { + if (normalizable_error_type == NM_SETTING_VERIFY_SUCCESS && (!s_ip4 || !s_ip6)) { + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error (&normalizable_error, "%s: ", + !s_ip4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME : NM_SETTING_IP6_CONFIG_SETTING_NAME); + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } + + if (normalizable_error_type != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error (error, normalizable_error); + normalizable_error = NULL; + success = normalizable_error_type; + } else + success = NM_SETTING_VERIFY_SUCCESS; + +EXIT: + g_clear_error (&normalizable_error); + return success; +} + +/** + * nm_connection_normalize: + * @connection: the #NMConnection to normalize + * @parameters: (allow-none) (element-type utf8 gpointer): a #GHashTable with + * normalization parameters to allow customization of the normalization by providing + * specific arguments. Unknown arguments will be ignored and the default will be + * used. The keys must be strings, hashed by g_str_hash() and g_str_equal() functions. + * The values are opaque and depend on the parameter name. + * @modified: (out) (allow-none): outputs whether any settings were modified. + * @error: location to store error, or %NULL. Contains the reason, + * why the connection is invalid, if the function returns an error. + * + * Does some basic normalization and fixup of well known inconsistencies + * and deprecated fields. If the connection was modified in any way, + * the output parameter @modified is set %TRUE. + * + * Finally the connection will be verified and %TRUE returns if the connection + * is valid. As this function only performs some specific normalization steps + * it cannot repair all connections. If the connection has errors that + * cannot be normalized, the connection will not be modified. + * + * Returns: %TRUE if the connection is valid, %FALSE if it is not + **/ +gboolean +nm_connection_normalize (NMConnection *connection, + GHashTable *parameters, + gboolean *modified, + GError **error) +{ + NMSettingVerifyResult success; + gboolean was_modified = FALSE; + GError *normalizable_error = NULL; + + success = _nm_connection_verify (connection, &normalizable_error); + + if (success == NM_SETTING_VERIFY_ERROR || + success == NM_SETTING_VERIFY_SUCCESS) { + if (normalizable_error) + g_propagate_error (error, normalizable_error); + if (modified) + *modified = FALSE; + if (success == NM_SETTING_VERIFY_ERROR && error && !*error) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unexpected failure to verify the connection")); + g_return_val_if_reached (FALSE); + } + return success == NM_SETTING_VERIFY_SUCCESS; + } + g_assert (success == NM_SETTING_VERIFY_NORMALIZABLE || success == NM_SETTING_VERIFY_NORMALIZABLE_ERROR); + g_clear_error (&normalizable_error); + + /* Try to perform all kind of normalizations on the settings to fix it. + * We only do this, after verifying that the connection contains no un-normalizable + * errors, because in that case we rather fail without touching the settings. */ + + was_modified |= _normalize_connection_uuid (connection); + was_modified |= _normalize_connection_type (connection); + was_modified |= _normalize_connection_slave_type (connection); + was_modified |= _normalize_ip_config (connection, parameters); + was_modified |= _normalize_infiniband_mtu (connection, parameters); + + /* Verify anew. */ + success = _nm_connection_verify (connection, error); + + if (modified) + *modified = was_modified; + + if (success != NM_SETTING_VERIFY_SUCCESS) { + /* we would expect, that after normalization, the connection can be verified. + * Also treat NM_SETTING_VERIFY_NORMALIZABLE as failure, because there is something + * odd going on. */ + if (error && !*error) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Unexpected failure to normalize the connection")); + } + g_return_val_if_reached (FALSE); + } + + /* we would expect, that the connection was modified during normalization. */ + g_return_val_if_fail (was_modified, TRUE); + + return TRUE; +} + +/** + * nm_connection_update_secrets: + * @connection: the #NMConnection + * @setting_name: the setting object name to which the secrets apply + * @secrets: a #GVariant of secrets, of type %NM_VARIANT_TYPE_CONNECTION + * or %NM_VARIANT_TYPE_SETTING + * @error: location to store error, or %NULL + * + * Update the specified setting's secrets, given a dictionary of secrets + * intended for that setting (deserialized from D-Bus for example). Will also + * extract the given setting's secrets hash if given a connection dictionary. + * If @setting_name is %NULL, expects a fully serialized #NMConnection as + * returned by nm_connection_to_dbus() and will update all secrets from all + * settings contained in @secrets. + * + * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update + * failed (tried to update secrets for a setting that doesn't exist, etc) + **/ +gboolean +nm_connection_update_secrets (NMConnection *connection, + const char *setting_name, + GVariant *secrets, + GError **error) +{ + NMSetting *setting; + gboolean success = TRUE, updated = FALSE; + GVariant *setting_dict = NULL; + GVariantIter iter; + const char *key; + gboolean full_connection; + int success_detail; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail ( g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING) + || g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION), FALSE); + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + + full_connection = g_variant_is_of_type (secrets, NM_VARIANT_TYPE_CONNECTION); + g_return_val_if_fail (setting_name != NULL || full_connection, FALSE); + + /* Empty @secrets means success */ + if (g_variant_n_children (secrets) == 0) + return TRUE; + + if (setting_name) { + /* Update just one setting's secrets */ + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (!setting) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + setting_name); + return FALSE; + } + + if (full_connection) { + setting_dict = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) { + /* The connection dictionary didn't contain any secrets for + * @setting_name; just return success. + */ + return TRUE; + } + } + + g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); + success_detail = _nm_setting_update_secrets (setting, + setting_dict ? setting_dict : secrets, + error); + g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + + g_clear_pointer (&setting_dict, g_variant_unref); + + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) + return FALSE; + if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + updated = TRUE; + } else { + /* check first, whether all the settings exist... */ + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, NULL)) { + setting = nm_connection_get_setting_by_name (connection, key); + if (!setting) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + key); + return FALSE; + } + } + + /* Update each setting with any secrets from the connection dictionary */ + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s@a{sv}}", &key, &setting_dict)) { + /* Update the secrets for this setting */ + setting = nm_connection_get_setting_by_name (connection, key); + + g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); + success_detail = _nm_setting_update_secrets (setting, setting_dict, error); + g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + + g_variant_unref (setting_dict); + + if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) { + success = FALSE; + break; + } + if (success_detail == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + updated = TRUE; + } + } + + if (updated) { + g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name); + g_signal_emit (connection, signals[CHANGED], 0); + } + + return success; +} + +/** + * nm_connection_need_secrets: + * @connection: the #NMConnection + * @hints: (out) (element-type utf8) (allow-none) (transfer container): + * the address of a pointer to a #GPtrArray, initialized to %NULL, which on + * return points to an allocated #GPtrArray containing the property names of + * secrets of the #NMSetting which may be required; the caller owns the array + * and must free the array itself with g_ptr_array_free(), but not free its + * elements + * + * Returns the name of the first setting object in the connection which would + * need secrets to make a successful connection. The returned hints are only + * intended as a guide to what secrets may be required, because in some + * circumstances, there is no way to conclusively determine exactly which + * secrets are needed. + * + * Returns: the setting name of the #NMSetting object which has invalid or + * missing secrets + **/ +const char * +nm_connection_need_secrets (NMConnection *connection, + GPtrArray **hints) +{ + NMConnectionPrivate *priv; + GHashTableIter hiter; + GSList *settings = NULL; + GSList *iter; + const char *name = NULL; + NMSetting *setting; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + if (hints) + g_return_val_if_fail (*hints == NULL, NULL); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + + /* Get list of settings in priority order */ + g_hash_table_iter_init (&hiter, priv->settings); + while (g_hash_table_iter_next (&hiter, NULL, (gpointer) &setting)) + settings = g_slist_insert_sorted (settings, setting, _nm_setting_compare_priority); + + for (iter = settings; iter; iter = g_slist_next (iter)) { + GPtrArray *secrets; + + setting = NM_SETTING (iter->data); + secrets = _nm_setting_need_secrets (setting); + if (secrets) { + if (hints) + *hints = secrets; + else + g_ptr_array_free (secrets, TRUE); + + name = nm_setting_get_name (setting); + break; + } + } + + g_slist_free (settings); + return name; +} + +/** + * nm_connection_clear_secrets: + * @connection: the #NMConnection + * + * Clears and frees any secrets that may be stored in the connection, to avoid + * keeping secret data in memory when not needed. + **/ +void +nm_connection_clear_secrets (NMConnection *connection) +{ + GHashTableIter iter; + NMSetting *setting; + gboolean changed = FALSE; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) { + g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); + changed |= _nm_setting_clear_secrets (setting); + g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + } + + g_signal_emit (connection, signals[SECRETS_CLEARED], 0); + if (changed) + g_signal_emit (connection, signals[CHANGED], 0); +} + +/** + * nm_connection_clear_secrets_with_flags: + * @connection: the #NMConnection + * @func: (scope call): function to be called to determine whether a + * specific secret should be cleared or not + * @user_data: caller-supplied data passed to @func + * + * Clears and frees secrets determined by @func. + **/ +void +nm_connection_clear_secrets_with_flags (NMConnection *connection, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + GHashTableIter iter; + NMSetting *setting; + gboolean changed = FALSE; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) { + g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); + changed |= _nm_setting_clear_secrets_with_flags (setting, func, user_data); + g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); + } + + g_signal_emit (connection, signals[SECRETS_CLEARED], 0); + if (changed) + g_signal_emit (connection, signals[CHANGED], 0); +} + +/** + * nm_connection_to_dbus: + * @connection: the #NMConnection + * @flags: serialization flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * + * Converts the #NMConnection into a #GVariant of type + * %NM_VARIANT_TYPE_CONNECTION describing the connection, suitable for + * marshalling over D-Bus or otherwise serializing. + * + * Returns: (transfer none): a new floating #GVariant describing the connection, + * its settings, and each setting's properties. + **/ +GVariant * +nm_connection_to_dbus (NMConnection *connection, + NMConnectionSerializationFlags flags) +{ + NMConnectionPrivate *priv; + GVariantBuilder builder; + GHashTableIter iter; + gpointer key, data; + GVariant *setting_dict, *ret; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + priv = NM_CONNECTION_GET_PRIVATE (connection); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + + /* Add each setting's hash to the main hash */ + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, &key, &data)) { + NMSetting *setting = NM_SETTING (data); + + setting_dict = _nm_setting_to_dbus (setting, connection, flags); + if (setting_dict) + g_variant_builder_add (&builder, "{s@a{sv}}", nm_setting_get_name (setting), setting_dict); + } + + ret = g_variant_builder_end (&builder); + + /* Don't send empty hashes */ + if (g_variant_n_children (ret) == 0) { + g_variant_unref (ret); + ret = NULL; + } + + return ret; +} + +/** + * nm_connection_is_type: + * @connection: the #NMConnection + * @type: a setting name to check the connection's type against (like + * %NM_SETTING_WIRELESS_SETTING_NAME or %NM_SETTING_WIRED_SETTING_NAME) + * + * A convenience function to check if the given @connection is a particular + * type (ie wired, Wi-Fi, ppp, etc). Checks the #NMSettingConnection:type + * property of the connection and matches that against @type. + * + * Returns: %TRUE if the connection is of the given @type, %FALSE if not + **/ +gboolean +nm_connection_is_type (NMConnection *connection, const char *type) +{ + NMSettingConnection *s_con; + const char *type2; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (type != NULL, FALSE); + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) + return FALSE; + + type2 = nm_setting_connection_get_connection_type (s_con); + + return (g_strcmp0 (type2, type) == 0); +} + +/** + * nm_connection_for_each_setting_value: + * @connection: the #NMConnection + * @func: (scope call): user-supplied function called for each setting's property + * @user_data: user data passed to @func at each invocation + * + * Iterates over the properties of each #NMSetting object in the #NMConnection, + * calling the supplied user function for each property. + **/ +void +nm_connection_for_each_setting_value (NMConnection *connection, + NMSettingValueIterFn func, + gpointer user_data) +{ + GHashTableIter iter; + gpointer value; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (func != NULL); + + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, &value)) + nm_setting_enumerate_values (NM_SETTING (value), func, user_data); +} + +/** + * nm_connection_dump: + * @connection: the #NMConnection + * + * Print the connection to stdout. For debugging purposes ONLY, should NOT + * be used for serialization of the connection or machine-parsed in any way. The + * output format is not guaranteed to be stable and may change at any time. + **/ +void +nm_connection_dump (NMConnection *connection) +{ + GHashTableIter iter; + NMSetting *setting; + const char *setting_name; + char *str; + + if (!connection) + return; + + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting)) { + str = nm_setting_to_string (setting); + g_print ("%s\n", str); + g_free (str); + } +} + +/** + * nm_connection_set_path: + * @connection: the #NMConnection + * @path: the D-Bus path of the connection as given by the settings service + * which provides the connection + * + * Sets the D-Bus path of the connection. This property is not serialized, and + * is only for the reference of the caller. Sets the #NMConnection:path + * property. + **/ +void +nm_connection_set_path (NMConnection *connection, const char *path) +{ + NMConnectionPrivate *priv; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + + priv = NM_CONNECTION_GET_PRIVATE (connection); + + g_free (priv->path); + priv->path = NULL; + + if (path) + priv->path = g_strdup (path); +} + +/** + * nm_connection_get_path: + * @connection: the #NMConnection + * + * Returns the connection's D-Bus path. + * + * Returns: the D-Bus path of the connection, previously set by a call to + * nm_connection_set_path(). + **/ +const char * +nm_connection_get_path (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return NM_CONNECTION_GET_PRIVATE (connection)->path; +} + +/** + * nm_connection_get_interface_name: + * @connection: The #NMConnection + * + * Returns the interface name as stored in NMSettingConnection:interface_name. + * If the connection contains no NMSettingConnection, it will return %NULL. + * + * For hardware devices and software devices created outside of NetworkManager, + * this name is used to match the device. for software devices created by + * NetworkManager, this is the name of the created interface. + * + * Returns: Name of the kernel interface or %NULL + */ +const char * +nm_connection_get_interface_name (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = nm_connection_get_setting_connection (connection); + + return s_con ? nm_setting_connection_get_interface_name (s_con) : NULL; +} + +gboolean +_nm_connection_verify_required_interface_name (NMConnection *connection, + GError **error) +{ + const char *interface_name; + + interface_name = nm_connection_get_interface_name (connection); + if (interface_name) + return TRUE; + + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; +} + +/** + * nm_connection_get_uuid: + * @connection: the #NMConnection + * + * A shortcut to return the UUID from the connection's #NMSettingConnection. + * + * Returns: the UUID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_uuid (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = nm_connection_get_setting_connection (connection); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_uuid (s_con); +} + +/** + * nm_connection_get_id: + * @connection: the #NMConnection + * + * A shortcut to return the ID from the connection's #NMSettingConnection. + * + * Returns: the ID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_id (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = nm_connection_get_setting_connection (connection); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_id (s_con); +} + +/** + * nm_connection_get_connection_type: + * @connection: the #NMConnection + * + * A shortcut to return the type from the connection's #NMSettingConnection. + * + * Returns: the type from the connection's 'connection' setting + **/ +const char * +nm_connection_get_connection_type (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = nm_connection_get_setting_connection (connection); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_connection_type (s_con); +} + +/** + * nm_connection_is_virtual: + * @connection: an #NMConnection + * + * Checks if @connection refers to a virtual device (and thus can potentially be + * activated even if the device it refers to doesn't exist). + * + * Returns: whether @connection refers to a virtual device + */ +gboolean +nm_connection_is_virtual (NMConnection *connection) +{ + const char *type; + + type = nm_connection_get_connection_type (connection); + g_return_val_if_fail (type != NULL, FALSE); + + if ( !strcmp (type, NM_SETTING_BOND_SETTING_NAME) + || !strcmp (type, NM_SETTING_TEAM_SETTING_NAME) + || !strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME) + || !strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) + return TRUE; + + if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + NMSettingInfiniband *s_ib; + + s_ib = nm_connection_get_setting_infiniband (connection); + g_return_val_if_fail (s_ib != NULL, FALSE); + return nm_setting_infiniband_get_virtual_interface_name (s_ib) != NULL; + } + + return FALSE; +} + +/** + * nm_connection_get_virtual_device_description: + * @connection: an #NMConnection for a virtual device type + * + * Returns the name that nm_device_disambiguate_names() would + * return for the virtual device that would be created for @connection. + * Eg, "VLAN (eth1.1)". + * + * Returns: (transfer full): the name of @connection's device, + * or %NULL if @connection is not a virtual connection type + */ +char * +nm_connection_get_virtual_device_description (NMConnection *connection) +{ + const char *type; + const char *iface = NULL, *display_type = NULL; + + iface = nm_connection_get_interface_name (connection); + + type = nm_connection_get_connection_type (connection); + g_return_val_if_fail (type != NULL, FALSE); + + if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME)) + display_type = _("Bond"); + else if (!strcmp (type, NM_SETTING_TEAM_SETTING_NAME)) + display_type = _("Team"); + else if (!strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME)) + display_type = _("Bridge"); + else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) + display_type = _("VLAN"); + else if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + display_type = _("InfiniBand"); + iface = nm_setting_infiniband_get_virtual_interface_name (nm_connection_get_setting_infiniband (connection)); + } + + if (!iface || !display_type) + return NULL; + + return g_strdup_printf ("%s (%s)", display_type, iface); +} + +/*************************************************************/ + +/** + * nm_connection_get_setting_802_1x: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSetting8021x the connection might contain. + * + * Returns: (transfer none): an #NMSetting8021x if the connection contains one, otherwise %NULL + **/ +NMSetting8021x * +nm_connection_get_setting_802_1x (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); +} + +/** + * nm_connection_get_setting_bluetooth: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBluetooth the connection might contain. + * + * Returns: (transfer none): an #NMSettingBluetooth if the connection contains one, otherwise %NULL + **/ +NMSettingBluetooth * +nm_connection_get_setting_bluetooth (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); +} + +/** + * nm_connection_get_setting_bond: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBond the connection might contain. + * + * Returns: (transfer none): an #NMSettingBond if the connection contains one, otherwise %NULL + **/ +NMSettingBond * +nm_connection_get_setting_bond (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBond *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BOND); +} + +/** + * nm_connection_get_setting_team: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTeam the connection might contain. + * + * Returns: (transfer none): an #NMSettingTeam if the connection contains one, otherwise %NULL + **/ +NMSettingTeam * +nm_connection_get_setting_team (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingTeam *) nm_connection_get_setting (connection, NM_TYPE_SETTING_TEAM); +} + +/** + * nm_connection_get_setting_team_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingTeamPort the connection might contain. + * + * Returns: (transfer none): an #NMSettingTeamPort if the connection contains one, otherwise %NULL + **/ +NMSettingTeamPort * +nm_connection_get_setting_team_port (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingTeamPort *) nm_connection_get_setting (connection, NM_TYPE_SETTING_TEAM_PORT); +} + +/** + * nm_connection_get_setting_bridge: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridge the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridge if the connection contains one, otherwise %NULL + **/ +NMSettingBridge * +nm_connection_get_setting_bridge (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBridge *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BRIDGE); +} + +/** + * nm_connection_get_setting_cdma: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingCdma the connection might contain. + * + * Returns: (transfer none): an #NMSettingCdma if the connection contains one, otherwise %NULL + **/ +NMSettingCdma * +nm_connection_get_setting_cdma (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); +} + +/** + * nm_connection_get_setting_connection: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingConnection the connection might contain. + * + * Returns: (transfer none): an #NMSettingConnection if the connection contains one, otherwise %NULL + **/ +NMSettingConnection * +nm_connection_get_setting_connection (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); +} + +/** + * nm_connection_get_setting_dcb: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingDcb the connection might contain. + * + * Returns: (transfer none): an #NMSettingDcb if the connection contains one, otherwise NULL + **/ +NMSettingDcb * +nm_connection_get_setting_dcb (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingDcb *) nm_connection_get_setting (connection, NM_TYPE_SETTING_DCB); +} + +/** + * nm_connection_get_setting_generic: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingGeneric the connection might contain. + * + * Returns: (transfer none): an #NMSettingGeneric if the connection contains one, otherwise NULL + **/ +NMSettingGeneric * +nm_connection_get_setting_generic (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingGeneric *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GENERIC); +} + +/** + * nm_connection_get_setting_gsm: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingGsm the connection might contain. + * + * Returns: (transfer none): an #NMSettingGsm if the connection contains one, otherwise %NULL + **/ +NMSettingGsm * +nm_connection_get_setting_gsm (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); +} + +/** + * nm_connection_get_setting_infiniband: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingInfiniband the connection might contain. + * + * Returns: (transfer none): an #NMSettingInfiniband if the connection contains one, otherwise %NULL + **/ +NMSettingInfiniband * +nm_connection_get_setting_infiniband (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingInfiniband *) nm_connection_get_setting (connection, NM_TYPE_SETTING_INFINIBAND); +} + +/** + * nm_connection_get_setting_ip4_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP4Config the connection might contain. + * + * Note that it returns the value as type #NMSettingIPConfig, since the vast + * majority of IPv4-setting-related methods are on that type, not + * #NMSettingIP4Config. + * + * Returns: (type NMSettingIP4Config) (transfer none): an #NMSettingIP4Config if the + * connection contains one, otherwise %NULL + **/ +NMSettingIPConfig * +nm_connection_get_setting_ip4_config (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingIPConfig *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); +} + +/** + * nm_connection_get_setting_ip6_config: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingIP6Config the connection might contain. + * + * Note that it returns the value as type #NMSettingIPConfig, since the vast + * majority of IPv6-setting-related methods are on that type, not + * #NMSettingIP6Config. + * + * Returns: (type NMSettingIP6Config) (transfer none): an #NMSettingIP6Config if the + * connection contains one, otherwise %NULL + **/ +NMSettingIPConfig * +nm_connection_get_setting_ip6_config (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingIPConfig *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); +} + +/** + * nm_connection_get_setting_olpc_mesh: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingOlpcMesh the connection might contain. + * + * Returns: (transfer none): an #NMSettingOlpcMesh if the connection contains one, otherwise %NULL + **/ +NMSettingOlpcMesh * +nm_connection_get_setting_olpc_mesh (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH); +} + +/** + * nm_connection_get_setting_ppp: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPpp the connection might contain. + * + * Returns: (transfer none): an #NMSettingPpp if the connection contains one, otherwise %NULL + **/ +NMSettingPpp * +nm_connection_get_setting_ppp (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingPpp *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); +} + +/** + * nm_connection_get_setting_pppoe: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingPppoe the connection might contain. + * + * Returns: (transfer none): an #NMSettingPppoe if the connection contains one, otherwise %NULL + **/ +NMSettingPppoe * +nm_connection_get_setting_pppoe (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingPppoe *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); +} + +/** + * nm_connection_get_setting_serial: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingSerial the connection might contain. + * + * Returns: (transfer none): an #NMSettingSerial if the connection contains one, otherwise %NULL + **/ +NMSettingSerial * +nm_connection_get_setting_serial (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); +} + +/** + * nm_connection_get_setting_vpn: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVpn the connection might contain. + * + * Returns: (transfer none): an #NMSettingVpn if the connection contains one, otherwise %NULL + **/ +NMSettingVpn * +nm_connection_get_setting_vpn (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingVpn *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); +} + +/** + * nm_connection_get_setting_wimax: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWimax the connection might contain. + * + * Returns: (transfer none): an #NMSettingWimax if the connection contains one, otherwise %NULL + **/ +NMSettingWimax * +nm_connection_get_setting_wimax (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX); +} + +/** + * nm_connection_get_setting_wired: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWired the connection might contain. + * + * Returns: (transfer none): an #NMSettingWired if the connection contains one, otherwise %NULL + **/ +NMSettingWired * +nm_connection_get_setting_wired (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); +} + +/** + * nm_connection_get_setting_adsl: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingAdsl the connection might contain. + * + * Returns: (transfer none): an #NMSettingAdsl if the connection contains one, otherwise %NULL + **/ +NMSettingAdsl * +nm_connection_get_setting_adsl (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingAdsl *) nm_connection_get_setting (connection, NM_TYPE_SETTING_ADSL); +} + +/** + * nm_connection_get_setting_wireless: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWireless the connection might contain. + * + * Returns: (transfer none): an #NMSettingWireless if the connection contains one, otherwise %NULL + **/ +NMSettingWireless * +nm_connection_get_setting_wireless (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); +} + +/** + * nm_connection_get_setting_wireless_security: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingWirelessSecurity the connection might contain. + * + * Returns: (transfer none): an #NMSettingWirelessSecurity if the connection contains one, otherwise %NULL + **/ +NMSettingWirelessSecurity * +nm_connection_get_setting_wireless_security (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); +} + +/** + * nm_connection_get_setting_bridge_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridgePort the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridgePort if the connection contains one, otherwise %NULL + **/ +NMSettingBridgePort * +nm_connection_get_setting_bridge_port (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBridgePort *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BRIDGE_PORT); +} + +/** + * nm_connection_get_setting_vlan: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingVlan the connection might contain. + * + * Returns: (transfer none): an #NMSettingVlan if the connection contains one, otherwise %NULL + **/ +NMSettingVlan * +nm_connection_get_setting_vlan (NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingVlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VLAN); +} + +/*************************************************************/ + +static void +nm_connection_private_free (NMConnectionPrivate *priv) +{ + NMConnection *self = priv->self; + + g_hash_table_foreach_remove (priv->settings, _setting_release, self); + g_hash_table_destroy (priv->settings); + g_free (priv->path); + + g_slice_free (NMConnectionPrivate, priv); +} + +static NMConnectionPrivate * +nm_connection_get_private (NMConnection *connection) +{ + NMConnectionPrivate *priv; + + priv = g_object_get_data (G_OBJECT (connection), "NMConnectionPrivate"); + if (!priv) { + priv = g_slice_new0 (NMConnectionPrivate); + g_object_set_data_full (G_OBJECT (connection), "NMConnectionPrivate", + priv, (GDestroyNotify) nm_connection_private_free); + + priv->self = connection; + priv->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + } + + return priv; +} + +static void +nm_connection_default_init (NMConnectionInterface *iface) +{ + /* Signals */ + + /** + * NMConnection::secrets-updated: + * @connection: the object on which the signal is emitted + * @setting_name: the setting name of the #NMSetting for which secrets were + * updated + * + * The ::secrets-updated signal is emitted when the secrets of a setting + * have been changed. + */ + signals[SECRETS_UPDATED] = + g_signal_new (NM_CONNECTION_SECRETS_UPDATED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMConnectionInterface, secrets_updated), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + /** + * NMConnection::secrets-cleared: + * @connection: the object on which the signal is emitted + * + * The ::secrets-cleared signal is emitted when the secrets of a connection + * are cleared. + */ + signals[SECRETS_CLEARED] = + g_signal_new (NM_CONNECTION_SECRETS_CLEARED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMConnectionInterface, secrets_cleared), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * NMConnection::changed: + * @connection: the object on which the signal is emitted + * + * The ::changed signal is emitted when any property of any property + * (including secrets) of any setting of the connection is modified, + * or when settings are added or removed. + */ + signals[CHANGED] = + g_signal_new (NM_CONNECTION_CHANGED, + NM_TYPE_CONNECTION, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMConnectionInterface, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} diff --git a/libnm-core/nm-connection.h b/libnm-core/nm-connection.h new file mode 100644 index 00000000..c76ad607 --- /dev/null +++ b/libnm-core/nm-connection.h @@ -0,0 +1,219 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_CONNECTION_H__ +#define __NM_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_CONNECTION (nm_connection_get_type ()) +#define NM_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION, NMConnection)) +#define NM_IS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION)) +#define NM_CONNECTION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_CONNECTION, NMConnectionClass)) + +/* Signals */ +#define NM_CONNECTION_SECRETS_UPDATED "secrets-updated" +#define NM_CONNECTION_SECRETS_CLEARED "secrets-cleared" +#define NM_CONNECTION_CHANGED "changed" + +/* + * NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD: overwrite the ip6 method + * when normalizing ip6 configuration. If omited, this defaults to + * @NM_SETTING_IP6_CONFIG_METHOD_AUTO. + */ +#define NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD "ip6-config-method" + +/** + * NMConnection: + * + * NMConnection is the interface implemented by #NMRemoteConnection on the + * client side, and #NMSettingsConnection on the daemon side. + */ + +/** + * NMConnectionInterface: + * @parent: the parent interace struct + * @secrets_updated: emitted when the connection's secrets are updated + * @secrets_cleared: emitted when the connection's secrets are cleared + * @changed: emitted when any change to the connection's settings occurs + */ +typedef struct { + GTypeInterface parent; + + /* Signals */ + void (*secrets_updated) (NMConnection *connection, + const char *setting); + void (*secrets_cleared) (NMConnection *connection); + void (*changed) (NMConnection *connection); + +} NMConnectionInterface; + +GType nm_connection_get_type (void); + +void nm_connection_add_setting (NMConnection *connection, + NMSetting *setting); + +void nm_connection_remove_setting (NMConnection *connection, + GType setting_type); + +NMSetting *nm_connection_get_setting (NMConnection *connection, + GType setting_type); + +NMSetting *nm_connection_get_setting_by_name (NMConnection *connection, + const char *name); + +/** + * NM_VARIANT_TYPE_CONNECTION: + * + * #GVariantType for a dictionary mapping from setting names to + * %NM_VARIANT_TYPE_SETTING variants. This is used to represent an + * #NMConnection, and is the type taken by nm_simple_connection_new_from_dbus() + * and returned from nm_connection_to_dbus(). + */ +#define NM_VARIANT_TYPE_CONNECTION (G_VARIANT_TYPE ("a{sa{sv}}")) + +/** + * NM_VARIANT_TYPE_SETTING: + * + * #GVariantType for a dictionary mapping from property names to values. This is + * an alias for %G_VARIANT_TYPE_VARDICT, and is the type of each element of + * an %NM_VARIANT_TYPE_CONNECTION dictionary. + */ +#define NM_VARIANT_TYPE_SETTING G_VARIANT_TYPE_VARDICT + +/** + * NMConnectionSerializationFlags: + * @NM_CONNECTION_SERIALIZE_ALL: serialize all properties (including secrets) + * @NM_CONNECTION_SERIALIZE_NO_SECRETS: do not include secrets + * @NM_CONNECTION_SERIALIZE_ONLY_SECRETS: only serialize secrets + * + * These flags determine which properties are serialized when calling when + * calling nm_connection_to_dbus(). + **/ +typedef enum { /*< flags >*/ + NM_CONNECTION_SERIALIZE_ALL = 0x00000000, + NM_CONNECTION_SERIALIZE_NO_SECRETS = 0x00000001, + NM_CONNECTION_SERIALIZE_ONLY_SECRETS = 0x00000002, +} NMConnectionSerializationFlags; + +GVariant *nm_connection_to_dbus (NMConnection *connection, + NMConnectionSerializationFlags flags); + +gboolean nm_connection_replace_settings (NMConnection *connection, + GVariant *new_settings, + GError **error); + +void nm_connection_replace_settings_from_connection (NMConnection *connection, + NMConnection *new_connection); + +void nm_connection_clear_settings (NMConnection *connection); + +gboolean nm_connection_compare (NMConnection *a, + NMConnection *b, + NMSettingCompareFlags flags); + +gboolean nm_connection_diff (NMConnection *a, + NMConnection *b, + NMSettingCompareFlags flags, + GHashTable **out_settings); + +gboolean nm_connection_verify (NMConnection *connection, GError **error); +gboolean nm_connection_normalize (NMConnection *connection, + GHashTable *parameters, + gboolean *modified, + GError **error); + +const char * nm_connection_need_secrets (NMConnection *connection, + GPtrArray **hints); + +void nm_connection_clear_secrets (NMConnection *connection); + +void nm_connection_clear_secrets_with_flags (NMConnection *connection, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + +gboolean nm_connection_update_secrets (NMConnection *connection, + const char *setting_name, + GVariant *secrets, + GError **error); + +void nm_connection_set_path (NMConnection *connection, + const char *path); + +const char * nm_connection_get_path (NMConnection *connection); + +const char * nm_connection_get_interface_name (NMConnection *connection); + +gboolean nm_connection_is_type (NMConnection *connection, const char *type); + +void nm_connection_for_each_setting_value (NMConnection *connection, + NMSettingValueIterFn func, + gpointer user_data); + +void nm_connection_dump (NMConnection *connection); + +/* Helpers */ +const char * nm_connection_get_uuid (NMConnection *connection); +const char * nm_connection_get_id (NMConnection *connection); +const char * nm_connection_get_connection_type (NMConnection *connection); + +gboolean nm_connection_is_virtual (NMConnection *connection); +char * nm_connection_get_virtual_device_description (NMConnection *connection); + +NMSetting8021x * nm_connection_get_setting_802_1x (NMConnection *connection); +NMSettingBluetooth * nm_connection_get_setting_bluetooth (NMConnection *connection); +NMSettingBond * nm_connection_get_setting_bond (NMConnection *connection); +NMSettingTeam * nm_connection_get_setting_team (NMConnection *connection); +NMSettingTeamPort * nm_connection_get_setting_team_port (NMConnection *connection); +NMSettingBridge * nm_connection_get_setting_bridge (NMConnection *connection); +NMSettingBridgePort * nm_connection_get_setting_bridge_port (NMConnection *connection); +NMSettingCdma * nm_connection_get_setting_cdma (NMConnection *connection); +NMSettingConnection * nm_connection_get_setting_connection (NMConnection *connection); +NMSettingDcb * nm_connection_get_setting_dcb (NMConnection *connection); +NMSettingGeneric * nm_connection_get_setting_generic (NMConnection *connection); +NMSettingGsm * nm_connection_get_setting_gsm (NMConnection *connection); +NMSettingInfiniband * nm_connection_get_setting_infiniband (NMConnection *connection); +NMSettingIPConfig * nm_connection_get_setting_ip4_config (NMConnection *connection); +NMSettingIPConfig * nm_connection_get_setting_ip6_config (NMConnection *connection); +NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection); +NMSettingPpp * nm_connection_get_setting_ppp (NMConnection *connection); +NMSettingPppoe * nm_connection_get_setting_pppoe (NMConnection *connection); +NMSettingSerial * nm_connection_get_setting_serial (NMConnection *connection); +NMSettingVpn * nm_connection_get_setting_vpn (NMConnection *connection); +NMSettingWimax * nm_connection_get_setting_wimax (NMConnection *connection); +NMSettingAdsl * nm_connection_get_setting_adsl (NMConnection *connection); +NMSettingWired * nm_connection_get_setting_wired (NMConnection *connection); +NMSettingWireless * nm_connection_get_setting_wireless (NMConnection *connection); +NMSettingWirelessSecurity *nm_connection_get_setting_wireless_security (NMConnection *connection); +NMSettingVlan * nm_connection_get_setting_vlan (NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_CONNECTION_H__ */ diff --git a/libnm-core/nm-core-enum-types.c b/libnm-core/nm-core-enum-types.c new file mode 100644 index 00000000..d7d4291b --- /dev/null +++ b/libnm-core/nm-core-enum-types.c @@ -0,0 +1,1031 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#include "nm-core-enum-types.h" + +#include "nm-version.h" +#include "nm-connection.h" +#include "nm-core-types.h" +#include "nm-dbus-interface.h" +#include "nm-errors.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-bridge.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip-config.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-team-port.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-setting.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "nm-vpn-dbus-interface.h" + +GType +nm_connection_serialization_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_CONNECTION_SERIALIZE_ALL, "NM_CONNECTION_SERIALIZE_ALL", "all" }, + { NM_CONNECTION_SERIALIZE_NO_SECRETS, "NM_CONNECTION_SERIALIZE_NO_SECRETS", "no-secrets" }, + { NM_CONNECTION_SERIALIZE_ONLY_SECRETS, "NM_CONNECTION_SERIALIZE_ONLY_SECRETS", "only-secrets" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMConnectionSerializationFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_STATE_UNKNOWN, "NM_STATE_UNKNOWN", "unknown" }, + { NM_STATE_ASLEEP, "NM_STATE_ASLEEP", "asleep" }, + { NM_STATE_DISCONNECTED, "NM_STATE_DISCONNECTED", "disconnected" }, + { NM_STATE_DISCONNECTING, "NM_STATE_DISCONNECTING", "disconnecting" }, + { NM_STATE_CONNECTING, "NM_STATE_CONNECTING", "connecting" }, + { NM_STATE_CONNECTED_LOCAL, "NM_STATE_CONNECTED_LOCAL", "connected-local" }, + { NM_STATE_CONNECTED_SITE, "NM_STATE_CONNECTED_SITE", "connected-site" }, + { NM_STATE_CONNECTED_GLOBAL, "NM_STATE_CONNECTED_GLOBAL", "connected-global" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_connectivity_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CONNECTIVITY_UNKNOWN, "NM_CONNECTIVITY_UNKNOWN", "unknown" }, + { NM_CONNECTIVITY_NONE, "NM_CONNECTIVITY_NONE", "none" }, + { NM_CONNECTIVITY_PORTAL, "NM_CONNECTIVITY_PORTAL", "portal" }, + { NM_CONNECTIVITY_LIMITED, "NM_CONNECTIVITY_LIMITED", "limited" }, + { NM_CONNECTIVITY_FULL, "NM_CONNECTIVITY_FULL", "full" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMConnectivityState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_TYPE_UNKNOWN, "NM_DEVICE_TYPE_UNKNOWN", "unknown" }, + { NM_DEVICE_TYPE_ETHERNET, "NM_DEVICE_TYPE_ETHERNET", "ethernet" }, + { NM_DEVICE_TYPE_WIFI, "NM_DEVICE_TYPE_WIFI", "wifi" }, + { NM_DEVICE_TYPE_UNUSED1, "NM_DEVICE_TYPE_UNUSED1", "unused1" }, + { NM_DEVICE_TYPE_UNUSED2, "NM_DEVICE_TYPE_UNUSED2", "unused2" }, + { NM_DEVICE_TYPE_BT, "NM_DEVICE_TYPE_BT", "bt" }, + { NM_DEVICE_TYPE_OLPC_MESH, "NM_DEVICE_TYPE_OLPC_MESH", "olpc-mesh" }, + { NM_DEVICE_TYPE_WIMAX, "NM_DEVICE_TYPE_WIMAX", "wimax" }, + { NM_DEVICE_TYPE_MODEM, "NM_DEVICE_TYPE_MODEM", "modem" }, + { NM_DEVICE_TYPE_INFINIBAND, "NM_DEVICE_TYPE_INFINIBAND", "infiniband" }, + { NM_DEVICE_TYPE_BOND, "NM_DEVICE_TYPE_BOND", "bond" }, + { NM_DEVICE_TYPE_VLAN, "NM_DEVICE_TYPE_VLAN", "vlan" }, + { NM_DEVICE_TYPE_ADSL, "NM_DEVICE_TYPE_ADSL", "adsl" }, + { NM_DEVICE_TYPE_BRIDGE, "NM_DEVICE_TYPE_BRIDGE", "bridge" }, + { NM_DEVICE_TYPE_GENERIC, "NM_DEVICE_TYPE_GENERIC", "generic" }, + { NM_DEVICE_TYPE_TEAM, "NM_DEVICE_TYPE_TEAM", "team" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_DEVICE_CAP_NONE, "NM_DEVICE_CAP_NONE", "none" }, + { NM_DEVICE_CAP_NM_SUPPORTED, "NM_DEVICE_CAP_NM_SUPPORTED", "nm-supported" }, + { NM_DEVICE_CAP_CARRIER_DETECT, "NM_DEVICE_CAP_CARRIER_DETECT", "carrier-detect" }, + { NM_DEVICE_CAP_IS_SOFTWARE, "NM_DEVICE_CAP_IS_SOFTWARE", "is-software" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMDeviceCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_wifi_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_WIFI_DEVICE_CAP_NONE, "NM_WIFI_DEVICE_CAP_NONE", "none" }, + { NM_WIFI_DEVICE_CAP_CIPHER_WEP40, "NM_WIFI_DEVICE_CAP_CIPHER_WEP40", "cipher-wep40" }, + { NM_WIFI_DEVICE_CAP_CIPHER_WEP104, "NM_WIFI_DEVICE_CAP_CIPHER_WEP104", "cipher-wep104" }, + { NM_WIFI_DEVICE_CAP_CIPHER_TKIP, "NM_WIFI_DEVICE_CAP_CIPHER_TKIP", "cipher-tkip" }, + { NM_WIFI_DEVICE_CAP_CIPHER_CCMP, "NM_WIFI_DEVICE_CAP_CIPHER_CCMP", "cipher-ccmp" }, + { NM_WIFI_DEVICE_CAP_WPA, "NM_WIFI_DEVICE_CAP_WPA", "wpa" }, + { NM_WIFI_DEVICE_CAP_RSN, "NM_WIFI_DEVICE_CAP_RSN", "rsn" }, + { NM_WIFI_DEVICE_CAP_AP, "NM_WIFI_DEVICE_CAP_AP", "ap" }, + { NM_WIFI_DEVICE_CAP_ADHOC, "NM_WIFI_DEVICE_CAP_ADHOC", "adhoc" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMDeviceWifiCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_802_11_ap_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_802_11_AP_FLAGS_NONE, "NM_802_11_AP_FLAGS_NONE", "none" }, + { NM_802_11_AP_FLAGS_PRIVACY, "NM_802_11_AP_FLAGS_PRIVACY", "privacy" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NM80211ApFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_802_11_ap_security_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_802_11_AP_SEC_NONE, "NM_802_11_AP_SEC_NONE", "none" }, + { NM_802_11_AP_SEC_PAIR_WEP40, "NM_802_11_AP_SEC_PAIR_WEP40", "pair-wep40" }, + { NM_802_11_AP_SEC_PAIR_WEP104, "NM_802_11_AP_SEC_PAIR_WEP104", "pair-wep104" }, + { NM_802_11_AP_SEC_PAIR_TKIP, "NM_802_11_AP_SEC_PAIR_TKIP", "pair-tkip" }, + { NM_802_11_AP_SEC_PAIR_CCMP, "NM_802_11_AP_SEC_PAIR_CCMP", "pair-ccmp" }, + { NM_802_11_AP_SEC_GROUP_WEP40, "NM_802_11_AP_SEC_GROUP_WEP40", "group-wep40" }, + { NM_802_11_AP_SEC_GROUP_WEP104, "NM_802_11_AP_SEC_GROUP_WEP104", "group-wep104" }, + { NM_802_11_AP_SEC_GROUP_TKIP, "NM_802_11_AP_SEC_GROUP_TKIP", "group-tkip" }, + { NM_802_11_AP_SEC_GROUP_CCMP, "NM_802_11_AP_SEC_GROUP_CCMP", "group-ccmp" }, + { NM_802_11_AP_SEC_KEY_MGMT_PSK, "NM_802_11_AP_SEC_KEY_MGMT_PSK", "key-mgmt-psk" }, + { NM_802_11_AP_SEC_KEY_MGMT_802_1X, "NM_802_11_AP_SEC_KEY_MGMT_802_1X", "key-mgmt-802-1x" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NM80211ApSecurityFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_802_11_mode_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_802_11_MODE_UNKNOWN, "NM_802_11_MODE_UNKNOWN", "unknown" }, + { NM_802_11_MODE_ADHOC, "NM_802_11_MODE_ADHOC", "adhoc" }, + { NM_802_11_MODE_INFRA, "NM_802_11_MODE_INFRA", "infra" }, + { NM_802_11_MODE_AP, "NM_802_11_MODE_AP", "ap" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NM80211Mode"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_bluetooth_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_BT_CAPABILITY_NONE, "NM_BT_CAPABILITY_NONE", "none" }, + { NM_BT_CAPABILITY_DUN, "NM_BT_CAPABILITY_DUN", "dun" }, + { NM_BT_CAPABILITY_NAP, "NM_BT_CAPABILITY_NAP", "nap" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMBluetoothCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_modem_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_DEVICE_MODEM_CAPABILITY_NONE, "NM_DEVICE_MODEM_CAPABILITY_NONE", "none" }, + { NM_DEVICE_MODEM_CAPABILITY_POTS, "NM_DEVICE_MODEM_CAPABILITY_POTS", "pots" }, + { NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO, "NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO", "cdma-evdo" }, + { NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS, "NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS", "gsm-umts" }, + { NM_DEVICE_MODEM_CAPABILITY_LTE, "NM_DEVICE_MODEM_CAPABILITY_LTE", "lte" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMDeviceModemCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_STATE_UNKNOWN, "NM_DEVICE_STATE_UNKNOWN", "unknown" }, + { NM_DEVICE_STATE_UNMANAGED, "NM_DEVICE_STATE_UNMANAGED", "unmanaged" }, + { NM_DEVICE_STATE_UNAVAILABLE, "NM_DEVICE_STATE_UNAVAILABLE", "unavailable" }, + { NM_DEVICE_STATE_DISCONNECTED, "NM_DEVICE_STATE_DISCONNECTED", "disconnected" }, + { NM_DEVICE_STATE_PREPARE, "NM_DEVICE_STATE_PREPARE", "prepare" }, + { NM_DEVICE_STATE_CONFIG, "NM_DEVICE_STATE_CONFIG", "config" }, + { NM_DEVICE_STATE_NEED_AUTH, "NM_DEVICE_STATE_NEED_AUTH", "need-auth" }, + { NM_DEVICE_STATE_IP_CONFIG, "NM_DEVICE_STATE_IP_CONFIG", "ip-config" }, + { NM_DEVICE_STATE_IP_CHECK, "NM_DEVICE_STATE_IP_CHECK", "ip-check" }, + { NM_DEVICE_STATE_SECONDARIES, "NM_DEVICE_STATE_SECONDARIES", "secondaries" }, + { NM_DEVICE_STATE_ACTIVATED, "NM_DEVICE_STATE_ACTIVATED", "activated" }, + { NM_DEVICE_STATE_DEACTIVATING, "NM_DEVICE_STATE_DEACTIVATING", "deactivating" }, + { NM_DEVICE_STATE_FAILED, "NM_DEVICE_STATE_FAILED", "failed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_state_reason_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_STATE_REASON_NONE, "NM_DEVICE_STATE_REASON_NONE", "none" }, + { NM_DEVICE_STATE_REASON_UNKNOWN, "NM_DEVICE_STATE_REASON_UNKNOWN", "unknown" }, + { NM_DEVICE_STATE_REASON_NOW_MANAGED, "NM_DEVICE_STATE_REASON_NOW_MANAGED", "now-managed" }, + { NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "NM_DEVICE_STATE_REASON_NOW_UNMANAGED", "now-unmanaged" }, + { NM_DEVICE_STATE_REASON_CONFIG_FAILED, "NM_DEVICE_STATE_REASON_CONFIG_FAILED", "config-failed" }, + { NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE", "ip-config-unavailable" }, + { NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED", "ip-config-expired" }, + { NM_DEVICE_STATE_REASON_NO_SECRETS, "NM_DEVICE_STATE_REASON_NO_SECRETS", "no-secrets" }, + { NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT", "supplicant-disconnect" }, + { NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, "NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED", "supplicant-config-failed" }, + { NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED", "supplicant-failed" }, + { NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT", "supplicant-timeout" }, + { NM_DEVICE_STATE_REASON_PPP_START_FAILED, "NM_DEVICE_STATE_REASON_PPP_START_FAILED", "ppp-start-failed" }, + { NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "NM_DEVICE_STATE_REASON_PPP_DISCONNECT", "ppp-disconnect" }, + { NM_DEVICE_STATE_REASON_PPP_FAILED, "NM_DEVICE_STATE_REASON_PPP_FAILED", "ppp-failed" }, + { NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "NM_DEVICE_STATE_REASON_DHCP_START_FAILED", "dhcp-start-failed" }, + { NM_DEVICE_STATE_REASON_DHCP_ERROR, "NM_DEVICE_STATE_REASON_DHCP_ERROR", "dhcp-error" }, + { NM_DEVICE_STATE_REASON_DHCP_FAILED, "NM_DEVICE_STATE_REASON_DHCP_FAILED", "dhcp-failed" }, + { NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "NM_DEVICE_STATE_REASON_SHARED_START_FAILED", "shared-start-failed" }, + { NM_DEVICE_STATE_REASON_SHARED_FAILED, "NM_DEVICE_STATE_REASON_SHARED_FAILED", "shared-failed" }, + { NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED", "autoip-start-failed" }, + { NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "NM_DEVICE_STATE_REASON_AUTOIP_ERROR", "autoip-error" }, + { NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "NM_DEVICE_STATE_REASON_AUTOIP_FAILED", "autoip-failed" }, + { NM_DEVICE_STATE_REASON_MODEM_BUSY, "NM_DEVICE_STATE_REASON_MODEM_BUSY", "modem-busy" }, + { NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE", "modem-no-dial-tone" }, + { NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER", "modem-no-carrier" }, + { NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT", "modem-dial-timeout" }, + { NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED", "modem-dial-failed" }, + { NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED", "modem-init-failed" }, + { NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "NM_DEVICE_STATE_REASON_GSM_APN_FAILED", "gsm-apn-failed" }, + { NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, "NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING", "gsm-registration-not-searching" }, + { NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, "NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED", "gsm-registration-denied" }, + { NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, "NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT", "gsm-registration-timeout" }, + { NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, "NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED", "gsm-registration-failed" }, + { NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED", "gsm-pin-check-failed" }, + { NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "NM_DEVICE_STATE_REASON_FIRMWARE_MISSING", "firmware-missing" }, + { NM_DEVICE_STATE_REASON_REMOVED, "NM_DEVICE_STATE_REASON_REMOVED", "removed" }, + { NM_DEVICE_STATE_REASON_SLEEPING, "NM_DEVICE_STATE_REASON_SLEEPING", "sleeping" }, + { NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "NM_DEVICE_STATE_REASON_CONNECTION_REMOVED", "connection-removed" }, + { NM_DEVICE_STATE_REASON_USER_REQUESTED, "NM_DEVICE_STATE_REASON_USER_REQUESTED", "user-requested" }, + { NM_DEVICE_STATE_REASON_CARRIER, "NM_DEVICE_STATE_REASON_CARRIER", "carrier" }, + { NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED", "connection-assumed" }, + { NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE", "supplicant-available" }, + { NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND", "modem-not-found" }, + { NM_DEVICE_STATE_REASON_BT_FAILED, "NM_DEVICE_STATE_REASON_BT_FAILED", "bt-failed" }, + { NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED", "gsm-sim-not-inserted" }, + { NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED", "gsm-sim-pin-required" }, + { NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED", "gsm-sim-puk-required" }, + { NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "NM_DEVICE_STATE_REASON_GSM_SIM_WRONG", "gsm-sim-wrong" }, + { NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "NM_DEVICE_STATE_REASON_INFINIBAND_MODE", "infiniband-mode" }, + { NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED", "dependency-failed" }, + { NM_DEVICE_STATE_REASON_BR2684_FAILED, "NM_DEVICE_STATE_REASON_BR2684_FAILED", "br2684-failed" }, + { NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, "NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE", "modem-manager-unavailable" }, + { NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "NM_DEVICE_STATE_REASON_SSID_NOT_FOUND", "ssid-not-found" }, + { NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, "NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED", "secondary-connection-failed" }, + { NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED", "dcb-fcoe-failed" }, + { NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED", "teamd-control-failed" }, + { NM_DEVICE_STATE_REASON_MODEM_FAILED, "NM_DEVICE_STATE_REASON_MODEM_FAILED", "modem-failed" }, + { NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "NM_DEVICE_STATE_REASON_MODEM_AVAILABLE", "modem-available" }, + { NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT", "sim-pin-incorrect" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceStateReason"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_active_connection_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_ACTIVE_CONNECTION_STATE_UNKNOWN, "NM_ACTIVE_CONNECTION_STATE_UNKNOWN", "unknown" }, + { NM_ACTIVE_CONNECTION_STATE_ACTIVATING, "NM_ACTIVE_CONNECTION_STATE_ACTIVATING", "activating" }, + { NM_ACTIVE_CONNECTION_STATE_ACTIVATED, "NM_ACTIVE_CONNECTION_STATE_ACTIVATED", "activated" }, + { NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, "NM_ACTIVE_CONNECTION_STATE_DEACTIVATING", "deactivating" }, + { NM_ACTIVE_CONNECTION_STATE_DEACTIVATED, "NM_ACTIVE_CONNECTION_STATE_DEACTIVATED", "deactivated" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMActiveConnectionState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_secret_agent_get_secrets_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, "NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE", "none" }, + { NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, "NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION", "allow-interaction" }, + { NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, "NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW", "request-new" }, + { NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED, "NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED", "user-requested" }, + { NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM, "NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM", "only-system" }, + { NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, "NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS", "no-errors" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMSecretAgentGetSecretsFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_secret_agent_capabilities_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_SECRET_AGENT_CAPABILITY_NONE, "NM_SECRET_AGENT_CAPABILITY_NONE", "none" }, + { NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, "NM_SECRET_AGENT_CAPABILITY_VPN_HINTS", "vpn-hints" }, + { NM_SECRET_AGENT_CAPABILITY_LAST, "NM_SECRET_AGENT_CAPABILITY_LAST", "last" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMSecretAgentCapabilities"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_agent_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_AGENT_MANAGER_ERROR_FAILED, "NM_AGENT_MANAGER_ERROR_FAILED", "Failed" }, + { NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER", "InvalidIdentifier" }, + { NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NM_AGENT_MANAGER_ERROR_NOT_REGISTERED", "NotRegistered" }, + { NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NM_AGENT_MANAGER_ERROR_NO_SECRETS", "NoSecrets" }, + { NM_AGENT_MANAGER_ERROR_USER_CANCELED, "NM_AGENT_MANAGER_ERROR_USER_CANCELED", "UserCanceled" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMAgentManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_connection_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CONNECTION_ERROR_FAILED, "NM_CONNECTION_ERROR_FAILED", "Failed" }, + { NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "NM_CONNECTION_ERROR_SETTING_NOT_FOUND", "SettingNotFound" }, + { NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, "NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND", "PropertyNotFound" }, + { NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, "NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET", "PropertyNotSecret" }, + { NM_CONNECTION_ERROR_MISSING_SETTING, "NM_CONNECTION_ERROR_MISSING_SETTING", "MissingSetting" }, + { NM_CONNECTION_ERROR_INVALID_SETTING, "NM_CONNECTION_ERROR_INVALID_SETTING", "InvalidSetting" }, + { NM_CONNECTION_ERROR_MISSING_PROPERTY, "NM_CONNECTION_ERROR_MISSING_PROPERTY", "MissingProperty" }, + { NM_CONNECTION_ERROR_INVALID_PROPERTY, "NM_CONNECTION_ERROR_INVALID_PROPERTY", "InvalidProperty" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMConnectionError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_crypto_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CRYPTO_ERROR_FAILED, "NM_CRYPTO_ERROR_FAILED", "failed" }, + { NM_CRYPTO_ERROR_INVALID_DATA, "NM_CRYPTO_ERROR_INVALID_DATA", "invalid-data" }, + { NM_CRYPTO_ERROR_INVALID_PASSWORD, "NM_CRYPTO_ERROR_INVALID_PASSWORD", "invalid-password" }, + { NM_CRYPTO_ERROR_UNKNOWN_CIPHER, "NM_CRYPTO_ERROR_UNKNOWN_CIPHER", "unknown-cipher" }, + { NM_CRYPTO_ERROR_DECRYPTION_FAILED, "NM_CRYPTO_ERROR_DECRYPTION_FAILED", "decryption-failed" }, + { NM_CRYPTO_ERROR_ENCRYPTION_FAILED, "NM_CRYPTO_ERROR_ENCRYPTION_FAILED", "encryption-failed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMCryptoError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_device_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_DEVICE_ERROR_FAILED, "NM_DEVICE_ERROR_FAILED", "Failed" }, + { NM_DEVICE_ERROR_CREATION_FAILED, "NM_DEVICE_ERROR_CREATION_FAILED", "CreationFailed" }, + { NM_DEVICE_ERROR_INVALID_CONNECTION, "NM_DEVICE_ERROR_INVALID_CONNECTION", "InvalidConnection" }, + { NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION", "IncompatibleConnection" }, + { NM_DEVICE_ERROR_NOT_ACTIVE, "NM_DEVICE_ERROR_NOT_ACTIVE", "NotActive" }, + { NM_DEVICE_ERROR_NOT_SOFTWARE, "NM_DEVICE_ERROR_NOT_SOFTWARE", "NotSoftware" }, + { NM_DEVICE_ERROR_NOT_ALLOWED, "NM_DEVICE_ERROR_NOT_ALLOWED", "NotAllowed" }, + { NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND", "SpecificObjectNotFound" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMDeviceError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_manager_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_MANAGER_ERROR_FAILED, "NM_MANAGER_ERROR_FAILED", "Failed" }, + { NM_MANAGER_ERROR_PERMISSION_DENIED, "NM_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "NM_MANAGER_ERROR_UNKNOWN_CONNECTION", "UnknownConnection" }, + { NM_MANAGER_ERROR_UNKNOWN_DEVICE, "NM_MANAGER_ERROR_UNKNOWN_DEVICE", "UnknownDevice" }, + { NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, "NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE", "ConnectionNotAvailable" }, + { NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE", "ConnectionNotActive" }, + { NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, "NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE", "ConnectionAlreadyActive" }, + { NM_MANAGER_ERROR_DEPENDENCY_FAILED, "NM_MANAGER_ERROR_DEPENDENCY_FAILED", "DependencyFailed" }, + { NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE", "AlreadyAsleepOrAwake" }, + { NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED", "AlreadyEnabledOrDisabled" }, + { NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL, "NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL", "UnknownLogLevel" }, + { NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN, "NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN", "UnknownLogDomain" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMManagerError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_secret_agent_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SECRET_AGENT_ERROR_FAILED, "NM_SECRET_AGENT_ERROR_FAILED", "Failed" }, + { NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, "NM_SECRET_AGENT_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "NM_SECRET_AGENT_ERROR_INVALID_CONNECTION", "InvalidConnection" }, + { NM_SECRET_AGENT_ERROR_USER_CANCELED, "NM_SECRET_AGENT_ERROR_USER_CANCELED", "UserCanceled" }, + { NM_SECRET_AGENT_ERROR_AGENT_CANCELED, "NM_SECRET_AGENT_ERROR_AGENT_CANCELED", "AgentCanceled" }, + { NM_SECRET_AGENT_ERROR_NO_SECRETS, "NM_SECRET_AGENT_ERROR_NO_SECRETS", "NoSecrets" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSecretAgentError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_settings_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTINGS_ERROR_FAILED, "NM_SETTINGS_ERROR_FAILED", "Failed" }, + { NM_SETTINGS_ERROR_PERMISSION_DENIED, "NM_SETTINGS_ERROR_PERMISSION_DENIED", "PermissionDenied" }, + { NM_SETTINGS_ERROR_NOT_SUPPORTED, "NM_SETTINGS_ERROR_NOT_SUPPORTED", "NotSupported" }, + { NM_SETTINGS_ERROR_INVALID_CONNECTION, "NM_SETTINGS_ERROR_INVALID_CONNECTION", "InvalidConnection" }, + { NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "NM_SETTINGS_ERROR_READ_ONLY_CONNECTION", "ReadOnlyConnection" }, + { NM_SETTINGS_ERROR_UUID_EXISTS, "NM_SETTINGS_ERROR_UUID_EXISTS", "UuidExists" }, + { NM_SETTINGS_ERROR_INVALID_HOSTNAME, "NM_SETTINGS_ERROR_INVALID_HOSTNAME", "InvalidHostname" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingsError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_plugin_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_PLUGIN_ERROR_FAILED, "NM_VPN_PLUGIN_ERROR_FAILED", "Failed" }, + { NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, "NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS", "StartingInProgress" }, + { NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, "NM_VPN_PLUGIN_ERROR_ALREADY_STARTED", "AlreadyStarted" }, + { NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, "NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS", "StoppingInProgress" }, + { NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, "NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED", "AlreadyStopped" }, + { NM_VPN_PLUGIN_ERROR_WRONG_STATE, "NM_VPN_PLUGIN_ERROR_WRONG_STATE", "WrongState" }, + { NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS", "BadArguments" }, + { NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED", "LaunchFailed" }, + { NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, "NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION", "InvalidConnection" }, + { NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, "NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED", "InteractiveNotSupported" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVpnPluginError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_802_1x_ck_format_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, "NM_SETTING_802_1X_CK_FORMAT_UNKNOWN", "unknown" }, + { NM_SETTING_802_1X_CK_FORMAT_X509, "NM_SETTING_802_1X_CK_FORMAT_X509", "x509" }, + { NM_SETTING_802_1X_CK_FORMAT_RAW_KEY, "NM_SETTING_802_1X_CK_FORMAT_RAW_KEY", "raw-key" }, + { NM_SETTING_802_1X_CK_FORMAT_PKCS12, "NM_SETTING_802_1X_CK_FORMAT_PKCS12", "pkcs12" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSetting8021xCKFormat"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_802_1x_ck_scheme_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_802_1X_CK_SCHEME_UNKNOWN, "NM_SETTING_802_1X_CK_SCHEME_UNKNOWN", "unknown" }, + { NM_SETTING_802_1X_CK_SCHEME_BLOB, "NM_SETTING_802_1X_CK_SCHEME_BLOB", "blob" }, + { NM_SETTING_802_1X_CK_SCHEME_PATH, "NM_SETTING_802_1X_CK_SCHEME_PATH", "path" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSetting8021xCKScheme"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_dcb_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_SETTING_DCB_FLAG_NONE, "NM_SETTING_DCB_FLAG_NONE", "none" }, + { NM_SETTING_DCB_FLAG_ENABLE, "NM_SETTING_DCB_FLAG_ENABLE", "enable" }, + { NM_SETTING_DCB_FLAG_ADVERTISE, "NM_SETTING_DCB_FLAG_ADVERTISE", "advertise" }, + { NM_SETTING_DCB_FLAG_WILLING, "NM_SETTING_DCB_FLAG_WILLING", "willing" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMSettingDcbFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_ip6_config_privacy_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, "NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN", "unknown" }, + { NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED, "NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED", "disabled" }, + { NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR, "NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR", "prefer-public-addr" }, + { NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, "NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR", "prefer-temp-addr" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingIP6ConfigPrivacy"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_serial_parity_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_SERIAL_PARITY_NONE, "NM_SETTING_SERIAL_PARITY_NONE", "none" }, + { NM_SETTING_SERIAL_PARITY_EVEN, "NM_SETTING_SERIAL_PARITY_EVEN", "even" }, + { NM_SETTING_SERIAL_PARITY_ODD, "NM_SETTING_SERIAL_PARITY_ODD", "odd" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingSerialParity"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vlan_priority_map_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VLAN_INGRESS_MAP, "NM_VLAN_INGRESS_MAP", "ingress-map" }, + { NM_VLAN_EGRESS_MAP, "NM_VLAN_EGRESS_MAP", "egress-map" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVlanPriorityMap"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vlan_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_VLAN_FLAG_REORDER_HEADERS, "NM_VLAN_FLAG_REORDER_HEADERS", "reorder-headers" }, + { NM_VLAN_FLAG_GVRP, "NM_VLAN_FLAG_GVRP", "gvrp" }, + { NM_VLAN_FLAG_LOOSE_BINDING, "NM_VLAN_FLAG_LOOSE_BINDING", "loose-binding" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMVlanFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_wep_key_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_WEP_KEY_TYPE_UNKNOWN, "NM_WEP_KEY_TYPE_UNKNOWN", "unknown" }, + { NM_WEP_KEY_TYPE_KEY, "NM_WEP_KEY_TYPE_KEY", "key" }, + { NM_WEP_KEY_TYPE_PASSPHRASE, "NM_WEP_KEY_TYPE_PASSPHRASE", "passphrase" }, + { NM_WEP_KEY_TYPE_LAST, "NM_WEP_KEY_TYPE_LAST", "last" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMWepKeyType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_secret_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_SETTING_SECRET_FLAG_NONE, "NM_SETTING_SECRET_FLAG_NONE", "none" }, + { NM_SETTING_SECRET_FLAG_AGENT_OWNED, "NM_SETTING_SECRET_FLAG_AGENT_OWNED", "agent-owned" }, + { NM_SETTING_SECRET_FLAG_NOT_SAVED, "NM_SETTING_SECRET_FLAG_NOT_SAVED", "not-saved" }, + { NM_SETTING_SECRET_FLAG_NOT_REQUIRED, "NM_SETTING_SECRET_FLAG_NOT_REQUIRED", "not-required" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMSettingSecretFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_compare_flags_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_COMPARE_FLAG_EXACT, "NM_SETTING_COMPARE_FLAG_EXACT", "exact" }, + { NM_SETTING_COMPARE_FLAG_FUZZY, "NM_SETTING_COMPARE_FLAG_FUZZY", "fuzzy" }, + { NM_SETTING_COMPARE_FLAG_IGNORE_ID, "NM_SETTING_COMPARE_FLAG_IGNORE_ID", "ignore-id" }, + { NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS", "ignore-secrets" }, + { NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS", "ignore-agent-owned-secrets" }, + { NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS", "ignore-not-saved-secrets" }, + { NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT, "NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT", "diff-result-with-default" }, + { NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, "NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT", "diff-result-no-default" }, + { NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP, "NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP", "ignore-timestamp" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingCompareFlags"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_setting_diff_result_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_SETTING_DIFF_RESULT_UNKNOWN, "NM_SETTING_DIFF_RESULT_UNKNOWN", "unknown" }, + { NM_SETTING_DIFF_RESULT_IN_A, "NM_SETTING_DIFF_RESULT_IN_A", "in-a" }, + { NM_SETTING_DIFF_RESULT_IN_B, "NM_SETTING_DIFF_RESULT_IN_B", "in-b" }, + { NM_SETTING_DIFF_RESULT_IN_A_DEFAULT, "NM_SETTING_DIFF_RESULT_IN_A_DEFAULT", "in-a-default" }, + { NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, "NM_SETTING_DIFF_RESULT_IN_B_DEFAULT", "in-b-default" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMSettingDiffResult"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_utils_security_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NMU_SEC_INVALID, "NMU_SEC_INVALID", "invalid" }, + { NMU_SEC_NONE, "NMU_SEC_NONE", "none" }, + { NMU_SEC_STATIC_WEP, "NMU_SEC_STATIC_WEP", "static-wep" }, + { NMU_SEC_LEAP, "NMU_SEC_LEAP", "leap" }, + { NMU_SEC_DYNAMIC_WEP, "NMU_SEC_DYNAMIC_WEP", "dynamic-wep" }, + { NMU_SEC_WPA_PSK, "NMU_SEC_WPA_PSK", "wpa-psk" }, + { NMU_SEC_WPA_ENTERPRISE, "NMU_SEC_WPA_ENTERPRISE", "wpa-enterprise" }, + { NMU_SEC_WPA2_PSK, "NMU_SEC_WPA2_PSK", "wpa2-psk" }, + { NMU_SEC_WPA2_ENTERPRISE, "NMU_SEC_WPA2_ENTERPRISE", "wpa2-enterprise" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMUtilsSecurityType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_service_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_SERVICE_STATE_UNKNOWN, "NM_VPN_SERVICE_STATE_UNKNOWN", "unknown" }, + { NM_VPN_SERVICE_STATE_INIT, "NM_VPN_SERVICE_STATE_INIT", "init" }, + { NM_VPN_SERVICE_STATE_SHUTDOWN, "NM_VPN_SERVICE_STATE_SHUTDOWN", "shutdown" }, + { NM_VPN_SERVICE_STATE_STARTING, "NM_VPN_SERVICE_STATE_STARTING", "starting" }, + { NM_VPN_SERVICE_STATE_STARTED, "NM_VPN_SERVICE_STATE_STARTED", "started" }, + { NM_VPN_SERVICE_STATE_STOPPING, "NM_VPN_SERVICE_STATE_STOPPING", "stopping" }, + { NM_VPN_SERVICE_STATE_STOPPED, "NM_VPN_SERVICE_STATE_STOPPED", "stopped" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVpnServiceState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_connection_state_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_CONNECTION_STATE_UNKNOWN, "NM_VPN_CONNECTION_STATE_UNKNOWN", "unknown" }, + { NM_VPN_CONNECTION_STATE_PREPARE, "NM_VPN_CONNECTION_STATE_PREPARE", "prepare" }, + { NM_VPN_CONNECTION_STATE_NEED_AUTH, "NM_VPN_CONNECTION_STATE_NEED_AUTH", "need-auth" }, + { NM_VPN_CONNECTION_STATE_CONNECT, "NM_VPN_CONNECTION_STATE_CONNECT", "connect" }, + { NM_VPN_CONNECTION_STATE_IP_CONFIG_GET, "NM_VPN_CONNECTION_STATE_IP_CONFIG_GET", "ip-config-get" }, + { NM_VPN_CONNECTION_STATE_ACTIVATED, "NM_VPN_CONNECTION_STATE_ACTIVATED", "activated" }, + { NM_VPN_CONNECTION_STATE_FAILED, "NM_VPN_CONNECTION_STATE_FAILED", "failed" }, + { NM_VPN_CONNECTION_STATE_DISCONNECTED, "NM_VPN_CONNECTION_STATE_DISCONNECTED", "disconnected" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVpnConnectionState"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_connection_state_reason_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_CONNECTION_STATE_REASON_UNKNOWN, "NM_VPN_CONNECTION_STATE_REASON_UNKNOWN", "unknown" }, + { NM_VPN_CONNECTION_STATE_REASON_NONE, "NM_VPN_CONNECTION_STATE_REASON_NONE", "none" }, + { NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED, "NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED", "user-disconnected" }, + { NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, "NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED", "device-disconnected" }, + { NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED, "NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED", "service-stopped" }, + { NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, "NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID", "ip-config-invalid" }, + { NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, "NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT", "connect-timeout" }, + { NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, "NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT", "service-start-timeout" }, + { NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED, "NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED", "service-start-failed" }, + { NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, "NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS", "no-secrets" }, + { NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED, "NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED", "login-failed" }, + { NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED, "NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED", "connection-removed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVpnConnectionStateReason"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_plugin_failure_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED, "NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED", "login-failed" }, + { NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED, "NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED", "connect-failed" }, + { NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG, "NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG", "bad-ip-config" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMVpnPluginFailure"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + + + diff --git a/libnm-core/nm-core-enum-types.h b/libnm-core/nm-core-enum-types.h new file mode 100644 index 00000000..162b704e --- /dev/null +++ b/libnm-core/nm-core-enum-types.h @@ -0,0 +1,97 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#ifndef __NM_CORE_ENUM_TYPES_H__ +#define __NM_CORE_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +GType nm_connection_serialization_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CONNECTION_SERIALIZATION_FLAGS (nm_connection_serialization_flags_get_type ()) +GType nm_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_STATE (nm_state_get_type ()) +GType nm_connectivity_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CONNECTIVITY_STATE (nm_connectivity_state_get_type ()) +GType nm_device_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_TYPE (nm_device_type_get_type ()) +GType nm_device_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_CAPABILITIES (nm_device_capabilities_get_type ()) +GType nm_device_wifi_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_WIFI_CAPABILITIES (nm_device_wifi_capabilities_get_type ()) +GType nm_802_11_ap_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_802_11_AP_FLAGS (nm_802_11_ap_flags_get_type ()) +GType nm_802_11_ap_security_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_802_11_AP_SECURITY_FLAGS (nm_802_11_ap_security_flags_get_type ()) +GType nm_802_11_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_802_11_MODE (nm_802_11_mode_get_type ()) +GType nm_bluetooth_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_BLUETOOTH_CAPABILITIES (nm_bluetooth_capabilities_get_type ()) +GType nm_device_modem_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_MODEM_CAPABILITIES (nm_device_modem_capabilities_get_type ()) +GType nm_device_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_STATE (nm_device_state_get_type ()) +GType nm_device_state_reason_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_STATE_REASON (nm_device_state_reason_get_type ()) +GType nm_active_connection_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_ACTIVE_CONNECTION_STATE (nm_active_connection_state_get_type ()) +GType nm_secret_agent_get_secrets_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SECRET_AGENT_GET_SECRETS_FLAGS (nm_secret_agent_get_secrets_flags_get_type ()) +GType nm_secret_agent_capabilities_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SECRET_AGENT_CAPABILITIES (nm_secret_agent_capabilities_get_type ()) +GType nm_agent_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) +GType nm_connection_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ()) +GType nm_crypto_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CRYPTO_ERROR (nm_crypto_error_get_type ()) +GType nm_device_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ()) +GType nm_manager_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MANAGER_ERROR (nm_manager_error_get_type ()) +GType nm_secret_agent_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SECRET_AGENT_ERROR (nm_secret_agent_error_get_type ()) +GType nm_settings_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) +GType nm_vpn_plugin_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_get_type ()) +GType nm_setting_802_1x_ck_format_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_802_1X_CK_FORMAT (nm_setting_802_1x_ck_format_get_type ()) +GType nm_setting_802_1x_ck_scheme_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_802_1X_CK_SCHEME (nm_setting_802_1x_ck_scheme_get_type ()) +GType nm_setting_dcb_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_DCB_FLAGS (nm_setting_dcb_flags_get_type ()) +GType nm_setting_ip6_config_privacy_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_IP6_CONFIG_PRIVACY (nm_setting_ip6_config_privacy_get_type ()) +GType nm_setting_serial_parity_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_SERIAL_PARITY (nm_setting_serial_parity_get_type ()) +GType nm_vlan_priority_map_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VLAN_PRIORITY_MAP (nm_vlan_priority_map_get_type ()) +GType nm_vlan_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VLAN_FLAGS (nm_vlan_flags_get_type ()) +GType nm_wep_key_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_WEP_KEY_TYPE (nm_wep_key_type_get_type ()) +GType nm_setting_secret_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_SECRET_FLAGS (nm_setting_secret_flags_get_type ()) +GType nm_setting_compare_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_COMPARE_FLAGS (nm_setting_compare_flags_get_type ()) +GType nm_setting_diff_result_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTING_DIFF_RESULT (nm_setting_diff_result_get_type ()) +GType nm_utils_security_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_UTILS_SECURITY_TYPE (nm_utils_security_type_get_type ()) +GType nm_vpn_service_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_SERVICE_STATE (nm_vpn_service_state_get_type ()) +GType nm_vpn_connection_state_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_CONNECTION_STATE (nm_vpn_connection_state_get_type ()) +GType nm_vpn_connection_state_reason_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_CONNECTION_STATE_REASON (nm_vpn_connection_state_reason_get_type ()) +GType nm_vpn_plugin_failure_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_PLUGIN_FAILURE (nm_vpn_plugin_failure_get_type ()) +G_END_DECLS + +#endif /* __NM_CORE_ENUM_TYPES_H__ */ + + + diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h new file mode 100644 index 00000000..5af90267 --- /dev/null +++ b/libnm-core/nm-core-internal.h @@ -0,0 +1,135 @@ +/* -*- 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 2014 Red Hat, Inc. + */ + +#ifndef NM_CORE_NM_INTERNAL_H +#define NM_CORE_NM_INTERNAL_H + +/* This header file contain functions that are provided as private API + * by libnm-core. It will contain functions to give privileged access to + * libnm-core. This can be useful for NetworkManager and libnm.so + * which both are special users of libnm-core. + * It also exposes some utility functions for reuse. + * + * These functions are not exported and are only available to components that link + * statically against libnm-core. This basically means libnm-core, libnm, NetworkManager + * and some test programs. + **/ + +#include "nm-connection.h" +#include "nm-core-enum-types.h" +#include "nm-dbus-interface.h" +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-bridge.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-dcb.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-infiniband.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-team-port.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-setting.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" +#include "nm-version.h" +#include "nm-vpn-dbus-interface.h" + +#define NM_UTILS_CLEAR_CANCELLABLE(c) \ + if (c) { \ + g_cancellable_cancel (c); \ + g_clear_object (&c); \ + } + +/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated + * connection can be replaced by a already-defined connection. This flag only + * takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE + * flag. + */ +#define NM_SETTING_COMPARE_FLAG_INFERRABLE 0x80000000 + + + +#define NM_SETTING_SECRET_FLAGS_ALL \ + (NM_SETTING_SECRET_FLAG_NONE | \ + NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ + NM_SETTING_SECRET_FLAG_NOT_SAVED | \ + NM_SETTING_SECRET_FLAG_NOT_REQUIRED) + +guint32 _nm_setting_get_setting_priority (NMSetting *setting); + +gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value); + +GSList * _nm_utils_hash_values_to_slist (GHashTable *hash); + +GHashTable *_nm_utils_copy_strdict (GHashTable *strdict); + +typedef gpointer (*NMUtilsCopyFunc) (gpointer); + +GPtrArray *_nm_utils_copy_slist_to_array (const GSList *list, + NMUtilsCopyFunc copy_func, + GDestroyNotify unref_func); +GSList *_nm_utils_copy_array_to_slist (const GPtrArray *array, + NMUtilsCopyFunc copy_func); + +GPtrArray *_nm_utils_copy_array (const GPtrArray *array, + NMUtilsCopyFunc copy_func, + GDestroyNotify free_func); +GPtrArray *_nm_utils_copy_object_array (const GPtrArray *array); + +gboolean _nm_utils_string_in_list (const char *str, + const char **valid_strings); + +char ** _nm_utils_strsplit_set (const char *str, + const char *delimiters, + int max_tokens); + +#define NM_UTILS_UUID_TYPE_LEGACY 0 +#define NM_UTILS_UUID_TYPE_VARIANT3 1 + +char *nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args); + +void _nm_dbus_errors_init (void); + +extern gboolean _nm_utils_is_manager_process; + +GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data, + gsize len, + const char *in_password, + char **out_password, + GError **error); + +#endif diff --git a/libnm-core/nm-core-types.h b/libnm-core/nm-core-types.h new file mode 100644 index 00000000..524d6396 --- /dev/null +++ b/libnm-core/nm-core-types.h @@ -0,0 +1,60 @@ +/* -*- 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 2014 Red Hat, Inc. + */ + +#ifndef __NM_CORE_TYPES_H__ +#define __NM_CORE_TYPES_H__ + +#include + +#include +#include + +typedef struct _NMConnection NMConnection; +typedef struct _NMSetting NMSetting; +typedef struct _NMSetting8021x NMSetting8021x; +typedef struct _NMSettingAdsl NMSettingAdsl; +typedef struct _NMSettingBluetooth NMSettingBluetooth; +typedef struct _NMSettingBond NMSettingBond; +typedef struct _NMSettingBridge NMSettingBridge; +typedef struct _NMSettingBridgePort NMSettingBridgePort; +typedef struct _NMSettingCdma NMSettingCdma; +typedef struct _NMSettingConnection NMSettingConnection; +typedef struct _NMSettingDcb NMSettingDcb; +typedef struct _NMSettingGeneric NMSettingGeneric; +typedef struct _NMSettingGsm NMSettingGsm; +typedef struct _NMSettingInfiniband NMSettingInfiniband; +typedef struct _NMSettingIPConfig NMSettingIPConfig; +typedef struct _NMSettingIP4Config NMSettingIP4Config; +typedef struct _NMSettingIP6Config NMSettingIP6Config; +typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh; +typedef struct _NMSettingPpp NMSettingPpp; +typedef struct _NMSettingPppoe NMSettingPppoe; +typedef struct _NMSettingSerial NMSettingSerial; +typedef struct _NMSettingTeam NMSettingTeam; +typedef struct _NMSettingTeamPort NMSettingTeamPort; +typedef struct _NMSettingVlan NMSettingVlan; +typedef struct _NMSettingVpn NMSettingVpn; +typedef struct _NMSettingWimax NMSettingWimax; +typedef struct _NMSettingWired NMSettingWired; +typedef struct _NMSettingWireless NMSettingWireless; +typedef struct _NMSettingWirelessSecurity NMSettingWirelessSecurity; +typedef struct _NMSimpleConnection NMSimpleConnection; + +#endif /* __NM_CORE_TYPES_H__ */ diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h new file mode 100644 index 00000000..dd2b70a0 --- /dev/null +++ b/libnm-core/nm-dbus-interface.h @@ -0,0 +1,611 @@ +/* -*- 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. + * + * Copyright 2004 - 2014 Red Hat, Inc. + */ + +/* Definitions related to NetworkManager's D-Bus interfaces. + * + * Note that although this header is installed as part of libnm, it is also + * used by some external code that does not link to libnm. + */ + +#ifndef __NM_DBUS_INTERFACE_H__ +#define __NM_DBUS_INTERFACE_H__ + +#include "nm-version.h" + +/* + * dbus services details + */ +#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" + +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device" +#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired" +#define NM_DBUS_INTERFACE_DEVICE_ADSL NM_DBUS_INTERFACE_DEVICE ".Adsl" +#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless" +#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH NM_DBUS_INTERFACE_DEVICE ".Bluetooth" +#define NM_DBUS_INTERFACE_DEVICE_OLPC_MESH NM_DBUS_INTERFACE_DEVICE ".OlpcMesh" +#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" +#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" +#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem" +#define NM_DBUS_INTERFACE_DEVICE_WIMAX NM_DBUS_INTERFACE_DEVICE ".WiMax" +#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp" +#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp" +#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active" +#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config" +#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config" +#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config" +#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" +#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband" +#define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond" +#define NM_DBUS_INTERFACE_DEVICE_TEAM NM_DBUS_INTERFACE_DEVICE ".Team" +#define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan" +#define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge" +#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic" +#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth" +#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun" +#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan" +#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan" +#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre" + + +#define NM_DBUS_INTERFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" +#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" + +#define NM_DBUS_INTERFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManager.Settings.Connection" +#define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManager/Settings/Connection" +#define NM_DBUS_INTERFACE_SETTINGS_CONNECTION_SECRETS "org.freedesktop.NetworkManager.Settings.Connection.Secrets" + +#define NM_DBUS_INTERFACE_AGENT_MANAGER NM_DBUS_INTERFACE ".AgentManager" +#define NM_DBUS_PATH_AGENT_MANAGER "/org/freedesktop/NetworkManager/AgentManager" + +#define NM_DBUS_INTERFACE_SECRET_AGENT NM_DBUS_INTERFACE ".SecretAgent" +#define NM_DBUS_PATH_SECRET_AGENT "/org/freedesktop/NetworkManager/SecretAgent" + +/** + * NMState: + * @NM_STATE_UNKNOWN: networking state is unknown + * @NM_STATE_ASLEEP: networking is not enabled + * @NM_STATE_DISCONNECTED: there is no active network connection + * @NM_STATE_DISCONNECTING: network connections are being cleaned up + * @NM_STATE_CONNECTING: a network connection is being started + * @NM_STATE_CONNECTED_LOCAL: there is only local IPv4 and/or IPv6 connectivity + * @NM_STATE_CONNECTED_SITE: there is only site-wide IPv4 and/or IPv6 connectivity + * @NM_STATE_CONNECTED_GLOBAL: there is global IPv4 and/or IPv6 Internet connectivity + * + * #NMState values indicate the current overall networking state. + * + * (Corresponds to the NM_STATE type in nm-manager.xml.) + **/ +typedef enum { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70 +} NMState; + +/** + * NMConnectivityState: + * @NM_CONNECTIVITY_UNKNOWN: Network connectivity is unknown. + * @NM_CONNECTIVITY_NONE: The host is not connected to any network. + * @NM_CONNECTIVITY_PORTAL: The host is behind a captive portal and + * cannot reach the full Internet. + * @NM_CONNECTIVITY_LIMITED: The host is connected to a network, but + * does not appear to be able to reach the full Internet. + * @NM_CONNECTIVITY_FULL: The host is connected to a network, and + * appears to be able to reach the full Internet. + * + * (Corresponds to the NM_CONNECTIVITY type in nm-manager.xml.) + */ +typedef enum { + NM_CONNECTIVITY_UNKNOWN, + NM_CONNECTIVITY_NONE, + NM_CONNECTIVITY_PORTAL, + NM_CONNECTIVITY_LIMITED, + NM_CONNECTIVITY_FULL +} NMConnectivityState; + +/** + * NMDeviceType: + * @NM_DEVICE_TYPE_UNKNOWN: unknown device + * @NM_DEVICE_TYPE_GENERIC: generic support for unrecognized device types + * @NM_DEVICE_TYPE_ETHERNET: a wired ethernet device + * @NM_DEVICE_TYPE_WIFI: an 802.11 WiFi device + * @NM_DEVICE_TYPE_UNUSED1: not used + * @NM_DEVICE_TYPE_UNUSED2: not used + * @NM_DEVICE_TYPE_BT: a Bluetooth device supporting PAN or DUN access protocols + * @NM_DEVICE_TYPE_OLPC_MESH: an OLPC XO mesh networking device + * @NM_DEVICE_TYPE_WIMAX: an 802.16e Mobile WiMAX broadband device + * @NM_DEVICE_TYPE_MODEM: a modem supporting analog telephone, CDMA/EVDO, + * GSM/UMTS, or LTE network access protocols + * @NM_DEVICE_TYPE_INFINIBAND: an IP-over-InfiniBand device + * @NM_DEVICE_TYPE_BOND: a bond master interface + * @NM_DEVICE_TYPE_VLAN: an 802.1Q VLAN interface + * @NM_DEVICE_TYPE_ADSL: ADSL modem + * @NM_DEVICE_TYPE_BRIDGE: a bridge master interface + * @NM_DEVICE_TYPE_TEAM: a team master interface + * + * #NMDeviceType values indicate the type of hardware represented by + * an #NMDevice. + * + * (Corresponds to the NM_DEVICE_TYPE type in nm-device.xml.) + **/ +typedef enum { + NM_DEVICE_TYPE_UNKNOWN = 0, + NM_DEVICE_TYPE_ETHERNET = 1, + NM_DEVICE_TYPE_WIFI = 2, + NM_DEVICE_TYPE_UNUSED1 = 3, + NM_DEVICE_TYPE_UNUSED2 = 4, + NM_DEVICE_TYPE_BT = 5, /* Bluetooth */ + NM_DEVICE_TYPE_OLPC_MESH = 6, + NM_DEVICE_TYPE_WIMAX = 7, + NM_DEVICE_TYPE_MODEM = 8, + NM_DEVICE_TYPE_INFINIBAND = 9, + NM_DEVICE_TYPE_BOND = 10, + NM_DEVICE_TYPE_VLAN = 11, + NM_DEVICE_TYPE_ADSL = 12, + NM_DEVICE_TYPE_BRIDGE = 13, + NM_DEVICE_TYPE_GENERIC = 14, + NM_DEVICE_TYPE_TEAM = 15, +} NMDeviceType; + +/** + * NMDeviceCapabilities: + * @NM_DEVICE_CAP_NONE: device has no special capabilities + * @NM_DEVICE_CAP_NM_SUPPORTED: NetworkManager supports this device + * @NM_DEVICE_CAP_CARRIER_DETECT: this device can indicate carrier status + * @NM_DEVICE_CAP_IS_SOFTWARE: this device is a software device + * + * General device capability flags. + * + * (Corresponds to the NM_DEVICE_CAP type in nm-device-wifi.xml.) + **/ +typedef enum { /*< flags >*/ + NM_DEVICE_CAP_NONE = 0x00000000, + NM_DEVICE_CAP_NM_SUPPORTED = 0x00000001, + NM_DEVICE_CAP_CARRIER_DETECT = 0x00000002, + NM_DEVICE_CAP_IS_SOFTWARE = 0x00000004, +} NMDeviceCapabilities; + + +/** + * NMDeviceWifiCapabilities: + * @NM_WIFI_DEVICE_CAP_NONE: device has no encryption/authentication capabilities + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP40: device supports 40/64-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP104: device supports 104/128-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_TKIP: device supports TKIP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_CCMP: device supports AES/CCMP encryption + * @NM_WIFI_DEVICE_CAP_WPA: device supports WPA1 authentication + * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication + * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode + * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode + * + * 802.11 specific device encryption and authentication capabilities. + * + * (Corresponds to the NM_802_11_DEVICE_CAP type in nm-device-wifi.xml.) + **/ +typedef enum { /*< flags >*/ + NM_WIFI_DEVICE_CAP_NONE = 0x00000000, + NM_WIFI_DEVICE_CAP_CIPHER_WEP40 = 0x00000001, + NM_WIFI_DEVICE_CAP_CIPHER_WEP104 = 0x00000002, + NM_WIFI_DEVICE_CAP_CIPHER_TKIP = 0x00000004, + NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008, + NM_WIFI_DEVICE_CAP_WPA = 0x00000010, + NM_WIFI_DEVICE_CAP_RSN = 0x00000020, + NM_WIFI_DEVICE_CAP_AP = 0x00000040, + NM_WIFI_DEVICE_CAP_ADHOC = 0x00000080 +} NMDeviceWifiCapabilities; + + +/** + * NM80211ApFlags: + * @NM_802_11_AP_FLAGS_NONE: access point has no special capabilities + * @NM_802_11_AP_FLAGS_PRIVACY: access point requires authentication and + * encryption (usually means WEP) + * + * 802.11 access point flags. + * + * (Corresponds to the NM_802_11_AP_FLAGS type in nm-access-point.xml.) + **/ +typedef enum { /*< underscore_name=nm_802_11_ap_flags, flags >*/ + NM_802_11_AP_FLAGS_NONE = 0x00000000, + NM_802_11_AP_FLAGS_PRIVACY = 0x00000001 +} NM80211ApFlags; + +/** + * NM80211ApSecurityFlags: + * @NM_802_11_AP_SEC_NONE: the access point has no special security requirements + * @NM_802_11_AP_SEC_PAIR_WEP40: 40/64-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_WEP104: 104/128-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_TKIP: TKIP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_CCMP: AES/CCMP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_GROUP_WEP40: 40/64-bit WEP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_GROUP_WEP104: 104/128-bit WEP is supported for + * group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_TKIP: TKIP is supported for group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_CCMP: AES/CCMP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_KEY_MGMT_PSK: WPA/RSN Pre-Shared Key encryption is + * supported + * @NM_802_11_AP_SEC_KEY_MGMT_802_1X: 802.1x authentication and key management + * is supported + * + * 802.11 access point security and authentication flags. These flags describe + * the current security requirements of an access point as determined from the + * access point's beacon. + * + * (Corresponds to the NM_802_11_AP_SEC type in nm-access-point.xml.) + **/ +typedef enum { /*< underscore_name=nm_802_11_ap_security_flags, flags >*/ + NM_802_11_AP_SEC_NONE = 0x00000000, + NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001, + NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002, + NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004, + NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008, + NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010, + NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020, + NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040, + NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080, + NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100, + NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200 +} NM80211ApSecurityFlags; + +/** + * NM80211Mode: + * @NM_802_11_MODE_UNKNOWN: the device or access point mode is unknown + * @NM_802_11_MODE_ADHOC: for both devices and access point objects, indicates + * the object is part of an Ad-Hoc 802.11 network without a central + * coordinating access point. + * @NM_802_11_MODE_INFRA: the device or access point is in infrastructure mode. + * For devices, this indicates the device is an 802.11 client/station. For + * access point objects, this indicates the object is an access point that + * provides connectivity to clients. + * @NM_802_11_MODE_AP: the device is an access point/hotspot. Not valid for + * access point objects; used only for hotspot mode on the local machine. + * + * Indicates the 802.11 mode an access point or device is currently in. + * + * (Corresponds to the NM_802_11_MODE type in generic-types.xml.) + **/ +typedef enum { /*< underscore_name=nm_802_11_mode >*/ + NM_802_11_MODE_UNKNOWN = 0, + NM_802_11_MODE_ADHOC, + NM_802_11_MODE_INFRA, + NM_802_11_MODE_AP +} NM80211Mode; + +/** + * NMBluetoothCapabilities: + * @NM_BT_CAPABILITY_NONE: device has no usable capabilities + * @NM_BT_CAPABILITY_DUN: device provides Dial-Up Networking capability + * @NM_BT_CAPABILITY_NAP: device provides Network Access Point capability + * + * #NMBluetoothCapabilities values indicate the usable capabilities of a + * Bluetooth device. + * + * (Corresponds to the NM_BT_CAPABILITY type in nm-device-bt.xml.) + **/ +typedef enum { /*< flags >*/ + NM_BT_CAPABILITY_NONE = 0x00000000, + NM_BT_CAPABILITY_DUN = 0x00000001, + NM_BT_CAPABILITY_NAP = 0x00000002, +} NMBluetoothCapabilities; + +/** + * NMDeviceModemCapabilities: + * @NM_DEVICE_MODEM_CAPABILITY_NONE: modem has no usable capabilities + * @NM_DEVICE_MODEM_CAPABILITY_POTS: modem uses the analog wired telephone + * network and is not a wireless/cellular device + * @NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO: modem supports at least one of CDMA + * 1xRTT, EVDO revision 0, EVDO revision A, or EVDO revision B + * @NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS: modem supports at least one of GSM, + * GPRS, EDGE, UMTS, HSDPA, HSUPA, or HSPA+ packet switched data capability + * @NM_DEVICE_MODEM_CAPABILITY_LTE: modem has LTE data capability + * + * #NMDeviceModemCapabilities values indicate the generic radio access + * technology families a modem device supports. For more information on the + * specific access technologies the device supports use the ModemManager D-Bus + * API. + * + * (Corresponds to the NM_DEVICE_MODEM_CAPABILITY type in nm-device-modem.xml.) + **/ +typedef enum { /*< flags >*/ + NM_DEVICE_MODEM_CAPABILITY_NONE = 0x00000000, + NM_DEVICE_MODEM_CAPABILITY_POTS = 0x00000001, + NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO = 0x00000002, + NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS = 0x00000004, + NM_DEVICE_MODEM_CAPABILITY_LTE = 0x00000008, +} NMDeviceModemCapabilities; + + +/** + * NMDeviceState: + * @NM_DEVICE_STATE_UNKNOWN: the device's state is unknown + * @NM_DEVICE_STATE_UNMANAGED: the device is recognized, but not managed by + * NetworkManager + * @NM_DEVICE_STATE_UNAVAILABLE: the device is managed by NetworkManager, but + * is not available for use. Reasons may include the wireless switched off, + * missing firmware, no ethernet carrier, missing supplicant or modem manager, + * etc. + * @NM_DEVICE_STATE_DISCONNECTED: the device can be activated, but is currently + * idle and not connected to a network. + * @NM_DEVICE_STATE_PREPARE: the device is preparing the connection to the + * network. This may include operations like changing the MAC address, + * setting physical link properties, and anything else required to connect + * to the requested network. + * @NM_DEVICE_STATE_CONFIG: the device is connecting to the requested network. + * This may include operations like associating with the WiFi AP, dialing + * the modem, connecting to the remote Bluetooth device, etc. + * @NM_DEVICE_STATE_NEED_AUTH: the device requires more information to continue + * connecting to the requested network. This includes secrets like WiFi + * passphrases, login passwords, PIN codes, etc. + * @NM_DEVICE_STATE_IP_CONFIG: the device is requesting IPv4 and/or IPv6 + * addresses and routing information from the network. + * @NM_DEVICE_STATE_IP_CHECK: the device is checking whether further action is + * required for the requested network connection. This may include checking + * whether only local network access is available, whether a captive portal + * is blocking access to the Internet, etc. + * @NM_DEVICE_STATE_SECONDARIES: the device is waiting for a secondary + * connection (like a VPN) which must activated before the device can be + * activated + * @NM_DEVICE_STATE_ACTIVATED: the device has a network connection, either local + * or global. + * @NM_DEVICE_STATE_DEACTIVATING: a disconnection from the current network + * connection was requested, and the device is cleaning up resources used for + * that connection. The network connection may still be valid. + * @NM_DEVICE_STATE_FAILED: the device failed to connect to the requested + * network and is cleaning up the connection request + * + * (Corresponds to the NM_DEVICE_STATE type in nm-device.xml.) + **/ +typedef enum { + NM_DEVICE_STATE_UNKNOWN = 0, + NM_DEVICE_STATE_UNMANAGED = 10, + NM_DEVICE_STATE_UNAVAILABLE = 20, + NM_DEVICE_STATE_DISCONNECTED = 30, + NM_DEVICE_STATE_PREPARE = 40, + NM_DEVICE_STATE_CONFIG = 50, + NM_DEVICE_STATE_NEED_AUTH = 60, + NM_DEVICE_STATE_IP_CONFIG = 70, + NM_DEVICE_STATE_IP_CHECK = 80, + NM_DEVICE_STATE_SECONDARIES = 90, + NM_DEVICE_STATE_ACTIVATED = 100, + NM_DEVICE_STATE_DEACTIVATING = 110, + NM_DEVICE_STATE_FAILED = 120 +} NMDeviceState; + + +/** + * NMDeviceStateReason: + * @NM_DEVICE_STATE_REASON_NONE: No reason given + * @NM_DEVICE_STATE_REASON_UNKNOWN: Unknown error + * @NM_DEVICE_STATE_REASON_NOW_MANAGED: Device is now managed + * @NM_DEVICE_STATE_REASON_NOW_UNMANAGED: Device is now unmanaged + * @NM_DEVICE_STATE_REASON_CONFIG_FAILED: The device could not be readied for configuration + * @NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: IP configuration could not be reserved (no available address, timeout, etc) + * @NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: The IP config is no longer valid + * @NM_DEVICE_STATE_REASON_NO_SECRETS: Secrets were required, but not provided + * @NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: 802.1x supplicant disconnected + * @NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: 802.1x supplicant configuration failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: 802.1x supplicant failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: 802.1x supplicant took too long to authenticate + * @NM_DEVICE_STATE_REASON_PPP_START_FAILED: PPP service failed to start + * @NM_DEVICE_STATE_REASON_PPP_DISCONNECT: PPP service disconnected + * @NM_DEVICE_STATE_REASON_PPP_FAILED: PPP failed + * @NM_DEVICE_STATE_REASON_DHCP_START_FAILED: DHCP client failed to start + * @NM_DEVICE_STATE_REASON_DHCP_ERROR: DHCP client error + * @NM_DEVICE_STATE_REASON_DHCP_FAILED: DHCP client failed + * @NM_DEVICE_STATE_REASON_SHARED_START_FAILED: Shared connection service failed to start + * @NM_DEVICE_STATE_REASON_SHARED_FAILED: Shared connection service failed + * @NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: AutoIP service failed to start + * @NM_DEVICE_STATE_REASON_AUTOIP_ERROR: AutoIP service error + * @NM_DEVICE_STATE_REASON_AUTOIP_FAILED: AutoIP service failed + * @NM_DEVICE_STATE_REASON_MODEM_BUSY: The line is busy + * @NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: No dial tone + * @NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: No carrier could be established + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: The dialing request timed out + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: The dialing attempt failed + * @NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: Modem initialization failed + * @NM_DEVICE_STATE_REASON_GSM_APN_FAILED: Failed to select the specified APN + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: Not searching for networks + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: Network registration denied + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: Network registration timed out + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: Failed to register with the requested network + * @NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: PIN check failed + * @NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: Necessary firmware for the device may be missing + * @NM_DEVICE_STATE_REASON_REMOVED: The device was removed + * @NM_DEVICE_STATE_REASON_SLEEPING: NetworkManager went to sleep + * @NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: The device's active connection disappeared + * @NM_DEVICE_STATE_REASON_USER_REQUESTED: Device disconnected by user or client + * @NM_DEVICE_STATE_REASON_CARRIER: Carrier/link changed + * @NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: The device's existing connection was assumed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: The supplicant is now available + * @NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: The modem could not be found + * @NM_DEVICE_STATE_REASON_BT_FAILED: The Bluetooth connection failed or timed out + * @NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: GSM Modem's SIM Card not inserted + * @NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: GSM Modem's SIM Pin required + * @NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: GSM Modem's SIM Puk required + * @NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: GSM Modem's SIM wrong + * @NM_DEVICE_STATE_REASON_INFINIBAND_MODE: InfiniBand device does not support connected mode + * @NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: A dependency of the connection failed + * @NM_DEVICE_STATE_REASON_BR2684_FAILED: Problem with the RFC 2684 Ethernet over ADSL bridge + * @NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE: ModemManager not running + * @NM_DEVICE_STATE_REASON_SSID_NOT_FOUND: The WiFi network could not be found + * @NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED: A secondary connection of the base connection failed + * @NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED: DCB or FCoE setup failed + * @NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED: teamd control failed + * @NM_DEVICE_STATE_REASON_MODEM_FAILED: Modem failed or no longer available + * @NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: Modem now ready and available + * @NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: SIM PIN was incorrect + * + * Device state change reason codes + * + * (Corresponds to the NM_DEVICE_STATE_REASON type in nm-device.xml.) + */ +typedef enum { + NM_DEVICE_STATE_REASON_NONE = 0, + NM_DEVICE_STATE_REASON_UNKNOWN = 1, + NM_DEVICE_STATE_REASON_NOW_MANAGED = 2, + NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3, + NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE = 5, + NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED = 6, + NM_DEVICE_STATE_REASON_NO_SECRETS = 7, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8, + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11, + NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13, + NM_DEVICE_STATE_REASON_PPP_FAILED = 14, + NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15, + NM_DEVICE_STATE_REASON_DHCP_ERROR = 16, + NM_DEVICE_STATE_REASON_DHCP_FAILED = 17, + NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18, + NM_DEVICE_STATE_REASON_SHARED_FAILED = 19, + NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20, + NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21, + NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22, + NM_DEVICE_STATE_REASON_MODEM_BUSY = 23, + NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25, + NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26, + NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27, + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28, + NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33, + NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34, + NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35, + NM_DEVICE_STATE_REASON_REMOVED = 36, + NM_DEVICE_STATE_REASON_SLEEPING = 37, + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38, + NM_DEVICE_STATE_REASON_USER_REQUESTED = 39, + NM_DEVICE_STATE_REASON_CARRIER = 40, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED = 41, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE = 42, + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND = 43, + NM_DEVICE_STATE_REASON_BT_FAILED = 44, + NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED = 45, + NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED = 46, + NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED = 47, + NM_DEVICE_STATE_REASON_GSM_SIM_WRONG = 48, + NM_DEVICE_STATE_REASON_INFINIBAND_MODE = 49, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED = 50, + NM_DEVICE_STATE_REASON_BR2684_FAILED = 51, + NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE = 52, + NM_DEVICE_STATE_REASON_SSID_NOT_FOUND = 53, + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED = 54, + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED = 56, + NM_DEVICE_STATE_REASON_MODEM_FAILED = 57, + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58, + NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59, +} NMDeviceStateReason; + + +/** + * NMActiveConnectionState: + * @NM_ACTIVE_CONNECTION_STATE_UNKNOWN: the state of the connection is unknown + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATING: a network connection is being prepared + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATED: there is a connection to the network + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: the network connection is being + * torn down and cleaned up + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: the network connection is disconnected + * and will be removed + * + * #NMActiveConnectionState values indicate the state of a connection to a + * specific network while it is starting, connected, or disconnecting from that + * network. + * + * (Corresponds to the NM_ACTIVE_CONNECTION_STATE type in nm-active-connection.xml.) + **/ +typedef enum { + NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, + NM_ACTIVE_CONNECTION_STATE_ACTIVATING, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED +} NMActiveConnectionState; + +/** + * NMSecretAgentGetSecretsFlags: + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE: no special behavior; by default no + * user interaction is allowed and requests for secrets are fulfilled from + * persistent storage, or if no secrets are available an error is returned. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION: allows the request to + * interact with the user, possibly prompting via UI for secrets if any are + * required, or if none are found in persistent storage. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW: explicitly prompt for new + * secrets from the user. This flag signals that NetworkManager thinks any + * existing secrets are invalid or wrong. This flag implies that interaction + * is allowed. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED: set if the request was + * initiated by user-requested action via the D-Bus interface, as opposed to + * automatically initiated by NetworkManager in response to (for example) scan + * results or carrier changes. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM: Internal flag, not part of + * the D-Bus API. + * @NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS: Internal flag, not part of + * the D-Bus API. + * + * #NMSecretAgentGetSecretsFlags values modify the behavior of a GetSecrets request. + * + * (Corresponds to the NM_SECRET_AGENT_GET_SECRETS_FLAGS type in nm-secret-agent.xml.) + */ +typedef enum { /*< flags >*/ + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2, + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED = 0x4, + + /* Internal to NM; not part of the D-Bus API */ + NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM = 0x80000000, + NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS = 0x40000000, +} NMSecretAgentGetSecretsFlags; + +/** + * NMSecretAgentCapabilities: + * @NM_SECRET_AGENT_CAPABILITY_NONE: the agent supports no special capabilities + * @NM_SECRET_AGENT_CAPABILITY_VPN_HINTS: the agent supports passing hints to + * VPN plugin authentication dialogs. + * @NM_SECRET_AGENT_CAPABILITY_LAST: bounds checking value; should not be used. + * + * #NMSecretAgentCapabilities indicate various capabilities of the agent. + * + * (Corresponds to the NM_SECRET_AGENT_CAPABILITIES type in nm-secret-agent.xml.) + */ +typedef enum /*< flags >*/ { + NM_SECRET_AGENT_CAPABILITY_NONE = 0x0, + NM_SECRET_AGENT_CAPABILITY_VPN_HINTS = 0x1, + + /* boundary value */ + NM_SECRET_AGENT_CAPABILITY_LAST = NM_SECRET_AGENT_CAPABILITY_VPN_HINTS +} NMSecretAgentCapabilities; + +#endif /* __NM_DBUS_INTERFACE_H__ */ diff --git a/libnm-core/nm-errors.c b/libnm-core/nm-errors.c new file mode 100644 index 00000000..229f14a0 --- /dev/null +++ b/libnm-core/nm-errors.c @@ -0,0 +1,90 @@ +/* -*- 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. + * + * Copyright 2004 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-errors.h" +#include "nm-glib-compat.h" +#include "nm-dbus-interface.h" +#include "nm-vpn-dbus-interface.h" +#include "nm-core-internal.h" + +G_DEFINE_QUARK (nm-agent-manager-error-quark, nm_agent_manager_error) +G_DEFINE_QUARK (nm-connection-error-quark, nm_connection_error) +G_DEFINE_QUARK (nm-crypto-error-quark, nm_crypto_error) +G_DEFINE_QUARK (nm-device-error-quark, nm_device_error) +G_DEFINE_QUARK (nm-manager-error-quark, nm_manager_error) +G_DEFINE_QUARK (nm-secret-agent-error-quark, nm_secret_agent_error) +G_DEFINE_QUARK (nm-settings-error-quark, nm_settings_error) +G_DEFINE_QUARK (nm-vpn-plugin-error-quark, nm_vpn_plugin_error) + +static void +register_error_domain (GQuark domain, + const char *interface, + GType enum_type) +{ + GEnumClass *enum_class; + GEnumValue *e; + char *error_name; + int i; + + enum_class = g_type_class_ref (enum_type); + for (i = 0; i < enum_class->n_values; i++) { + e = &enum_class->values[i]; + g_assert (strchr (e->value_nick, '-') == NULL); + error_name = g_strdup_printf ("%s.%s", interface, e->value_nick); + g_dbus_error_register_error (domain, e->value, error_name); + g_free (error_name); + } + + g_type_class_unref (enum_class); +} + +void +_nm_dbus_errors_init (void) +{ + register_error_domain (NM_AGENT_MANAGER_ERROR, + NM_DBUS_INTERFACE_AGENT_MANAGER, + NM_TYPE_AGENT_MANAGER_ERROR); + register_error_domain (NM_CONNECTION_ERROR, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NM_TYPE_CONNECTION_ERROR); + register_error_domain (NM_DEVICE_ERROR, + NM_DBUS_INTERFACE_DEVICE, + NM_TYPE_DEVICE_ERROR); + register_error_domain (NM_MANAGER_ERROR, + NM_DBUS_INTERFACE, + NM_TYPE_MANAGER_ERROR); + register_error_domain (NM_SECRET_AGENT_ERROR, + NM_DBUS_INTERFACE_SECRET_AGENT, + NM_TYPE_SECRET_AGENT_ERROR); + register_error_domain (NM_SETTINGS_ERROR, + NM_DBUS_INTERFACE_SETTINGS, + NM_TYPE_SETTINGS_ERROR); + register_error_domain (NM_SETTINGS_ERROR, + NM_DBUS_INTERFACE_SETTINGS, + NM_TYPE_SETTINGS_ERROR); + register_error_domain (NM_VPN_PLUGIN_ERROR, + NM_VPN_DBUS_PLUGIN_INTERFACE, + NM_TYPE_VPN_PLUGIN_ERROR); +} diff --git a/libnm-core/nm-errors.h b/libnm-core/nm-errors.h new file mode 100644 index 00000000..a9857445 --- /dev/null +++ b/libnm-core/nm-errors.h @@ -0,0 +1,319 @@ +/* -*- 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. + * + * Copyright 2004 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_ERRORS_H__ +#define __NM_ERRORS_H__ + +/** + * NMAgentManagerError: + * @NM_AGENT_MANAGER_ERROR_FAILED: unknown or unspecified error + * @NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED: The caller does not have permission + * to register a secret agent, or is trying to register the same secret agent + * twice. + * @NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER: The identifier is not a valid + * secret agent identifier. + * @NM_AGENT_MANAGER_ERROR_NOT_REGISTERED: The caller tried to unregister an agent + * that was not registered. + * @NM_AGENT_MANAGER_ERROR_NO_SECRETS: No secret agent returned secrets for this + * request + * @NM_AGENT_MANAGER_ERROR_USER_CANCELED: The user canceled the secrets request. + * + * Errors returned from the secret-agent manager. + * + * These errors may be returned from operations that could cause secrets to be + * requested (such as nm_client_activate_connection()), and correspond to D-Bus + * errors in the "org.freedesktop.NetworkManager.AgentManager" namespace. + */ +typedef enum { + NM_AGENT_MANAGER_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, /*< nick=InvalidIdentifier >*/ + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, /*< nick=NotRegistered >*/ + NM_AGENT_MANAGER_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ + NM_AGENT_MANAGER_ERROR_USER_CANCELED, /*< nick=UserCanceled >*/ +} NMAgentManagerError; + +GQuark nm_agent_manager_error_quark (void); +#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ()) + +/** + * NMConnectionError: + * @NM_CONNECTION_ERROR_FAILED: unknown or unclassified error + * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object + * did not contain the specified #NMSetting object + * @NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND: the #NMConnection did not contain the + * requested #NMSetting property + * @NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET: an operation which requires a secret + * was attempted on a non-secret property + * @NM_CONNECTION_ERROR_MISSING_SETTING: the #NMConnection object is missing an + * #NMSetting which is required for its configuration. The error message will + * always be prefixed with "<setting-name>: ", where "<setting-name>" is the + * name of the setting that is missing. + * @NM_CONNECTION_ERROR_INVALID_SETTING: the #NMConnection object contains an + * invalid or inappropriate #NMSetting. The error message will always be + * prefixed with "<setting-name>: ", where "<setting-name>" is the name of the + * setting that is invalid. + * @NM_CONNECTION_ERROR_MISSING_PROPERTY: the #NMConnection object is invalid + * because it is missing a required property. The error message will always be + * prefixed with "<setting-name>.<property-name>: ", where "<setting-name>" is + * the name of the setting with the missing property, and "<property-name>" is + * the property that is missing. + * @NM_CONNECTION_ERROR_INVALID_PROPERTY: the #NMConnection object is invalid + * because a property has an invalid value. The error message will always be + * prefixed with "<setting-name>.<property-name>: ", where "<setting-name>" is + * the name of the setting with the invalid property, and "<property-name>" is + * the property that is invalid. + * + * Describes errors that may result from operations involving a #NMConnection + * or its #NMSettings. + * + * These errors may be returned directly from #NMConnection and #NMSetting + * methods, or may be returned from D-Bus operations (eg on #NMClient or + * #NMDevice), where they correspond to errors in the + * "org.freedesktop.NetworkManager.Settings.Connection" namespace. + */ +typedef enum { + NM_CONNECTION_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, /*< nick=PropertyNotFound >*/ + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, /*< nick=PropertyNotSecret >*/ + NM_CONNECTION_ERROR_MISSING_SETTING, /*< nick=MissingSetting >*/ + NM_CONNECTION_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ + NM_CONNECTION_ERROR_MISSING_PROPERTY, /*< nick=MissingProperty >*/ + NM_CONNECTION_ERROR_INVALID_PROPERTY, /*< nick=InvalidProperty >*/ +} NMConnectionError; + +#define NM_CONNECTION_ERROR nm_connection_error_quark () +GQuark nm_connection_error_quark (void); + +/** + * NMCryptoError: + * @NM_CRYPTO_ERROR_FAILED: generic failure + * @NM_CRYPTO_ERROR_INVALID_DATA: the certificate or key data provided + * was invalid + * @NM_CRYPTO_ERROR_INVALID_PASSWORD: the password was invalid + * @NM_CRYPTO_ERROR_UNKNOWN_CIPHER: the data uses an unknown cipher + * @NM_CRYPTO_ERROR_DECRYPTION_FAILED: decryption failed + * @NM_CRYPTO_ERROR_ENCRYPTION_FAILED: encryption failed + * + * Cryptography-related errors that can be returned from some nm-utils methods, + * and some #NMSetting8021x operations. + */ +typedef enum { + NM_CRYPTO_ERROR_FAILED = 0, + NM_CRYPTO_ERROR_INVALID_DATA, + NM_CRYPTO_ERROR_INVALID_PASSWORD, + NM_CRYPTO_ERROR_UNKNOWN_CIPHER, + NM_CRYPTO_ERROR_DECRYPTION_FAILED, + NM_CRYPTO_ERROR_ENCRYPTION_FAILED, +} NMCryptoError; + +#define NM_CRYPTO_ERROR nm_crypto_error_quark () +GQuark nm_crypto_error_quark (void); + +/** + * NMDeviceError: + * @NM_DEVICE_ERROR_FAILED: unknown or unclassified error + * @NM_DEVICE_ERROR_CREATION_FAILED: NetworkManager failed to create the device + * @NM_DEVICE_ERROR_INVALID_CONNECTION: the specified connection is not valid + * @NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION: the specified connection is not + * compatible with this device. + * @NM_DEVICE_ERROR_NOT_ACTIVE: the device does not have an active connection + * @NM_DEVICE_ERROR_NOT_SOFTWARE: the requested operation is only valid on + * software devices. + * @NM_DEVICE_ERROR_NOT_ALLOWED: the requested operation is not allowed at + * this time. + * @NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND: the "specific object" in the + * activation request (eg, the #NMAccessPoint or #NMWimaxNsp) was not + * found. + * + * Device-related errors. + * + * These errors may be returned directly from #NMDevice methods, or may be + * returned from D-Bus operations (where they correspond to errors in the + * "org.freedesktop.NetworkManager.Device" namespace). + */ +typedef enum { + NM_DEVICE_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_DEVICE_ERROR_CREATION_FAILED, /*< nick=CreationFailed >*/ + NM_DEVICE_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, /*< nick=IncompatibleConnection >*/ + NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ + NM_DEVICE_ERROR_NOT_SOFTWARE, /*< nick=NotSoftware >*/ + NM_DEVICE_ERROR_NOT_ALLOWED, /*< nick=NotAllowed >*/ + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, /*< nick=SpecificObjectNotFound >*/ +} NMDeviceError; + +#define NM_DEVICE_ERROR nm_device_error_quark () +GQuark nm_device_error_quark (void); + +/** + * NMManagerError: + * @NM_MANAGER_ERROR_FAILED: unknown or unclassified error + * @NM_MANAGER_ERROR_PERMISSION_DENIED: Permission denied. + * @NM_MANAGER_ERROR_UNKNOWN_CONNECTION: The requested connection is not known. + * @NM_MANAGER_ERROR_UNKNOWN_DEVICE: The requested device is not known. + * @NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE: The requested connection cannot be + * activated at this time. + * @NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE: The request could not be completed + * because a required connection is not active. + * @NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE: The connection to be activated was + * already active on another device. + * @NM_MANAGER_ERROR_DEPENDENCY_FAILED: An activation request failed due to a + * dependency being unavailable. + * @NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE: The manager is already in the requested + * sleep/wake state. + * @NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED: The network is already + * enabled/disabled. + * @NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL: Unknown log level in SetLogging + * @NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN: Unknown log domain in SetLogging + * + * Errors related to the main "network management" interface of NetworkManager. + * These may be returned from #NMClient methods that invoke D-Bus operations on + * the "org.freedesktop.NetworkManager" interface, and correspond to D-Bus + * errors in that namespace. + */ +typedef enum { + NM_MANAGER_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_MANAGER_ERROR_UNKNOWN_CONNECTION, /*< nick=UnknownConnection >*/ + NM_MANAGER_ERROR_UNKNOWN_DEVICE, /*< nick=UnknownDevice >*/ + NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, /*< nick=ConnectionNotAvailable >*/ + NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, /*< nick=ConnectionNotActive >*/ + NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, /*< nick=ConnectionAlreadyActive >*/ + NM_MANAGER_ERROR_DEPENDENCY_FAILED, /*< nick=DependencyFailed >*/ + NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, /*< nick=AlreadyAsleepOrAwake >*/ + NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, /*< nick=AlreadyEnabledOrDisabled >*/ + NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL, /*< nick=UnknownLogLevel >*/ + NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN, /*< nick=UnknownLogDomain >*/ +} NMManagerError; + +GQuark nm_manager_error_quark (void); +#define NM_MANAGER_ERROR (nm_manager_error_quark ()) + +/** + * NMSecretAgentError: + * @NM_SECRET_AGENT_ERROR_FAILED: unknown or unclassified error + * @NM_SECRET_AGENT_ERROR_PERMISSION_DENIED: the caller (ie, NetworkManager) is + * not authorized to make this request + * @NM_SECRET_AGENT_ERROR_INVALID_CONNECTION: the connection for which secrets + * were requested is invalid + * @NM_SECRET_AGENT_ERROR_USER_CANCELED: the request was canceled by the user + * @NM_SECRET_AGENT_ERROR_AGENT_CANCELED: the agent canceled the request + * because it was requested to do so by NetworkManager + * @NM_SECRET_AGENT_ERROR_NO_SECRETS: the agent cannot find any secrets for this + * connection + * + * #NMSecretAgentError values are passed by secret agents back to NetworkManager + * when they encounter problems retrieving secrets on behalf of NM. They + * correspond to errors in the "org.freedesktop.NetworkManager.SecretManager" + * namespace. + * + * Client APIs such as nm_client_activate_connection() will not see these error + * codes; instead, the secret agent manager will translate them to the + * corresponding #NMAgentManagerError codes. + */ +typedef enum { + NM_SECRET_AGENT_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_SECRET_AGENT_ERROR_USER_CANCELED, /*< nick=UserCanceled >*/ + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, /*< nick=AgentCanceled >*/ + NM_SECRET_AGENT_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ +} NMSecretAgentError; + +GQuark nm_secret_agent_error_quark (void); +#define NM_SECRET_AGENT_ERROR (nm_secret_agent_error_quark ()) + +/** + * NMSettingsError: + * @NM_SETTINGS_ERROR_FAILED: unknown or unclassified error + * @NM_SETTINGS_ERROR_PERMISSION_DENIED: permission denied + * @NM_SETTINGS_ERROR_NOT_SUPPORTED: the requested operation is not supported by any + * active settings backend + * @NM_SETTINGS_ERROR_INVALID_CONNECTION: the connection was invalid + * @NM_SETTINGS_ERROR_READ_ONLY_CONNECTION: attempted to modify a read-only connection + * @NM_SETTINGS_ERROR_UUID_EXISTS: a connection with that UUID already exists + * @NM_SETTINGS_ERROR_INVALID_HOSTNAME: attempted to set an invalid hostname + * + * Errors related to the settings/persistent configuration interface of + * NetworkManager. + * + * These may be returned from #NMClient methods that invoke D-Bus operations on + * the "org.freedesktop.NetworkManager.Settings" interface, and correspond to + * D-Bus errors in that namespace. + */ +typedef enum { + NM_SETTINGS_ERROR_FAILED = 0, /*< nick=Failed >*/ + NM_SETTINGS_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ + NM_SETTINGS_ERROR_NOT_SUPPORTED, /*< nick=NotSupported >*/ + NM_SETTINGS_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, /*< nick=ReadOnlyConnection >*/ + NM_SETTINGS_ERROR_UUID_EXISTS, /*< nick=UuidExists >*/ + NM_SETTINGS_ERROR_INVALID_HOSTNAME, /*< nick=InvalidHostname >*/ +} NMSettingsError; + +GQuark nm_settings_error_quark (void); +#define NM_SETTINGS_ERROR (nm_settings_error_quark ()) + +/** + * NMVpnPluginError: + * @NM_VPN_PLUGIN_ERROR_FAILED: unknown or unclassified error + * @NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS: the plugin is already starting, + * and another connect request was received + * @NM_VPN_PLUGIN_ERROR_ALREADY_STARTED: the plugin is already connected, and + * another connect request was received + * @NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS: the plugin is already stopping, + * and another stop request was received + * @NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED: the plugin is already stopped, and + * another disconnect request was received + * @NM_VPN_PLUGIN_ERROR_WRONG_STATE: the operation could not be performed in + * this state + * @NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS: the operation could not be performed as + * the request contained malformed arguments, or arguments of unexpected type. + * Usually means that one of the VPN setting data items or secrets was not of + * the expected type (ie int, string, bool, etc). + * @NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED: a child process failed to launch + * @NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION: the operation could not be performed + * because the connection was invalid. Usually means that the connection's + * VPN setting was missing some required data item or secret. + * @NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED: the operation could not be + * performed as the plugin does not support interactive operations, such as + * ConnectInteractive() or NewSecrets() + * + * Returned by the VPN service plugin to indicate errors. These codes correspond + * to errors in the "org.freedesktop.NetworkManager.VPN.Error" namespace. + **/ +typedef enum { + NM_VPN_PLUGIN_ERROR_FAILED, /*< nick=Failed >*/ + NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, /*< nick=StartingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, /*< nick=AlreadyStarted >*/ + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, /*< nick=StoppingInProgress >*/ + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, /*< nick=AlreadyStopped >*/ + NM_VPN_PLUGIN_ERROR_WRONG_STATE, /*< nick=WrongState >*/ + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, /*< nick=BadArguments >*/ + NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, /*< nick=LaunchFailed >*/ + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, /*< nick=InteractiveNotSupported >*/ +} NMVpnPluginError; + +#define NM_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_quark ()) +GQuark nm_vpn_plugin_error_quark (void); + +#endif /* __NM_ERRORS_H__ */ diff --git a/libnm-core/nm-property-compare.c b/libnm-core/nm-property-compare.c new file mode 100644 index 00000000..5d270706 --- /dev/null +++ b/libnm-core/nm-property-compare.c @@ -0,0 +1,122 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include "nm-property-compare.h" +#include "nm-glib-compat.h" + +#include +#include +#include +#include + +static gint +_nm_property_compare_collection (GVariant *value1, GVariant *value2) +{ + GVariant *child1, *child2; + int i, len1, len2; + int ret; + + len1 = g_variant_n_children (value1); + len2 = g_variant_n_children (value2); + + if (len1 != len2) + return len1 < len2 ? -1 : len1 > len2; + + for (i = 0; i < len1; i++) { + child1 = g_variant_get_child_value (value1, i); + child2 = g_variant_get_child_value (value2, i); + + ret = nm_property_compare (child1, child2); + g_variant_unref (child1); + g_variant_unref (child2); + + if (ret) + return ret; + } + + return 0; +} + +static gint +_nm_property_compare_strdict (GVariant *value1, GVariant *value2) +{ + GVariantIter iter; + int len1, len2; + const char *key, *val1, *val2; + int ret; + + len1 = g_variant_n_children (value1); + len2 = g_variant_n_children (value2); + + if (len1 != len2) + return len1 < len2 ? -1 : len1 > len2; + + g_variant_iter_init (&iter, value1); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &val1)) { + if (!g_variant_lookup (value2, key, "&s", &val2)) + return -1; + + ret = strcmp (val1, val2); + if (ret) + return ret; + } + + return 0; +} + +int +nm_property_compare (GVariant *value1, GVariant *value2) +{ + const GVariantType *type1; + const GVariantType *type2; + gint ret; + + if (value1 == value2) + return 0; + if (!value1) + return 1; + if (!value2) + return -1; + + type1 = g_variant_get_type (value1); + type2 = g_variant_get_type (value2); + + if (!g_variant_type_equal (type1, type2)) + return type1 < type2 ? -1 : type1 > type2; + + if (g_variant_type_is_basic (type1)) + ret = g_variant_compare (value1, value2); + else if (g_variant_is_of_type (value1, G_VARIANT_TYPE ("a{ss}"))) + ret = _nm_property_compare_strdict (value1, value2); + else if (g_variant_type_is_array (type1)) + ret = _nm_property_compare_collection (value1, value2); + else if (g_variant_type_is_tuple (type1)) + ret = _nm_property_compare_collection (value1, value2); + else { + g_warning ("Don't know how to compare variant type '%s'", (const char *) type1); + ret = value1 == value2; + } + + return ret; +} diff --git a/libnm-core/nm-property-compare.h b/libnm-core/nm-property-compare.h new file mode 100644 index 00000000..33016787 --- /dev/null +++ b/libnm-core/nm-property-compare.h @@ -0,0 +1,30 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_PROPERTY_COMPARE_H__ +#define __NM_PROPERTY_COMPARE_H__ + +#include + +int nm_property_compare (GVariant *value1, GVariant *value2); + +#endif /* __NM_PROPERTY_COMPARE_H__ */ diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c new file mode 100644 index 00000000..f739f2c7 --- /dev/null +++ b/libnm-core/nm-setting-8021x.c @@ -0,0 +1,3864 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-8021x.h" +#include "nm-utils.h" +#include "crypto.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-8021x + * @short_description: Describes 802.1x-authenticated connection properties + * + * The #NMSetting8021x object is a #NMSetting subclass that describes + * properties necessary for connection to 802.1x-authenticated networks, such as + * WPA and WPA2 Enterprise Wi-Fi networks and wired 802.1x networks. 802.1x + * connections typically use certificates and/or EAP authentication methods to + * securely verify, identify, and authenticate the client to the network itself, + * instead of simply relying on a widely shared static key. + * + * It's a good idea to read up on wpa_supplicant configuration before using this + * setting extensively, since most of the options here correspond closely with + * the relevant wpa_supplicant configuration options. + * + * Furthermore, to get a good idea of 802.1x, EAP, TLS, TTLS, etc and their + * applications to Wi-Fi and wired networks, you'll want to get copies of the + * following books. + * + * 802.11 Wireless Networks: The Definitive Guide, Second Edition + * Author: Matthew Gast + * ISBN: 978-0596100520 + * + * Cisco Wireless LAN Security + * Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky + * ISBN: 978-1587051548 + **/ + +#define SCHEME_PATH "file://" + +G_DEFINE_TYPE_WITH_CODE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING, + _nm_register_setting (802_1X, 2)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_802_1X) + +#define NM_SETTING_802_1X_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) + +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_UNKNOWN == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_UNKNOWN) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_X509 == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_X509) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_RAW_KEY == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_RAW_KEY) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_PKCS12 == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_PKCS12) ); + +typedef struct { + GSList *eap; /* GSList of strings */ + char *identity; + char *anonymous_identity; + char *pac_file; + GBytes *ca_cert; + char *ca_path; + char *subject_match; + GSList *altsubject_matches; + GBytes *client_cert; + char *phase1_peapver; + char *phase1_peaplabel; + char *phase1_fast_provisioning; + char *phase2_auth; + char *phase2_autheap; + GBytes *phase2_ca_cert; + char *phase2_ca_path; + char *phase2_subject_match; + GSList *phase2_altsubject_matches; + GBytes *phase2_client_cert; + char *password; + NMSettingSecretFlags password_flags; + GBytes *password_raw; + NMSettingSecretFlags password_raw_flags; + char *pin; + NMSettingSecretFlags pin_flags; + GBytes *private_key; + char *private_key_password; + NMSettingSecretFlags private_key_password_flags; + GBytes *phase2_private_key; + char *phase2_private_key_password; + NMSettingSecretFlags phase2_private_key_password_flags; + gboolean system_ca_certs; +} NMSetting8021xPrivate; + +enum { + PROP_0, + PROP_EAP, + PROP_IDENTITY, + PROP_ANONYMOUS_IDENTITY, + PROP_PAC_FILE, + PROP_CA_CERT, + PROP_CA_PATH, + PROP_SUBJECT_MATCH, + PROP_ALTSUBJECT_MATCHES, + PROP_CLIENT_CERT, + PROP_PHASE1_PEAPVER, + PROP_PHASE1_PEAPLABEL, + PROP_PHASE1_FAST_PROVISIONING, + PROP_PHASE2_AUTH, + PROP_PHASE2_AUTHEAP, + PROP_PHASE2_CA_CERT, + PROP_PHASE2_CA_PATH, + PROP_PHASE2_SUBJECT_MATCH, + PROP_PHASE2_ALTSUBJECT_MATCHES, + PROP_PHASE2_CLIENT_CERT, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_PASSWORD_RAW, + PROP_PASSWORD_RAW_FLAGS, + PROP_PRIVATE_KEY, + PROP_PRIVATE_KEY_PASSWORD, + PROP_PRIVATE_KEY_PASSWORD_FLAGS, + PROP_PHASE2_PRIVATE_KEY, + PROP_PHASE2_PRIVATE_KEY_PASSWORD, + PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + PROP_PIN, + PROP_PIN_FLAGS, + PROP_SYSTEM_CA_CERTS, + + LAST_PROP +}; + +/** + * nm_setting_802_1x_new: + * + * Creates a new #NMSetting8021x object with default values. + * + * Returns: the new empty #NMSetting8021x object + **/ +NMSetting * +nm_setting_802_1x_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_802_1X, NULL); +} + +/** + * nm_setting_802_1x_get_num_eap_methods: + * @setting: the #NMSetting8021x + * + * Returns the number of eap methods allowed for use when connecting to the + * network. Generally only one EAP method is used. Use the functions + * nm_setting_802_1x_get_eap_method(), nm_setting_802_1x_add_eap_method(), + * and nm_setting_802_1x_remove_eap_method() for adding, removing, and retrieving + * allowed EAP methods. + * + * Returns: the number of allowed EAP methods + **/ +guint32 +nm_setting_802_1x_get_num_eap_methods (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0); + + return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->eap); +} + +/** + * nm_setting_802_1x_get_eap_method: + * @setting: the #NMSetting8021x + * @i: the index of the EAP method name to return + * + * Returns the name of the allowed EAP method at index @i. + * + * Returns: the name of the allowed EAP method at index @i + **/ +const char * +nm_setting_802_1x_get_eap_method (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->eap), NULL); + + return (const char *) g_slist_nth_data (priv->eap, i); +} + +/** + * nm_setting_802_1x_add_eap_method: + * @setting: the #NMSetting8021x + * @eap: the name of the EAP method to allow for this connection + * + * Adds an allowed EAP method. The setting is not valid until at least one + * EAP method has been added. See #NMSetting8021x:eap property for a list of + * allowed EAP methods. + * + * Returns: %TRUE if the EAP method was successfully added, %FALSE if it was + * not a valid method or if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_eap_method (NMSetting8021x *setting, const char *eap) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (eap != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->eap; iter; iter = g_slist_next (iter)) { + if (!strcmp (eap, (char *) iter->data)) + return FALSE; + } + + priv->eap = g_slist_append (priv->eap, g_ascii_strdown (eap, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_eap_method: + * @setting: the #NMSetting8021x + * @i: the index of the EAP method to remove + * + * Removes the allowed EAP method at the specified index. + **/ +void +nm_setting_802_1x_remove_eap_method (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + elt = g_slist_nth (priv->eap, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->eap = g_slist_delete_link (priv->eap, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); +} + +/** + * nm_setting_802_1x_remove_eap_method_by_value: + * @setting: the #NMSetting8021x + * @eap: the name of the EAP method to remove + * + * Removes the allowed EAP method @method. + * + * Returns: %TRUE if the EAP method was founs and removed, %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_eap_method_by_value (NMSetting8021x *setting, + const char *eap) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (eap != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->eap; iter; iter = g_slist_next (iter)) { + if (!strcmp (eap, (char *) iter->data)) { + priv->eap = g_slist_delete_link (priv->eap, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_eap_methods: + * @setting: the #NMSetting8021x + * + * Clears all allowed EAP methods. + **/ +void +nm_setting_802_1x_clear_eap_methods (NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_slist_free_full (priv->eap, g_free); + priv->eap = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP); +} + +/** + * nm_setting_802_1x_get_identity: + * @setting: the #NMSetting8021x + * + * Returns the identifier used by some EAP methods (like TLS) to + * authenticate the user. Often this is a username or login name. + * + * Returns: the user identifier + **/ +const char * +nm_setting_802_1x_get_identity (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->identity; +} + +/** + * nm_setting_802_1x_get_anonymous_identity: + * @setting: the #NMSetting8021x + * + * Returns the anonymous identifier used by some EAP methods (like TTLS) to + * authenticate the user in the outer unencrypted "phase 1" authentication. The + * inner "phase 2" authentication will use the #NMSetting8021x:identity in + * a secure form, if applicable for that EAP method. + * + * Returns: the anonymous identifier + **/ +const char * +nm_setting_802_1x_get_anonymous_identity (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->anonymous_identity; +} + +/** + * nm_setting_802_1x_get_pac_file: + * @setting: the #NMSetting8021x + * + * Returns the file containing PAC credentials used by EAP-FAST method. + * + * Returns: the PAC file + **/ +const char * +nm_setting_802_1x_get_pac_file (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pac_file; +} + +/** + * nm_setting_802_1x_get_ca_path: + * @setting: the #NMSetting8021x + * + * Returns the path of the CA certificate directory if previously set. Systems + * will often have a directory that contains multiple individual CA certificates + * which the supplicant can then add to the verification chain. This may be + * used in addition to the #NMSetting8021x:ca-cert property to add more CA + * certificates for verifying the network to client. + * + * Returns: the CA certificate directory path + **/ +const char * +nm_setting_802_1x_get_ca_path (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_path; +} + +/** + * nm_setting_802_1x_get_system_ca_certs: + * @setting: the #NMSetting8021x + * + * Sets the #NMSetting8021x:system-ca-certs property. The + * #NMSetting8021x:ca-path and #NMSetting8021x:phase2-ca-path + * properties are ignored if the #NMSetting8021x:system-ca-certs property is + * %TRUE, in which case a system-wide CA certificate directory specified at + * compile time (using the --system-ca-path configure option) is used in place + * of these properties. + * + * Returns: %TRUE if a system CA certificate path should be used, %FALSE if not + **/ +gboolean +nm_setting_802_1x_get_system_ca_certs (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->system_ca_certs; +} + +static NMSetting8021xCKScheme +get_cert_scheme (GBytes *bytes) +{ + gconstpointer data; + gsize length; + + if (!bytes) + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + + data = g_bytes_get_data (bytes, &length); + if (!length) + return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN; + + if ( (length > strlen (SCHEME_PATH)) + && !memcmp (data, SCHEME_PATH, strlen (SCHEME_PATH))) + return NM_SETTING_802_1X_CK_SCHEME_PATH; + + return NM_SETTING_802_1X_CK_SCHEME_BLOB; +} + +/** + * nm_setting_802_1x_get_ca_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the CA certificate. If the returned scheme + * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_ca_cert_blob(); + * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_ca_cert_path(). + * + * Returns: scheme used to store the CA certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_ca_cert_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert); +} + +/** + * nm_setting_802_1x_get_ca_cert_blob: + * @setting: the #NMSetting8021x + * + * Returns the CA certificate blob if the CA certificate is stored using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use a + * CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: (transfer none): the CA certificate data + **/ +GBytes * +nm_setting_802_1x_get_ca_cert_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_ca_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert; +} + +/** + * nm_setting_802_1x_get_ca_cert_path: + * @setting: the #NMSetting8021x + * + * Returns the CA certificate path if the CA certificate is stored using the + * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. Not all EAP methods use a + * CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: path to the CA certificate file + **/ +const char * +nm_setting_802_1x_get_ca_cert_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_ca_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +static GBytes * +path_to_scheme_value (const char *path) +{ + GByteArray *array; + + g_return_val_if_fail (path != NULL, NULL); + + /* Add the path scheme tag to the front, then the fielname */ + array = g_byte_array_sized_new (strlen (path) + strlen (SCHEME_PATH) + 1); + g_byte_array_append (array, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (array, (const guint8 *) path, strlen (path)); + g_byte_array_append (array, (const guint8 *) "\0", 1); + + return g_byte_array_free_to_bytes (array); +} + +/** + * nm_setting_802_1x_set_ca_cert: + * @setting: the #NMSetting8021x + * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the CA certificate + * file (PEM or DER format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the CA certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:ca-cert property + * with the raw certificate data if using the %NM_SETTING_802_1X_CK_SCHEME_BLOB + * scheme, or with the path to the certificate file if using the + * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_ca_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (cert_path) { + g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + g_clear_pointer (&priv->ca_cert, g_bytes_unref); + + if (!cert_path) { + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CA_CERT); + return TRUE; + } + + data = crypto_load_and_verify_certificate (cert_path, &format, error); + if (data) { + /* wpa_supplicant can only use raw x509 CA certs */ + if (format == NM_CRYPTO_FILE_FORMAT_X509) { + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->ca_cert = g_byte_array_free_to_bytes (data); + data = NULL; + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->ca_cert = path_to_scheme_value (cert_path); + else + g_assert_not_reached (); + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("CA certificate must be in X.509 format")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CA_CERT); + } + if (data) + g_byte_array_unref (data); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CA_CERT); + return priv->ca_cert != NULL; +} + +/** + * nm_setting_802_1x_get_subject_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:subject-match property. This is the + * substring to be matched against the subject of the authentication + * server certificate, or %NULL no subject verification is to be + * performed. + **/ +const char * +nm_setting_802_1x_get_subject_match (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->subject_match; +} + +/** + * nm_setting_802_1x_get_num_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Returns the number of entries in the + * #NMSetting8021x:altsubject-matches property of this setting. + * + * Returns: the number of altsubject-matches entries. + **/ +guint32 +nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0); + + return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->altsubject_matches); +} + +/** + * nm_setting_802_1x_get_altsubject_match: + * @setting: the #NMSettingConnection + * @i: the zero-based index of the array of altSubjectName matches + * + * Returns the altSubjectName match at index @i. + * + * Returns: the altSubjectName match at index @i + **/ +const char * +nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->altsubject_matches), NULL); + + return (const char *) g_slist_nth_data (priv->altsubject_matches, i); +} + +/** + * nm_setting_802_1x_add_altsubject_match: + * @setting: the #NMSetting8021x + * @altsubject_match: the altSubjectName to allow for this connection + * + * Adds an allowed alternate subject name match. Until at least one + * match is added, the altSubjectName of the remote authentication + * server is not verified. + * + * Returns: %TRUE if the alternative subject name match was + * successfully added, %FALSE if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting, + const char *altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (altsubject_match, (char *) iter->data)) + return FALSE; + } + + priv->altsubject_matches = g_slist_append (priv->altsubject_matches, + g_strdup (altsubject_match)); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_altsubject_match: + * @setting: the #NMSetting8021x + * @i: the index of the altSubjectName match to remove + * + * Removes the allowed altSubjectName at the specified index. + **/ +void +nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + elt = g_slist_nth (priv->altsubject_matches, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_remove_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @altsubject_match: the altSubjectName to remove + * + * Removes the allowed altSubjectName @altsubject_match. + * + * Returns: %TRUE if the alternative subject name match was found and removed, + * %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_altsubject_match_by_value (NMSetting8021x *setting, + const char *altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (altsubject_match, (char *) iter->data)) { + priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Clears all altSubjectName matches. + **/ +void +nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_slist_free_full (priv->altsubject_matches, g_free); + priv->altsubject_matches = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_get_client_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the client certificate. If the returned scheme + * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_client_cert_blob(); + * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_client_cert_path(). + * + * Returns: scheme used to store the client certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_client_cert_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert); +} + +/** + * nm_setting_802_1x_get_client_cert_blob: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: (transfer none): the client certificate data + **/ +GBytes * +nm_setting_802_1x_get_client_cert_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_client_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert; +} + +/** + * nm_setting_802_1x_get_client_cert_path: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the client certificate file + **/ +const char * +nm_setting_802_1x_get_client_cert_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_client_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +/** + * nm_setting_802_1x_set_client_cert: + * @setting: the #NMSetting8021x + * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the client + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with + * any @scheme clears the client certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:client-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (cert_path) { + g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + g_clear_pointer (&priv->client_cert, g_bytes_unref); + + if (!cert_path) { + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT); + return TRUE; + } + + data = crypto_load_and_verify_certificate (cert_path, &format, error); + if (data) { + gboolean valid = FALSE; + + switch (format) { + case NM_CRYPTO_FILE_FORMAT_X509: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + valid = TRUE; + break; + case NM_CRYPTO_FILE_FORMAT_PKCS12: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; + valid = TRUE; + break; + default: + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid certificate format")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); + break; + } + + if (valid) { + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->client_cert = g_byte_array_free_to_bytes (data); + data = NULL; + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->client_cert = path_to_scheme_value (cert_path); + else + g_assert_not_reached (); + } + if (data) + g_byte_array_unref (data); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT); + return priv->client_cert != NULL; +} + +/** + * nm_setting_802_1x_get_phase1_peapver: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 1" PEAP version to be used when authenticating with + * EAP-PEAP as contained in the #NMSetting8021x:phase1-peapver property. Valid + * values are %NULL (unset), "0" (PEAP version 0), and "1" (PEAP version 1). + **/ +const char * +nm_setting_802_1x_get_phase1_peapver (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_peapver; +} + +/** + * nm_setting_802_1x_get_phase1_peaplabel: + * @setting: the #NMSetting8021x + * + * Returns: whether the "phase 1" PEAP label is new-style or old-style, to be + * used when authenticating with EAP-PEAP, as contained in the + * #NMSetting8021x:phase1-peaplabel property. Valid values are %NULL (unset), + * "0" (use old-style label), and "1" (use new-style label). See the + * wpa_supplicant documentation for more details. + **/ +const char * +nm_setting_802_1x_get_phase1_peaplabel (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_peaplabel; +} + +/** + * nm_setting_802_1x_get_phase1_fast_provisioning: + * @setting: the #NMSetting8021x + * + * Returns: whether "phase 1" PEAP fast provisioning should be used, as specified + * by the #NMSetting8021x:phase1-fast-provisioning property. See the + * wpa_supplicant documentation for more details. + **/ +const char * +nm_setting_802_1x_get_phase1_fast_provisioning (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_fast_provisioning; +} + +/** + * nm_setting_802_1x_get_phase2_auth: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 2" non-EAP (ex MD5) allowed authentication method as + * specified by the #NMSetting8021x:phase2-auth property. + **/ +const char * +nm_setting_802_1x_get_phase2_auth (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_auth; +} + +/** + * nm_setting_802_1x_get_phase2_autheap: + * @setting: the #NMSetting8021x + * + * Returns: the "phase 2" EAP-based (ex TLS) allowed authentication method as + * specified by the #NMSetting8021x:phase2-autheap property. + **/ +const char * +nm_setting_802_1x_get_phase2_autheap (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_autheap; +} + +/** + * nm_setting_802_1x_get_phase2_ca_path: + * @setting: the #NMSetting8021x + * + * Returns the path of the "phase 2" CA certificate directory if previously set. + * Systems will often have a directory that contains multiple individual CA + * certificates which the supplicant can then add to the verification chain. + * This may be used in addition to the #NMSetting8021x:phase2-ca-cert property + * to add more CA certificates for verifying the network to client. + * + * Returns: the "phase 2" CA certificate directory path + **/ +const char * +nm_setting_802_1x_get_phase2_ca_path (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_path; +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" CA certificate. If the + * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_ca_cert_blob(); if %NM_SETTING_802_1X_CK_SCHEME_PATH, + * use nm_setting_802_1x_get_ca_cert_path(). + * + * Returns: scheme used to store the "phase 2" CA certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_ca_cert_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert); +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_blob: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" CA certificate blob if the CA certificate is stored + * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use + * a CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: (transfer none): the "phase 2" CA certificate data + **/ +GBytes * +nm_setting_802_1x_get_phase2_ca_cert_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert; +} + +/** + * nm_setting_802_1x_get_phase2_ca_cert_path: + * @setting: the #NMSetting8021x + * + * Returns the "phase 2" CA certificate path if the CA certificate is stored + * using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. Not all EAP methods use + * a CA certificate (LEAP for example), and those that can take advantage of the + * CA certificate allow it to be unset. Note that lack of a CA certificate + * reduces security by allowing man-in-the-middle attacks, because the identity + * of the network cannot be confirmed by the client. + * + * Returns: path to the "phase 2" CA certificate file + **/ +const char * +nm_setting_802_1x_get_phase2_ca_cert_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +/** + * nm_setting_802_1x_set_phase2_ca_cert: + * @setting: the #NMSetting8021x + * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" CA + * certificate file (PEM or DER format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the "phase2" CA certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:phase2-ca-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (cert_path) { + g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + g_clear_pointer (&priv->phase2_ca_cert, g_bytes_unref); + + if (!cert_path) { + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT); + return TRUE; + } + + data = crypto_load_and_verify_certificate (cert_path, &format, error); + if (data) { + /* wpa_supplicant can only use raw x509 CA certs */ + if (format == NM_CRYPTO_FILE_FORMAT_X509) { + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->phase2_ca_cert = g_byte_array_free_to_bytes (data); + data = NULL; + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_ca_cert = path_to_scheme_value (cert_path); + else + g_assert_not_reached (); + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid certificate format")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CA_CERT); + } + if (data) + g_byte_array_unref (data); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT); + return priv->phase2_ca_cert != NULL; +} + +/** + * nm_setting_802_1x_get_phase2_subject_match: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSetting8021x:phase2-subject-match property. This is + * the substring to be matched against the subject of the "phase 2" + * authentication server certificate, or %NULL no subject verification + * is to be performed. + **/ +const char * +nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_subject_match; +} + +/** + * nm_setting_802_1x_get_num_phase2_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Returns the number of entries in the + * #NMSetting8021x:phase2-altsubject-matches property of this setting. + * + * Returns: the number of phase2-altsubject-matches entries. + **/ +guint32 +nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0); + + return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_altsubject_matches); +} + +/** + * nm_setting_802_1x_get_phase2_altsubject_match: + * @setting: the #NMSettingConnection + * @i: the zero-based index of the array of "phase 2" altSubjectName matches + * + * Returns the "phase 2" altSubjectName match at index @i. + * + * Returns: the "phase 2" altSubjectName match at index @i + **/ +const char * +nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->phase2_altsubject_matches), NULL); + + return (const char *) g_slist_nth_data (priv->phase2_altsubject_matches, i); +} + +/** + * nm_setting_802_1x_add_phase2_altsubject_match: + * @setting: the #NMSetting8021x + * @phase2_altsubject_match: the "phase 2" altSubjectName to allow for this + * connection + * + * Adds an allowed alternate subject name match for "phase 2". Until + * at least one match is added, the altSubjectName of the "phase 2" + * remote authentication server is not verified. + * + * Returns: %TRUE if the "phase 2" alternative subject name match was + * successfully added, %FALSE if it was already allowed. + **/ +gboolean +nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting, + const char *phase2_altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (phase2_altsubject_match, (char *) iter->data)) + return FALSE; + } + + priv->phase2_altsubject_matches = g_slist_append (priv->phase2_altsubject_matches, + g_strdup (phase2_altsubject_match)); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); + return TRUE; +} + +/** + * nm_setting_802_1x_remove_phase2_altsubject_match: + * @setting: the #NMSetting8021x + * @i: the index of the "phase 2" altSubjectName match to remove + * + * Removes the allowed "phase 2" altSubjectName at the specified index. + **/ +void +nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, guint32 i) +{ + NMSetting8021xPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + elt = g_slist_nth (priv->phase2_altsubject_matches, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); +} + + +/** + * nm_setting_802_1x_remove_phase2_altsubject_match_by_value: + * @setting: the #NMSetting8021x + * @phase2_altsubject_match: the "phase 2" altSubjectName to remove + * + * Removes the allowed "phase 2" altSubjectName @phase2_altsubject_match. + * + * Returns: %TRUE if the alternative subject name match for "phase 2" was found and removed, + * %FALSE if it was not. + **/ +gboolean +nm_setting_802_1x_remove_phase2_altsubject_match_by_value (NMSetting8021x *setting, + const char *phase2_altsubject_match) +{ + NMSetting8021xPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) { + if (!strcmp (phase2_altsubject_match, (char *) iter->data)) { + priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_802_1x_clear_phase2_altsubject_matches: + * @setting: the #NMSetting8021x + * + * Clears all "phase 2" altSubjectName matches. + **/ +void +nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_802_1X (setting)); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + g_slist_free_full (priv->phase2_altsubject_matches, g_free); + priv->phase2_altsubject_matches = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" client certificate. If the + * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(). + * + * Returns: scheme used to store the "phase 2" client certificate (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_client_cert_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert); +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_blob: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: (transfer none): the "phase 2" client certificate data + **/ +GBytes * +nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert; +} + +/** + * nm_setting_802_1x_get_phase2_client_cert_path: + * @setting: the #NMSetting8021x + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the "phase 2" client certificate file + **/ +const char * +nm_setting_802_1x_get_phase2_client_cert_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +/** + * nm_setting_802_1x_set_phase2_client_cert: + * @setting: the #NMSetting8021x + * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH + * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" client + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with + * any @scheme clears the "phase2" client certificate. + * @scheme: desired storage scheme for the certificate + * @out_format: on successful return, the type of the certificate added + * @error: on unsuccessful return, an error + * + * Reads a certificate from disk and sets the #NMSetting8021x:phase2-client-cert + * property with the raw certificate data if using the + * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate + * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * Client certificates are used to identify the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (cert_path) { + g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + g_clear_pointer (&priv->phase2_client_cert, g_bytes_unref); + + if (!cert_path) { + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return TRUE; + } + + data = crypto_load_and_verify_certificate (cert_path, &format, error); + if (data) { + gboolean valid = FALSE; + + /* wpa_supplicant can only use raw x509 CA certs */ + switch (format) { + case NM_CRYPTO_FILE_FORMAT_X509: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_X509; + valid = TRUE; + break; + case NM_CRYPTO_FILE_FORMAT_PKCS12: + if (out_format) + *out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12; + valid = TRUE; + break; + default: + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid certificate format")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + break; + } + + if (valid) { + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + priv->phase2_client_cert = g_byte_array_free_to_bytes (data); + data = NULL; + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_client_cert = path_to_scheme_value (cert_path); + else + g_assert_not_reached (); + } + if (data) + g_byte_array_unref (data); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return priv->phase2_client_cert != NULL; +} + +/** + * nm_setting_802_1x_get_password: + * @setting: the #NMSetting8021x + * + * Returns: the password used by the authentication method, if any, as specified + * by the #NMSetting8021x:password property + **/ +const char * +nm_setting_802_1x_get_password (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password; +} + +/** + * nm_setting_802_1x_get_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSetting8021x:password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_flags; +} + +/** + * nm_setting_802_1x_get_password_raw: + * @setting: the #NMSetting8021x + * + * Returns: (transfer none): the password used by the authentication method as a + * UTF-8-encoded array of bytes, as specified by the + * #NMSetting8021x:password-raw property + **/ +GBytes * +nm_setting_802_1x_get_password_raw (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_raw; +} + +/** + * nm_setting_802_1x_get_password_raw_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:password-raw + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_password_raw_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_raw_flags; +} + +/** + * nm_setting_802_1x_get_pin: + * @setting: the #NMSetting8021x + * + * Returns: the PIN used by the authentication method, if any, as specified + * by the #NMSetting8021x:pin property + **/ +const char * +nm_setting_802_1x_get_pin (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin; +} + +/** + * nm_setting_802_1x_get_pin_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:pin + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin_flags; +} + +/** + * nm_setting_802_1x_get_private_key_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the private key. If the returned scheme is + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(). + * + * Returns: scheme used to store the private key (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key); +} + +/** + * nm_setting_802_1x_get_private_key_blob: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * + * Returns: (transfer none): the private key data + **/ +GBytes * +nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_private_key_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key; +} + +/** + * nm_setting_802_1x_get_private_key_path: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the private key file + **/ +const char * +nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_private_key_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +static void +free_secure_bytes (gpointer data) +{ + GByteArray *array = data; + + memset (array->data, 0, array->len); + g_byte_array_unref (array); +} + +static GBytes * +file_to_secure_bytes (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); + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + g_free (contents); + return g_bytes_new_with_free_func (array->data, array->len, free_secure_bytes, array); + } + return NULL; +} + +/** + * nm_setting_802_1x_set_private_key: + * @setting: the #NMSetting8021x + * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the private key file + * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use + * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme + * clears the private key. + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. + * @scheme: desired storage scheme for the private key + * @out_format: on successful return, the type of the private key added + * @error: on unsuccessful return, an error + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * This function reads a private key from disk and sets the + * #NMSetting8021x:private-key property with the private key file data if using + * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the private + * key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:private-key-password property with the given @password. If + * the decryption is unsuccessful, %FALSE is returned, @error is set, and no + * internal data is changed. If no @password is given, the private key is + * assumed to be valid, no decryption is performed, and the password may be set + * at a later time. + * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_private_key (NMSetting8021x *setting, + const char *key_path, + const char *password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean key_cleared = FALSE, password_cleared = FALSE; + GError *local_err = NULL; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (key_path) { + g_return_val_if_fail (g_utf8_validate (key_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + /* Ensure the private key is a recognized format and if the password was + * given, that it decrypts the private key. + */ + if (key_path) { + format = crypto_verify_private_key (key_path, password, NULL, &local_err); + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + local_err ? local_err->message : _("invalid private key")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY); + g_clear_error (&local_err); + return FALSE; + } + } + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + /* Clear out any previous private key data */ + if (priv->private_key) { + g_bytes_unref (priv->private_key); + priv->private_key = NULL; + key_cleared = TRUE; + } + + if (priv->private_key_password) { + g_free (priv->private_key_password); + priv->private_key_password = NULL; + password_cleared = TRUE; + } + + if (key_path == NULL) { + if (key_cleared) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY); + if (password_cleared) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + return TRUE; + } + + priv->private_key_password = g_strdup (password); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + /* Shouldn't fail this since we just verified the private key above */ + priv->private_key = file_to_secure_bytes (key_path); + g_assert (priv->private_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->private_key = path_to_scheme_value (key_path); + else + g_assert_not_reached (); + + /* As required by NM and wpa_supplicant, set the client-cert + * property to the same PKCS#12 data. + */ + g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { + if (priv->client_cert) + g_bytes_unref (priv->client_cert); + priv->client_cert = g_bytes_ref (priv->private_key); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY); + if (password_cleared || password) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + + if (out_format) + *out_format = (NMSetting8021xCKFormat) format; + return priv->private_key != NULL; +} + +/** + * nm_setting_802_1x_get_private_key_password: + * @setting: the #NMSetting8021x + * + * Returns: the private key password used to decrypt the private key if + * previously set with nm_setting_802_1x_set_private_key(), or the + * #NMSetting8021x:private-key-password property. + **/ +const char * +nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password; +} + +/** + * nm_setting_802_1x_get_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password_flags; +} + +/** + * nm_setting_802_1x_get_private_key_format: + * @setting: the #NMSetting8021x + * + * Returns: the data format of the private key data stored in the + * #NMSetting8021x:private-key property + **/ +NMSetting8021xCKFormat +nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + const char *path; + GError *error = NULL; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + if (!priv->private_key) + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + + switch (nm_setting_802_1x_get_private_key_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + if (crypto_is_pkcs12_data (g_bytes_get_data (priv->private_key, NULL), + g_bytes_get_size (priv->private_key), + NULL)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_private_key_path (setting); + if (crypto_is_pkcs12_file (path, &error)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + if (error && error->domain == G_FILE_ERROR) { + g_error_free (error); + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + } + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + default: + break; + } + + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_password: + * @setting: the #NMSetting8021x + * + * Returns: the private key password used to decrypt the private key if + * previously set with nm_setting_802_1x_set_phase2_private_key() or the + * #NMSetting8021x:phase2-private-key-password property. + **/ +const char * +nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password_flags; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_scheme: + * @setting: the #NMSetting8021x + * + * Returns the scheme used to store the "phase 2" private key. If the returned + * scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use + * nm_setting_802_1x_get_client_cert_blob(); if + * %NM_SETTING_802_1X_CK_SCHEME_PATH, use + * nm_setting_802_1x_get_client_cert_path(). + * + * Returns: scheme used to store the "phase 2" private key (blob or path) + **/ +NMSetting8021xCKScheme +nm_setting_802_1x_get_phase2_private_key_scheme (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); + + return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key); +} + +/** + * nm_setting_802_1x_get_phase2_private_key_blob: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * WARNING: the phase2 private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * + * Returns: (transfer none): the "phase 2" private key data + **/ +GBytes * +nm_setting_802_1x_get_phase2_private_key_blob (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_path: + * @setting: the #NMSetting8021x + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * Returns: path to the "phase 2" private key file + **/ +const char * +nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting) +{ + NMSetting8021xCKScheme scheme; + gconstpointer data; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting); + g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL); + + data = g_bytes_get_data (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key, NULL); + return (const char *)data + strlen (SCHEME_PATH); +} + +/** + * nm_setting_802_1x_set_phase2_private_key: + * @setting: the #NMSetting8021x + * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or + * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private + * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; + * use g_filename_to_utf8() to convert if needed. Passing %NULL with any + * @scheme clears the private key. + * @password: password used to decrypt the private key, or %NULL if the password + * is unknown. If the password is given but fails to decrypt the private key, + * an error is returned. + * @scheme: desired storage scheme for the private key + * @out_format: on successful return, the type of the private key added + * @error: on unsuccessful return, an error + * + * Private keys are used to authenticate the connecting client to the network + * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x + * authentication method. + * + * This function reads a private key from disk and sets the + * #NMSetting8021x:phase2-private-key property with the private key file data if + * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the + * private key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme. + * + * If @password is given, this function attempts to decrypt the private key to + * verify that @password is correct, and if it is, updates the + * #NMSetting8021x:phase2-private-key-password property with the given + * @password. If the decryption is unsuccessful, %FALSE is returned, @error is + * set, and no internal data is changed. If no @password is given, the private + * key is assumed to be valid, no decryption is performed, and the password may + * be set at a later time. + * + * WARNING: the "phase2" private key property is not a "secret" property, and + * thus unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * + * Returns: %TRUE if the operation succeeded, %FALSE if it was unsuccessful + **/ +gboolean +nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, + const char *key_path, + const char *password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + NMSetting8021xPrivate *priv; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean key_cleared = FALSE, password_cleared = FALSE; + GError *local_err = NULL; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE); + + if (key_path) { + g_return_val_if_fail (g_utf8_validate (key_path, -1, NULL), FALSE); + g_return_val_if_fail ( scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB + || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, + FALSE); + } + + if (out_format) + g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE); + + /* Ensure the private key is a recognized format and if the password was + * given, that it decrypts the private key. + */ + if (key_path) { + format = crypto_verify_private_key (key_path, password, NULL, &local_err); + if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + local_err ? local_err->message : _("invalid phase2 private key")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + g_clear_error (&local_err); + return FALSE; + } + } + + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + /* Clear out any previous private key data */ + if (priv->phase2_private_key) { + g_bytes_unref (priv->phase2_private_key); + priv->phase2_private_key = NULL; + key_cleared = TRUE; + } + + if (priv->phase2_private_key_password) { + g_free (priv->phase2_private_key_password); + priv->phase2_private_key_password = NULL; + password_cleared = TRUE; + } + + if (key_path == NULL) { + if (key_cleared) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + if (password_cleared) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + return TRUE; + } + + priv->phase2_private_key_password = g_strdup (password); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + /* Shouldn't fail this since we just verified the private key above */ + priv->phase2_private_key = file_to_secure_bytes (key_path); + g_assert (priv->phase2_private_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + priv->phase2_private_key = path_to_scheme_value (key_path); + else + g_assert_not_reached (); + + /* As required by NM and wpa_supplicant, set the client-cert + * property to the same PKCS#12 data. + */ + g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN); + if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) { + if (priv->phase2_client_cert) + g_bytes_unref (priv->phase2_client_cert); + + priv->phase2_client_cert = g_bytes_ref (priv->phase2_private_key); + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + if (password_cleared || password) + g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + + if (out_format) + *out_format = (NMSetting8021xCKFormat) format; + return priv->phase2_private_key != NULL; +} + +/** + * nm_setting_802_1x_get_phase2_private_key_format: + * @setting: the #NMSetting8021x + * + * Returns: the data format of the "phase 2" private key data stored in the + * #NMSetting8021x:phase2-private-key property + **/ +NMSetting8021xCKFormat +nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting) +{ + NMSetting8021xPrivate *priv; + const char *path; + GError *error = NULL; + + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_FORMAT_UNKNOWN); + priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + if (!priv->phase2_private_key) + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + + switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + if (crypto_is_pkcs12_data (g_bytes_get_data (priv->phase2_private_key, NULL), + g_bytes_get_size (priv->phase2_private_key), + NULL)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + path = nm_setting_802_1x_get_phase2_private_key_path (setting); + if (crypto_is_pkcs12_file (path, &error)) + return NM_SETTING_802_1X_CK_FORMAT_PKCS12; + if (error && error->domain == G_FILE_ERROR) { + g_error_free (error); + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + } + return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY; + default: + break; + } + + return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; +} + +static void +need_secrets_password (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + if ( (!priv->password || !strlen (priv->password)) + && (!priv->password_raw || !g_bytes_get_size (priv->password_raw))) { + g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD); + g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD_RAW); + } +} + +static void +need_secrets_sim (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + if (!priv->pin || !strlen (priv->pin)) + g_ptr_array_add (secrets, NM_SETTING_802_1X_PIN); +} + +static gboolean +need_private_key_password (GBytes *blob, + const char *path, + const char *password) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + + /* Private key password is required */ + if (password) { + if (path) + format = crypto_verify_private_key (path, password, NULL, NULL); + else if (blob) + format = crypto_verify_private_key_data (g_bytes_get_data (blob, NULL), + g_bytes_get_size (blob), + password, NULL, NULL); + else + g_warning ("%s: unknown private key password scheme", __func__); + } + + return (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN); +} + +static void +need_secrets_tls (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + NMSetting8021xCKScheme scheme; + GBytes *blob = NULL; + const char *path = NULL; + + if (phase2) { + scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + path = nm_setting_802_1x_get_phase2_private_key_path (self); + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = nm_setting_802_1x_get_phase2_private_key_blob (self); + else { + g_warning ("%s: unknown phase2 private key scheme %d", __func__, scheme); + g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return; + } + + if (need_private_key_password (blob, path, priv->phase2_private_key_password)) + g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); + } else { + scheme = nm_setting_802_1x_get_private_key_scheme (self); + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + path = nm_setting_802_1x_get_private_key_path (self); + else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) + blob = nm_setting_802_1x_get_private_key_blob (self); + else { + g_warning ("%s: unknown private key scheme %d", __func__, scheme); + g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY); + return; + } + + if (need_private_key_password (blob, path, priv->private_key_password)) + g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + } +} + +static gboolean +verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + if (phase2) { + if (!priv->phase2_client_cert) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } else if (!g_bytes_get_size (priv->phase2_client_cert)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } + + /* Private key is required for TLS */ + if (!priv->phase2_private_key) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } else if (!g_bytes_get_size (priv->phase2_private_key)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + + /* If the private key is PKCS#12, check that it matches the client cert */ + if (crypto_is_pkcs12_data (g_bytes_get_data (priv->phase2_private_key, NULL), + g_bytes_get_size (priv->phase2_private_key), + NULL)) { + if (!g_bytes_equal (priv->phase2_private_key, priv->phase2_client_cert)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has to match '%s' property for PKCS#12"), + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT); + return FALSE; + } + } + } else { + if (!priv->client_cert) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } else if (!g_bytes_get_size (priv->client_cert)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } + + /* Private key is required for TLS */ + if (!priv->private_key) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } else if (!g_bytes_get_size (priv->private_key)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + + /* If the private key is PKCS#12, check that it matches the client cert */ + if (crypto_is_pkcs12_data (g_bytes_get_data (priv->private_key, NULL), + g_bytes_get_size (priv->private_key), + NULL)) { + if (!g_bytes_equal (priv->private_key, priv->client_cert)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has to match '%s' property for PKCS#12"), + NM_SETTING_802_1X_PRIVATE_KEY); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +verify_ttls (NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + if ( (!priv->identity || !strlen (priv->identity)) + && (!priv->anonymous_identity || !strlen (priv->anonymous_identity))) { + if (!priv->identity) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY); + } else if (!strlen (priv->identity)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY); + } else if (!priv->anonymous_identity) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } + return FALSE; + } + + if ( (!priv->phase2_auth || !strlen (priv->phase2_auth)) + && (!priv->phase2_autheap || !strlen (priv->phase2_autheap))) { + if (!priv->phase2_auth) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!strlen (priv->phase2_auth)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH); + } else if (!priv->phase2_autheap) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP); + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP); + } + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_identity (NMSetting8021x *self, gboolean phase2, GError **error) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + if (!priv->identity) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY); + return FALSE; + } else if (!strlen (priv->identity)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY); + return FALSE; + } + + return TRUE; +} + +/* Implemented below... */ +static void need_secrets_phase2 (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2); + + +typedef void (*EAPMethodNeedSecretsFunc) (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2); + +typedef gboolean (*EAPMethodValidateFunc)(NMSetting8021x *self, + gboolean phase2, + GError **error); + +typedef struct { + const char *method; + EAPMethodNeedSecretsFunc ns_func; + EAPMethodValidateFunc v_func; +} EAPMethodsTable; + +static EAPMethodsTable eap_methods_table[] = { + { "leap", need_secrets_password, verify_identity }, + { "pwd", need_secrets_password, verify_identity }, + { "md5", need_secrets_password, verify_identity }, + { "pap", need_secrets_password, verify_identity }, + { "chap", need_secrets_password, verify_identity }, + { "mschap", need_secrets_password, verify_identity }, + { "mschapv2", need_secrets_password, verify_identity }, + { "fast", need_secrets_password, verify_identity }, + { "tls", need_secrets_tls, verify_tls }, + { "peap", need_secrets_phase2, verify_ttls }, + { "ttls", need_secrets_phase2, verify_ttls }, + { "sim", need_secrets_sim, NULL }, + { "gtc", need_secrets_password, verify_identity }, + { "otp", NULL, NULL }, // FIXME: implement + { NULL, NULL, NULL } +}; + +static void +need_secrets_phase2 (NMSetting8021x *self, + GPtrArray *secrets, + gboolean phase2) +{ + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + char *method = NULL; + int i; + + g_return_if_fail (phase2 == FALSE); + + /* Check phase2_auth and phase2_autheap */ + method = priv->phase2_auth; + if (!method && priv->phase2_autheap) + method = priv->phase2_autheap; + + if (!method) { + g_warning ("Couldn't find EAP method."); + g_assert_not_reached(); + return; + } + + /* Ask the configured phase2 method if it needs secrets */ + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].ns_func == NULL) + continue; + if (!strcmp (eap_methods_table[i].method, method)) { + (*eap_methods_table[i].ns_func) (self, secrets, TRUE); + break; + } + } +} + + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSetting8021x *self = NM_SETTING_802_1X (setting); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + GSList *iter; + GPtrArray *secrets; + gboolean eap_method_found = FALSE; + + secrets = g_ptr_array_sized_new (4); + + /* Ask each configured EAP method if it needs secrets */ + for (iter = priv->eap; iter && !eap_method_found; iter = g_slist_next (iter)) { + const char *method = (const char *) iter->data; + int i; + + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].ns_func == NULL) + continue; + if (!strcmp (eap_methods_table[i].method, method)) { + (*eap_methods_table[i].ns_func) (self, secrets, FALSE); + + /* Only break out of the outer loop if this EAP method + * needed secrets. + */ + if (secrets->len > 0) + eap_method_found = TRUE; + break; + } + } + } + + if (secrets->len == 0) { + g_ptr_array_free (secrets, TRUE); + secrets = NULL; + } + + return secrets; +} + +static gboolean +verify_cert (GBytes *bytes, const char *prop_name, GError **error) +{ + gconstpointer data; + gsize length; + + if (!bytes) + return TRUE; + + switch (get_cert_scheme (bytes)) { + case NM_SETTING_802_1X_CK_SCHEME_BLOB: + return TRUE; + case NM_SETTING_802_1X_CK_SCHEME_PATH: + /* For path-based schemes, verify that the path is zero-terminated */ + data = g_bytes_get_data (bytes, &length); + if (((const guchar *)data)[length - 1] == '\0') { + /* And ensure it's UTF-8 valid too so we can pass it through + * D-Bus and stuff like that. + */ + if (g_utf8_validate ((const char *)data + strlen (SCHEME_PATH), -1, NULL)) + return TRUE; + } + break; + default: + break; + } + + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, prop_name); + return FALSE; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSetting8021x *self = NM_SETTING_802_1X (setting); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd", NULL }; + const char *valid_phase1_peapver[] = { "0", "1", NULL }; + const char *valid_phase1_peaplabel[] = { "0", "1", NULL }; + const char *valid_phase1_fast_pac[] = { "0", "1", "2", "3", NULL }; + const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL }; + const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL }; + GSList *iter; + + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + + if (!priv->eap) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP); + return FALSE; + } + + if (!_nm_utils_string_slist_validate (priv->eap, valid_eap)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP); + return FALSE; + } + + /* Ask each configured EAP method if its valid */ + for (iter = priv->eap; iter; iter = g_slist_next (iter)) { + const char *method = (const char *) iter->data; + int i; + + for (i = 0; eap_methods_table[i].method; i++) { + if (eap_methods_table[i].v_func == NULL) + continue; + if (!strcmp (eap_methods_table[i].method, method)) { + if (!(*eap_methods_table[i].v_func) (self, FALSE, error)) + return FALSE; + break; + } + } + } + + if (priv->phase1_peapver && !_nm_utils_string_in_list (priv->phase1_peapver, valid_phase1_peapver)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_peapver); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_PEAPVER); + return FALSE; + } + + if (priv->phase1_peaplabel && !_nm_utils_string_in_list (priv->phase1_peaplabel, valid_phase1_peaplabel)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_peaplabel); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_PEAPLABEL); + return FALSE; + } + + if (priv->phase1_fast_provisioning && !_nm_utils_string_in_list (priv->phase1_fast_provisioning, valid_phase1_fast_pac)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase1_fast_provisioning); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING); + return FALSE; + } + + if (priv->phase2_auth && !_nm_utils_string_in_list (priv->phase2_auth, valid_phase2_auth)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase2_auth); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH); + return FALSE; + } + + if (priv->phase2_autheap && !_nm_utils_string_in_list (priv->phase2_autheap, valid_phase2_autheap)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->phase2_autheap); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP); + return FALSE; + } + + if (!verify_cert (priv->ca_cert, NM_SETTING_802_1X_CA_CERT, error)) + return FALSE; + if (!verify_cert (priv->phase2_ca_cert, NM_SETTING_802_1X_PHASE2_CA_CERT, error)) + return FALSE; + + if (!verify_cert (priv->client_cert, NM_SETTING_802_1X_CLIENT_CERT, error)) + return FALSE; + if (!verify_cert (priv->phase2_client_cert, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, error)) + return FALSE; + + if (!verify_cert (priv->private_key, NM_SETTING_802_1X_PRIVATE_KEY, error)) + return FALSE; + if (!verify_cert (priv->phase2_private_key, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, error)) + return FALSE; + + /* FIXME: finish */ + + return TRUE; +} + +static void +nm_setting_802_1x_init (NMSetting8021x *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSetting8021x *self = NM_SETTING_802_1X (object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); + + /* Strings first. g_free() already checks for NULLs so we don't have to */ + + g_free (priv->identity); + g_free (priv->anonymous_identity); + g_free (priv->ca_path); + g_free (priv->subject_match); + g_free (priv->phase1_peapver); + g_free (priv->phase1_peaplabel); + g_free (priv->phase1_fast_provisioning); + g_free (priv->phase2_auth); + g_free (priv->phase2_autheap); + g_free (priv->phase2_ca_path); + g_free (priv->phase2_subject_match); + g_free (priv->password); + if (priv->password_raw) + g_bytes_unref (priv->password_raw); + g_free (priv->pin); + + g_slist_free_full (priv->eap, g_free); + g_slist_free_full (priv->altsubject_matches, g_free); + g_slist_free_full (priv->phase2_altsubject_matches, g_free); + + if (priv->ca_cert) + g_bytes_unref (priv->ca_cert); + if (priv->client_cert) + g_bytes_unref (priv->client_cert); + if (priv->private_key) + g_bytes_unref (priv->private_key); + g_free (priv->private_key_password); + if (priv->phase2_ca_cert) + g_bytes_unref (priv->phase2_ca_cert); + if (priv->phase2_client_cert) + g_bytes_unref (priv->phase2_client_cert); + if (priv->phase2_private_key) + g_bytes_unref (priv->phase2_private_key); + g_free (priv->phase2_private_key_password); + + G_OBJECT_CLASS (nm_setting_802_1x_parent_class)->finalize (object); +} + +static GBytes * +set_cert_prop_helper (const GValue *value, const char *prop_name, GError **error) +{ + gboolean valid; + GBytes *bytes = NULL; + + bytes = g_value_dup_boxed (value); + /* Verify the new data */ + if (bytes) { + valid = verify_cert (bytes, prop_name, error); + if (!valid) + g_clear_pointer (&bytes, g_bytes_unref); + } + return bytes; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSetting8021x *setting = NM_SETTING_802_1X (object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + GError *error = NULL; + + switch (prop_id) { + case PROP_EAP: + g_slist_free_full (priv->eap, g_free); + priv->eap = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_IDENTITY: + g_free (priv->identity); + priv->identity = g_value_dup_string (value); + break; + case PROP_ANONYMOUS_IDENTITY: + g_free (priv->anonymous_identity); + priv->anonymous_identity = g_value_dup_string (value); + break; + case PROP_PAC_FILE: + g_free (priv->pac_file); + priv->pac_file = g_value_dup_string (value); + break; + case PROP_CA_CERT: + if (priv->ca_cert) + g_bytes_unref (priv->ca_cert); + priv->ca_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_CA_CERT, &error); + if (error) { + g_warning ("Error setting certificate (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_CA_PATH: + g_free (priv->ca_path); + priv->ca_path = g_value_dup_string (value); + break; + case PROP_SUBJECT_MATCH: + g_free (priv->subject_match); + priv->subject_match = g_value_dup_string (value); + break; + case PROP_ALTSUBJECT_MATCHES: + g_slist_free_full (priv->altsubject_matches, g_free); + priv->altsubject_matches = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_CLIENT_CERT: + if (priv->client_cert) + g_bytes_unref (priv->client_cert); + priv->client_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_CLIENT_CERT, &error); + if (error) { + g_warning ("Error setting certificate (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_PHASE1_PEAPVER: + g_free (priv->phase1_peapver); + priv->phase1_peapver = g_value_dup_string (value); + break; + case PROP_PHASE1_PEAPLABEL: + g_free (priv->phase1_peaplabel); + priv->phase1_peaplabel = g_value_dup_string (value); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_free (priv->phase1_fast_provisioning); + priv->phase1_fast_provisioning = g_value_dup_string (value); + break; + case PROP_PHASE2_AUTH: + g_free (priv->phase2_auth); + priv->phase2_auth = g_value_dup_string (value); + break; + case PROP_PHASE2_AUTHEAP: + g_free (priv->phase2_autheap); + priv->phase2_autheap = g_value_dup_string (value); + break; + case PROP_PHASE2_CA_CERT: + if (priv->phase2_ca_cert) + g_bytes_unref (priv->phase2_ca_cert); + priv->phase2_ca_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_CA_CERT, &error); + if (error) { + g_warning ("Error setting certificate (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_PHASE2_CA_PATH: + g_free (priv->phase2_ca_path); + priv->phase2_ca_path = g_value_dup_string (value); + break; + case PROP_PHASE2_SUBJECT_MATCH: + g_free (priv->phase2_subject_match); + priv->phase2_subject_match = g_value_dup_string (value); + break; + case PROP_PHASE2_ALTSUBJECT_MATCHES: + g_slist_free_full (priv->phase2_altsubject_matches, g_free); + priv->phase2_altsubject_matches = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_PHASE2_CLIENT_CERT: + if (priv->phase2_client_cert) + g_bytes_unref (priv->phase2_client_cert); + priv->phase2_client_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, &error); + if (error) { + g_warning ("Error setting certificate (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_PASSWORD: + g_free (priv->password); + priv->password = g_value_dup_string (value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags (value); + break; + case PROP_PASSWORD_RAW: + if (priv->password_raw) + g_bytes_unref (priv->password_raw); + priv->password_raw = g_value_dup_boxed (value); + break; + case PROP_PASSWORD_RAW_FLAGS: + priv->password_raw_flags = g_value_get_flags (value); + break; + case PROP_PRIVATE_KEY: + if (priv->private_key) + g_bytes_unref (priv->private_key); + priv->private_key = set_cert_prop_helper (value, NM_SETTING_802_1X_PRIVATE_KEY, &error); + if (error) { + g_warning ("Error setting private key (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_PRIVATE_KEY_PASSWORD: + g_free (priv->private_key_password); + priv->private_key_password = g_value_dup_string (value); + break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + priv->private_key_password_flags = g_value_get_flags (value); + break; + case PROP_PHASE2_PRIVATE_KEY: + if (priv->phase2_private_key) + g_bytes_unref (priv->phase2_private_key); + priv->phase2_private_key = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &error); + if (error) { + g_warning ("Error setting private key (invalid data): (%d) %s", + error->code, error->message); + g_error_free (error); + } + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD: + g_free (priv->phase2_private_key_password); + priv->phase2_private_key_password = g_value_dup_string (value); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + priv->phase2_private_key_password_flags = g_value_get_flags (value); + break; + case PROP_PIN: + g_free (priv->pin); + priv->pin = g_value_dup_string (value); + break; + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_flags (value); + break; + case PROP_SYSTEM_CA_CERTS: + priv->system_ca_certs = g_value_get_boolean (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) +{ + NMSetting8021x *setting = NM_SETTING_802_1X (object); + NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_EAP: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->eap)); + break; + case PROP_IDENTITY: + g_value_set_string (value, priv->identity); + break; + case PROP_ANONYMOUS_IDENTITY: + g_value_set_string (value, priv->anonymous_identity); + break; + case PROP_PAC_FILE: + g_value_set_string (value, priv->pac_file); + break; + case PROP_CA_CERT: + g_value_set_boxed (value, priv->ca_cert); + break; + case PROP_CA_PATH: + g_value_set_string (value, priv->ca_path); + break; + case PROP_SUBJECT_MATCH: + g_value_set_string (value, priv->subject_match); + break; + case PROP_ALTSUBJECT_MATCHES: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->altsubject_matches)); + break; + case PROP_CLIENT_CERT: + g_value_set_boxed (value, priv->client_cert); + break; + case PROP_PHASE1_PEAPVER: + g_value_set_string (value, priv->phase1_peapver); + break; + case PROP_PHASE1_PEAPLABEL: + g_value_set_string (value, priv->phase1_peaplabel); + break; + case PROP_PHASE1_FAST_PROVISIONING: + g_value_set_string (value, priv->phase1_fast_provisioning); + break; + case PROP_PHASE2_AUTH: + g_value_set_string (value, priv->phase2_auth); + break; + case PROP_PHASE2_AUTHEAP: + g_value_set_string (value, priv->phase2_autheap); + break; + case PROP_PHASE2_CA_CERT: + g_value_set_boxed (value, priv->phase2_ca_cert); + break; + case PROP_PHASE2_CA_PATH: + g_value_set_string (value, priv->phase2_ca_path); + break; + case PROP_PHASE2_SUBJECT_MATCH: + g_value_set_string (value, priv->phase2_subject_match); + break; + case PROP_PHASE2_ALTSUBJECT_MATCHES: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->phase2_altsubject_matches)); + break; + case PROP_PHASE2_CLIENT_CERT: + g_value_set_boxed (value, priv->phase2_client_cert); + break; + case PROP_PASSWORD: + g_value_set_string (value, priv->password); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags (value, priv->password_flags); + break; + case PROP_PASSWORD_RAW: + g_value_set_boxed (value, priv->password_raw); + break; + case PROP_PASSWORD_RAW_FLAGS: + g_value_set_flags (value, priv->password_raw_flags); + break; + case PROP_PRIVATE_KEY: + g_value_set_boxed (value, priv->private_key); + break; + case PROP_PRIVATE_KEY_PASSWORD: + g_value_set_string (value, priv->private_key_password); + break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_flags (value, priv->private_key_password_flags); + break; + case PROP_PHASE2_PRIVATE_KEY: + g_value_set_boxed (value, priv->phase2_private_key); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD: + g_value_set_string (value, priv->phase2_private_key_password); + break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_flags (value, priv->phase2_private_key_password_flags); + break; + case PROP_PIN: + g_value_set_string (value, priv->pin); + break; + case PROP_PIN_FLAGS: + g_value_set_flags (value, priv->pin_flags); + break; + case PROP_SYSTEM_CA_CERTS: + g_value_set_boolean (value, priv->system_ca_certs); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSetting8021xPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + + /** + * NMSetting8021x:eap: + * + * The allowed EAP method to be used when authenticating to the network with + * 802.1x. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", + * and "fast". Each method requires different configuration using the + * properties of this setting; refer to wpa_supplicant documentation for the + * allowed combinations. + **/ + /* ---ifcfg-rh--- + * property: eap + * variable: IEEE_8021X_EAP_METHODS(+) + * values: "LEAP", "PWD", "TLS", "PEAP", "TTLS", "FAST" + * description: EAP method for 802.1X authentication. + * example: IEEE_8021X_EAP_METHODS=PEAP + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_EAP, + g_param_spec_boxed (NM_SETTING_802_1X_EAP, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:identity: + * + * Identity string for EAP authentication methods. Often the user's user or + * login name. + **/ + /* ---ifcfg-rh--- + * property: identity + * variable: IEEE_8021X_IDENTITY(+) + * description: Identity for EAP authentication methods. + * example: IEEE_8021X_IDENTITY=itsme + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_IDENTITY, + g_param_spec_string (NM_SETTING_802_1X_IDENTITY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:anonymous-identity: + * + * Anonymous identity string for EAP authentication methods. Used as the + * unencrypted identity with EAP types that support different tunneled + * identity like EAP-TTLS. + **/ + /* ---ifcfg-rh--- + * property: anonymous-identity + * variable: IEEE_8021X_ANON_IDENTITY(+) + * description: Anonymous identity for EAP authentication methods. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ANONYMOUS_IDENTITY, + g_param_spec_string (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:pac-file: + * + * UTF-8 encoded file path containing PAC for EAP-FAST. + **/ + /* ---ifcfg-rh--- + * property: pac-file + * variable: IEEE_8021X_PAC_FILE(+) + * description: File with PAC (Protected Access Credential) for EAP-FAST. + * example: IEEE_8021X_PAC_FILE=/home/joe/my-fast.pac + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PAC_FILE, + g_param_spec_string (NM_SETTING_802_1X_PAC_FILE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:ca-cert: + * + * Contains the CA certificate if used by the EAP method specified in the + * #NMSetting8021x:eap property. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. This + * property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_ca_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: ca-cert + * variable: IEEE_8021X_CA_CERT(+) + * description: CA certificate for EAP. + * example: IEEE_8021X_CA_CERT=/home/joe/cacert.crt + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CA_CERT, + g_param_spec_boxed (NM_SETTING_802_1X_CA_CERT, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:ca-path: + * + * UTF-8 encoded path to a directory containing PEM or DER formatted + * certificates to be added to the verification chain in addition to the + * certificate specified in the #NMSetting8021x:ca-cert property. + **/ + /* ---ifcfg-rh--- + * property: ca-path + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CA_PATH, + g_param_spec_string (NM_SETTING_802_1X_CA_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:subject-match: + * + * Substring to be matched against the subject of the certificate presented + * by the authentication server. When unset, no verification of the + * authentication server certificate's subject is performed. + **/ + /* ---ifcfg-rh--- + * property: subject-match + * variable: IEEE_8021X_SUBJECT_MATCH(+) + * description: Substring to match subject of server certificate against. + * example: IEEE_8021X_SUBJECT_MATCH="Red Hat" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SUBJECT_MATCH, + g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:altsubject-matches: + * + * List of strings to be matched against the altSubjectName of the + * certificate presented by the authentication server. If the list is empty, + * no verification of the server certificate's altSubjectName is performed. + **/ + /* ---ifcfg-rh--- + * property: altubject-matches + * variable: IEEE_8021X_AlTSUBJECT_MATCHES(+) + * description: List of strings to be matched against the altSubjectName. + * example: IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ALTSUBJECT_MATCHES, + g_param_spec_boxed (NM_SETTING_802_1X_ALTSUBJECT_MATCHES, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:client-cert: + * + * Contains the client certificate if used by the EAP method specified in + * the #NMSetting8021x:eap property. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_client_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: client-cert + * variable: IEEE_8021X_CLIENT_CERT(+) + * description: Client certificate for EAP. + * example: IEEE_8021X_CLIENT_CERT=/home/joe/mycert.crt + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CLIENT_CERT, + g_param_spec_boxed (NM_SETTING_802_1X_CLIENT_CERT, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase1-peapver: + * + * Forces which PEAP version is used when PEAP is set as the EAP method in + * the #NMSetting8021x:eap property. When unset, the version reported by + * the server will be used. Sometimes when using older RADIUS servers, it + * is necessary to force the client to use a particular PEAP version. To do + * so, this property may be set to "0" or "1" to force that specific PEAP + * version. + **/ + /* ---ifcfg-rh--- + * property: phase1-peapver + * variable: IEEE_8021X_PEAP_VERSION(+) + * values: 0, 1 + * description: Use to force a specific PEAP version. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE1_PEAPVER, + g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPVER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase1-peaplabel: + * + * Forces use of the new PEAP label during key derivation. Some RADIUS + * servers may require forcing the new PEAP label to interoperate with + * PEAPv1. Set to "1" to force use of the new PEAP label. See the + * wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase1-peaplabel + * variable: IEEE_8021X_PEAP_FORCE_NEW_LABEL(+) + * values: yes, no + * default: no + * description: Use to force the new PEAP label during key derivation. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE1_PEAPLABEL, + g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPLABEL, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase1-fast-provisioning: + * + * Enables or disables in-line provisioning of EAP-FAST credentials when + * FAST is specified as the EAP method in the #NMSetting8021x:eap property. + * Recognized values are "0" (disabled), "1" (allow unauthenticated + * provisioning), "2" (allow authenticated provisioning), and "3" (allow + * both authenticated and unauthenticated provisioning). See the + * wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase1-fast-provisioning + * variable: IEEE_8021X_FAST_PROVISIONING(+) + * values: space-separated list of these values [allow-auth, allow-unauth] + * description: Enable in-line provisioning of EAP-FAST credentials. + * example: IEEE_8021X_FAST_PROVISIONING="allow-auth allow-unauth" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE1_FAST_PROVISIONING, + g_param_spec_string (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-auth: + * + * Specifies the allowed "phase 2" inner non-EAP authentication methods when + * an EAP method that uses an inner TLS tunnel is specified in the + * #NMSetting8021x:eap property. Recognized non-EAP "phase 2" methods are + * "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", and "tls". + * Each "phase 2" inner method requires specific parameters for successful + * authentication; see the wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase2-auth + * variable: IEEE_8021X_INNER_AUTH_METHODS(+) + * values: "PAP", "CHAP", "MSCHAP", "MSCHAPV2", "GTC", "OTP", "MD5" and "TLS" + * description: Inner non-EAP authentication methods. IEEE_8021X_INNER_AUTH_METHODS + * can contain values both for 'phase2-auth' and 'phase2-autheap' properties. + * example: IEEE_8021X_INNER_AUTH_METHODS=PAP + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_AUTH, + g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-autheap: + * + * Specifies the allowed "phase 2" inner EAP-based authentication methods + * when an EAP method that uses an inner TLS tunnel is specified in the + * #NMSetting8021x:eap property. Recognized EAP-based "phase 2" methods are + * "md5", "mschapv2", "otp", "gtc", and "tls". Each "phase 2" inner method + * requires specific parameters for successful authentication; see the + * wpa_supplicant documentation for more details. + **/ + /* ---ifcfg-rh--- + * property: phase2-autheap + * variable: IEEE_8021X_INNER_AUTH_METHODS(+) + * values: "EAP-MD5", "EAP-MSCHAPV2", "EAP-GTC", "EAP-OTP" and "EAP-TLS" + * description: Inner EAP-based authentication methods. Note that + * IEEE_8021X_INNER_AUTH_METHODS is also used for 'phase2-auth' values. + * example: IEEE_8021X_INNER_AUTH_METHODS="MSCHAPV2 EAP-TLS" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_AUTHEAP, + g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTHEAP, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-ca-cert: + * + * Contains the "phase 2" CA certificate if used by the EAP method specified + * in the #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap + * properties. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. This + * property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_ca_cert() function instead. + **/ + g_object_class_install_property + (object_class, PROP_PHASE2_CA_CERT, + g_param_spec_boxed (NM_SETTING_802_1X_PHASE2_CA_CERT, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-ca-path: + * + * UTF-8 encoded path to a directory containing PEM or DER formatted + * certificates to be added to the verification chain in addition to the + * certificate specified in the #NMSetting8021x:phase2-ca-cert property. + **/ + g_object_class_install_property + (object_class, PROP_PHASE2_CA_PATH, + g_param_spec_string (NM_SETTING_802_1X_PHASE2_CA_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-subject-match: + * + * Substring to be matched against the subject of the certificate presented + * by the authentication server during the inner "phase 2" + * authentication. When unset, no verification of the authentication server + * certificate's subject is performed. + **/ + /* ---ifcfg-rh--- + * property: phase2-subject-match + * variable: IEEE_8021X_PHASE2_SUBJECT_MATCH(+) + * description: Substring to match subject of server certificate against. + * example: IEEE_8021X_PHASE2_SUBJECT_MATCH="Red Hat" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_SUBJECT_MATCH, + g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-altsubject-matches: + * + * List of strings to be matched against the altSubjectName of the + * certificate presented by the authentication server during the inner + * "phase 2" authentication. If the list is empty, no verification of the + * server certificate's altSubjectName is performed. + **/ + /* ---ifcfg-rh--- + * property: phase2-altsubject-matches + * variable: IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES(+) + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES, + g_param_spec_boxed (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-client-cert: + * + * Contains the "phase 2" client certificate if used by the EAP method + * specified in the #NMSetting8021x:phase2-auth or + * #NMSetting8021x:phase2-autheap properties. + * + * Certificate data is specified using a "scheme"; two are currently + * supported: blob and path. When using the blob scheme (which is backwards + * compatible with NM 0.7.x) this property should be set to the + * certificate's DER encoded data. When using the path scheme, this property + * should be set to the full UTF-8 encoded path of the certificate, prefixed + * with the string "file://" and ending with a terminating NUL byte. This + * property can be unset even if the EAP method supports CA certificates, + * but this allows man-in-the-middle attacks and is NOT recommended. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_client_cert() function instead. + **/ + /* ---ifcfg-rh--- + * property: phase2-client-cert + * variable: IEEE_8021X_INNER_CLIENT_CERT(+) + * description: Client certificate for inner EAP method. + * example: IEEE_8021X_INNER_CLIENT_CERT=/home/joe/mycert.crt + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_CLIENT_CERT, + g_param_spec_boxed (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:password: + * + * UTF-8 encoded password used for EAP authentication methods. If both the + * #NMSetting8021x:password property and the #NMSetting8021x:password-raw + * property are specified, #NMSetting8021x:password is preferred. + **/ + /* ---ifcfg-rh--- + * property: password + * variable: IEEE_8021X_PASSWORD(+) + * description: UTF-8 encoded password used for EAP. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_802_1X_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:password property. + **/ + /* ---ifcfg-rh--- + * property: password-flags + * variable: IEEE_8021X_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PASSWORD password. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_802_1X_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:password-raw: + * + * Password used for EAP authentication methods, given as a byte array to + * allow passwords in other encodings than UTF-8 to be used. If both the + * #NMSetting8021x:password property and the #NMSetting8021x:password-raw + * property are specified, #NMSetting8021x:password is preferred. + **/ + /* ---ifcfg-rh--- + * property: password-raw + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PASSWORD_RAW, + g_param_spec_boxed (NM_SETTING_802_1X_PASSWORD_RAW, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:password-raw-flags: + * + * Flags indicating how to handle the #NMSetting8021x:password-raw property. + **/ + /* ---ifcfg-rh--- + * property: password-raw-flags + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PASSWORD_RAW_FLAGS, + g_param_spec_flags (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:private-key: + * + * Contains the private key when the #NMSetting8021x:eap property is set to + * "tls". + * + * Key data is specified using a "scheme"; two are currently supported: blob + * and path. When using the blob scheme and private keys, this property + * should be set to the key's encrypted PEM encoded data. When using private + * keys with the path scheme, this property should be set to the full UTF-8 + * encoded path of the key, prefixed with the string "file://" and ending + * with a terminating NUL byte. When using PKCS#12 format private + * keys and the blob scheme, this property should be set to the + * PKCS#12 data and the #NMSetting8021x:private-key-password + * property must be set to password used to decrypt the PKCS#12 + * certificate and key. When using PKCS#12 files and the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * key, prefixed with the string "file://" and and ending with a terminating + * NUL byte, and as with the blob scheme the "private-key-password" property + * must be set to the password used to decode the PKCS#12 private + * key and certificate. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_private_key() function instead. + * + * WARNING: #NMSetting8021x:private-key is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a + * private key password to prevent unauthorized access to unencrypted + * private key data. + **/ + /* ---ifcfg-rh--- + * property: private-key + * variable: IEEE_8021X_PRIVATE_KEY(+) + * description: Private key for EAP-TLS. + * example: IEEE_8021X_PRIVATE_KEY=/home/joe/mykey.p12 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY, + g_param_spec_boxed (NM_SETTING_802_1X_PRIVATE_KEY, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:private-key-password: + * + * The password used to decrypt the private key specified in the + * #NMSetting8021x:private-key property when the private key either uses the + * path scheme, or if the private key is a PKCS#12 format key. Setting this + * property directly is not generally necessary except when returning + * secrets to NetworkManager; it is generally set automatically when setting + * the private key by the nm_setting_802_1x_set_private_key() function. + **/ + /* ---ifcfg-rh--- + * property: private-key-password + * variable: IEEE_8021X_PRIVATE_KEY_PASSWORD(+) + * description: Password for IEEE_8021X_PRIVATE_KEY. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY_PASSWORD, + g_param_spec_string (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:private-key-password-flags: + * + * Flags indicating how to handle the #NMSetting8021x:private-key-password + * property. + **/ + /* ---ifcfg-rh--- + * property: private-key-password-flags + * variable: IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PRIVATE_KEY_PASSWORD password. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-private-key: + * + * Contains the "phase 2" inner private key when the + * #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap property is + * set to "tls". + * + * Key data is specified using a "scheme"; two are currently supported: blob + * and path. When using the blob scheme and private keys, this property + * should be set to the key's encrypted PEM encoded data. When using private + * keys with the path scheme, this property should be set to the full UTF-8 + * encoded path of the key, prefixed with the string "file://" and ending + * with a terminating NUL byte. When using PKCS#12 format private + * keys and the blob scheme, this property should be set to the + * PKCS#12 data and the #NMSetting8021x:phase2-private-key-password + * property must be set to password used to decrypt the PKCS#12 + * certificate and key. When using PKCS#12 files and the path + * scheme, this property should be set to the full UTF-8 encoded path of the + * key, prefixed with the string "file://" and and ending with a terminating + * NUL byte, and as with the blob scheme the + * #NMSetting8021x:phase2-private-key-password property must be set to the + * password used to decode the PKCS#12 private key and certificate. + * + * Setting this property directly is discouraged; use the + * nm_setting_802_1x_set_phase2_private_key() function instead. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key + * variable: IEEE_8021X_INNER_PRIVATE_KEY(+) + * description: Private key for inner authentication method for EAP-TLS. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY, + g_param_spec_boxed (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-private-key-password: + * + * The password used to decrypt the "phase 2" private key specified in the + * #NMSetting8021x:phase2-private-key property when the private key either + * uses the path scheme, or is a PKCS#12 format key. Setting this + * property directly is not generally necessary except when returning + * secrets to NetworkManager; it is generally set automatically when setting + * the private key by the nm_setting_802_1x_set_phase2_private_key() + * function. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key-password + * variable: IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD(+) + * description: Password for IEEE_8021X_INNER_PRIVATE_KEY. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD, + g_param_spec_string (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:phase2-private-key-password-flags: + * + * Flags indicating how to handle the + * #NMSetting8021x:phase2-private-key-password property. + **/ + /* ---ifcfg-rh--- + * property: phase2-private-key-password-flags + * variable: IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD password. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:pin: + * + * PIN used for EAP authentication methods. + **/ + /* ---ifcfg-rh--- + * property: pin + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PIN, + g_param_spec_string (NM_SETTING_802_1X_PIN, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:pin-flags: + * + * Flags indicating how to handle the #NMSetting8021x:pin property. + **/ + /* ---ifcfg-rh--- + * property: pin-flags + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PIN_FLAGS, + g_param_spec_flags (NM_SETTING_802_1X_PIN_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSetting8021x:system-ca-certs: + * + * When %TRUE, overrides the #NMSetting8021x:ca-path and + * #NMSetting8021x:phase2-ca-path properties using the system CA directory + * specified at configure time with the --system-ca-path switch. The + * certificates in this directory are added to the verification chain in + * addition to any certificates specified by the #NMSetting8021x:ca-cert and + * #NMSetting8021x:phase2-ca-cert properties. + **/ + /* ---ifcfg-rh--- + * property: system-ca-certs + * variable: (none) + * description: The property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SYSTEM_CA_CERTS, + g_param_spec_boolean (NM_SETTING_802_1X_SYSTEM_CA_CERTS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h new file mode 100644 index 00000000..43885daa --- /dev/null +++ b/libnm-core/nm-setting-8021x.h @@ -0,0 +1,278 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_8021X_H__ +#define __NM_SETTING_8021X_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * NMSetting8021xCKFormat: + * @NM_SETTING_802_1X_CK_FORMAT_UNKNOWN: unknown file format + * @NM_SETTING_802_1X_CK_FORMAT_X509: file contains an X.509 format certificate + * @NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: file contains an old-style OpenSSL PEM + * or DER private key + * @NM_SETTING_802_1X_CK_FORMAT_PKCS12: file contains a PKCS#12 certificate + * and private key + * + * #NMSetting8021xCKFormat values indicate the general type of a certificate + * or private key + */ +typedef enum { /*< underscore_name=nm_setting_802_1x_ck_format >*/ + NM_SETTING_802_1X_CK_FORMAT_UNKNOWN = 0, + NM_SETTING_802_1X_CK_FORMAT_X509, + NM_SETTING_802_1X_CK_FORMAT_RAW_KEY, + NM_SETTING_802_1X_CK_FORMAT_PKCS12 +} NMSetting8021xCKFormat; + +/** + * NMSetting8021xCKScheme: + * @NM_SETTING_802_1X_CK_SCHEME_UNKNOWN: unknown certificate or private key + * scheme + * @NM_SETTING_802_1X_CK_SCHEME_BLOB: certificate or key is stored as the raw + * item data + * @NM_SETTING_802_1X_CK_SCHEME_PATH: certificate or key is stored as a path + * to a file containing the certificate or key data + * + * #NMSetting8021xCKScheme values indicate how a certificate or private key is + * stored in the setting properties, either as a blob of the item's data, or as + * a path to a certificate or private key file on the filesystem + */ +typedef enum { /*< underscore_name=nm_setting_802_1x_ck_scheme >*/ + NM_SETTING_802_1X_CK_SCHEME_UNKNOWN = 0, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NM_SETTING_802_1X_CK_SCHEME_PATH +} NMSetting8021xCKScheme; + + +#define NM_TYPE_SETTING_802_1X (nm_setting_802_1x_get_type ()) +#define NM_SETTING_802_1X(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021x)) +#define NM_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) +#define NM_IS_SETTING_802_1X(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_802_1X)) +#define NM_IS_SETTING_802_1X_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_802_1X)) +#define NM_SETTING_802_1X_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021xClass)) + +#define NM_SETTING_802_1X_SETTING_NAME "802-1x" + +#define NM_SETTING_802_1X_EAP "eap" +#define NM_SETTING_802_1X_IDENTITY "identity" +#define NM_SETTING_802_1X_ANONYMOUS_IDENTITY "anonymous-identity" +#define NM_SETTING_802_1X_PAC_FILE "pac-file" +#define NM_SETTING_802_1X_CA_CERT "ca-cert" +#define NM_SETTING_802_1X_CA_PATH "ca-path" +#define NM_SETTING_802_1X_SUBJECT_MATCH "subject-match" +#define NM_SETTING_802_1X_ALTSUBJECT_MATCHES "altsubject-matches" +#define NM_SETTING_802_1X_CLIENT_CERT "client-cert" +#define NM_SETTING_802_1X_PHASE1_PEAPVER "phase1-peapver" +#define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel" +#define NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning" +#define NM_SETTING_802_1X_PHASE2_AUTH "phase2-auth" +#define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap" +#define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert" +#define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path" +#define NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH "phase2-subject-match" +#define NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES "phase2-altsubject-matches" +#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert" +#define NM_SETTING_802_1X_PASSWORD "password" +#define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_802_1X_PASSWORD_RAW "password-raw" +#define NM_SETTING_802_1X_PASSWORD_RAW_FLAGS "password-raw-flags" +#define NM_SETTING_802_1X_PRIVATE_KEY "private-key" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD "private-key-password" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS "private-key-password-flags" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD "phase2-private-key-password" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS "phase2-private-key-password-flags" +#define NM_SETTING_802_1X_PIN "pin" +#define NM_SETTING_802_1X_PIN_FLAGS "pin-flags" +#define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" + +/* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties + * using the "blob" scheme, the data must be passed in PKCS#12 binary format. + * In this case, the appropriate "client-cert" (or "phase2-client-cert") + * property of the NMSetting8021x object must also contain the exact same + * PKCS#12 binary data that the private key does. This is because the + * PKCS#12 file contains both the private key and client certificate, so both + * properties need to be set to the same thing. When using the "path" scheme, + * just set both the private-key and client-cert properties to the same path. + * + * When setting OpenSSL-derived "traditional" format (ie S/MIME style, not + * PKCS#8) RSA and DSA keys directly via properties with the "blob" scheme, they + * should be passed to NetworkManager in PEM format with the "DEK-Info" and + * "Proc-Type" tags intact. Decrypted private keys should not be used as this + * is insecure and could allow unprivileged users to access the decrypted + * private key data. + * + * When using the "path" scheme, just set the private-key and client-cert + * properties to the paths to their respective objects. + */ + +struct _NMSetting8021x { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSetting8021xClass; + +GType nm_setting_802_1x_get_type (void); + +NMSetting *nm_setting_802_1x_new (void); + +guint32 nm_setting_802_1x_get_num_eap_methods (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_eap_method (NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_add_eap_method (NMSetting8021x *setting, const char *eap); +void nm_setting_802_1x_remove_eap_method (NMSetting8021x *setting, guint32 i); +gboolean nm_setting_802_1x_remove_eap_method_by_value (NMSetting8021x *setting, const char *eap); +void nm_setting_802_1x_clear_eap_methods (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_identity (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_anonymous_identity (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_pac_file (NMSetting8021x *setting); + +gboolean nm_setting_802_1x_get_system_ca_certs (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_ca_path (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_ca_path (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_ca_cert_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_ca_cert_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_ca_cert_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_ca_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); + +const char * nm_setting_802_1x_get_subject_match (NMSetting8021x *setting); + +guint32 nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, + guint32 i); +gboolean nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting, + const char *altsubject_match); +void nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, + guint32 i); +gboolean nm_setting_802_1x_remove_altsubject_match_by_value (NMSetting8021x *setting, + const char *altsubject_match); +void nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_client_cert_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_client_cert_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_client_cert_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_client_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); + +const char * nm_setting_802_1x_get_phase1_peapver (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_phase1_peaplabel (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_phase1_fast_provisioning (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_phase2_auth (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_phase2_autheap (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_ca_cert_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_ca_cert_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_ca_cert_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); + +const char * nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting); + +guint32 nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, + guint32 i); +gboolean nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting, + const char *phase2_altsubject_match); +void nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, + guint32 i); +gboolean nm_setting_802_1x_remove_phase2_altsubject_match_by_value (NMSetting8021x *setting, + const char *phase2_altsubject_match); +void nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_client_cert_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_client_cert_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting, + const char *cert_path, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); + +const char * nm_setting_802_1x_get_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_flags (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_password_raw (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_raw_flags (NMSetting8021x *setting); + +const char * nm_setting_802_1x_get_pin (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_private_key (NMSetting8021x *setting, + const char *key_path, + const char *password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); +const char * nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting); + +NMSetting8021xCKFormat nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting); + +NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_private_key_scheme (NMSetting8021x *setting); +GBytes * nm_setting_802_1x_get_phase2_private_key_blob (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting); +gboolean nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, + const char *key_path, + const char *password, + NMSetting8021xCKScheme scheme, + NMSetting8021xCKFormat *out_format, + GError **error); +const char * nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting); + +NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting); + + +G_END_DECLS + +#endif /* __NM_SETTING_8021X_H__ */ diff --git a/libnm-core/nm-setting-adsl.c b/libnm-core/nm-setting-adsl.c new file mode 100644 index 00000000..00bcef54 --- /dev/null +++ b/libnm-core/nm-setting-adsl.c @@ -0,0 +1,448 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-adsl.h" +#include "nm-setting-ppp.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-adsl + * @short_description: Describes ADSL-based properties + * + * The #NMSettingAdsl object is a #NMSetting subclass that describes + * properties of ADSL connections. + */ + +G_DEFINE_TYPE_WITH_CODE (NMSettingAdsl, nm_setting_adsl, NM_TYPE_SETTING, + _nm_register_setting (ADSL, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_ADSL) + +#define NM_SETTING_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_ADSL, NMSettingAdslPrivate)) + +typedef struct { + char * username; + char * password; + NMSettingSecretFlags password_flags; + char * protocol; + char * encapsulation; + guint32 vpi; + guint32 vci; +} NMSettingAdslPrivate; + +enum { + PROP_0, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_PROTOCOL, + PROP_ENCAPSULATION, + PROP_VPI, + PROP_VCI, + + LAST_PROP +}; + +/** + * nm_setting_adsl_new: + * + * Creates a new #NMSettingAdsl object with default values. + * + * Returns: the new empty #NMSettingAdsl object + **/ +NMSetting * +nm_setting_adsl_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_ADSL, NULL); +} + +/** + * nm_setting_adsl_get_username: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:username property of the setting + **/ +const char * +nm_setting_adsl_get_username (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->username; +} + +/** + * nm_setting_adsl_get_password: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:password property of the setting + **/ +const char * +nm_setting_adsl_get_password (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->password; +} + +/** + * nm_setting_adsl_get_password_flags: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingAdsl:password + **/ +NMSettingSecretFlags +nm_setting_adsl_get_password_flags (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->password_flags; +} + +/** + * nm_setting_adsl_get_protocol: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:protocol property of the setting + **/ +const char * +nm_setting_adsl_get_protocol (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->protocol; +} + +/** + * nm_setting_adsl_get_encapsulation: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:encapsulation property of the setting + **/ +const char * +nm_setting_adsl_get_encapsulation (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), NULL); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->encapsulation; +} + +/** + * nm_setting_adsl_get_vpi: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:vpi property of the setting + **/ +guint32 +nm_setting_adsl_get_vpi (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), 0); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->vpi; +} + +/** + * nm_setting_adsl_get_vci: + * @setting: the #NMSettingAdsl + * + * Returns: the #NMSettingAdsl:vci property of the setting + **/ +guint32 +nm_setting_adsl_get_vci (NMSettingAdsl *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_ADSL (setting), 0); + + return NM_SETTING_ADSL_GET_PRIVATE (setting)->vci; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE (setting); + + if (!priv->username) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME); + return FALSE; + } else if (!strlen (priv->username)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_USERNAME); + return FALSE; + } + + if (priv->password && !strlen (priv->password)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PASSWORD); + return FALSE; + } + + if ( !priv->protocol + || ( strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) + && strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) + && strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM))){ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->protocol ? priv->protocol : "(null)"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL); + return FALSE; + } + + if ( priv->encapsulation + && ( strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) + && strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_LLC) )) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->encapsulation); + g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_ENCAPSULATION); + return FALSE; + } + + return TRUE; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE (setting); + GPtrArray *secrets = NULL; + + if (priv->password) + return NULL; + + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_ADSL_PASSWORD); + } + + return secrets; +} + +static void +nm_setting_adsl_init (NMSettingAdsl *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE (object); + + g_free (priv->username); + g_free (priv->password); + g_free (priv->protocol); + g_free (priv->encapsulation); + + G_OBJECT_CLASS (nm_setting_adsl_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingAdslPrivate *priv = NM_SETTING_ADSL_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_USERNAME: + g_free (priv->username); + priv->username = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (priv->password); + priv->password = g_value_dup_string (value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags (value); + break; + case PROP_PROTOCOL: + g_free (priv->protocol); + priv->protocol = g_ascii_strdown (g_value_get_string (value), -1); + break; + case PROP_ENCAPSULATION: + g_free (priv->encapsulation); + priv->encapsulation = g_ascii_strdown (g_value_get_string (value), -1); + break; + case PROP_VPI: + priv->vpi = g_value_get_uint (value); + break; + case PROP_VCI: + priv->vci = g_value_get_uint (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) +{ + NMSettingAdsl *setting = NM_SETTING_ADSL (object); + + switch (prop_id) { + case PROP_USERNAME: + g_value_set_string (value, nm_setting_adsl_get_username (setting)); + break; + case PROP_PASSWORD: + g_value_set_string (value, nm_setting_adsl_get_password (setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags (value, nm_setting_adsl_get_password_flags (setting)); + break; + case PROP_PROTOCOL: + g_value_set_string (value, nm_setting_adsl_get_protocol (setting)); + break; + case PROP_ENCAPSULATION: + g_value_set_string (value, nm_setting_adsl_get_encapsulation (setting)); + break; + case PROP_VPI: + g_value_set_uint (value, nm_setting_adsl_get_vpi (setting)); + break; + case PROP_VCI: + g_value_set_uint (value, nm_setting_adsl_get_vci (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingAdslPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + + /** + * NMSettingAdsl:username: + * + * Username used to authenticate with the ADSL service. + **/ + g_object_class_install_property + (object_class, PROP_USERNAME, + g_param_spec_string (NM_SETTING_ADSL_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:password: + * + * Password used to authenticate with the ADSL service. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_ADSL_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:password-flags: + * + * Flags indicating how to handle the #NMSettingAdsl:password property. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_ADSL_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:protocol: + * + * ADSL connection protocol. Can be "pppoa", "pppoe" or "ipoatm". + **/ + g_object_class_install_property + (object_class, PROP_PROTOCOL, + g_param_spec_string (NM_SETTING_ADSL_PROTOCOL, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:encapsulation: + * + * Encapsulation of ADSL connection. Can be "vcmux" or "llc". + **/ + g_object_class_install_property + (object_class, PROP_ENCAPSULATION, + g_param_spec_string (NM_SETTING_ADSL_ENCAPSULATION, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:vpi: + * + * VPI of ADSL connection + **/ + g_object_class_install_property + (object_class, PROP_VPI, + g_param_spec_uint (NM_SETTING_ADSL_VPI, "", "", + 0, 65536, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingAdsl:vci: + * + * VCI of ADSL connection + **/ + g_object_class_install_property + (object_class, PROP_VCI, + g_param_spec_uint (NM_SETTING_ADSL_VCI, "", "", + 0, 65536, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-adsl.h b/libnm-core/nm-setting-adsl.h new file mode 100644 index 00000000..2b44d686 --- /dev/null +++ b/libnm-core/nm-setting-adsl.h @@ -0,0 +1,81 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_ADSL_H__ +#define __NM_SETTING_ADSL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_ADSL (nm_setting_adsl_get_type ()) +#define NM_SETTING_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_ADSL, NMSettingAdsl)) +#define NM_SETTING_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_ADSL, NMSettingAdslClass)) +#define NM_IS_SETTING_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_ADSL)) +#define NM_IS_SETTING_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_ADSL)) +#define NM_SETTING_ADSL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_ADSL, NMSettingAdslClass)) + +#define NM_SETTING_ADSL_SETTING_NAME "adsl" + +#define NM_SETTING_ADSL_USERNAME "username" +#define NM_SETTING_ADSL_PASSWORD "password" +#define NM_SETTING_ADSL_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_ADSL_PROTOCOL "protocol" +#define NM_SETTING_ADSL_ENCAPSULATION "encapsulation" +#define NM_SETTING_ADSL_VPI "vpi" +#define NM_SETTING_ADSL_VCI "vci" + +#define NM_SETTING_ADSL_PROTOCOL_PPPOA "pppoa" +#define NM_SETTING_ADSL_PROTOCOL_PPPOE "pppoe" +#define NM_SETTING_ADSL_PROTOCOL_IPOATM "ipoatm" + +#define NM_SETTING_ADSL_ENCAPSULATION_VCMUX "vcmux" +#define NM_SETTING_ADSL_ENCAPSULATION_LLC "llc" + +struct _NMSettingAdsl { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingAdslClass; + +GType nm_setting_adsl_get_type (void); + +NMSetting *nm_setting_adsl_new (void); +const char *nm_setting_adsl_get_username (NMSettingAdsl *setting); +const char *nm_setting_adsl_get_password (NMSettingAdsl *setting); +const char *nm_setting_adsl_get_protocol (NMSettingAdsl *setting); +const char *nm_setting_adsl_get_encapsulation (NMSettingAdsl *setting); +guint32 nm_setting_adsl_get_vpi (NMSettingAdsl *setting); +guint32 nm_setting_adsl_get_vci (NMSettingAdsl *setting); +NMSettingSecretFlags nm_setting_adsl_get_password_flags (NMSettingAdsl *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_ADSL_H__ */ diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c new file mode 100644 index 00000000..41a0b4c2 --- /dev/null +++ b/libnm-core/nm-setting-bluetooth.c @@ -0,0 +1,285 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-bluetooth.h" +#include "nm-setting-cdma.h" +#include "nm-setting-gsm.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-bluetooth + * @short_description: Describes Bluetooth connection properties + * + * The #NMSettingBluetooth object is a #NMSetting subclass that describes + * properties necessary for connection to devices that provide network + * connections via the Bluetooth Dial-Up Networking (DUN) and Network Access + * Point (NAP) profiles. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING, + _nm_register_setting (BLUETOOTH, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BLUETOOTH) + +#define NM_SETTING_BLUETOOTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothPrivate)) + +typedef struct { + char *bdaddr; + char *type; +} NMSettingBluetoothPrivate; + +enum { + PROP_0, + PROP_BDADDR, + PROP_TYPE, + + LAST_PROP +}; + +/** + * nm_setting_bluetooth_new: + * + * Creates a new #NMSettingBluetooth object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBluetooth object + **/ +NMSetting *nm_setting_bluetooth_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_BLUETOOTH, NULL); +} + +/** + * nm_setting_bluetooth_get_connection_type: + * @setting: the #NMSettingBluetooth + * + * Returns the connection method for communicating with the remote device (i.e. + * either DUN to a DUN-capable device or PANU to a NAP-capable device). + * + * Returns: the type, either %NM_SETTING_BLUETOOTH_TYPE_PANU or + * %NM_SETTING_BLUETOOTH_TYPE_DUN + **/ +const char * +nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BLUETOOTH (setting), NULL); + + return NM_SETTING_BLUETOOTH_GET_PRIVATE (setting)->type; +} + +/** + * nm_setting_bluetooth_get_bdaddr: + * @setting: the #NMSettingBluetooth + * + * Gets the Bluetooth address of the remote device which this setting + * describes a connection to. + * + * Returns: the Bluetooth address + **/ +const char * +nm_setting_bluetooth_get_bdaddr (NMSettingBluetooth *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BLUETOOTH (setting), NULL); + + return NM_SETTING_BLUETOOTH_GET_PRIVATE (setting)->bdaddr; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (setting); + + if (!priv->bdaddr) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + + if (!nm_utils_hwaddr_valid (priv->bdaddr, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + + if (!priv->type) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } else if (!g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN) && + !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); + return FALSE; + } + + /* Make sure the corresponding 'type' setting is present */ + if ( connection + && !strcmp (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN)) { + gboolean gsm = FALSE, cdma = FALSE; + + gsm = !!nm_connection_get_setting_gsm (connection); + cdma = !!nm_connection_get_setting_cdma (connection); + + if (!gsm && !cdma) { + /* We can't return MISSING_SETTING here, because we don't know + * whether to prefix the message with NM_SETTING_GSM_SETTING_NAME or + * NM_SETTING_CDMA_SETTING_NAME. + */ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("'%s' connection requires '%s' or '%s' setting"), + NM_SETTING_BLUETOOTH_TYPE_DUN, + NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME); + g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); + return FALSE; + } + } + /* PANU doesn't need a 'type' setting since no further configuration + * is required at the interface level. + */ + + return TRUE; +} + +static void +nm_setting_bluetooth_init (NMSettingBluetooth *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (object); + + g_free (priv->bdaddr); + g_free (priv->type); + + G_OBJECT_CLASS (nm_setting_bluetooth_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_BDADDR: + g_free (priv->bdaddr); + priv->bdaddr = g_value_dup_string (value); + break; + case PROP_TYPE: + g_free (priv->type); + priv->type = 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) +{ + NMSettingBluetooth *setting = NM_SETTING_BLUETOOTH (object); + + switch (prop_id) { + case PROP_BDADDR: + g_value_set_string (value, nm_setting_bluetooth_get_bdaddr (setting)); + break; + case PROP_TYPE: + g_value_set_string (value, nm_setting_bluetooth_get_connection_type (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingBluetoothPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingBluetooth:bdaddr: + * + * The Bluetooth address of the device. + **/ + g_object_class_install_property + (object_class, PROP_BDADDR, + g_param_spec_string (NM_SETTING_BLUETOOTH_BDADDR, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_BLUETOOTH_BDADDR, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingBluetooth:type: + * + * Either "dun" for Dial-Up Networking connections or "panu" for Personal + * Area Networking connections to devices supporting the NAP profile. + **/ + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_SETTING_BLUETOOTH_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-bluetooth.h b/libnm-core/nm-setting-bluetooth.h new file mode 100644 index 00000000..6bb5ce80 --- /dev/null +++ b/libnm-core/nm-setting-bluetooth.h @@ -0,0 +1,81 @@ +/* -*- 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. + * + * Copyright 2007 - 2009 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_BLUETOOTH_H__ +#define __NM_SETTING_BLUETOOTH_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BLUETOOTH (nm_setting_bluetooth_get_type ()) +#define NM_SETTING_BLUETOOTH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetooth)) +#define NM_SETTING_BLUETOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothClass)) +#define NM_IS_SETTING_BLUETOOTH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_BLUETOOTH)) +#define NM_IS_SETTING_BLUETOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_BLUETOOTH)) +#define NM_SETTING_BLUETOOTH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothClass)) + +#define NM_SETTING_BLUETOOTH_SETTING_NAME "bluetooth" + +#define NM_SETTING_BLUETOOTH_BDADDR "bdaddr" +#define NM_SETTING_BLUETOOTH_TYPE "type" + +/** + * NM_SETTING_BLUETOOTH_TYPE_DUN: + * + * Connection type describing a connection to devices that support the Bluetooth + * DUN profile. + */ +#define NM_SETTING_BLUETOOTH_TYPE_DUN "dun" + +/** + * NM_SETTING_BLUETOOTH_TYPE_PANU: + * + * Connection type describing a connection to devices that support the Bluetooth + * NAP (Network Access Point) protocol, which accepts connections via PANU. + */ +#define NM_SETTING_BLUETOOTH_TYPE_PANU "panu" + +struct _NMSettingBluetooth { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBluetoothClass; + +GType nm_setting_bluetooth_get_type (void); + +NMSetting * nm_setting_bluetooth_new (void); +const char * nm_setting_bluetooth_get_bdaddr (NMSettingBluetooth *setting); +const char * nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BLUETOOTH_H__ */ diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c new file mode 100644 index 00000000..bb053125 --- /dev/null +++ b/libnm-core/nm-setting-bond.c @@ -0,0 +1,760 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "nm-setting-bond.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-infiniband.h" + +/** + * SECTION:nm-setting-bond + * @short_description: Describes connection properties for bonds + * + * The #NMSettingBond object is a #NMSetting subclass that describes properties + * necessary for bond connections. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingBond, nm_setting_bond, NM_TYPE_SETTING, + _nm_register_setting (BOND, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BOND) + +#define NM_SETTING_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BOND, NMSettingBondPrivate)) + +typedef struct { + GHashTable *options; +} NMSettingBondPrivate; + +enum { + PROP_0, + PROP_OPTIONS, + LAST_PROP +}; + +enum { + TYPE_INT, + TYPE_STR, + TYPE_BOTH, + TYPE_IP, + TYPE_IFNAME, +}; + +typedef struct { + const char *opt; + const char *val; + guint opt_type; + guint min; + guint max; + char *list[10]; +} BondDefault; + +static const BondDefault defaults[] = { + { NM_SETTING_BOND_OPTION_MODE, "balance-rr", TYPE_BOTH, 0, 6, + { "balance-rr", "active-backup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb", NULL } }, + { NM_SETTING_BOND_OPTION_MIIMON, "100", TYPE_INT, 0, G_MAXINT }, + { NM_SETTING_BOND_OPTION_DOWNDELAY, "0", TYPE_INT, 0, G_MAXINT }, + { NM_SETTING_BOND_OPTION_UPDELAY, "0", TYPE_INT, 0, G_MAXINT }, + { NM_SETTING_BOND_OPTION_ARP_INTERVAL, "0", TYPE_INT, 0, G_MAXINT }, + { NM_SETTING_BOND_OPTION_ARP_IP_TARGET, "", TYPE_IP }, + { NM_SETTING_BOND_OPTION_ARP_VALIDATE, "0", TYPE_BOTH, 0, 3, + { "none", "active", "backup", "all", NULL } }, + { NM_SETTING_BOND_OPTION_PRIMARY, "", TYPE_IFNAME }, + { NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, "0", TYPE_BOTH, 0, 2, + { "always", "better", "failure", NULL } }, + { NM_SETTING_BOND_OPTION_FAIL_OVER_MAC, "0", TYPE_BOTH, 0, 2, + { "none", "active", "follow", NULL } }, + { NM_SETTING_BOND_OPTION_USE_CARRIER, "1", TYPE_INT, 0, 1 }, + { NM_SETTING_BOND_OPTION_AD_SELECT, "0", TYPE_BOTH, 0, 2, + { "stable", "bandwidth", "count", NULL } }, + { NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "0", TYPE_BOTH, 0, 2, + { "layer2", "layer3+4", "layer2+3", NULL } }, + { NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", TYPE_INT, 0, 255 }, + { NM_SETTING_BOND_OPTION_LACP_RATE, "0", TYPE_BOTH, 0, 1, + { "slow", "fast", NULL } }, +}; + +/** + * nm_setting_bond_new: + * + * Creates a new #NMSettingBond object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBond object + **/ +NMSetting * +nm_setting_bond_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_BOND, NULL); +} + +/** + * nm_setting_bond_get_num_options: + * @setting: the #NMSettingBond + * + * Returns the number of options that should be set for this bond when it + * is activated. This can be used to retrieve each option individually + * using nm_setting_bond_get_option(). + * + * Returns: the number of bonding options + **/ +guint32 +nm_setting_bond_get_num_options (NMSettingBond *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0); + + return g_hash_table_size (NM_SETTING_BOND_GET_PRIVATE (setting)->options); +} + +/** + * nm_setting_bond_get_option: + * @setting: the #NMSettingBond + * @idx: index of the desired option, from 0 to + * nm_setting_bond_get_num_options() - 1 + * @out_name: (out) (transfer none): on return, the name of the bonding option; + * this value is owned by the setting and should not be modified + * @out_value: (out) (transfer none): on return, the value of the name of the + * bonding option; this value is owned by the setting and should not be + * modified + * + * Given an index, return the value of the bonding option at that index. Indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_bond_add_option() and nm_setting_bond_remove_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_bond_get_option (NMSettingBond *setting, + guint32 idx, + const char **out_name, + const char **out_value) +{ + NMSettingBondPrivate *priv; + GList *keys; + const char *_key = NULL, *_value = NULL; + + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); + + priv = NM_SETTING_BOND_GET_PRIVATE (setting); + + if (idx >= nm_setting_bond_get_num_options (setting)) + return FALSE; + + keys = g_hash_table_get_keys (priv->options); + _key = g_list_nth_data (keys, idx); + _value = g_hash_table_lookup (priv->options, _key); + + if (out_name) + *out_name = _key; + if (out_value) + *out_value = _value; + + g_list_free (keys); + return TRUE; +} + +static gboolean +validate_int (const char *name, const char *value, const BondDefault *def) +{ + glong num; + guint i; + + for (i = 0; i < strlen (value); i++) { + if (!g_ascii_isdigit (value[i]) && value[i] != '-') + return FALSE; + } + + errno = 0; + num = strtol (value, NULL, 10); + if (errno) + return FALSE; + if (num < def->min || num > def->max) + return FALSE; + + return TRUE; +} + +static gboolean +validate_list (const char *name, const char *value, const BondDefault *def) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (def->list) && def->list[i]; i++) { + if (g_strcmp0 (def->list[i], value) == 0) + return TRUE; + } + + /* empty validation list means all values pass */ + return def->list[0] == NULL ? TRUE : FALSE; +} + +static gboolean +validate_ip (const char *name, const char *value) +{ + char **ips, **iter; + gboolean success = TRUE; + struct in_addr addr; + + if (!value || !value[0]) + return FALSE; + + ips = g_strsplit_set (value, ",", 0); + for (iter = ips; iter && *iter && success; iter++) + success = !!inet_aton (*iter, &addr); + g_strfreev (ips); + + return success; +} + +static gboolean +validate_ifname (const char *name, const char *value) +{ + if (!value || !value[0]) + return FALSE; + + return nm_utils_iface_valid_name (value); +} + +/** + * nm_setting_bond_validate_option: + * @name: the name of the option to validate + * @value: the value of the option to validate + * + * Checks whether @name is a valid bond option and @value is a valid value for + * the @name. If @value is %NULL, the function only validates the option name. + * + * Returns: %TRUE, if the @value is valid for the given name. + * If the @name is not a valid option, %FALSE will be returned. + **/ +gboolean +nm_setting_bond_validate_option (const char *name, + const char *value) +{ + guint i; + + if (!name || !name[0]) + return FALSE; + + for (i = 0; i < G_N_ELEMENTS (defaults); i++) { + if (g_strcmp0 (defaults[i].opt, name) == 0) { + if (value == NULL) + return TRUE; + switch (defaults[i].opt_type) { + case TYPE_INT: + return validate_int (name, value, &defaults[i]); + case TYPE_STR: + return validate_list (name, value, &defaults[i]); + case TYPE_BOTH: + return ( validate_int (name, value, &defaults[i]) + || validate_list (name, value, &defaults[i])); + case TYPE_IP: + return validate_ip (name, value); + case TYPE_IFNAME: + return validate_ifname (name, value); + } + return FALSE; + } + } + return FALSE; +} + +/** + * nm_setting_bond_get_option_by_name: + * @setting: the #NMSettingBond + * @name: the option name for which to retrieve the value + * + * Returns the value associated with the bonding option specified by + * @name, if it exists. + * + * Returns: the value, or %NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_bond_get_option_by_name (NMSettingBond *setting, + const char *name) +{ + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); + + if (!nm_setting_bond_validate_option (name, NULL)) + return NULL; + + return g_hash_table_lookup (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name); +} + +/** + * nm_setting_bond_add_option: + * @setting: the #NMSettingBond + * @name: name for the option + * @value: value for the option + * + * Add an option to the table. The option is compared to an internal list + * of allowed options. Option names may contain only alphanumeric characters + * (ie [a-zA-Z0-9]). Adding a new name replaces any existing name/value pair + * that may already exist. + * + * The order of how to set several options is relevant because there are options + * that conflict with each other. + * + * Returns: %TRUE if the option was valid and was added to the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_bond_add_option (NMSettingBond *setting, + const char *name, + const char *value) +{ + NMSettingBondPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); + + if (!value || !nm_setting_bond_validate_option (name, value)) + return FALSE; + + priv = NM_SETTING_BOND_GET_PRIVATE (setting); + + g_hash_table_insert (priv->options, g_strdup (name), g_strdup (value)); + + if ( !strcmp (name, NM_SETTING_BOND_OPTION_MIIMON) + && strcmp (value, "0") != 0) { + g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + } else if ( !strcmp (name, NM_SETTING_BOND_OPTION_ARP_INTERVAL) + && strcmp (value, "0") != 0) { + g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_MIIMON); + g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY); + g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_UPDELAY); + } + + g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS); + + return TRUE; +} + +/** + * nm_setting_bond_remove_option: + * @setting: the #NMSettingBond + * @name: name of the option to remove + * + * Remove the bonding option referenced by @name from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_bond_remove_option (NMSettingBond *setting, + const char *name) +{ + gboolean found; + + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); + + if (!nm_setting_bond_validate_option (name, NULL)) + return FALSE; + + found = g_hash_table_remove (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name); + if (found) + g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS); + return found; +} + +/** + * nm_setting_bond_get_valid_options: + * @setting: the #NMSettingBond + * + * Returns a list of valid bond options. + * + * Returns: (transfer none): a %NULL-terminated array of strings of valid bond options. + **/ +const char ** +nm_setting_bond_get_valid_options (NMSettingBond *setting) +{ + static const char *array[G_N_ELEMENTS (defaults) + 1] = { NULL }; + int i; + + /* initialize the array once */ + if (G_UNLIKELY (array[0] == NULL)) { + for (i = 0; i < G_N_ELEMENTS (defaults); i++) + array[i] = defaults[i].opt; + array[i] = NULL; + } + return array; +} + +/** + * nm_setting_bond_get_option_default: + * @setting: the #NMSettingBond + * @name: the name of the option + * + * Returns: the value of the bond option if not overridden by an entry in + * the #NMSettingBond:options property. + **/ +const char * +nm_setting_bond_get_option_default (NMSettingBond *setting, const char *name) +{ + guint i; + + g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); + g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NULL); + + for (i = 0; i < G_N_ELEMENTS (defaults); i++) { + if (g_strcmp0 (defaults[i].opt, name) == 0) + return defaults[i].val; + } + /* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */ + g_assert_not_reached (); +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting); + GHashTableIter iter; + const char *key, *value; + const char *valid_modes[] = { "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + NULL }; + int miimon = 0, arp_interval = 0; + const char *arp_ip_target = NULL; + const char *lacp_rate; + const char *primary; + + g_hash_table_iter_init (&iter, priv->options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if (!value[0] || !nm_setting_bond_validate_option (key, value)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid option '%s' or its value '%s'"), + key, value); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MIIMON); + if (value) + miimon = atoi (value); + value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + if (value) + arp_interval = atoi (value); + + /* Can only set one of miimon and arp_interval */ + if (miimon > 0 && arp_interval > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("only one of '%s' and '%s' can be set"), + NM_SETTING_BOND_OPTION_MIIMON, + NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + } + + value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE); + if (!value) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("mandatory option '%s' is missing"), + NM_SETTING_BOND_OPTION_MODE); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + if (!_nm_utils_string_in_list (value, valid_modes)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for '%s'"), + value, NM_SETTING_BOND_OPTION_MODE); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + /* Make sure mode is compatible with other settings */ + if ( strcmp (value, "balance-alb") == 0 + || strcmp (value, "balance-tlb") == 0) { + if (arp_interval > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s=%s' is incompatible with '%s > 0'"), + NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + primary = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_PRIMARY); + if (strcmp (value, "active-backup") == 0) { + if (primary && !nm_utils_iface_valid_name (primary)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name for '%s' option"), + primary, NM_SETTING_BOND_OPTION_PRIMARY); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } else { + if (primary) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is only valid for '%s=%s'"), + NM_SETTING_BOND_OPTION_PRIMARY, + NM_SETTING_BOND_OPTION_MODE, "active-backup"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + if (nm_connection_get_setting_infiniband (connection)) { + if (strcmp (value, "active-backup") != 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s=%s' is not a valid configuration for '%s'"), + NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_INFINIBAND_SETTING_NAME); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + if (miimon == 0) { + /* updelay and downdelay can only be used with miimon */ + if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_UPDELAY)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_UPDELAY, NM_SETTING_BOND_OPTION_MIIMON); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_DOWNDELAY, NM_SETTING_BOND_OPTION_MIIMON); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + /* arp_ip_target can only be used with arp_interval, and must + * contain a comma-separated list of IPv4 addresses. + */ + arp_ip_target = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + if (arp_interval > 0) { + char **addrs; + guint32 addr; + int i; + + if (!arp_ip_target) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_ARP_INTERVAL, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + addrs = g_strsplit (arp_ip_target, ",", -1); + if (!addrs[0]) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is empty"), + NM_SETTING_BOND_OPTION_ARP_IP_TARGET); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + g_strfreev (addrs); + return FALSE; + } + + for (i = 0; addrs[i]; i++) { + if (!inet_pton (AF_INET, addrs[i], &addr)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid IPv4 address for '%s' option"), + NM_SETTING_BOND_OPTION_ARP_IP_TARGET, addrs[i]); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + g_strfreev (addrs); + return FALSE; + } + } + g_strfreev (addrs); + } else { + if (arp_ip_target) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option requires '%s' option to be set"), + NM_SETTING_BOND_OPTION_ARP_IP_TARGET, NM_SETTING_BOND_OPTION_ARP_INTERVAL); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + } + + lacp_rate = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_LACP_RATE); + if ( lacp_rate + && (g_strcmp0 (value, "802.3ad") != 0 && g_strcmp0 (value, "4") != 0) + && (strcmp (lacp_rate, "slow") != 0 && strcmp (lacp_rate, "0") != 0)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option is only valid with mode '%s'"), + NM_SETTING_BOND_OPTION_LACP_RATE, "802.3ad"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + return _nm_connection_verify_required_interface_name (connection, error); +} + +static void +nm_setting_bond_init (NMSettingBond *setting) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting); + + priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* Default values: */ + nm_setting_bond_add_option (setting, NM_SETTING_BOND_OPTION_MODE, "balance-rr"); +} + +static void +finalize (GObject *object) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object); + + g_hash_table_destroy (priv->options); + + G_OBJECT_CLASS (nm_setting_bond_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_OPTIONS: + g_hash_table_unref (priv->options); + priv->options = _nm_utils_copy_strdict (g_value_get_boxed (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) +{ + NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_OPTIONS: + g_value_take_boxed (value, _nm_utils_copy_strdict (priv->options)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_bond_class_init (NMSettingBondClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingBondPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingBond:options: + * + * Dictionary of key/value pairs of bonding options. Both keys and values + * must be strings. Option names must contain only alphanumeric characters + * (ie, [a-zA-Z0-9]). + * + * Type: GHashTable(utf8,utf8) + **/ + /* ---ifcfg-rh--- + * property: options + * variable: BONDING_OPTS + * description: Bonding options. + * example: BONDING_OPTS="miimon=100 mode=broadcast" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_OPTIONS, + g_param_spec_boxed (NM_SETTING_BOND_OPTIONS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_BOND_OPTIONS, + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * bond's interface name. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); +} diff --git a/libnm-core/nm-setting-bond.h b/libnm-core/nm-setting-bond.h new file mode 100644 index 00000000..055801a5 --- /dev/null +++ b/libnm-core/nm-setting-bond.h @@ -0,0 +1,98 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BOND_H__ +#define __NM_SETTING_BOND_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BOND (nm_setting_bond_get_type ()) +#define NM_SETTING_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_BOND, NMSettingBond)) +#define NM_SETTING_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_BOND, NMSettingBondClass)) +#define NM_IS_SETTING_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_BOND)) +#define NM_IS_SETTING_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_BOND)) +#define NM_SETTING_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_BOND, NMSettingBondClass)) + +#define NM_SETTING_BOND_SETTING_NAME "bond" + +#define NM_SETTING_BOND_OPTIONS "options" + +/* Valid options for the 'options' property */ +#define NM_SETTING_BOND_OPTION_MODE "mode" +#define NM_SETTING_BOND_OPTION_MIIMON "miimon" +#define NM_SETTING_BOND_OPTION_DOWNDELAY "downdelay" +#define NM_SETTING_BOND_OPTION_UPDELAY "updelay" +#define NM_SETTING_BOND_OPTION_ARP_INTERVAL "arp_interval" +#define NM_SETTING_BOND_OPTION_ARP_IP_TARGET "arp_ip_target" +#define NM_SETTING_BOND_OPTION_ARP_VALIDATE "arp_validate" +#define NM_SETTING_BOND_OPTION_PRIMARY "primary" +#define NM_SETTING_BOND_OPTION_PRIMARY_RESELECT "primary_reselect" +#define NM_SETTING_BOND_OPTION_FAIL_OVER_MAC "fail_over_mac" +#define NM_SETTING_BOND_OPTION_USE_CARRIER "use_carrier" +#define NM_SETTING_BOND_OPTION_AD_SELECT "ad_select" +#define NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY "xmit_hash_policy" +#define NM_SETTING_BOND_OPTION_RESEND_IGMP "resend_igmp" +#define NM_SETTING_BOND_OPTION_LACP_RATE "lacp_rate" + +struct _NMSettingBond { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBondClass; + +GType nm_setting_bond_get_type (void); + +NMSetting * nm_setting_bond_new (void); +guint32 nm_setting_bond_get_num_options (NMSettingBond *setting); +gboolean nm_setting_bond_get_option (NMSettingBond *setting, + guint32 idx, + const char **out_name, + const char **out_value); +const char * nm_setting_bond_get_option_by_name (NMSettingBond *setting, + const char *name); +gboolean nm_setting_bond_add_option (NMSettingBond *setting, + const char *name, + const char *value); +gboolean nm_setting_bond_remove_option (NMSettingBond *setting, + const char *name); + +gboolean nm_setting_bond_validate_option (const char *name, + const char *value); + +const char **nm_setting_bond_get_valid_options (NMSettingBond *setting); + +const char * nm_setting_bond_get_option_default (NMSettingBond *setting, + const char *name); + +G_END_DECLS + +#endif /* __NM_SETTING_BOND_H__ */ diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c new file mode 100644 index 00000000..763af37b --- /dev/null +++ b/libnm-core/nm-setting-bridge-port.c @@ -0,0 +1,321 @@ +/* -*- 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. + * + * Copyright 2012 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-setting-bridge-port.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-bridge.h" + +/** + * SECTION:nm-setting-bridge-port + * @short_description: Describes connection properties for bridge ports + * + * The #NMSettingBridgePort object is a #NMSetting subclass that describes + * optional properties that apply to bridge ports. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING, + _nm_register_setting (BRIDGE_PORT, 3)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BRIDGE_PORT) + +#define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate)) + +typedef struct { + guint16 priority; + guint16 path_cost; + gboolean hairpin_mode; +} NMSettingBridgePortPrivate; + +enum { + PROP_0, + PROP_PRIORITY, + PROP_PATH_COST, + PROP_HAIRPIN_MODE, + LAST_PROP +}; + +/**************************************************************************/ + +/** + * nm_setting_bridge_port_get_priority: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:priority property of the setting + **/ +guint16 +nm_setting_bridge_port_get_priority (NMSettingBridgePort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), 0); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting)->priority; +} + +/** + * nm_setting_bridge_port_get_path_cost: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:path-cost property of the setting + **/ +guint16 +nm_setting_bridge_port_get_path_cost (NMSettingBridgePort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), 0); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting)->path_cost; +} + +/** + * nm_setting_bridge_port_get_hairpin_mode: + * @setting: the #NMSettingBridgePort + * + * Returns: the #NMSettingBridgePort:hairpin-mode property of the setting + **/ +gboolean +nm_setting_bridge_port_get_hairpin_mode (NMSettingBridgePort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), FALSE); + + return NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting)->hairpin_mode; +} + +/**************************************************************************/ + +#define BR_MAX_PORT_PRIORITY 63 +#define BR_DEF_PRIORITY 32 + +#define BR_MIN_PATH_COST 1 +#define BR_MAX_PATH_COST 65535 + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting); + + if (priv->priority > BR_MAX_PORT_PRIORITY) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid value for the property (should be <= %d)"), + priv->priority, BR_MAX_PORT_PRIORITY); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_PORT_PRIORITY); + return FALSE; + } + + if (priv->path_cost > BR_MAX_PATH_COST) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid value for the property (should be <= %d)"), + priv->path_cost, BR_MAX_PATH_COST); + g_prefix_error (error, "%s.%s: ", + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_PORT_PATH_COST); + return FALSE; + } + + + if (connection) { + NMSettingConnection *s_con; + const char *slave_type; + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type (s_con); + if ( slave_type + && strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"), + NM_SETTING_BRIDGE_PORT_SETTING_NAME, + NM_SETTING_BRIDGE_SETTING_NAME, + slave_type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + + return TRUE; +} + +/**************************************************************************/ + +/** + * nm_setting_bridge_port_new: + * + * Creates a new #NMSettingBridgePort object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBridgePort object + **/ +NMSetting * +nm_setting_bridge_port_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_BRIDGE_PORT, NULL); +} + +static void +nm_setting_bridge_port_init (NMSettingBridgePort *setting) +{ +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PRIORITY: + priv->priority = (guint16) (g_value_get_uint (value) & 0xFFFF); + break; + case PROP_PATH_COST: + priv->path_cost = (guint16) (g_value_get_uint (value) & 0xFFFF); + break; + case PROP_HAIRPIN_MODE: + priv->hairpin_mode = g_value_get_boolean (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) +{ + NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PRIORITY: + g_value_set_uint (value, priv->priority); + break; + case PROP_PATH_COST: + g_value_set_uint (value, priv->path_cost); + break; + case PROP_HAIRPIN_MODE: + g_value_set_boolean (value, priv->hairpin_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_bridge_port_class_init (NMSettingBridgePortClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingBridgePortPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingBridgePort:priority: + * + * The Spanning Tree Protocol (STP) priority of this bridge port. + **/ + /* ---ifcfg-rh--- + * property: priority + * variable: BRIDGING_OPTS: priority= + * values: 0 - 63 + * default: 32 + * description: STP priority. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY, + g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PRIORITY, "", "", + 0, BR_MAX_PORT_PRIORITY, BR_DEF_PRIORITY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridgePort:path-cost: + * + * The Spanning Tree Protocol (STP) port cost for destinations via this + * port. + **/ + /* ---ifcfg-rh--- + * property: path-cost + * variable: BRIDGING_OPTS: path_cost= + * values: 1 - 65535 + * default: 100 + * description: STP cost. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PATH_COST, + g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PATH_COST, "", "", + 0, BR_MAX_PATH_COST, 100, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridgePort:hairpin-mode: + * + * Enables or disabled "hairpin mode" for the port, which allows frames to + * be sent back out through the port the frame was received on. + **/ + /* ---ifcfg-rh--- + * property: hairpin-mode + * variable: BRIDGING_OPTS: hairpin_mode= + * default: yes + * description: Hairpin mode of the bridge port. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_HAIRPIN_MODE, + g_param_spec_boolean (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "", "", + FALSE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-bridge-port.h b/libnm-core/nm-setting-bridge-port.h new file mode 100644 index 00000000..49ca38b3 --- /dev/null +++ b/libnm-core/nm-setting-bridge-port.h @@ -0,0 +1,69 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BRIDGE_PORT_H__ +#define __NM_SETTING_BRIDGE_PORT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BRIDGE_PORT (nm_setting_bridge_port_get_type ()) +#define NM_SETTING_BRIDGE_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePort)) +#define NM_SETTING_BRIDGE_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortClass)) +#define NM_IS_SETTING_BRIDGE_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_BRIDGE_PORT)) +#define NM_IS_SETTING_BRIDGE_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_BRIDGE_PORT)) +#define NM_SETTING_BRIDGE_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortClass)) + +#define NM_SETTING_BRIDGE_PORT_SETTING_NAME "bridge-port" + +#define NM_SETTING_BRIDGE_PORT_PRIORITY "priority" +#define NM_SETTING_BRIDGE_PORT_PATH_COST "path-cost" +#define NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE "hairpin-mode" + +struct _NMSettingBridgePort { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBridgePortClass; + +GType nm_setting_bridge_port_get_type (void); + +NMSetting * nm_setting_bridge_port_new (void); + +guint16 nm_setting_bridge_port_get_priority (NMSettingBridgePort *setting); + +guint16 nm_setting_bridge_port_get_path_cost (NMSettingBridgePort *setting); + +gboolean nm_setting_bridge_port_get_hairpin_mode (NMSettingBridgePort *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BRIDGE_PORT_H__ */ diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c new file mode 100644 index 00000000..51c6ac5a --- /dev/null +++ b/libnm-core/nm-setting-bridge.c @@ -0,0 +1,540 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-setting-bridge.h" +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-bridge + * @short_description: Describes connection properties for bridges + * + * The #NMSettingBridge object is a #NMSetting subclass that describes properties + * necessary for bridging connections. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING, + _nm_register_setting (BRIDGE, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BRIDGE) + +#define NM_SETTING_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE, NMSettingBridgePrivate)) + +typedef struct { + char * mac_address; + gboolean stp; + guint16 priority; + guint16 forward_delay; + guint16 hello_time; + guint16 max_age; + guint32 ageing_time; +} NMSettingBridgePrivate; + +enum { + PROP_0, + PROP_MAC_ADDRESS, + PROP_STP, + PROP_PRIORITY, + PROP_FORWARD_DELAY, + PROP_HELLO_TIME, + PROP_MAX_AGE, + PROP_AGEING_TIME, + LAST_PROP +}; + +/** + * nm_setting_bridge_new: + * + * Creates a new #NMSettingBridge object with default values. + * + * Returns: (transfer full): the new empty #NMSettingBridge object + **/ +NMSetting * +nm_setting_bridge_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_BRIDGE, NULL); +} + +/** + * nm_setting_bridge_get_mac_address: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:mac-address property of the setting + **/ +const char * +nm_setting_bridge_get_mac_address (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), NULL); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->mac_address; +} + +/** + * nm_setting_bridge_get_stp: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:stp property of the setting + **/ +gboolean +nm_setting_bridge_get_stp (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->stp; +} + +/** + * nm_setting_bridge_get_priority: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:priority property of the setting + **/ +guint16 +nm_setting_bridge_get_priority (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->priority; +} + +/** + * nm_setting_bridge_get_forward_delay: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:forward-delay property of the setting + **/ +guint16 +nm_setting_bridge_get_forward_delay (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->forward_delay; +} + +/** + * nm_setting_bridge_get_hello_time: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:hello-time property of the setting + **/ +guint16 +nm_setting_bridge_get_hello_time (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->hello_time; +} + +/** + * nm_setting_bridge_get_max_age: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:max-age property of the setting + **/ +guint16 +nm_setting_bridge_get_max_age (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->max_age; +} + +/** + * nm_setting_bridge_get_ageing_time: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:ageing-time property of the setting + **/ +guint +nm_setting_bridge_get_ageing_time (NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->ageing_time; +} + +/* IEEE 802.1D-1998 timer values */ +#define BR_MIN_HELLO_TIME 1 +#define BR_MAX_HELLO_TIME 10 + +#define BR_MIN_FORWARD_DELAY 2 +#define BR_MAX_FORWARD_DELAY 30 + +#define BR_MIN_MAX_AGE 6 +#define BR_MAX_MAX_AGE 40 + +/* IEEE 802.1D-1998 Table 7.4 */ +#define BR_MIN_AGEING_TIME 0 +#define BR_MAX_AGEING_TIME 1000000 + +static inline gboolean +check_range (guint32 val, + guint32 min, + guint32 max, + const char *prop, + GError **error) +{ + if ((val != 0) && (val < min || val > max)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value '%d' is out of range <%d-%d>"), + val, min, max); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, prop); + return FALSE; + } + return TRUE; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting); + + if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid MAC address")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS); + return FALSE; + } + + if (!check_range (priv->forward_delay, + BR_MIN_FORWARD_DELAY, + BR_MAX_FORWARD_DELAY, + NM_SETTING_BRIDGE_FORWARD_DELAY, + error)) + return FALSE; + + if (!check_range (priv->hello_time, + BR_MIN_HELLO_TIME, + BR_MAX_HELLO_TIME, + NM_SETTING_BRIDGE_HELLO_TIME, + error)) + return FALSE; + + if (!check_range (priv->max_age, + BR_MIN_MAX_AGE, + BR_MAX_MAX_AGE, + NM_SETTING_BRIDGE_MAX_AGE, + error)) + return FALSE; + + if (!check_range (priv->ageing_time, + BR_MIN_AGEING_TIME, + BR_MAX_AGEING_TIME, + NM_SETTING_BRIDGE_AGEING_TIME, + error)) + return FALSE; + + return _nm_connection_verify_required_interface_name (connection, error); +} + +static void +nm_setting_bridge_init (NMSettingBridge *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); + + g_free (priv->mac_address); + + G_OBJECT_CLASS (nm_setting_bridge_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_free (priv->mac_address); + priv->mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + break; + case PROP_STP: + priv->stp = g_value_get_boolean (value); + break; + case PROP_PRIORITY: + priv->priority = (guint16) g_value_get_uint (value); + break; + case PROP_FORWARD_DELAY: + priv->forward_delay = (guint16) g_value_get_uint (value); + break; + case PROP_HELLO_TIME: + priv->hello_time = (guint16) g_value_get_uint (value); + break; + case PROP_MAX_AGE: + priv->max_age = (guint16) g_value_get_uint (value); + break; + case PROP_AGEING_TIME: + priv->ageing_time = g_value_get_uint (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) +{ + NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); + NMSettingBridge *setting = NM_SETTING_BRIDGE (object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_value_set_string (value, nm_setting_bridge_get_mac_address (setting)); + break; + case PROP_STP: + g_value_set_boolean (value, priv->stp); + break; + case PROP_PRIORITY: + g_value_set_uint (value, priv->priority); + break; + case PROP_FORWARD_DELAY: + g_value_set_uint (value, priv->forward_delay); + break; + case PROP_HELLO_TIME: + g_value_set_uint (value, priv->hello_time); + break; + case PROP_MAX_AGE: + g_value_set_uint (value, priv->max_age); + break; + case PROP_AGEING_TIME: + g_value_set_uint (value, priv->ageing_time); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingBridgePrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingBridge:mac-address: + * + * If specified, the MAC address of bridge. When creating a new bridge, this + * MAC address will be set. When matching an existing (outside + * NetworkManager created) bridge, this MAC address must match. + **/ + /* ---keyfile--- + * property: mac-address + * format: ususal hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation, + * or semicolon separated list of 6 decimal bytes (obsolete) + * example: mac-address=00:22:68:12:79:A2 + * mac-address=0;34;104;18;121;162; + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: MACADDR(+) + * description: MAC address of the bridge. Note that this requires a recent + * kernel support, originally introduced in 3.15 upstream kernel) + * MACADDR for bridges is an NM extension. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_BRIDGE_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_BRIDGE_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingBridge:stp: + * + * Controls whether Spanning Tree Protocol (STP) is enabled for this bridge. + **/ + /* ---ifcfg-rh--- + * property: stp + * variable: STP + * default: no + * description: Span tree protocol participation. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_STP, + g_param_spec_boolean (NM_SETTING_BRIDGE_STP, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridge:priority: + * + * Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower + * values are "better"; the lowest priority bridge will be elected the root + * bridge. + **/ + /* ---ifcfg-rh--- + * property: priority + * variable: BRIDGING_OPTS: priority= + * values: 0 - 32768 + * default: 32768 + * description: STP priority. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY, + g_param_spec_uint (NM_SETTING_BRIDGE_PRIORITY, "", "", + 0, G_MAXUINT16, 0x8000, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridge:forward-delay: + * + * The Spanning Tree Protocol (STP) forwarding delay, in seconds. + **/ + /* ---ifcfg-rh--- + * property: forward-delay + * variable: DELAY + * values: 2 - 30 + * default: 15 + * description: STP forwarding delay. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_FORWARD_DELAY, + g_param_spec_uint (NM_SETTING_BRIDGE_FORWARD_DELAY, "", "", + 0, BR_MAX_FORWARD_DELAY, 15, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridge:hello-time: + * + * The Spanning Tree Protocol (STP) hello time, in seconds. + **/ + /* ---ifcfg-rh--- + * property: hello-time + * variable: BRIDGING_OPTS: hello_time= + * values: 1 - 10 + * default: 2 + * description: STP hello time. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_HELLO_TIME, + g_param_spec_uint (NM_SETTING_BRIDGE_HELLO_TIME, "", "", + 0, BR_MAX_HELLO_TIME, 2, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridge:max-age: + * + * The Spanning Tree Protocol (STP) maximum message age, in seconds. + **/ + /* ---ifcfg-rh--- + * property: max-age + * variable: BRIDGING_OPTS: max_age= + * values: 6 - 40 + * default: 20 + * description: STP maximum message age. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAX_AGE, + g_param_spec_uint (NM_SETTING_BRIDGE_MAX_AGE, "", "", + 0, BR_MAX_MAX_AGE, 20, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingBridge:ageing-time: + * + * The Ethernet MAC address aging time, in seconds. + **/ + /* ---ifcfg-rh--- + * property: ageing-time + * variable: BRIDGING_OPTS: ageing_time= + * values: 0 - 1000000 + * default: 300 + * description: Ethernet MAC ageing time. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_AGEING_TIME, + g_param_spec_uint (NM_SETTING_BRIDGE_AGEING_TIME, "", "", + 0, BR_MAX_AGEING_TIME, 300, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * bridge's interface name. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); +} diff --git a/libnm-core/nm-setting-bridge.h b/libnm-core/nm-setting-bridge.h new file mode 100644 index 00000000..b4fe7477 --- /dev/null +++ b/libnm-core/nm-setting-bridge.h @@ -0,0 +1,81 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_BRIDGE_H__ +#define __NM_SETTING_BRIDGE_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_BRIDGE (nm_setting_bridge_get_type ()) +#define NM_SETTING_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_BRIDGE, NMSettingBridge)) +#define NM_SETTING_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_BRIDGE, NMSettingBridgeClass)) +#define NM_IS_SETTING_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_BRIDGE)) +#define NM_IS_SETTING_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_BRIDGE)) +#define NM_SETTING_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_BRIDGE, NMSettingBridgeClass)) + +#define NM_SETTING_BRIDGE_SETTING_NAME "bridge" + +#define NM_SETTING_BRIDGE_MAC_ADDRESS "mac-address" +#define NM_SETTING_BRIDGE_STP "stp" +#define NM_SETTING_BRIDGE_PRIORITY "priority" +#define NM_SETTING_BRIDGE_FORWARD_DELAY "forward-delay" +#define NM_SETTING_BRIDGE_HELLO_TIME "hello-time" +#define NM_SETTING_BRIDGE_MAX_AGE "max-age" +#define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time" + +struct _NMSettingBridge { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingBridgeClass; + +GType nm_setting_bridge_get_type (void); + +NMSetting * nm_setting_bridge_new (void); + +const char * nm_setting_bridge_get_mac_address (NMSettingBridge *setting); + +gboolean nm_setting_bridge_get_stp (NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_priority (NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_forward_delay (NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_hello_time (NMSettingBridge *setting); + +guint16 nm_setting_bridge_get_max_age (NMSettingBridge *setting); + +guint32 nm_setting_bridge_get_ageing_time (NMSettingBridge *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_BRIDGE_H__ */ diff --git a/libnm-core/nm-setting-cdma.c b/libnm-core/nm-setting-cdma.c new file mode 100644 index 00000000..ebbbda74 --- /dev/null +++ b/libnm-core/nm-setting-cdma.c @@ -0,0 +1,336 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-cdma.h" +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-cdma + * @short_description: Describes CDMA-based mobile broadband properties + * + * The #NMSettingCdma object is a #NMSetting subclass that describes + * properties that allow connections to IS-95-based mobile broadband + * networks, including those using CDMA2000/EVDO technology. + */ + +G_DEFINE_TYPE_WITH_CODE (NMSettingCdma, nm_setting_cdma, NM_TYPE_SETTING, + _nm_register_setting (CDMA, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_CDMA) + +#define NM_SETTING_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CDMA, NMSettingCdmaPrivate)) + +typedef struct { + char *number; /* For dialing, duh */ + char *username; + char *password; + NMSettingSecretFlags password_flags; +} NMSettingCdmaPrivate; + +enum { + PROP_0, + PROP_NUMBER, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + + LAST_PROP +}; + +/** + * nm_setting_cdma_new: + * + * Creates a new #NMSettingCdma object with default values. + * + * Returns: the new empty #NMSettingCdma object + **/ +NMSetting * +nm_setting_cdma_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_CDMA, NULL); +} + +/** + * nm_setting_cdma_get_number: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:number property of the setting + **/ +const char * +nm_setting_cdma_get_number (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->number; +} + +/** + * nm_setting_cdma_get_username: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:username property of the setting + **/ +const char * +nm_setting_cdma_get_username (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->username; +} + +/** + * nm_setting_cdma_get_password: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingCdma:password property of the setting + **/ +const char * +nm_setting_cdma_get_password (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NULL); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->password; +} + +/** + * nm_setting_cdma_get_password_flags: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingCdma:password + **/ +NMSettingSecretFlags +nm_setting_cdma_get_password_flags (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->password_flags; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (setting); + + if (!priv->number) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_NUMBER); + return FALSE; + } else if (!strlen (priv->number)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty'")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_NUMBER); + return FALSE; + } + + if (priv->username && !strlen (priv->username)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_USERNAME); + return FALSE; + } + + if (priv->password && !strlen (priv->password)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CDMA_SETTING_NAME, NM_SETTING_CDMA_PASSWORD); + return FALSE; + } + + return TRUE; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (setting); + GPtrArray *secrets = NULL; + + if (priv->password) + return NULL; + + if (priv->username) { + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_CDMA_PASSWORD); + } + } + + return secrets; +} + +static void +nm_setting_cdma_init (NMSettingCdma *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (object); + + g_free (priv->number); + g_free (priv->username); + g_free (priv->password); + + G_OBJECT_CLASS (nm_setting_cdma_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_NUMBER: + g_free (priv->number); + priv->number = g_value_dup_string (value); + break; + case PROP_USERNAME: + g_free (priv->username); + priv->username = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (priv->password); + priv->password = g_value_dup_string (value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags (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) +{ + NMSettingCdma *setting = NM_SETTING_CDMA (object); + + switch (prop_id) { + case PROP_NUMBER: + g_value_set_string (value, nm_setting_cdma_get_number (setting)); + break; + case PROP_USERNAME: + g_value_set_string (value, nm_setting_cdma_get_username (setting)); + break; + case PROP_PASSWORD: + g_value_set_string (value, nm_setting_cdma_get_password (setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags (value, nm_setting_cdma_get_password_flags (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingCdmaPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + + /** + * NMSettingCdma:number: + * + * The number to dial to establish the connection to the CDMA-based mobile + * broadband network, if any. If not specified, the default number (#777) + * is used when required. + **/ + g_object_class_install_property + (object_class, PROP_NUMBER, + g_param_spec_string (NM_SETTING_CDMA_NUMBER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingCdma:username: + * + * The username used to authenticate with the network, if required. Many + * providers do not require a username, or accept any username. But if a + * username is required, it is specified here. + **/ + g_object_class_install_property + (object_class, PROP_USERNAME, + g_param_spec_string (NM_SETTING_CDMA_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingCdma:password: + * + * The password used to authenticate with the network, if required. Many + * providers do not require a password, or accept any password. But if a + * password is required, it is specified here. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_CDMA_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingCdma:password-flags: + * + * Flags indicating how to handle the #NMSettingCdma:password property. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_CDMA_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-cdma.h b/libnm-core/nm-setting-cdma.h new file mode 100644 index 00000000..6e333dcc --- /dev/null +++ b/libnm-core/nm-setting-cdma.h @@ -0,0 +1,69 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_CDMA_H__ +#define __NM_SETTING_CDMA_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_CDMA (nm_setting_cdma_get_type ()) +#define NM_SETTING_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_CDMA, NMSettingCdma)) +#define NM_SETTING_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_CDMA, NMSettingCdmaClass)) +#define NM_IS_SETTING_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_CDMA)) +#define NM_IS_SETTING_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_CDMA)) +#define NM_SETTING_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_CDMA, NMSettingCdmaClass)) + +#define NM_SETTING_CDMA_SETTING_NAME "cdma" + +#define NM_SETTING_CDMA_NUMBER "number" +#define NM_SETTING_CDMA_USERNAME "username" +#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_PASSWORD_FLAGS "password-flags" + +struct _NMSettingCdma { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingCdmaClass; + +GType nm_setting_cdma_get_type (void); + +NMSetting *nm_setting_cdma_new (void); +const char *nm_setting_cdma_get_number (NMSettingCdma *setting); +const char *nm_setting_cdma_get_username (NMSettingCdma *setting); +const char *nm_setting_cdma_get_password (NMSettingCdma *setting); +NMSettingSecretFlags nm_setting_cdma_get_password_flags (NMSettingCdma *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_CDMA_H__ */ diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c new file mode 100644 index 00000000..01f5d423 --- /dev/null +++ b/libnm-core/nm-setting-connection.c @@ -0,0 +1,1569 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-connection.h" +#include "nm-connection-private.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" + +/** + * SECTION:nm-setting-connection + * @short_description: Describes general connection properties + * + * The #NMSettingConnection object is a #NMSetting subclass that describes + * properties that apply to all #NMConnection objects, regardless of what type + * of network connection they describe. Each #NMConnection object must contain + * a #NMSettingConnection setting. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING, + _nm_register_setting (CONNECTION, 0)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_CONNECTION) + +#define NM_SETTING_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) + +typedef enum { + PERM_TYPE_USER = 0, +} PermType; + +typedef struct { + guint8 ptype; + char *item; +} Permission; + +typedef struct { + char *id; + char *uuid; + char *interface_name; + char *type; + char *master; + char *slave_type; + GSList *permissions; /* list of Permission structs */ + gboolean autoconnect; + gint autoconnect_priority; + guint64 timestamp; + gboolean read_only; + char *zone; + GSList *secondaries; /* secondary connections to activate with the base connection */ + guint gateway_ping_timeout; +} NMSettingConnectionPrivate; + +enum { + PROP_0, + PROP_ID, + PROP_UUID, + PROP_INTERFACE_NAME, + PROP_TYPE, + PROP_PERMISSIONS, + PROP_AUTOCONNECT, + PROP_AUTOCONNECT_PRIORITY, + PROP_TIMESTAMP, + PROP_READ_ONLY, + PROP_ZONE, + PROP_MASTER, + PROP_SLAVE_TYPE, + PROP_SECONDARIES, + PROP_GATEWAY_PING_TIMEOUT, + + LAST_PROP +}; + +/***********************************************************************/ + +#define PERM_USER_PREFIX "user:" + +static Permission * +permission_new_from_str (const char *str) +{ + Permission *p; + const char *last_colon; + size_t ulen = 0, i; + + g_return_val_if_fail (strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0, NULL); + str += strlen (PERM_USER_PREFIX); + + last_colon = strrchr (str, ':'); + if (last_colon) { + /* Ensure that somebody didn't pass "user::" */ + g_return_val_if_fail (last_colon > str, NULL); + + /* Reject :[detail] for now */ + g_return_val_if_fail (*(last_colon + 1) == '\0', NULL); + + /* Make sure we don't include detail in the username */ + ulen = last_colon - str; + } else + ulen = strlen (str); + + /* Sanity check the length of the username */ + g_return_val_if_fail (ulen < 100, NULL); + + /* Make sure there's no ':' in the username */ + for (i = 0; i < ulen; i++) + g_return_val_if_fail (str[i] != ':', NULL); + + /* And the username must be valid UTF-8 */ + g_return_val_if_fail (g_utf8_validate (str, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + if (last_colon) { + p->item = g_malloc (ulen + 1); + memcpy (p->item, str, ulen); + p->item[ulen] = '\0'; + } else + p->item = g_strdup (str); + + return p; +} + +static Permission * +permission_new (const char *uname) +{ + Permission *p; + + g_return_val_if_fail (uname, NULL); + g_return_val_if_fail (uname[0] != '\0', NULL); + g_return_val_if_fail (strchr (uname, ':') == NULL, NULL); + g_return_val_if_fail (g_utf8_validate (uname, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + p->item = g_strdup (uname); + return p; +} + +static char * +permission_to_string (Permission *p) +{ + return g_strdup_printf (PERM_USER_PREFIX "%s:", p->item); +} + +static void +permission_free (Permission *p) +{ + g_free (p->item); + memset (p, 0, sizeof (*p)); + g_slice_free (Permission, p); +} + +/***********************************************************************/ + +/** + * nm_setting_connection_new: + * + * Creates a new #NMSettingConnection object with default values. + * + * Returns: the new empty #NMSettingConnection object + **/ +NMSetting *nm_setting_connection_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_CONNECTION, NULL); +} + +/** + * nm_setting_connection_get_id: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:id property of the connection. + * + * Returns: the connection ID + **/ +const char * +nm_setting_connection_get_id (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->id; +} + +/** + * nm_setting_connection_get_uuid: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:uuid property of the connection. + * + * Returns: the connection UUID + **/ +const char * +nm_setting_connection_get_uuid (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->uuid; +} + +/** + * nm_setting_connection_get_interface_name: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:interface-name property of the connection. + * + * Returns: the connection's interface name + **/ +const char * +nm_setting_connection_get_interface_name (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->interface_name; +} + +/** + * nm_setting_connection_get_connection_type: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:type property of the connection. + * + * Returns: the connection type + **/ +const char * +nm_setting_connection_get_connection_type (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->type; +} + + +/** + * nm_setting_connection_get_num_permissions: + * @setting: the #NMSettingConnection + * + * Returns the number of entires in the #NMSettingConnection:permissions + * property of this setting. + * + * Returns: the number of permissions entires + */ +guint32 +nm_setting_connection_get_num_permissions (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions); +} + +/** + * nm_setting_connection_get_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permissions entry + * @out_ptype: on return, the permission type (at this time, always "user") + * @out_pitem: on return, the permission item (formatted accoring to @ptype, see + * #NMSettingConnection:permissions for more detail + * @out_detail: on return, the permission detail (at this time, always %NULL) + * + * Retrieve one of the entries of the #NMSettingConnection:permissions property + * of this setting. + * + * Returns: %TRUE if a permission was returned, %FALSE if @idx was invalid + */ +gboolean +nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + g_return_val_if_fail (idx < g_slist_length (priv->permissions), FALSE); + + p = g_slist_nth_data (priv->permissions, idx); + if (out_ptype) + *out_ptype = "user"; + if (out_pitem) + *out_pitem = p->item; + if (out_detail) + *out_detail = NULL; + + return TRUE; +} + +/** + * nm_setting_connection_permissions_user_allowed: + * @setting: the #NMSettingConnection + * @uname: the user name to check permissions for + * + * Checks whether the given username is allowed to view/access this connection. + * + * Returns: %TRUE if the requested user is allowed to view this connection, + * %FALSE if the given user is not allowed to view this connection + */ +gboolean +nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, + const char *uname) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (uname != NULL, FALSE); + g_return_val_if_fail (*uname != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + /* If no permissions, visible to all */ + if (priv->permissions == NULL) + return TRUE; + + /* Find the username in the permissions list */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + Permission *p = iter->data; + + if (strcmp (uname, p->item) == 0) + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_connection_add_permission: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Adds a permission to the connection's permission list. At this time, only + * the "user" permission type is supported, and @pitem must be a username. See + * #NMSettingConnection:permissions: for more details. + * + * Returns: %TRUE if the permission was unique and was successfully added to the + * list, %FALSE if @ptype or @pitem was invalid or it the permission was already + * present in the list + */ +gboolean +nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (ptype, FALSE); + g_return_val_if_fail (strlen (ptype) > 0, FALSE); + g_return_val_if_fail (detail == NULL, FALSE); + + /* Only "user" for now... */ + g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + /* No dupes */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (strcmp (pitem, p->item) == 0) + return FALSE; + } + + p = permission_new (pitem); + g_return_val_if_fail (p != NULL, FALSE); + priv->permissions = g_slist_append (priv->permissions, p); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS); + + return TRUE; +} + +/** + * nm_setting_connection_remove_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permission to remove + * + * Removes the permission at index @idx from the connection. + */ +void +nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_if_fail (NM_IS_SETTING_CONNECTION (setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + iter = g_slist_nth (priv->permissions, idx); + g_return_if_fail (iter != NULL); + + permission_free ((Permission *) iter->data); + priv->permissions = g_slist_delete_link (priv->permissions, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS); +} + +/** + * nm_setting_connection_remove_permission_by_value: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: (allow-none): unused at this time; must be %NULL + * + * Removes the permission from the connection. + * At this time, only the "user" permission type is supported, and @pitem must + * be a username. See #NMSettingConnection:permissions: for more details. + * + * Returns: %TRUE if the permission was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail) +{ + NMSettingConnectionPrivate *priv; + Permission *p; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (ptype, FALSE); + g_return_val_if_fail (strlen (ptype) > 0, FALSE); + g_return_val_if_fail (detail == NULL, FALSE); + + /* Only "user" for now... */ + g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (strcmp (pitem, p->item) == 0) { + permission_free ((Permission *) iter->data); + priv->permissions = g_slist_delete_link (priv->permissions, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_connection_get_autoconnect: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect property of the connection. + * + * Returns: the connection's autoconnect behavior + **/ +gboolean +nm_setting_connection_get_autoconnect (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect; +} + +/** + * nm_setting_connection_get_autoconnect_priority: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-priority property of the connection. + * The higher number, the higher priority. + * + * Returns: the connection's autoconnect priority + **/ +gint +nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_priority; +} + +/** + * nm_setting_connection_get_timestamp: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:timestamp property of the connection. + * + * Returns: the connection's timestamp + **/ +guint64 +nm_setting_connection_get_timestamp (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->timestamp; +} + +/** + * nm_setting_connection_get_read_only: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:read-only property of the connection. + * + * Returns: %TRUE if the connection is read-only, %FALSE if it is not + **/ +gboolean +nm_setting_connection_get_read_only (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), TRUE); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->read_only; +} + +/** + * nm_setting_connection_get_zone: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:zone property of the connection. + * + * Returns: the trust level of a connection + **/ +const char * +nm_setting_connection_get_zone (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->zone; +} + +/** + * nm_setting_connection_get_master: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:master property of the connection. + * + * Returns: interface name of the master device or UUID of the master + * connection. + */ +const char * +nm_setting_connection_get_master (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->master; +} + +/** + * nm_setting_connection_get_slave_type: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:slave-type property of the connection. + * + * Returns: the type of slave this connection is, if any + */ +const char * +nm_setting_connection_get_slave_type (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->slave_type; +} + +/** + * nm_setting_connection_is_slave_type: + * @setting: the #NMSettingConnection + * @type: the setting name (ie #NM_SETTING_BOND_SETTING_NAME) to be matched + * against @setting's slave type + * + * Returns: %TRUE if connection is of the given slave @type + */ +gboolean +nm_setting_connection_is_slave_type (NMSettingConnection *setting, + const char *type) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + + return !g_strcmp0 (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->slave_type, type); +} + +/** + * nm_setting_connection_get_num_secondaries: + * @setting: the #NMSettingConnection + * + * Returns: the number of configured secondary connection UUIDs + **/ +guint32 +nm_setting_connection_get_num_secondaries (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->secondaries); +} + +/** + * nm_setting_connection_get_secondary: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the secondary connection UUID entry + * + * Returns: the secondary connection UUID at index @idx + **/ +const char * +nm_setting_connection_get_secondary (NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + g_return_val_if_fail (idx <= g_slist_length (priv->secondaries), NULL); + + return (const char *) g_slist_nth_data (priv->secondaries, idx); +} + +/** + * nm_setting_connection_add_secondary: + * @setting: the #NMSettingConnection + * @sec_uuid: the secondary connection UUID to add + * + * Adds a new secondary connetion UUID to the setting. + * + * Returns: %TRUE if the secondary connection UUID was added; %FALSE if the UUID + * was already present + **/ +gboolean +nm_setting_connection_add_secondary (NMSettingConnection *setting, + const char *sec_uuid) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (sec_uuid != NULL, FALSE); + g_return_val_if_fail (sec_uuid[0] != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + for (iter = priv->secondaries; iter; iter = g_slist_next (iter)) { + if (!strcmp (sec_uuid, (char *) iter->data)) + return FALSE; + } + + priv->secondaries = g_slist_append (priv->secondaries, g_strdup (sec_uuid)); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES); + return TRUE; +} + +/** + * nm_setting_connection_remove_secondary: + * @setting: the #NMSettingConnection + * @idx: index number of the secondary connection UUID + * + * Removes the secondary coonnection UUID at index @idx. + **/ +void +nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_CONNECTION (setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + elt = g_slist_nth (priv->secondaries, idx); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->secondaries = g_slist_delete_link (priv->secondaries, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES); +} + +/** + * nm_setting_connection_remove_secondary_by_value: + * @setting: the #NMSettingConnection + * @sec_uuid: the secondary connection UUID to remove + * + * Removes the secondary coonnection UUID @sec_uuid. + * + * Returns: %TRUE if the secondary connection UUID was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting, + const char *sec_uuid) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (sec_uuid != NULL, FALSE); + g_return_val_if_fail (sec_uuid[0] != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + for (iter = priv->secondaries; iter; iter = g_slist_next (iter)) { + if (!strcmp (sec_uuid, (char *) iter->data)) { + priv->secondaries = g_slist_delete_link (priv->secondaries, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_connection_get_gateway_ping_timeout: + * @setting: the #NMSettingConnection + * + * Returns: the value contained in the #NMSettingConnection:gateway-ping-timeout + * property. + **/ +guint32 +nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->gateway_ping_timeout; +} + +static void +_set_error_missing_base_setting (GError **error, const char *type) +{ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting required for connection of type '%s'"), + type); + g_prefix_error (error, "%s: ", type); +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + gboolean is_slave; + const char *slave_setting_type = NULL; + NMSetting *normerr_base_type = NULL; + const char *normerr_slave_setting_type = NULL; + const char *normerr_missing_slave_type = NULL; + const char *normerr_missing_slave_type_port = NULL; + gboolean normerr_base_setting = FALSE; + + if (!priv->id) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID); + return FALSE; + } else if (!priv->id[0]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID); + return FALSE; + } + + if (priv->uuid && !nm_utils_is_uuid (priv->uuid)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid UUID"), + priv->uuid); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID); + return FALSE; + } + + if (priv->interface_name) { + if (!nm_utils_iface_valid_name (priv->interface_name)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + priv->interface_name); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } + + if (!priv->type) { + if (!connection || !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + } else { + GType base_type; + + if (!priv->type[0]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + + base_type = nm_setting_lookup_type (priv->type); + if (base_type == G_TYPE_INVALID || !_nm_setting_type_is_base_type (base_type)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection type '%s' is not valid"), + priv->type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE); + return FALSE; + } + + /* Make sure the corresponding 'type' item is present */ + if ( connection + && !nm_connection_get_setting_by_name (connection, priv->type)) { + NMSetting *s_base; + NMConnection *connection2; + + s_base = g_object_new (base_type, NULL); + connection2 = nm_simple_connection_new_clone (connection); + nm_connection_add_setting (connection2, s_base); + + normerr_base_setting = nm_setting_verify (s_base, connection2, NULL); + + g_object_unref (connection2); + + if (!normerr_base_setting) { + _set_error_missing_base_setting (error, priv->type); + return FALSE; + } + } + } + + is_slave = FALSE; + if (priv->slave_type) + is_slave = _nm_setting_slave_type_is_valid (priv->slave_type, &slave_setting_type); + + if (priv->slave_type && !is_slave) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown slave type '%s'"), priv->slave_type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + + if (is_slave) { + if (!priv->master) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Slave connections need a valid '%s' property"), NM_SETTING_CONNECTION_MASTER); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER); + return FALSE; + } + if ( slave_setting_type + && connection + && !nm_connection_get_setting_by_name (connection, slave_setting_type)) + normerr_slave_setting_type = slave_setting_type; + } else { + if (priv->master) { + const char *slave_type; + NMSetting *s_port; + + if ( connection + && (slave_type = _nm_connection_detect_slave_type (connection, &s_port))) { + normerr_missing_slave_type = slave_type; + normerr_missing_slave_type_port = nm_setting_get_name (s_port); + } else { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Cannot set '%s' without '%s'"), + NM_SETTING_CONNECTION_MASTER, NM_SETTING_CONNECTION_SLAVE_TYPE); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + } + + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + if (!priv->uuid) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_base_type) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property type should be set to '%s'"), + nm_setting_get_name (normerr_base_type)); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_base_setting) { + _set_error_missing_base_setting (error, priv->type); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_slave_setting_type) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("slave-type '%s' requires a '%s' setting in the connection"), + priv->slave_type, normerr_slave_setting_type); + g_prefix_error (error, "%s: ", normerr_slave_setting_type); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + if (normerr_missing_slave_type) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("Detect a slave connection with '%s' set and a port type '%s'. '%s' should be set to '%s'"), + NM_SETTING_CONNECTION_MASTER, normerr_missing_slave_type_port, + NM_SETTING_CONNECTION_SLAVE_TYPE, normerr_missing_slave_type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +static const char * +find_virtual_interface_name (GVariant *connection_dict) +{ + GVariant *setting_dict; + const char *interface_name; + + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BOND_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BRIDGE_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_TEAM_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + + if (!setting_dict) + return NULL; + + /* All of the deprecated virtual interface name properties were named "interface-name". */ + if (!g_variant_lookup (setting_dict, "interface-name", "&s", &interface_name)) + return NULL; + + return interface_name; +} + +static void +nm_setting_connection_set_interface_name (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + const char *interface_name; + + /* For compatibility reasons, if there is an invalid virtual interface name, + * we need to make verification fail, even if that virtual name would be + * overridden by a valid connection.interface-name. + */ + interface_name = find_virtual_interface_name (connection_dict); + if (!interface_name || nm_utils_iface_valid_name (interface_name)) + interface_name = g_variant_get_string (value, NULL); + + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, + NULL); +} + +static void +nm_setting_connection_no_interface_name (NMSetting *setting, + GVariant *connection_dict, + const char *property) +{ + const char *virtual_interface_name; + + virtual_interface_name = find_virtual_interface_name (connection_dict); + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_INTERFACE_NAME, virtual_interface_name, + NULL); +} + +static gboolean +compare_property (NMSetting *setting, + NMSetting *other, + const GParamSpec *prop_spec, + NMSettingCompareFlags flags) +{ + /* Handle ignore ID */ + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID) + && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_ID) == 0) + return TRUE; + + /* Handle ignore timestamp */ + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP) + && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_TIMESTAMP) == 0) + return TRUE; + + /* Otherwise chain up to parent to handle generic compare */ + return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags); +} + +static void +nm_setting_connection_init (NMSettingConnection *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object); + + g_free (priv->id); + g_free (priv->uuid); + g_free (priv->interface_name); + g_free (priv->type); + g_free (priv->zone); + g_free (priv->master); + g_free (priv->slave_type); + g_slist_free_full (priv->permissions, (GDestroyNotify) permission_free); + g_slist_free_full (priv->secondaries, g_free); + + G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); +} + +static GSList * +perm_strv_to_permlist (char **strv) +{ + GSList *list = NULL; + int i; + + if (!strv) + return NULL; + + for (i = 0; strv[i]; i++) { + Permission *p; + + p = permission_new_from_str (strv[i]); + if (p) + list = g_slist_append (list, p); + } + + return list; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_ID: + g_free (priv->id); + priv->id = g_value_dup_string (value); + break; + case PROP_UUID: + g_free (priv->uuid); + priv->uuid = g_value_dup_string (value); + break; + case PROP_INTERFACE_NAME: + g_free (priv->interface_name); + priv->interface_name = g_value_dup_string (value); + break; + case PROP_TYPE: + g_free (priv->type); + priv->type = g_value_dup_string (value); + break; + case PROP_PERMISSIONS: + g_slist_free_full (priv->permissions, (GDestroyNotify) permission_free); + priv->permissions = perm_strv_to_permlist (g_value_get_boxed (value)); + break; + case PROP_AUTOCONNECT: + priv->autoconnect = g_value_get_boolean (value); + break; + case PROP_AUTOCONNECT_PRIORITY: + priv->autoconnect_priority = g_value_get_int (value); + break; + case PROP_TIMESTAMP: + priv->timestamp = g_value_get_uint64 (value); + break; + case PROP_READ_ONLY: + priv->read_only = g_value_get_boolean (value); + break; + case PROP_ZONE: + g_free (priv->zone); + priv->zone = g_value_dup_string (value); + break; + case PROP_MASTER: + g_free (priv->master); + priv->master = g_value_dup_string (value); + break; + case PROP_SLAVE_TYPE: + g_free (priv->slave_type); + priv->slave_type = g_value_dup_string (value); + break; + case PROP_SECONDARIES: + g_slist_free_full (priv->secondaries, g_free); + priv->secondaries = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_GATEWAY_PING_TIMEOUT: + priv->gateway_ping_timeout = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static char ** +perm_permlist_to_strv (GSList *permlist) +{ + GPtrArray *strings; + GSList *iter; + + strings = g_ptr_array_new (); + for (iter = permlist; iter; iter = g_slist_next (iter)) + g_ptr_array_add (strings, permission_to_string ((Permission *) iter->data)); + g_ptr_array_add (strings, NULL); + + return (char **) g_ptr_array_free (strings, FALSE); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingConnection *setting = NM_SETTING_CONNECTION (object); + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_ID: + g_value_set_string (value, nm_setting_connection_get_id (setting)); + break; + case PROP_UUID: + g_value_set_string (value, nm_setting_connection_get_uuid (setting)); + break; + case PROP_INTERFACE_NAME: + g_value_set_string (value, nm_setting_connection_get_interface_name (setting)); + break; + case PROP_TYPE: + g_value_set_string (value, nm_setting_connection_get_connection_type (setting)); + break; + case PROP_PERMISSIONS: + g_value_take_boxed (value, perm_permlist_to_strv (priv->permissions)); + break; + case PROP_AUTOCONNECT: + g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); + break; + case PROP_AUTOCONNECT_PRIORITY: + g_value_set_int (value, nm_setting_connection_get_autoconnect_priority (setting)); + break; + case PROP_TIMESTAMP: + g_value_set_uint64 (value, nm_setting_connection_get_timestamp (setting)); + break; + case PROP_READ_ONLY: + g_value_set_boolean (value, nm_setting_connection_get_read_only (setting)); + break; + case PROP_ZONE: + g_value_set_string (value, nm_setting_connection_get_zone (setting)); + break; + case PROP_MASTER: + g_value_set_string (value, nm_setting_connection_get_master (setting)); + break; + case PROP_SLAVE_TYPE: + g_value_set_string (value, nm_setting_connection_get_slave_type (setting)); + break; + case PROP_SECONDARIES: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->secondaries)); + break; + case PROP_GATEWAY_PING_TIMEOUT: + g_value_set_uint (value, priv->gateway_ping_timeout); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingConnectionPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + parent_class->compare_property = compare_property; + + /* Properties */ + + /** + * NMSettingConnection:id: + * + * A human readable unique identifier for the connection, like "Work Wi-Fi" + * or "T-Mobile 3G". + **/ + /* ---ifcfg-rh--- + * property: id + * variable: NAME(+) + * description: User friendly name for the connection profile. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_string (NM_SETTING_CONNECTION_ID, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:uuid: + * + * A universally unique identifier for the connection, for example generated + * with libuuid. It should be assigned when the connection is created, and + * never changed as long as the connection still applies to the same + * network. For example, it should not be changed when the + * #NMSettingConnection:id property or #NMSettingIP4Config changes, but + * might need to be re-created when the Wi-Fi SSID, mobile broadband network + * provider, or #NMSettingConnection:type property changes. + * + * The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" + * (ie, contains only hexadecimal characters and "-"). A suitable UUID may + * be generated by nm_utils_uuid_generate() or + * nm_utils_uuid_generate_from_string(). + **/ + /* ---ifcfg-rh--- + * property: uuid + * variable: UUID(+) + * description: UUID for the connection profile. When missing, NetworkManager + * creates the UUID itself (by hashing the file). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_UUID, + g_param_spec_string (NM_SETTING_CONNECTION_UUID, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:interface-name: + * + * The name of the network interface this connection is bound to. If not + * set, then the connection can be attached to any interface of the + * appropriate type (subject to restrictions imposed by other settings). + * + * For software devices this specifies the name of the created device. + * + * For connection types where interface names cannot easily be made + * persistent (e.g. mobile broadband or USB Ethernet), this property should + * not be used. Setting this property restricts the interfaces a connection + * can be used with, and if interface names change or are reordered the + * connection may be applied to the wrong interface. + **/ + /* ---ifcfg-rh--- + * property: interface-name + * variable: DEVICE + * description: Interface name of the device this profile is bound to. The variable + * can be left out when the profile should apply for more devices. Note that DEVICE + * can be required for some connection types. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_INTERFACE_NAME, + g_param_spec_string (NM_SETTING_CONNECTION_INTERFACE_NAME, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_override_property (parent_class, NM_SETTING_CONNECTION_INTERFACE_NAME, + G_VARIANT_TYPE_STRING, + NULL, + nm_setting_connection_set_interface_name, + nm_setting_connection_no_interface_name); + + /** + * NMSettingConnection:type: + * + * Base type of the connection. For hardware-dependent connections, should + * contain the setting name of the hardware-type specific setting (ie, + * "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for + * non-hardware dependent connections like VPN or otherwise, should contain + * the setting name of that setting type (ie, "vpn" or "bridge", etc). + **/ + /* ---ifcfg-rh--- + * property: type + * variable: TYPE (DEVICETYPE, DEVICE) + * values: Ethernet, Wireless, InfiniBand, Bridge, Bond, Vlan, Team, TeamPort + * description: Base type of the connection. DEVICETYPE is used for teaming + * connections. + * example: TYPE=Ethernet; TYPE=Bond; TYPE=Bridge; DEVICETYPE=TeamPort + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_SETTING_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:permissions: + * + * An array of strings defining what access a given user has to this + * connection. If this is %NULL or empty, all users are allowed to access + * this connection. Otherwise a user is allowed to access this connection + * if and only if they are in this list. Each entry is of the form + * "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". + * + * At this time only the "user" [type] is allowed. Any other values are + * ignored and reserved for future use. [id] is the username that this + * permission refers to, which may not contain the ":" character. Any + * [reserved] information present must be ignored and is reserved for future + * use. All of [type], [id], and [reserved] must be valid UTF-8. + */ + /* ---ifcfg-rh--- + * property: permissions + * variable: USERS(+) + * description: USERS restrict the access for this conenction to certain + * users only. + * example: USERS="joe bob" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PERMISSIONS, + g_param_spec_boxed (NM_SETTING_CONNECTION_PERMISSIONS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:autoconnect: + * + * Whether or not the connection should be automatically connected by + * NetworkManager when the resources for the connection are available. + * %TRUE to automatically activate the connection, %FALSE to require manual + * intervention to activate the connection. + **/ + /* ---ifcfg-rh--- + * property: autoconnect + * variable: ONBOOT + * default: yes + * description: Whether the connection should be autoconnected (not only while booting). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_AUTOCONNECT, + g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:autoconnect-priority: + * + * The autoconnect priority. If the connection is set to autoconnect, + * connections with higher priority will be preferred. Defaults to 0. + * The higher number means higher priority. + **/ + /* ---ifcfg-rh--- + * property: autoconnect-priority + * variable: AUTOCONNECT_PRIORITY(+) + * values: -999 to 999 + * default: 0 + * description: Connection priority for automatic activation. Connections with + * higher numbers are preferred when selecting profiles for automatic activation. + * example: AUTOCONNECT_PRIORITY=20 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_AUTOCONNECT_PRIORITY, + g_param_spec_int (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, "", "", + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:timestamp: + * + * The time, in seconds since the Unix Epoch, that the connection was last + * _successfully_ fully activated. + * + * NetworkManager updates the connection timestamp periodically when the + * connection is active to ensure that an active connection has the latest + * timestamp. The property is only meant for reading (changes to this + * property will not be preserved). + **/ + g_object_class_install_property + (object_class, PROP_TIMESTAMP, + g_param_spec_uint64 (NM_SETTING_CONNECTION_TIMESTAMP, "", "", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:read-only: + * + * %FALSE if the connection can be modified using the provided settings + * service's D-Bus interface with the right privileges, or %TRUE if the + * connection is read-only and cannot be modified. + **/ + g_object_class_install_property + (object_class, PROP_READ_ONLY, + g_param_spec_boolean (NM_SETTING_CONNECTION_READ_ONLY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:zone: + * + * The trust level of a the connection. Free form case-insensitive string + * (for example "Home", "Work", "Public"). %NULL or unspecified zone means + * the connection will be placed in the default zone as defined by the + * firewall. + **/ + /* ---ifcfg-rh--- + * property: zone + * variable: ZONE(+) + * description: Trust level of this connection. The string is usually used + * for a firewall. + * example: ZONE=Work + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ZONE, + g_param_spec_string (NM_SETTING_CONNECTION_ZONE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:master: + * + * Interface name of the master device or UUID of the master connection. + **/ + /* ---ifcfg-rh--- + * property: master + * variable: MASTER, TEAM_MASTER, BRIDGE + * description: Reference to master connection. The variable used depends on + * the connection type. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MASTER, + g_param_spec_string (NM_SETTING_CONNECTION_MASTER, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:slave-type: + * + * Setting name of the device type of this slave's master connection (eg, + * %NM_SETTING_BOND_SETTING_NAME), or %NULL if this connection is not a + * slave. + **/ + /* ---ifcfg-rh--- + * property: slave-type + * variable: MASTER, TEAM_MASTER, DEVICETYPE, BRIDGE + * description: Slave type doesn't map directly to a variable, but it is + * recognized using different variables. MASTER for bonding, + * TEAM_MASTER and DEVICETYPE for teaming, BRIDGE for bridging. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SLAVE_TYPE, + g_param_spec_string (NM_SETTING_CONNECTION_SLAVE_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:secondaries: + * + * List of connection UUIDs that should be activated when the base + * connection itself is activated. Currently only VPN connections are + * supported. + **/ + /* ---ifcfg-rh--- + * property: secondaries + * variable: SECONDARY_UUIDS(+) + * description: UUID of VPN connections that should be activated + * together with this connection. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SECONDARIES, + g_param_spec_boxed (NM_SETTING_CONNECTION_SECONDARIES, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingConnection:gateway-ping-timeout: + * + * If greater than zero, delay success of IP addressing until either the + * timeout is reached, or an IP gateway replies to a ping. + **/ + /* ---ifcfg-rh--- + * property: gateway-ping-timeout + * variable: GATEWAY_PING_TIMEOUT(+) + * default: 0 + * description: If greater than zero, the IP connectivity will be checked by + * pinging the gateway and waiting for the specified timeout (in seconds). + * example: GATEWAY_PING_TIMEOUT=5 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_GATEWAY_PING_TIMEOUT, + g_param_spec_uint (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, "", "", + 0, 30, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-connection.h b/libnm-core/nm-setting-connection.h new file mode 100644 index 00000000..d1ad0fe1 --- /dev/null +++ b/libnm-core/nm-setting-connection.h @@ -0,0 +1,125 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_CONNECTION_H__ +#define __NM_SETTING_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_CONNECTION (nm_setting_connection_get_type ()) +#define NM_SETTING_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnection)) +#define NM_SETTING_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) +#define NM_IS_SETTING_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_CONNECTION)) +#define NM_IS_SETTING_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_CONNECTION)) +#define NM_SETTING_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionClass)) + +#define NM_SETTING_CONNECTION_SETTING_NAME "connection" + +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN -999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX 999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT 0 + +#define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" +#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY "autoconnect-priority" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" +#define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" +#define NM_SETTING_CONNECTION_ZONE "zone" +#define NM_SETTING_CONNECTION_MASTER "master" +#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" +#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" +#define NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT "gateway-ping-timeout" + +/** + * NMSettingConnection: + * + * The NMSettingConnection struct contains only private data. + * It should only be accessed through the functions described below. + */ +struct _NMSettingConnection { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingConnectionClass; + +GType nm_setting_connection_get_type (void); + +NMSetting * nm_setting_connection_new (void); +const char *nm_setting_connection_get_id (NMSettingConnection *setting); +const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); +const char *nm_setting_connection_get_interface_name (NMSettingConnection *setting); +const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); +gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); +gint nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting); +guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); +gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); + +guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); +gboolean nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail); +const char *nm_setting_connection_get_zone (NMSettingConnection *setting); +gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); +gboolean nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail); +void nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx); +gboolean nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail); + +const char *nm_setting_connection_get_master (NMSettingConnection *setting); +gboolean nm_setting_connection_is_slave_type (NMSettingConnection *setting, + const char *type); +const char *nm_setting_connection_get_slave_type (NMSettingConnection *setting); + +guint32 nm_setting_connection_get_num_secondaries (NMSettingConnection *setting); +const char *nm_setting_connection_get_secondary (NMSettingConnection *setting, guint32 idx); +gboolean nm_setting_connection_add_secondary (NMSettingConnection *setting, const char *sec_uuid); +void nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 idx); +gboolean nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting, const char *sec_uuid); + +guint32 nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_CONNECTION_H__ */ diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c new file mode 100644 index 00000000..a4fa00c8 --- /dev/null +++ b/libnm-core/nm-setting-dcb.c @@ -0,0 +1,1280 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-dcb.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-dcb + * @short_description: Connection properties for Data Center Bridging + * + * The #NMSettingDcb object is a #NMSetting subclass that describes properties + * for enabling and using Data Center Bridging (DCB) on Ethernet networks. + * DCB is a set of protocols (including 802.1Qbb, 802.1Qaz, 802.1Qau, and + * 802.1AB) to eliminate packet loss in Ethernet networks and support the use + * of storage technologies like Fibre Channel over Ethernet (FCoE) and iSCSI. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING, + _nm_register_setting (DCB, 2)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_DCB) + +#define NM_SETTING_DCB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate)) + +typedef struct { + NMSettingDcbFlags app_fcoe_flags; + gint app_fcoe_priority; + const char * app_fcoe_mode; + + NMSettingDcbFlags app_iscsi_flags; + gint app_iscsi_priority; + + NMSettingDcbFlags app_fip_flags; + gint app_fip_priority; + + /* Priority Flow Control */ + NMSettingDcbFlags pfc_flags; + guint pfc[8]; + + /* Priority Groups */ + NMSettingDcbFlags priority_group_flags; + guint priority_group_id[8]; + guint priority_group_bandwidth[8]; + guint priority_bandwidth[8]; + guint priority_strict[8]; + guint priority_traffic_class[8]; +} NMSettingDcbPrivate; + +enum { + PROP_0, + PROP_APP_FCOE_FLAGS, + PROP_APP_FCOE_PRIORITY, + PROP_APP_FCOE_MODE, + + PROP_APP_ISCSI_FLAGS, + PROP_APP_ISCSI_PRIORITY, + + PROP_APP_FIP_FLAGS, + PROP_APP_FIP_PRIORITY, + + PROP_PFC_FLAGS, + PROP_PFC, + + PROP_PRIORITY_GROUP_FLAGS, + PROP_PRIORITY_GROUP_ID, + PROP_PRIORITY_GROUP_BANDWIDTH, + PROP_PRIORITY_BANDWIDTH, + PROP_PRIORITY_STRICT, + PROP_PRIORITY_TRAFFIC_CLASS, + + LAST_PROP +}; + +/** + * nm_setting_dcb_new: + * + * Creates a new #NMSettingDcb object with default values. + * + * Returns: (transfer full): the new empty #NMSettingDcb object + **/ +NMSetting * +nm_setting_dcb_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_DCB, NULL); +} + +/** + * nm_setting_dcb_get_app_fcoe_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_fcoe_flags (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_flags; +} + +/** + * nm_setting_dcb_get_app_fcoe_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-priority property of the setting + **/ +gint +nm_setting_dcb_get_app_fcoe_priority (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_priority; +} + +/** + * nm_setting_dcb_get_app_fcoe_mode: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fcoe-mode property of the setting + **/ +const char * +nm_setting_dcb_get_app_fcoe_mode (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), NULL); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_mode; +} + +/** + * nm_setting_dcb_get_app_iscsi_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-iscsi-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_iscsi_flags (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_iscsi_flags; +} + +/** + * nm_setting_dcb_get_app_iscsi_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-iscsi-priority property of the setting + **/ +gint +nm_setting_dcb_get_app_iscsi_priority (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_iscsi_priority; +} + +/** + * nm_setting_dcb_get_app_fip_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fip-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_app_fip_flags (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fip_flags; +} + +/** + * nm_setting_dcb_get_app_fip_priority: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:app-fip-priority property of the setting + **/ +gint +nm_setting_dcb_get_app_fip_priority (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fip_priority; +} + +/** + * nm_setting_dcb_get_priority_flow_control_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:priority-flow-control-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_priority_flow_control_flags (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->pfc_flags; +} + +/** + * nm_setting_dcb_get_priority_flow_control: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve flow control for + * + * Returns: %TRUE if flow control is enabled for the given @user_priority, + * %FALSE if not enabled + **/ +gboolean +nm_setting_dcb_get_priority_flow_control (NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), FALSE); + g_return_val_if_fail (user_priority <= 7, FALSE); + + return !!NM_SETTING_DCB_GET_PRIVATE (setting)->pfc[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_flow_control: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set flow control for + * @enabled: %TRUE to enable flow control for this priority, %FALSE to disable it + * + * These values are only valid when #NMSettingDcb:priority-flow-control includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_flow_control (NMSettingDcb *setting, + guint user_priority, + gboolean enabled) +{ + NMSettingDcbPrivate *priv; + guint uint_enabled = enabled ? 1 : 0; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (user_priority <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->pfc[user_priority] != uint_enabled) { + priv->pfc[user_priority] = uint_enabled; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL); + } +} + +/** + * nm_setting_dcb_get_priority_group_flags: + * @setting: the #NMSettingDcb + * + * Returns: the #NMSettingDcb:priority-group-flags property of the setting + **/ +NMSettingDcbFlags +nm_setting_dcb_get_priority_group_flags (NMSettingDcb *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_flags; +} + +/** + * nm_setting_dcb_get_priority_group_id: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the group ID for + * + * Returns: the group number @user_priority is assigned to. These values are + * only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_group_id (NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + g_return_val_if_fail (user_priority <= 7, 0); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_id[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_group_id: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set flow control for + * @group_id: the group (0 - 7) to assign @user_priority to, or 15 for the + * unrestricted group. + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_group_id (NMSettingDcb *setting, + guint user_priority, + guint group_id) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (user_priority <= 7); + g_return_if_fail (group_id <= 7 || group_id == 15); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->priority_group_id[user_priority] != group_id) { + priv->priority_group_id[user_priority] = group_id; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_GROUP_ID); + } +} + +/** + * nm_setting_dcb_get_priority_group_bandwidth: + * @setting: the #NMSettingDcb + * @group_id: the priority group (0 - 7) to retrieve the bandwidth percentage for + * + * Returns: the bandwidth percentage assigned to @group_id. These values are + * only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_group_bandwidth (NMSettingDcb *setting, guint group_id) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + g_return_val_if_fail (group_id <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_bandwidth[group_id]; +} + +/** + * nm_setting_dcb_set_priority_group_bandwidth: + * @setting: the #NMSettingDcb + * @group_id: the priority group (0 - 7) to set the bandwidth percentage for + * @bandwidth_percent: the bandwidth percentage (0 - 100) to assign to @group_id to + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_group_bandwidth (NMSettingDcb *setting, + guint group_id, + guint bandwidth_percent) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (group_id <= 7); + g_return_if_fail (bandwidth_percent <= 100); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->priority_group_bandwidth[group_id] != bandwidth_percent) { + priv->priority_group_bandwidth[group_id] = bandwidth_percent; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the group bandwidth percentage for + * + * Returns: the allowed bandwidth percentage of @user_priority in its priority group. + * These values are only valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_bandwidth (NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + g_return_val_if_fail (user_priority <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_bandwidth[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for + * @bandwidth_percent: the bandwidth percentage (0 - 100) that @user_priority is + * allowed to use within its priority group + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_bandwidth (NMSettingDcb *setting, + guint user_priority, + guint bandwidth_percent) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (user_priority <= 7); + g_return_if_fail (bandwidth_percent <= 100); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->priority_bandwidth[user_priority] != bandwidth_percent) { + priv->priority_bandwidth[user_priority] = bandwidth_percent; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_strict_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve strict bandwidth for + * + * Returns: %TRUE if @user_priority may use all of the bandwidth allocated to its + * assigned group, or %FALSE if not. These values are only valid when + * #NMSettingDcb:priority-group-flags includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +gboolean +nm_setting_dcb_get_priority_strict_bandwidth (NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + g_return_val_if_fail (user_priority <= 7, FALSE); + + return !!NM_SETTING_DCB_GET_PRIVATE (setting)->priority_strict[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_strict_bandwidth: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set strict bandwidth for + * @strict: %TRUE to allow @user_priority to use all the bandwidth allocated to + * its priority group, or %FALSE if not + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_strict_bandwidth (NMSettingDcb *setting, + guint user_priority, + gboolean strict) +{ + NMSettingDcbPrivate *priv; + guint uint_strict = strict ? 1 : 0; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (user_priority <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->priority_strict[user_priority] != uint_strict) { + priv->priority_strict[user_priority] = uint_strict; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH); + } +} + +/** + * nm_setting_dcb_get_priority_traffic_class: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to retrieve the traffic class for + * + * Returns: the traffic class assigned to @user_priority. These values are only + * valid when #NMSettingDcb:priority-group-flags includes the + * %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +guint +nm_setting_dcb_get_priority_traffic_class (NMSettingDcb *setting, guint user_priority) +{ + g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0); + g_return_val_if_fail (user_priority <= 7, FALSE); + + return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_traffic_class[user_priority]; +} + +/** + * nm_setting_dcb_set_priority_traffic_clas: + * @setting: the #NMSettingDcb + * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for + * @traffic_class: the traffic_class (0 - 7) that @user_priority should map to + * + * These values are only valid when #NMSettingDcb:priority-group-flags includes + * the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ +void +nm_setting_dcb_set_priority_traffic_class (NMSettingDcb *setting, + guint user_priority, + guint traffic_class) +{ + NMSettingDcbPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_DCB (setting)); + g_return_if_fail (user_priority <= 7); + g_return_if_fail (traffic_class <= 7); + + priv = NM_SETTING_DCB_GET_PRIVATE (setting); + if (priv->priority_traffic_class[user_priority] != traffic_class) { + priv->priority_traffic_class[user_priority] = traffic_class; + g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS); + } +} + +/******************************************************************/ + +#define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \ + NM_SETTING_DCB_FLAG_ADVERTISE | \ + NM_SETTING_DCB_FLAG_WILLING) + +static gboolean +check_dcb_flags (NMSettingDcbFlags flags, const char *prop_name, GError **error) +{ + if (flags & ~DCB_FLAGS_ALL) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (flags & ~NM_SETTING_DCB_FLAG_ENABLE)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags invalid - disabled")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +check_uint_array (const guint *array, + guint len, + NMSettingDcbFlags flags, + guint max, + guint extra, + gboolean sum_pct, + const char *prop_name, + GError **error) +{ + guint i, sum = 0; + + /* Ensure each element is <= to max or equals extra */ + for (i = 0; i < len; i++) { + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && array[i]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid (not enabled)")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if ((array[i] > max) && (array[i] != extra)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("element invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + sum += array[i]; + } + + /* Verify sum of percentages */ + if (sum_pct) { + if (flags & NM_SETTING_DCB_FLAG_ENABLE) { + /* If the feature is enabled, sum must equal 100% */ + if (sum != 100) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("sum not 100%")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + } else { + /* If the feature is disabled, sum must equal 0%, which was checked + * by the for() loop above. + */ + g_assert_cmpint (sum, ==, 0); + } + } + + return TRUE; +} + +static gboolean +check_priority (gint val, + NMSettingDcbFlags flags, + const char *prop_name, + GError **error) +{ + if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (val >= 0)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid (not enabled)")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + + if (val < -1 || val > 7) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name); + return FALSE; + } + return TRUE; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (setting); + + if (!check_dcb_flags (priv->app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_FLAGS, error)) + return FALSE; + + if (!check_priority (priv->app_fcoe_priority, priv->app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_PRIORITY, error)) + return FALSE; + + if (!priv->app_fcoe_mode) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE); + return FALSE; + } + + if (strcmp (priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_FABRIC) && + strcmp (priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_VN2VN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE); + return FALSE; + } + + if (!check_dcb_flags (priv->app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_FLAGS, error)) + return FALSE; + + if (!check_priority (priv->app_iscsi_priority, priv->app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_PRIORITY, error)) + return FALSE; + + if (!check_dcb_flags (priv->app_fip_flags, NM_SETTING_DCB_APP_FIP_FLAGS, error)) + return FALSE; + + if (!check_priority (priv->app_fip_priority, priv->app_fip_flags, NM_SETTING_DCB_APP_FIP_PRIORITY, error)) + return FALSE; + + if (!check_dcb_flags (priv->pfc_flags, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, error)) + return FALSE; + + if (!check_uint_array (priv->pfc, G_N_ELEMENTS (priv->pfc), priv->pfc_flags, 1, 0, FALSE, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, error)) + return FALSE; + + if (!check_dcb_flags (priv->priority_group_flags, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, error)) + return FALSE; + + if (!check_uint_array (priv->priority_group_id, + G_N_ELEMENTS (priv->priority_group_id), + priv->priority_group_flags, + 7, + 15, + FALSE, + NM_SETTING_DCB_PRIORITY_GROUP_ID, + error)) + return FALSE; + + if (!check_uint_array (priv->priority_group_bandwidth, + G_N_ELEMENTS (priv->priority_group_bandwidth), + priv->priority_group_flags, + 100, + 0, + TRUE, + NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, + error)) + return FALSE; + + /* FIXME: sum bandwidths in each group */ + if (!check_uint_array (priv->priority_bandwidth, + G_N_ELEMENTS (priv->priority_bandwidth), + priv->priority_group_flags, + 100, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_BANDWIDTH, + error)) + return FALSE; + + if (!check_uint_array (priv->priority_strict, + G_N_ELEMENTS (priv->priority_strict), + priv->priority_group_flags, + 1, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, + error)) + return FALSE; + + if (!check_uint_array (priv->priority_traffic_class, + G_N_ELEMENTS (priv->priority_traffic_class), + priv->priority_group_flags, + 7, + 0, + FALSE, + NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, + error)) + return FALSE; + + return TRUE; +} + +/******************************************************************/ + +static void +nm_setting_dcb_init (NMSettingDcb *setting) +{ +} + +G_STATIC_ASSERT (sizeof (guint) == sizeof (gboolean)); + +static inline void +set_array_from_gvalue (const GValue *v, uint *a, size_t len) +{ + GArray *src = g_value_get_boxed (v); + const guint total_len = len * sizeof (a[0]); + + memset (a, 0, total_len); + if (src) { + g_return_if_fail (g_array_get_element_size (src) == sizeof (a[0])); + g_return_if_fail (src->len == len); + memcpy (a, src->data, total_len); + } +} +#define SET_ARRAY_FROM_GVALUE(v, a) set_array_from_gvalue (v, a, G_N_ELEMENTS (a)) + +static inline void +set_gvalue_from_array (GValue *v, uint *a, size_t len) +{ + GArray *src = g_array_sized_new (FALSE, TRUE, sizeof (guint), len); + + g_array_append_vals (src, a, len); + g_value_take_boxed (v, src); +} + +#define SET_GVALUE_FROM_ARRAY(v, a) set_gvalue_from_array (v, a, G_N_ELEMENTS (a)) + +static GVariant * +_nm_setting_dcb_uint_array_to_dbus (const GValue *prop_value) +{ + GArray *src = g_value_get_boxed (prop_value); + + return g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, src->data, src->len, sizeof (guint32)); +} + +static void +_nm_setting_dcb_uint_array_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + gconstpointer array; + gsize length; + + array = g_variant_get_fixed_array (dbus_value, &length, sizeof (guint32)); + set_gvalue_from_array (prop_value, (guint *) array, length); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_APP_FCOE_FLAGS: + priv->app_fcoe_flags = g_value_get_flags (value); + break; + case PROP_APP_FCOE_PRIORITY: + priv->app_fcoe_priority = g_value_get_int (value); + break; + case PROP_APP_FCOE_MODE: + priv->app_fcoe_mode = g_value_dup_string (value); + break; + case PROP_APP_ISCSI_FLAGS: + priv->app_iscsi_flags = g_value_get_flags (value); + break; + case PROP_APP_ISCSI_PRIORITY: + priv->app_iscsi_priority = g_value_get_int (value); + break; + case PROP_APP_FIP_FLAGS: + priv->app_fip_flags = g_value_get_flags (value); + break; + case PROP_APP_FIP_PRIORITY: + priv->app_fip_priority = g_value_get_int (value); + break; + case PROP_PFC_FLAGS: + priv->pfc_flags = g_value_get_flags (value); + break; + case PROP_PFC: + SET_ARRAY_FROM_GVALUE (value, priv->pfc); + break; + case PROP_PRIORITY_GROUP_FLAGS: + priv->priority_group_flags = g_value_get_flags (value); + break; + case PROP_PRIORITY_GROUP_ID: + SET_ARRAY_FROM_GVALUE (value, priv->priority_group_id); + break; + case PROP_PRIORITY_GROUP_BANDWIDTH: + SET_ARRAY_FROM_GVALUE (value, priv->priority_group_bandwidth); + break; + case PROP_PRIORITY_BANDWIDTH: + SET_ARRAY_FROM_GVALUE (value, priv->priority_bandwidth); + break; + case PROP_PRIORITY_STRICT: + SET_ARRAY_FROM_GVALUE (value, priv->priority_strict); + break; + case PROP_PRIORITY_TRAFFIC_CLASS: + SET_ARRAY_FROM_GVALUE (value, priv->priority_traffic_class); + 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) +{ + NMSettingDcb *setting = NM_SETTING_DCB (object); + NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_APP_FCOE_FLAGS: + g_value_set_flags (value, priv->app_fcoe_flags); + break; + case PROP_APP_FCOE_PRIORITY: + g_value_set_int (value, priv->app_fcoe_priority); + break; + case PROP_APP_FCOE_MODE: + g_value_set_string (value, priv->app_fcoe_mode); + break; + case PROP_APP_ISCSI_FLAGS: + g_value_set_flags (value, priv->app_iscsi_flags); + break; + case PROP_APP_ISCSI_PRIORITY: + g_value_set_int (value, priv->app_iscsi_priority); + break; + case PROP_APP_FIP_FLAGS: + g_value_set_flags (value, priv->app_fip_flags); + break; + case PROP_APP_FIP_PRIORITY: + g_value_set_int (value, priv->app_fip_priority); + break; + case PROP_PFC_FLAGS: + g_value_set_flags (value, priv->pfc_flags); + break; + case PROP_PFC: + SET_GVALUE_FROM_ARRAY (value, priv->pfc); + break; + case PROP_PRIORITY_GROUP_FLAGS: + g_value_set_flags (value, priv->priority_group_flags); + break; + case PROP_PRIORITY_GROUP_ID: + SET_GVALUE_FROM_ARRAY (value, priv->priority_group_id); + break; + case PROP_PRIORITY_GROUP_BANDWIDTH: + SET_GVALUE_FROM_ARRAY (value, priv->priority_group_bandwidth); + break; + case PROP_PRIORITY_BANDWIDTH: + SET_GVALUE_FROM_ARRAY (value, priv->priority_bandwidth); + break; + case PROP_PRIORITY_STRICT: + SET_GVALUE_FROM_ARRAY (value, priv->priority_strict); + break; + case PROP_PRIORITY_TRAFFIC_CLASS: + SET_GVALUE_FROM_ARRAY (value, priv->priority_traffic_class); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingDcbPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingDcb:app-fcoe-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB FCoE application. Flags may + * be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-flags + * variable: DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING + * description: FCOE flags. + * default: no + * example: DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_FCOE_FLAGS, + g_param_spec_flags (NM_SETTING_DCB_APP_FCOE_FLAGS, "", "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-fcoe-priority: + * + * The highest User Priority (0 - 7) which FCoE frames should use, or -1 for + * default priority. Only used when the #NMSettingDcb:app-fcoe-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-priority + * variable: DCB_APP_FCOE_PRIORITY + * values: 0 - 7 + * description: Priority of FCoE frames. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_FCOE_PRIORITY, + g_param_spec_int (NM_SETTING_DCB_APP_FCOE_PRIORITY, "", "", + -1, 7, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-fcoe-mode: + * + * The FCoE controller mode; either %NM_SETTING_DCB_FCOE_MODE_FABRIC + * (default) or %NM_SETTING_DCB_FCOE_MODE_VN2VN. + **/ + /* ---ifcfg-rh--- + * property: app-fcoe-mode + * variable: DCB_APP_FCOE_MODE + * values: fabric, vn2vn + * default: fabric + * description: FCoE controller mode. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_FCOE_MODE, + g_param_spec_string (NM_SETTING_DCB_APP_FCOE_MODE, "", "", + NM_SETTING_DCB_FCOE_MODE_FABRIC, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-iscsi-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB iSCSI application. Flags + * may be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-iscsi-flags + * variable: DCB_APP_ISCSI_ENABLE, DCB_APP_ISCSI_ADVERTISE, DCB_APP_ISCSI_WILLING + * default: no + * description: iSCSI flags. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_ISCSI_FLAGS, + g_param_spec_flags (NM_SETTING_DCB_APP_ISCSI_FLAGS, "", "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-iscsi-priority: + * + * The highest User Priority (0 - 7) which iSCSI frames should use, or -1 + * for default priority. Only used when the #NMSettingDcb:app-iscsi-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-iscsi-priority + * variable: DCB_APP_ISCSI_PRIORITY + * values: 0 - 7 + * description: Priority of iSCSI frames. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_ISCSI_PRIORITY, + g_param_spec_int (NM_SETTING_DCB_APP_ISCSI_PRIORITY, "", "", + -1, 7, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-fip-flags: + * + * Specifies the #NMSettingDcbFlags for the DCB FIP application. Flags may + * be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: app-fip-flags + * variable: DCB_APP_FIP_ENABLE, DCB_APP_FIP_ADVERTISE, DCB_APP_FIP_WILLING + * default: no + * description: FIP flags. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_FIP_FLAGS, + g_param_spec_flags (NM_SETTING_DCB_APP_FIP_FLAGS, "", "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:app-fip-priority: + * + * The highest User Priority (0 - 7) which FIP frames should use, or -1 for + * default priority. Only used when the #NMSettingDcb:app-fip-flags + * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag. + **/ + /* ---ifcfg-rh--- + * property: app-fip-priority + * variable: DCB_APP_FIP_PRIORITY + * values: 0 - 7 + * description: Priority of FIP frames. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_APP_FIP_PRIORITY, + g_param_spec_int (NM_SETTING_DCB_APP_FIP_PRIORITY, "", "", + -1, 7, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:priority-flow-control-flags: + * + * Specifies the #NMSettingDcbFlags for DCB Priority Flow Control (PFC). + * Flags may be any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: priority-flow-control-flags + * variable: DCB_PFC_ENABLE, DCB_PFC_ADVERTISE, DCB_PFC_WILLING + * default: no + * description: Priority flow control flags. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PFC_FLAGS, + g_param_spec_flags (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, "", "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:priority-flow-control: + * + * An array of 8 boolean values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates whether or not the corresponding + * priority should transmit priority pause. + * + * Element-type: gboolean + **/ + /* ---ifcfg-rh--- + * property: priority-flow-control + * variable: DCB_PFC_UP + * description: Priority flow control values. String of 8 "0" and "1", where "0". + * means "do not transmit priority pause", "1" means "transmit pause". + * example: DCB_PFC_UP=01101110 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PFC, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + /** + * NMSettingDcb:priority-group-flags: + * + * Specifies the #NMSettingDcbFlags for DCB Priority Groups. Flags may be + * any combination of %NM_SETTING_DCB_FLAG_ENABLE, + * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING. + **/ + /* ---ifcfg-rh--- + * property: priority-group-flags + * variable: DCB_PG_ENABLE, DCB_PG_ADVERTISE, DCB_PG_WILLING + * default: no + * description: Priority groups flags. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_GROUP_FLAGS, + g_param_spec_flags (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, "", "", + NM_TYPE_SETTING_DCB_FLAGS, + NM_SETTING_DCB_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingDcb:priority-group-id: + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the Priority Group ID. Allowed + * Priority Group ID values are 0 - 7 or 15 for the unrestricted group. + * + * Element-type: guint + **/ + /* ---ifcfg-rh--- + * property: priority-group-id + * variable: DCB_PG_ID + * description: Priority groups values. String of eight priorities (0 - 7) or "f" + * (unrestricted). + * example: DCB_PG_ID=1205f173 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_GROUP_ID, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_GROUP_ID, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_ID, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + /** + * NMSettingDcb:priority-group-bandwidth: + * + * An array of 8 uint values, where the array index corresponds to the + * Priority Group ID (0 - 7) and the value indicates the percentage of link + * bandwidth allocated to that group. Allowed values are 0 - 100, and the + * sum of all values must total 100 percent. + * + * Element-type: guint + **/ + /* ---ifcfg-rh--- + * property: priority-group-bandwidth + * variable: DCB_PG_PCT + * description: Priority groups values. Eight bandwidths (in percent), separated with commas. + * example: DCB_PG_PCT=10,5,10,15,10,10,10,30 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_GROUP_BANDWIDTH, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + /** + * NMSettingDcb:priority-bandwidth: + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the percentage of bandwidth of + * the priority's assigned group that the priority may use. The sum of all + * percentages for priorities which belong to the same group must total 100 + * percent. + * + * Element-type: guint + **/ + /* ---ifcfg-rh--- + * property: priority-bandwidth + * variable: DCB_PG_UPPCT + * description: Priority values. Eight bandwidths (in percent), separated with commas. + * The sum of the numbers must be 100. + * example: DCB_PG_UPPCT=7,13,10,10,15,15,10,20 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_BANDWIDTH, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_BANDWIDTH, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + /** + * NMSettingDcb:priority-strict-bandwidth: + * + * An array of 8 boolean values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates whether or not the priority may + * use all of the bandwidth allocated to its assigned group. + * + * Element-type: gboolean + **/ + /* ---ifcfg-rh--- + * property: priority-strict-bandwidth + * variable: DCB_PG_STRICT + * description: Priority values. String of eight "0" or "1", where "0" means + * "may not utilize all bandwidth", "1" means "may utilize all bandwidth". + * example: DCB_PG_STRICT=01101110 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_STRICT, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); + + /** + * NMSettingDcb:priority-traffic-class: + * + * An array of 8 uint values, where the array index corresponds to the User + * Priority (0 - 7) and the value indicates the traffic class (0 - 7) to + * which the priority is mapped. + * + * Element-type: guint + **/ + /* ---ifcfg-rh--- + * property: priority-traffic-class + * variable: DCB_PG_UP2TC + * description: Priority values. String of eight trafic class values (0 - 7). + * example: DCB_PG_UP2TC=01623701 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PRIORITY_TRAFFIC_CLASS, + g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, "", "", + G_TYPE_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, + G_VARIANT_TYPE ("au"), + _nm_setting_dcb_uint_array_to_dbus, + _nm_setting_dcb_uint_array_from_dbus); +} diff --git a/libnm-core/nm-setting-dcb.h b/libnm-core/nm-setting-dcb.h new file mode 100644 index 00000000..e5bc4bcf --- /dev/null +++ b/libnm-core/nm-setting-dcb.h @@ -0,0 +1,164 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_DCB_H__ +#define __NM_SETTING_DCB_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_DCB (nm_setting_dcb_get_type ()) +#define NM_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_DCB, NMSettingDcb)) +#define NM_SETTING_DCB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_DCB, NMSettingDcbClass)) +#define NM_IS_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_DCB)) +#define NM_IS_SETTING_DCB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_DCB)) +#define NM_SETTING_DCB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_DCB, NMSettingDcbClass)) + +#define NM_SETTING_DCB_SETTING_NAME "dcb" + +/** + * NMSettingDcbFlags: + * @NM_SETTING_DCB_FLAG_NONE: no flag + * @NM_SETTING_DCB_FLAG_ENABLE: the feature is enabled + * @NM_SETTING_DCB_FLAG_ADVERTISE: the feature is advertised + * @NM_SETTING_DCB_FLAG_WILLING: the feature is willing to change based on + * peer configuration advertisements + * + * DCB feature flags. + **/ +typedef enum { /*< flags >*/ + NM_SETTING_DCB_FLAG_NONE = 0x00000000, + NM_SETTING_DCB_FLAG_ENABLE = 0x00000001, + NM_SETTING_DCB_FLAG_ADVERTISE = 0x00000002, + NM_SETTING_DCB_FLAG_WILLING = 0x00000004 +} NMSettingDcbFlags; + +/** + * NM_SETTING_DCB_FCOE_MODE_FABRIC: + * + * Indicates that the FCoE controller should use "fabric" mode (default) + */ +#define NM_SETTING_DCB_FCOE_MODE_FABRIC "fabric" + +/** + * NM_SETTING_DCB_FCOE_MODE_VN2VN: + * + * Indicates that the FCoE controller should use "VN2VN" mode. + */ +#define NM_SETTING_DCB_FCOE_MODE_VN2VN "vn2vn" + + +/* Properties */ +#define NM_SETTING_DCB_APP_FCOE_FLAGS "app-fcoe-flags" +#define NM_SETTING_DCB_APP_FCOE_PRIORITY "app-fcoe-priority" +#define NM_SETTING_DCB_APP_FCOE_MODE "app-fcoe-mode" + +#define NM_SETTING_DCB_APP_ISCSI_FLAGS "app-iscsi-flags" +#define NM_SETTING_DCB_APP_ISCSI_PRIORITY "app-iscsi-priority" + +#define NM_SETTING_DCB_APP_FIP_FLAGS "app-fip-flags" +#define NM_SETTING_DCB_APP_FIP_PRIORITY "app-fip-priority" + +#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS "priority-flow-control-flags" +#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL "priority-flow-control" + +#define NM_SETTING_DCB_PRIORITY_GROUP_FLAGS "priority-group-flags" +#define NM_SETTING_DCB_PRIORITY_GROUP_ID "priority-group-id" +#define NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH "priority-group-bandwidth" +#define NM_SETTING_DCB_PRIORITY_BANDWIDTH "priority-bandwidth" +#define NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH "priority-strict-bandwidth" +#define NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS "priority-traffic-class" + + +struct _NMSettingDcb { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingDcbClass; + +GType nm_setting_dcb_get_type (void); + +NMSetting * nm_setting_dcb_new (void); + +NMSettingDcbFlags nm_setting_dcb_get_app_fcoe_flags (NMSettingDcb *setting); +gint nm_setting_dcb_get_app_fcoe_priority (NMSettingDcb *setting); +const char * nm_setting_dcb_get_app_fcoe_mode (NMSettingDcb *setting); + +NMSettingDcbFlags nm_setting_dcb_get_app_iscsi_flags (NMSettingDcb *setting); +gint nm_setting_dcb_get_app_iscsi_priority (NMSettingDcb *setting); + +NMSettingDcbFlags nm_setting_dcb_get_app_fip_flags (NMSettingDcb *setting); +gint nm_setting_dcb_get_app_fip_priority (NMSettingDcb *setting); + +/* Priority Flow Control */ +NMSettingDcbFlags nm_setting_dcb_get_priority_flow_control_flags (NMSettingDcb *setting); +gboolean nm_setting_dcb_get_priority_flow_control (NMSettingDcb *setting, + guint user_priority); +void nm_setting_dcb_set_priority_flow_control (NMSettingDcb *setting, + guint user_priority, + gboolean enabled); + +/* Priority Groups */ +NMSettingDcbFlags nm_setting_dcb_get_priority_group_flags (NMSettingDcb *setting); + +guint nm_setting_dcb_get_priority_group_id (NMSettingDcb *setting, + guint user_priority); +void nm_setting_dcb_set_priority_group_id (NMSettingDcb *setting, + guint user_priority, + guint group_id); + +guint nm_setting_dcb_get_priority_group_bandwidth (NMSettingDcb *setting, + guint group_id); +void nm_setting_dcb_set_priority_group_bandwidth (NMSettingDcb *setting, + guint group_id, + guint bandwidth_percent); + +guint nm_setting_dcb_get_priority_bandwidth (NMSettingDcb *setting, + guint user_priority); +void nm_setting_dcb_set_priority_bandwidth (NMSettingDcb *setting, + guint user_priority, + guint bandwidth_percent); + +gboolean nm_setting_dcb_get_priority_strict_bandwidth (NMSettingDcb *setting, + guint user_priority); +void nm_setting_dcb_set_priority_strict_bandwidth (NMSettingDcb *setting, + guint user_priority, + gboolean strict); + +guint nm_setting_dcb_get_priority_traffic_class (NMSettingDcb *setting, + guint user_priority); +void nm_setting_dcb_set_priority_traffic_class (NMSettingDcb *setting, + guint user_priority, + guint traffic_class); + +G_END_DECLS + +#endif /* __NM_SETTING_DCB_H__ */ diff --git a/libnm-core/nm-setting-generic.c b/libnm-core/nm-setting-generic.c new file mode 100644 index 00000000..35deb2de --- /dev/null +++ b/libnm-core/nm-setting-generic.c @@ -0,0 +1,73 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-setting-generic.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-generic + * @short_description: Describes connection properties for generic devices + * + * The #NMSettingGeneric object is a #NMSetting subclass that describes + * optional properties that apply to "generic" devices (ie, devices that + * NetworkManager does not specifically recognize). + * + * There are currently no properties on this object; it exists only to be + * the "connection type" setting on #NMConnections for generic devices. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingGeneric, nm_setting_generic, NM_TYPE_SETTING, + _nm_register_setting (GENERIC, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_GENERIC) + +#define NM_SETTING_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_GENERIC, NMSettingGenericPrivate)) + +typedef struct { + int dummy; +} NMSettingGenericPrivate; + +/**************************************************************************/ + +/** + * nm_setting_generic_new: + * + * Creates a new #NMSettingGeneric object with default values. + * + * Returns: (transfer full): the new empty #NMSettingGeneric object + **/ +NMSetting * +nm_setting_generic_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_GENERIC, NULL); +} + +static void +nm_setting_generic_init (NMSettingGeneric *setting) +{ +} + +static void +nm_setting_generic_class_init (NMSettingGenericClass *setting_class) +{ + g_type_class_add_private (setting_class, sizeof (NMSettingGenericPrivate)); +} diff --git a/libnm-core/nm-setting-generic.h b/libnm-core/nm-setting-generic.h new file mode 100644 index 00000000..7a209da2 --- /dev/null +++ b/libnm-core/nm-setting-generic.h @@ -0,0 +1,59 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_GENERIC_H__ +#define __NM_SETTING_GENERIC_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_GENERIC (nm_setting_generic_get_type ()) +#define NM_SETTING_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_GENERIC, NMSettingGeneric)) +#define NM_SETTING_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_GENERIC, NMSettingGenericClass)) +#define NM_IS_SETTING_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_GENERIC)) +#define NM_IS_SETTING_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_GENERIC)) +#define NM_SETTING_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_GENERIC, NMSettingGenericClass)) + +#define NM_SETTING_GENERIC_SETTING_NAME "generic" + +struct _NMSettingGeneric { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingGenericClass; + +GType nm_setting_generic_get_type (void); + +NMSetting * nm_setting_generic_new (void); + +G_END_DECLS + +#endif /* __NM_SETTING_GENERIC_H__ */ diff --git a/libnm-core/nm-setting-gsm.c b/libnm-core/nm-setting-gsm.c new file mode 100644 index 00000000..22f8cdba --- /dev/null +++ b/libnm-core/nm-setting-gsm.c @@ -0,0 +1,616 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-gsm.h" +#include "nm-utils.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-gsm + * @short_description: Describes GSM/3GPP-based mobile broadband properties + * + * The #NMSettingGsm object is a #NMSetting subclass that describes + * properties that allow connections to 3GPP-based mobile broadband + * networks, including those using GPRS/EDGE and UMTS/HSPA technology. + */ + +G_DEFINE_TYPE_WITH_CODE (NMSettingGsm, nm_setting_gsm, NM_TYPE_SETTING, + _nm_register_setting (GSM, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_GSM) + +#define NM_SETTING_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_GSM, NMSettingGsmPrivate)) + +typedef struct { + char *number; /* For dialing, duh */ + char *username; + char *password; + NMSettingSecretFlags password_flags; + + char *apn; /* NULL for dynamic */ + char *network_id; /* for manual registration or NULL for automatic */ + + char *pin; + NMSettingSecretFlags pin_flags; + + gboolean home_only; +} NMSettingGsmPrivate; + +enum { + PROP_0, + PROP_NUMBER, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + PROP_APN, + PROP_NETWORK_ID, + PROP_PIN, + PROP_PIN_FLAGS, + PROP_HOME_ONLY, + + LAST_PROP +}; + +/** + * nm_setting_gsm_new: + * + * Creates a new #NMSettingGsm object with default values. + * + * Returns: the new empty #NMSettingGsm object + **/ +NMSetting * +nm_setting_gsm_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_GSM, NULL); +} + +/** + * nm_setting_gsm_get_number: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:number property of the setting + **/ +const char * +nm_setting_gsm_get_number (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->number; +} + +/** + * nm_setting_gsm_get_username: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:username property of the setting + **/ +const char * +nm_setting_gsm_get_username (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->username; +} + +/** + * nm_setting_gsm_get_password: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:password property of the setting + **/ +const char * +nm_setting_gsm_get_password (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->password; +} + +/** + * nm_setting_gsm_get_password_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:password + **/ +NMSettingSecretFlags +nm_setting_gsm_get_password_flags (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->password_flags; +} + +/** + * nm_setting_gsm_get_apn: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:apn property of the setting + **/ +const char * +nm_setting_gsm_get_apn (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->apn; +} + +/** + * nm_setting_gsm_get_network_id: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:network-id property of the setting + **/ +const char * +nm_setting_gsm_get_network_id (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->network_id; +} + +/** + * nm_setting_gsm_get_pin: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:pin property of the setting + **/ +const char * +nm_setting_gsm_get_pin (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->pin; +} + +/** + * nm_setting_gsm_get_pin_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:pin + **/ +NMSettingSecretFlags +nm_setting_gsm_get_pin_flags (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->pin_flags; +} + +/** + * nm_setting_gsm_get_home_only: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:home-only property of the setting + **/ +gboolean +nm_setting_gsm_get_home_only (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->home_only; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (setting); + + if (priv->number && !priv->number[0]) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NUMBER); + return FALSE; + } + + if (priv->apn) { + guint32 apn_len = strlen (priv->apn); + guint32 i; + + if (apn_len < 1 || apn_len > 64) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property value '%s' is empty or too long (>64)"), + priv->apn); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); + return FALSE; + } + + /* APNs roughly follow the same rules as DNS domain names. Allowed + * characters are a-z, 0-9, . and -. GSM 03.03 Section 9.1 states: + * + * The syntax of the APN shall follow the Name Syntax defined in + * RFC 2181 [14] and RFC 1035 [15]. The APN consists of one or + * more labels. Each label is coded as one octet length field + * followed by that number of octets coded as 8 bit ASCII characters. + * Following RFC 1035 [15] the labels should consist only of the + * alphabetic characters (A-Z and a-z), digits (0-9) and the + * dash (-). The case of alphabetic characters is not significant. + * + * A dot (.) is commonly used to separate parts of the APN, and + * apparently the underscore (_) is used as well. RFC 2181 indicates + * that no restrictions of any kind are placed on DNS labels, and thus + * it would appear that none are placed on APNs either, but many modems + * and networks will fail to accept APNs that include odd characters + * like space ( ) and such. + */ + for (i = 0; i < apn_len; i++) { + if ( !g_ascii_isalnum (priv->apn[i]) + && (priv->apn[i] != '.') + && (priv->apn[i] != '_') + && (priv->apn[i] != '-')) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' contains invalid char(s) (use [A-Za-z._-])"), + priv->apn); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); + return FALSE; + } + } + } + + if (priv->username && !strlen (priv->username)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME); + return FALSE; + } + + if (priv->password && !strlen (priv->password)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME); + return FALSE; + } + + if (priv->network_id) { + guint32 nid_len = strlen (priv->network_id); + guint32 i; + + /* Accept both 5 and 6 digit MCC/MNC codes */ + if ((nid_len < 5) || (nid_len > 6)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' length is invalid (should be 5 or 6 digits)"), + priv->network_id); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NETWORK_ID); + return FALSE; + } + + for (i = 0; i < nid_len; i++) { + if (!g_ascii_isdigit (priv->network_id[i])) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a number"), + priv->network_id); + g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NETWORK_ID); + return FALSE; + } + } + } + + return TRUE; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (setting); + GPtrArray *secrets = NULL; + + if (priv->password) + return NULL; + + if (priv->username) { + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_GSM_PASSWORD); + } + } + + return secrets; +} + +static void +nm_setting_gsm_init (NMSettingGsm *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object); + + g_free (priv->number); + g_free (priv->username); + g_free (priv->password); + g_free (priv->apn); + g_free (priv->network_id); + g_free (priv->pin); + + G_OBJECT_CLASS (nm_setting_gsm_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object); + char *tmp; + + switch (prop_id) { + case PROP_NUMBER: + g_free (priv->number); + priv->number = g_value_dup_string (value); + break; + case PROP_USERNAME: + g_free (priv->username); + priv->username = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (priv->password); + priv->password = g_value_dup_string (value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags (value); + break; + case PROP_APN: + g_free (priv->apn); + priv->apn = NULL; + tmp = g_value_dup_string (value); + if (tmp) + priv->apn = g_strstrip (tmp); + break; + case PROP_NETWORK_ID: + g_free (priv->network_id); + priv->network_id = NULL; + tmp = g_value_dup_string (value); + if (tmp) + priv->network_id = g_strstrip (tmp); + break; + case PROP_PIN: + g_free (priv->pin); + priv->pin = g_value_dup_string (value); + break; + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_flags (value); + break; + case PROP_HOME_ONLY: + priv->home_only = g_value_get_boolean (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) +{ + NMSettingGsm *setting = NM_SETTING_GSM (object); + + switch (prop_id) { + case PROP_NUMBER: + g_value_set_string (value, nm_setting_gsm_get_number (setting)); + break; + case PROP_USERNAME: + g_value_set_string (value, nm_setting_gsm_get_username (setting)); + break; + case PROP_PASSWORD: + g_value_set_string (value, nm_setting_gsm_get_password (setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags (value, nm_setting_gsm_get_password_flags (setting)); + break; + case PROP_APN: + g_value_set_string (value, nm_setting_gsm_get_apn (setting)); + break; + case PROP_NETWORK_ID: + g_value_set_string (value, nm_setting_gsm_get_network_id (setting)); + break; + case PROP_PIN: + g_value_set_string (value, nm_setting_gsm_get_pin (setting)); + break; + case PROP_PIN_FLAGS: + g_value_set_flags (value, nm_setting_gsm_get_pin_flags (setting)); + break; + case PROP_HOME_ONLY: + g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingGsmPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + + /** + * NMSettingGsm:number: + * + * Number to dial when establishing a PPP data session with the GSM-based + * mobile broadband network. Many modems do not require PPP for connections + * to the mobile network and thus this property should be left blank, which + * allows NetworkManager to select the appropriate settings automatically. + **/ + g_object_class_install_property + (object_class, PROP_NUMBER, + g_param_spec_string (NM_SETTING_GSM_NUMBER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:username: + * + * The username used to authenticate with the network, if required. Many + * providers do not require a username, or accept any username. But if a + * username is required, it is specified here. + **/ + g_object_class_install_property + (object_class, PROP_USERNAME, + g_param_spec_string (NM_SETTING_GSM_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:password: + * + * The password used to authenticate with the network, if required. Many + * providers do not require a password, or accept any password. But if a + * password is required, it is specified here. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_GSM_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:password-flags: + * + * Flags indicating how to handle the #NMSettingGsm:password property. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_GSM_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:apn: + * + * The GPRS Access Point Name specifying the APN used when establishing a + * data session with the GSM-based network. The APN often determines how + * the user will be billed for their network usage and whether the user has + * access to the Internet or just a provider-specific walled-garden, so it + * is important to use the correct APN for the user's mobile broadband plan. + * The APN may only be composed of the characters a-z, 0-9, ., and - per GSM + * 03.60 Section 14.9. + **/ + g_object_class_install_property + (object_class, PROP_APN, + g_param_spec_string (NM_SETTING_GSM_APN, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:network-id: + * + * The Network ID (GSM LAI format, ie MCC-MNC) to force specific network + * registration. If the Network ID is specified, NetworkManager will + * attempt to force the device to register only on the specified network. + * This can be used to ensure that the device does not roam when direct + * roaming control of the device is not otherwise possible. + **/ + g_object_class_install_property + (object_class, PROP_NETWORK_ID, + g_param_spec_string (NM_SETTING_GSM_NETWORK_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:pin: + * + * If the SIM is locked with a PIN it must be unlocked before any other + * operations are requested. Specify the PIN here to allow operation of the + * device. + **/ + g_object_class_install_property + (object_class, PROP_PIN, + g_param_spec_string (NM_SETTING_GSM_PIN, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:pin-flags: + * + * Flags indicating how to handle the #NMSettingGsm:pin property. + **/ + g_object_class_install_property + (object_class, PROP_PIN_FLAGS, + g_param_spec_flags (NM_SETTING_GSM_PIN_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingGsm:home-only: + * + * When %TRUE, only connections to the home network will be allowed. + * Connections to roaming networks will not be made. + **/ + g_object_class_install_property + (object_class, PROP_HOME_ONLY, + g_param_spec_boolean (NM_SETTING_GSM_HOME_ONLY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* Ignore incoming deprecated properties */ + _nm_setting_class_add_dbus_only_property (parent_class, "allowed-bands", + G_VARIANT_TYPE_UINT32, + NULL, NULL); + _nm_setting_class_add_dbus_only_property (parent_class, "network-type", + G_VARIANT_TYPE_INT32, + NULL, NULL); +} diff --git a/libnm-core/nm-setting-gsm.h b/libnm-core/nm-setting-gsm.h new file mode 100644 index 00000000..90756738 --- /dev/null +++ b/libnm-core/nm-setting-gsm.h @@ -0,0 +1,80 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_GSM_H__ +#define __NM_SETTING_GSM_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_GSM (nm_setting_gsm_get_type ()) +#define NM_SETTING_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_GSM, NMSettingGsm)) +#define NM_SETTING_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_GSM, NMSettingGsmClass)) +#define NM_IS_SETTING_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_GSM)) +#define NM_IS_SETTING_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_GSM)) +#define NM_SETTING_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_GSM, NMSettingGsmClass)) + +#define NM_SETTING_GSM_SETTING_NAME "gsm" + +#define NM_SETTING_GSM_NUMBER "number" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" + +struct _NMSettingGsm { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingGsmClass; + +GType nm_setting_gsm_get_type (void); + +NMSetting *nm_setting_gsm_new (void); +const char *nm_setting_gsm_get_number (NMSettingGsm *setting); +const char *nm_setting_gsm_get_username (NMSettingGsm *setting); +const char *nm_setting_gsm_get_password (NMSettingGsm *setting); +const char *nm_setting_gsm_get_apn (NMSettingGsm *setting); +const char *nm_setting_gsm_get_network_id (NMSettingGsm *setting); +const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); +gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); + +NMSettingSecretFlags nm_setting_gsm_get_pin_flags (NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_GSM_H__ */ diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c new file mode 100644 index 00000000..b0afe04f --- /dev/null +++ b/libnm-core/nm-setting-infiniband.c @@ -0,0 +1,522 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-infiniband.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-setting-connection.h" + +/** + * SECTION:nm-setting-infiniband + * @short_description: Describes connection properties for IP-over-InfiniBand networks + * + * The #NMSettingInfiniband object is a #NMSetting subclass that describes properties + * necessary for connection to IP-over-InfiniBand networks. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingInfiniband, nm_setting_infiniband, NM_TYPE_SETTING, + _nm_register_setting (INFINIBAND, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_INFINIBAND) + +#define NM_SETTING_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandPrivate)) + +typedef struct { + char *mac_address; + char *transport_mode; + guint32 mtu; + int p_key; + char *parent, *virtual_iface_name; +} NMSettingInfinibandPrivate; + +enum { + PROP_0, + PROP_MAC_ADDRESS, + PROP_MTU, + PROP_TRANSPORT_MODE, + PROP_P_KEY, + PROP_PARENT, + + LAST_PROP +}; + +/** + * nm_setting_infiniband_new: + * + * Creates a new #NMSettingInfiniband object with default values. + * + * Returns: (transfer full): the new empty #NMSettingInfiniband object + **/ +NMSetting * +nm_setting_infiniband_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_INFINIBAND, NULL); +} + +/** + * nm_setting_infiniband_get_mac_address: + * @setting: the #NMSettingInfiniband + * + * Returns: the #NMSettingInfiniband:mac-address property of the setting + **/ +const char * +nm_setting_infiniband_get_mac_address (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->mac_address; +} + +/** + * nm_setting_infiniband_get_mtu: + * @setting: the #NMSettingInfiniband + * + * Returns: the #NMSettingInfiniband:mtu property of the setting + **/ +guint32 +nm_setting_infiniband_get_mtu (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), 0); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->mtu; +} + +/** + * nm_setting_infiniband_get_transport_mode: + * @setting: the #NMSettingInfiniband + * + * Returns the transport mode for this device. Either 'datagram' or + * 'connected'. + * + * Returns: the IPoIB transport mode + **/ +const char * +nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->transport_mode; +} + +/** + * nm_setting_infiniband_get_p_key: + * @setting: the #NMSettingInfiniband + * + * Returns the P_Key to use for this device. A value of -1 means to + * use the default P_Key (aka "the P_Key at index 0"). Otherwise it is + * a 16-bit unsigned integer. + * + * Returns: the IPoIB P_Key + **/ +int +nm_setting_infiniband_get_p_key (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), -1); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->p_key; +} + +/** + * nm_setting_infiniband_get_parent: + * @setting: the #NMSettingInfiniband + * + * Returns the parent interface name for this device, if set. + * + * Returns: the parent interface name + **/ +const char * +nm_setting_infiniband_get_parent (NMSettingInfiniband *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), NULL); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_infiniband_get_virtual_interface_name: + * @setting: the #NMSettingInfiniband + * + * Returns the interface name created by combining #NMSettingInfiniband:parent + * and #NMSettingInfiniband:p-key. (If either property is unset, this will + * return %NULL.) + * + * Returns: the interface name, or %NULL + **/ +const char * +nm_setting_infiniband_get_virtual_interface_name (NMSettingInfiniband *setting) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting); + + if (priv->p_key == -1 || !priv->parent) + return NULL; + + if (!priv->virtual_iface_name) + priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key); + + return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->virtual_iface_name; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting); + guint32 normerr_max_mtu = 0; + + if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, INFINIBAND_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS); + return FALSE; + } + + if (!g_strcmp0 (priv->transport_mode, "datagram")) { + if (priv->mtu > 2044) + normerr_max_mtu = 2044; + } else if (!g_strcmp0 (priv->transport_mode, "connected")) { + if (priv->mtu > 65520) + normerr_max_mtu = 65520; + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE); + return FALSE; + } + + if (priv->parent) { + if (!nm_utils_iface_valid_name (priv->parent)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("not a valid interface name")); + g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + return FALSE; + } + if (priv->p_key == -1) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Must specify a P_Key if specifying parent")); + g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + } + } + + if (priv->p_key != -1) { + if (!priv->mac_address && !priv->parent) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("InfiniBand P_Key connection did not specify parent interface name")); + g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + return FALSE; + } + } + + s_con = nm_connection_get_setting_connection (connection); + if (s_con) { + const char *interface_name = nm_setting_connection_get_interface_name (s_con); + + if (!interface_name) + ; + else if (!nm_utils_iface_valid_name (interface_name)) { + /* report the error for NMSettingConnection:interface-name, because + * it's that property that is invalid -- although we currently verify() + * NMSettingInfiniband. + **/ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + interface_name); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } else { + if (priv->p_key != -1) { + if (!priv->virtual_iface_name) + priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key); + + if (strcmp (interface_name, priv->virtual_iface_name) != 0) { + /* We don't support renaming software infiniband devices. Later we might, but + * for now just reject such connections. + **/ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("interface name of software infiniband device must be '%s' or unset (instead it is '%s')"), + priv->virtual_iface_name, interface_name); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } + } + } + + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ + + if (normerr_max_mtu > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("mtu for transport mode '%s' can be at most %d but it is %d"), + priv->transport_mode, normerr_max_mtu, priv->mtu); + g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + + return TRUE; +} + +static void +nm_setting_infiniband_init (NMSettingInfiniband *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (object); + + g_free (priv->transport_mode); + g_free (priv->mac_address); + g_free (priv->parent); + g_free (priv->virtual_iface_name); + + G_OBJECT_CLASS (nm_setting_infiniband_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_free (priv->mac_address); + priv->mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + INFINIBAND_ALEN); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; + case PROP_TRANSPORT_MODE: + g_free (priv->transport_mode); + priv->transport_mode = g_value_dup_string (value); + break; + case PROP_P_KEY: + priv->p_key = g_value_get_int (value); + g_clear_pointer (&priv->virtual_iface_name, g_free); + break; + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + g_clear_pointer (&priv->virtual_iface_name, g_free); + 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) +{ + NMSettingInfiniband *setting = NM_SETTING_INFINIBAND (object); + + switch (prop_id) { + case PROP_MAC_ADDRESS: + g_value_set_string (value, nm_setting_infiniband_get_mac_address (setting)); + break; + case PROP_MTU: + g_value_set_uint (value, nm_setting_infiniband_get_mtu (setting)); + break; + case PROP_TRANSPORT_MODE: + g_value_set_string (value, nm_setting_infiniband_get_transport_mode (setting)); + break; + case PROP_P_KEY: + g_value_set_int (value, nm_setting_infiniband_get_p_key (setting)); + break; + case PROP_PARENT: + g_value_set_string (value, nm_setting_infiniband_get_parent (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingInfinibandPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingInfiniband:mac-address: + * + * If specified, this connection will only apply to the IPoIB device whose + * permanent MAC address matches. This property does not change the MAC + * address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: ususal hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation, or + * or semicolon separated list of 20 decimal bytes (obsolete) + * example: mac-address= 80:00:00:6d:fe:80:00:00:00:00:00:00:00:02:55:00:70:33:cf:01 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: IBoIP 20-byte hardware address of the device (in traditional + * hex-digits-and-colons notation). + * example: HWADDR=01:02:03:04:05:06:07:08:09:0A:01:02:03:04:05:06:07:08:09:11 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_INFINIBAND_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_INFINIBAND_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingInfiniband:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the interface. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_INFINIBAND_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingInfiniband:transport-mode: + * + * The IP-over-InfiniBand transport mode. Either "datagram" or + * "connected". + **/ + /* ---ifcfg-rh--- + * property: transport-mode + * variable: CONNECTED_MODE + * default: CONNECTED_MODE=no + * description: CONNECTED_MODE=yes for "connected" mode, CONNECTED_MODE=no for + * "datagram" mode + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_TRANSPORT_MODE, + g_param_spec_string (NM_SETTING_INFINIBAND_TRANSPORT_MODE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingInfiniband:p-key: + * + * The InfiniBand P_Key to use for this device. A value of -1 means to use + * the default P_Key (aka "the P_Key at index 0"). Otherwise it is a 16-bit + * unsigned integer, whose high bit is set if it is a "full membership" + * P_Key. + **/ + /* ---ifcfg-rh--- + * property: p-key + * variable: PKEY_ID (and PKEY=yes) + * default: PKEY=no + * description: InfiniBand P_Key. The value can be a hex number prefixed with "0x" + * or a decimal number. + * When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified. + * example: PKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0.8002 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_P_KEY, + g_param_spec_int (NM_SETTING_INFINIBAND_P_KEY, "", "", + -1, 0xFFFF, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingInfiniband:parent: + * + * The interface name of the parent device of this device. Normally %NULL, + * but if the #NMSettingInfiniband:p_key property is set, then you must + * specify the base device by setting either this property or + * #NMSettingInfiniband:mac-address. + **/ + /* ---ifcfg-rh--- + * property: parent + * variable: PHYSDEV (PKEY=yes) + * default: PKEY=no + * description: InfiniBand parent device. + * example: PHYSDEV=ib0 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_INFINIBAND_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + +} diff --git a/libnm-core/nm-setting-infiniband.h b/libnm-core/nm-setting-infiniband.h new file mode 100644 index 00000000..c5ad418b --- /dev/null +++ b/libnm-core/nm-setting-infiniband.h @@ -0,0 +1,72 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_INFINIBAND_H__ +#define __NM_SETTING_INFINIBAND_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_INFINIBAND (nm_setting_infiniband_get_type ()) +#define NM_SETTING_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_INFINIBAND, NMSettingInfiniband)) +#define NM_SETTING_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandClass)) +#define NM_IS_SETTING_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_INFINIBAND)) +#define NM_IS_SETTING_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_INFINIBAND)) +#define NM_SETTING_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_INFINIBAND, NMSettingInfinibandClass)) + +#define NM_SETTING_INFINIBAND_SETTING_NAME "infiniband" + +#define NM_SETTING_INFINIBAND_MAC_ADDRESS "mac-address" +#define NM_SETTING_INFINIBAND_MTU "mtu" +#define NM_SETTING_INFINIBAND_TRANSPORT_MODE "transport-mode" +#define NM_SETTING_INFINIBAND_P_KEY "p-key" +#define NM_SETTING_INFINIBAND_PARENT "parent" + +struct _NMSettingInfiniband { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingInfinibandClass; + +GType nm_setting_infiniband_get_type (void); + +NMSetting * nm_setting_infiniband_new (void); +const char * nm_setting_infiniband_get_mac_address (NMSettingInfiniband *setting); +guint32 nm_setting_infiniband_get_mtu (NMSettingInfiniband *setting); +const char * nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting); +int nm_setting_infiniband_get_p_key (NMSettingInfiniband *setting); +const char * nm_setting_infiniband_get_parent (NMSettingInfiniband *setting); + +const char * nm_setting_infiniband_get_virtual_interface_name (NMSettingInfiniband *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_INFINIBAND_H__ */ diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c new file mode 100644 index 00000000..e6f0401a --- /dev/null +++ b/libnm-core/nm-setting-ip-config.c @@ -0,0 +1,2363 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-ip-config.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" +#include "nm-utils.h" +#include "nm-glib-compat.h" +#include "nm-setting-private.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-ip-config + * @short_description: Abstract base class for IPv4 and IPv6 + * addressing, routing, and name service properties + * @include: nm-setting-ip-config.h + * @see_also: #NMSettingIP4Config, #NMSettingIP6Config + * + * #NMSettingIPConfig is the abstract base class of + * #NMSettingIP4Config and #NMSettingIP6Config, providing properties + * related to IP addressing, routing, and Domain Name Service. + **/ + +static char * +canonicalize_ip (int family, const char *ip, gboolean null_any) +{ + guint8 addr_bytes[sizeof (struct in6_addr)]; + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + int ret; + + if (!ip) { + g_return_val_if_fail (null_any == TRUE, NULL); + return NULL; + } + + ret = inet_pton (family, ip, addr_bytes); + g_return_val_if_fail (ret == 1, NULL); + + if (null_any) { + int addrlen = (family == AF_INET ? sizeof (struct in_addr) : sizeof (struct in6_addr)); + + if (!memcmp (addr_bytes, &in6addr_any, addrlen)) + return NULL; + } + + return g_strdup (inet_ntop (family, addr_bytes, addr_str, sizeof (addr_str))); +} + +static gboolean +valid_ip (int family, const char *ip, GError **error) +{ + if (!nm_utils_ipaddr_valid (family, ip)) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("Invalid IPv4 address '%s'") : _("Invalid IPv6 address '%s"), + ip); + return FALSE; + } else + return TRUE; +} + +static gboolean +valid_prefix (int family, guint prefix, GError **error, gboolean allow_zero_prefix) +{ + if ( (family == AF_INET && prefix > 32) + || (family == AF_INET6 && prefix > 128) + || (!allow_zero_prefix && prefix == 0)) { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + family == AF_INET ? _("Invalid IPv4 address prefix '%u'") : _("Invalid IPv6 address prefix '%u"), + prefix); + return FALSE; + } + + return TRUE; +} + +static gboolean +valid_metric (gint64 metric, GError **error) +{ + if (metric < -1 || metric > G_MAXUINT32) { + if (error) { + char buf[64]; + + /* We can't concatenate G_GINT64_FORMAT into a translatable string */ + g_snprintf (buf, sizeof (buf), "%" G_GINT64_FORMAT, metric); + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED, + _("Invalid routing metric '%s'"), buf); + } + return FALSE; + } + + return TRUE; +} + + +G_DEFINE_BOXED_TYPE (NMIPAddress, nm_ip_address, nm_ip_address_dup, nm_ip_address_unref) + +struct NMIPAddress { + guint refcount; + + char *address; + int prefix, family; + + GHashTable *attributes; +}; + +/** + * nm_ip_address_new: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @addr: the IP address + * @prefix: the address prefix length + * @error: location to store error, or %NULL + * + * Creates a new #NMIPAddress object. + * + * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error + **/ +NMIPAddress * +nm_ip_address_new (int family, + const char *addr, guint prefix, + GError **error) +{ + NMIPAddress *address; + + g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail (addr != NULL, NULL); + + if (!valid_ip (family, addr, error)) + return NULL; + if (!valid_prefix (family, prefix, error, FALSE)) + return NULL; + + address = g_slice_new0 (NMIPAddress); + address->refcount = 1; + + address->family = family; + address->address = canonicalize_ip (family, addr, FALSE); + address->prefix = prefix; + + return address; +} + +/** + * nm_ip_address_new_binary: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @addr: the IP address + * @prefix: the address prefix length + * @error: location to store error, or %NULL + * + * Creates a new #NMIPAddress object. @addr must point to a buffer of the + * correct size for @family. + * + * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error + **/ +NMIPAddress * +nm_ip_address_new_binary (int family, + gconstpointer addr, guint prefix, + GError **error) +{ + NMIPAddress *address; + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL); + g_return_val_if_fail (addr != NULL, NULL); + + if (!valid_prefix (family, prefix, error, FALSE)) + return NULL; + + address = g_slice_new0 (NMIPAddress); + address->refcount = 1; + + address->family = family; + address->address = g_strdup (inet_ntop (family, addr, string, sizeof (string))); + address->prefix = prefix; + + return address; +} + +/** + * nm_ip_address_ref: + * @address: the #NMIPAddress + * + * Increases the reference count of the object. + **/ +void +nm_ip_address_ref (NMIPAddress *address) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (address->refcount > 0); + + address->refcount++; +} + +/** + * nm_ip_address_unref: + * @address: the #NMIPAddress + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + **/ +void +nm_ip_address_unref (NMIPAddress *address) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (address->refcount > 0); + + address->refcount--; + if (address->refcount == 0) { + g_free (address->address); + if (address->attributes) + g_hash_table_unref (address->attributes); + g_slice_free (NMIPAddress, address); + } +} + +/** + * nm_ip_address_equal: + * @address: the #NMIPAddress + * @other: the #NMIPAddress to compare @address to. + * + * Determines if two #NMIPAddress objects contain the same address and prefix + * (attributes are not compared). + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + **/ +gboolean +nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other) +{ + g_return_val_if_fail (address != NULL, FALSE); + g_return_val_if_fail (address->refcount > 0, FALSE); + + g_return_val_if_fail (other != NULL, FALSE); + g_return_val_if_fail (other->refcount > 0, FALSE); + + if ( address->family != other->family + || address->prefix != other->prefix + || strcmp (address->address, other->address) != 0) + return FALSE; + return TRUE; +} + +/** + * nm_ip_address_dup: + * @address: the #NMIPAddress + * + * Creates a copy of @address + * + * Returns: (transfer full): a copy of @address + **/ +NMIPAddress * +nm_ip_address_dup (NMIPAddress *address) +{ + NMIPAddress *copy; + + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail (address->refcount > 0, NULL); + + copy = nm_ip_address_new (address->family, + address->address, address->prefix, + NULL); + if (address->attributes) { + GHashTableIter iter; + const char *key; + GVariant *value; + + g_hash_table_iter_init (&iter, address->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) + nm_ip_address_set_attribute (copy, key, value); + } + + return copy; +} + +/** + * nm_ip_address_get_family: + * @address: the #NMIPAddress + * + * Gets the IP address family (eg, AF_INET) property of this address + * object. + * + * Returns: the IP address family + **/ +int +nm_ip_address_get_family (NMIPAddress *address) +{ + g_return_val_if_fail (address != NULL, 0); + g_return_val_if_fail (address->refcount > 0, 0); + + return address->family; +} + +/** + * nm_ip_address_get_address: + * @address: the #NMIPAddress + * + * Gets the IP address property of this address object. + * + * Returns: the IP address + **/ +const char * +nm_ip_address_get_address (NMIPAddress *address) +{ + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail (address->refcount > 0, NULL); + + return address->address; +} + +/** + * nm_ip_address_set_address: + * @address: the #NMIPAddress + * @addr: the IP address, as a string + * + * Sets the IP address property of this address object. + * + * @addr must be a valid address of @address's family. If you aren't sure you + * have a valid address, use nm_utils_ipaddr_valid() to check it. + **/ +void +nm_ip_address_set_address (NMIPAddress *address, + const char *addr) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (addr != NULL); + g_return_if_fail (nm_utils_ipaddr_valid (address->family, addr)); + + g_free (address->address); + address->address = canonicalize_ip (address->family, addr, FALSE); +} + +/** + * nm_ip_address_get_address_binary: (skip) + * @address: the #NMIPAddress + * @addr: a buffer in which to store the address in binary format. + * + * Gets the IP address property of this address object. + * + * @addr must point to a buffer that is the correct size for @address's family. + **/ +void +nm_ip_address_get_address_binary (NMIPAddress *address, + gpointer addr) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (addr != NULL); + + inet_pton (address->family, address->address, addr); +} + +/** + * nm_ip_address_set_address_binary: (skip) + * @address: the #NMIPAddress + * @addr: the address, in binary format + * + * Sets the IP address property of this address object. + * + * @addr must point to a buffer that is the correct size for @address's family. + **/ +void +nm_ip_address_set_address_binary (NMIPAddress *address, + gconstpointer addr) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_if_fail (address != NULL); + g_return_if_fail (addr != NULL); + + g_free (address->address); + address->address = g_strdup (inet_ntop (address->family, addr, string, sizeof (string))); +} + +/** + * nm_ip_address_get_prefix: + * @address: the #NMIPAddress + * + * Gets the IP address prefix (ie "24" or "30" etc) property of this address + * object. + * + * Returns: the IP address prefix + **/ +guint +nm_ip_address_get_prefix (NMIPAddress *address) +{ + g_return_val_if_fail (address != NULL, 0); + g_return_val_if_fail (address->refcount > 0, 0); + + return address->prefix; +} + +/** + * nm_ip_address_set_prefix: + * @address: the #NMIPAddress + * @prefix: the IP address prefix + * + * Sets the IP address prefix property of this address object. + **/ +void +nm_ip_address_set_prefix (NMIPAddress *address, + guint prefix) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (valid_prefix (address->family, prefix, NULL, FALSE)); + + address->prefix = prefix; +} + +/** + * nm_ip_address_get_attribute_names: + * @address: the #NMIPAddress + * + * Gets an array of attribute names defined on @address. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names, + **/ +char ** +nm_ip_address_get_attribute_names (NMIPAddress *address) +{ + GHashTableIter iter; + const char *key; + GPtrArray *names; + + g_return_val_if_fail (address != NULL, NULL); + + names = g_ptr_array_new (); + + if (address->attributes) { + g_hash_table_iter_init (&iter, address->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) + g_ptr_array_add (names, g_strdup (key)); + } + g_ptr_array_add (names, NULL); + + return (char **) g_ptr_array_free (names, FALSE); +} + +/** + * nm_ip_address_get_attribute: + * @address: the #NMIPAddress + * @name: the name of an address attribute + * + * Gets the value of the attribute with name @name on @address + * + * Returns: (transfer none): the value of the attribute with name @name on + * @address, or %NULL if @address has no such attribute. + **/ +GVariant * +nm_ip_address_get_attribute (NMIPAddress *address, const char *name) +{ + g_return_val_if_fail (address != NULL, NULL); + g_return_val_if_fail (name != NULL && *name != '\0', NULL); + + if (address->attributes) + return g_hash_table_lookup (address->attributes, name); + else + return NULL; +} + +/** + * nm_ip_address_set_attribute: + * @address: the #NMIPAddress + * @name: the name of an address attribute + * @value: (transfer none) (allow-none): the value + * + * Sets or clears the named attribute on @address to the given value. + **/ +void +nm_ip_address_set_attribute (NMIPAddress *address, const char *name, GVariant *value) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (name != NULL && *name != '\0'); + g_return_if_fail (strcmp (name, "address") != 0 && strcmp (name, "prefix") != 0); + + if (!address->attributes) { + address->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert (address->attributes, g_strdup (name), g_variant_ref_sink (value)); + else + g_hash_table_remove (address->attributes, name); +} + + +G_DEFINE_BOXED_TYPE (NMIPRoute, nm_ip_route, nm_ip_route_dup, nm_ip_route_unref) + +struct NMIPRoute { + guint refcount; + + int family; + char *dest; + guint prefix; + char *next_hop; + gint64 metric; + + GHashTable *attributes; +}; + +/** + * nm_ip_route_new: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @dest: the IP address of the route's destination + * @prefix: the address prefix length + * @next_hop: (allow-none): the IP address of the next hop (or %NULL) + * @metric: the route metric (or -1 for "default") + * @error: location to store error, or %NULL + * + * Creates a new #NMIPRoute object. + * + * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error + **/ +NMIPRoute * +nm_ip_route_new (int family, + const char *dest, + guint prefix, + const char *next_hop, + gint64 metric, + GError **error) +{ + NMIPRoute *route; + + g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL); + + if (!valid_ip (family, dest, error)) + return NULL; + if (!valid_prefix (family, prefix, error, TRUE)) + return NULL; + if (next_hop && !valid_ip (family, next_hop, error)) + return NULL; + if (!valid_metric (metric, error)) + return NULL; + + route = g_slice_new0 (NMIPRoute); + route->refcount = 1; + + route->family = family; + route->dest = canonicalize_ip (family, dest, FALSE); + route->prefix = prefix; + route->next_hop = canonicalize_ip (family, next_hop, TRUE); + route->metric = metric; + + return route; +} + +/** + * nm_ip_route_new_binary: + * @family: the IP address family (AF_INET or + * AF_INET6) + * @dest: the IP address of the route's destination + * @prefix: the address prefix length + * @next_hop: (allow-none): the IP address of the next hop (or %NULL) + * @metric: the route metric (or -1 for "default") + * @error: location to store error, or %NULL + * + * Creates a new #NMIPRoute object. @dest and @next_hop (if non-%NULL) must + * point to buffers of the correct size for @family. + * + * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error + **/ +NMIPRoute * +nm_ip_route_new_binary (int family, + gconstpointer dest, + guint prefix, + gconstpointer next_hop, + gint64 metric, + GError **error) +{ + NMIPRoute *route; + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL); + + if (!valid_prefix (family, prefix, error, TRUE)) + return NULL; + if (!valid_metric (metric, error)) + return NULL; + + route = g_slice_new0 (NMIPRoute); + route->refcount = 1; + + route->family = family; + route->dest = g_strdup (inet_ntop (family, dest, string, sizeof (string))); + route->prefix = prefix; + if (next_hop) + route->next_hop = g_strdup (inet_ntop (family, next_hop, string, sizeof (string))); + route->metric = metric; + + return route; +} + +/** + * nm_ip_route_ref: + * @route: the #NMIPRoute + * + * Increases the reference count of the object. + **/ +void +nm_ip_route_ref (NMIPRoute *route) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (route->refcount > 0); + + route->refcount++; +} + +/** + * nm_ip_route_unref: + * @route: the #NMIPRoute + * + * Decreases the reference count of the object. If the reference count + * reaches zero, the object will be destroyed. + **/ +void +nm_ip_route_unref (NMIPRoute *route) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (route->refcount > 0); + + route->refcount--; + if (route->refcount == 0) { + g_free (route->dest); + g_free (route->next_hop); + if (route->attributes) + g_hash_table_unref (route->attributes); + g_slice_free (NMIPRoute, route); + } +} + +/** + * nm_ip_route_equal: + * @route: the #NMIPRoute + * @other: the #NMIPRoute to compare @route to. + * + * Determines if two #NMIPRoute objects contain the same destination, prefix, + * next hop, and metric. (Attributes are not compared.) + * + * Returns: %TRUE if the objects contain the same values, %FALSE if they do not. + **/ +gboolean +nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other) +{ + g_return_val_if_fail (route != NULL, FALSE); + g_return_val_if_fail (route->refcount > 0, FALSE); + + g_return_val_if_fail (other != NULL, FALSE); + g_return_val_if_fail (other->refcount > 0, FALSE); + + if ( route->prefix != other->prefix + || route->metric != other->metric + || strcmp (route->dest, other->dest) != 0 + || g_strcmp0 (route->next_hop, other->next_hop) != 0) + return FALSE; + return TRUE; +} + +/** + * nm_ip_route_dup: + * @route: the #NMIPRoute + * + * Creates a copy of @route + * + * Returns: (transfer full): a copy of @route + **/ +NMIPRoute * +nm_ip_route_dup (NMIPRoute *route) +{ + NMIPRoute *copy; + + g_return_val_if_fail (route != NULL, NULL); + g_return_val_if_fail (route->refcount > 0, NULL); + + copy = nm_ip_route_new (route->family, + route->dest, route->prefix, + route->next_hop, route->metric, + NULL); + if (route->attributes) { + GHashTableIter iter; + const char *key; + GVariant *value; + + g_hash_table_iter_init (&iter, route->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) + nm_ip_route_set_attribute (copy, key, value); + } + + return copy; +} + +/** + * nm_ip_route_get_family: + * @route: the #NMIPRoute + * + * Gets the IP address family (eg, AF_INET) property of this route + * object. + * + * Returns: the IP address family + **/ +int +nm_ip_route_get_family (NMIPRoute *route) +{ + g_return_val_if_fail (route != NULL, 0); + g_return_val_if_fail (route->refcount > 0, 0); + + return route->family; +} + +/** + * nm_ip_route_get_dest: + * @route: the #NMIPRoute + * + * Gets the IP destination address property of this route object. + * + * Returns: the IP address of the route's destination + **/ +const char * +nm_ip_route_get_dest (NMIPRoute *route) +{ + g_return_val_if_fail (route != NULL, NULL); + g_return_val_if_fail (route->refcount > 0, NULL); + + return route->dest; +} + +/** + * nm_ip_route_set_dest: + * @route: the #NMIPRoute + * @dest: the route's destination, as a string + * + * Sets the destination property of this route object. + * + * @dest must be a valid address of @route's family. If you aren't sure you + * have a valid address, use nm_utils_ipaddr_valid() to check it. + **/ +void +nm_ip_route_set_dest (NMIPRoute *route, + const char *dest) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (dest != NULL); + g_return_if_fail (nm_utils_ipaddr_valid (route->family, dest)); + + g_free (route->dest); + route->dest = canonicalize_ip (route->family, dest, FALSE); +} + +/** + * nm_ip_route_get_dest_binary: (skip) + * @route: the #NMIPRoute + * @dest: a buffer in which to store the destination in binary format. + * + * Gets the destination property of this route object. + * + * @dest must point to a buffer that is the correct size for @route's family. + **/ +void +nm_ip_route_get_dest_binary (NMIPRoute *route, + gpointer dest) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (dest != NULL); + + inet_pton (route->family, route->dest, dest); +} + +/** + * nm_ip_route_set_dest_binary: (skip) + * @route: the #NMIPRoute + * @dest: the route's destination, in binary format + * + * Sets the destination property of this route object. + * + * @dest must point to a buffer that is the correct size for @route's family. + **/ +void +nm_ip_route_set_dest_binary (NMIPRoute *route, + gconstpointer dest) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_if_fail (route != NULL); + g_return_if_fail (dest != NULL); + + g_free (route->dest); + route->dest = g_strdup (inet_ntop (route->family, dest, string, sizeof (string))); +} + +/** + * nm_ip_route_get_prefix: + * @route: the #NMIPRoute + * + * Gets the IP prefix (ie "24" or "30" etc) of this route. + * + * Returns: the IP prefix + **/ +guint +nm_ip_route_get_prefix (NMIPRoute *route) +{ + g_return_val_if_fail (route != NULL, 0); + g_return_val_if_fail (route->refcount > 0, 0); + + return route->prefix; +} + +/** + * nm_ip_route_set_prefix: + * @route: the #NMIPRoute + * @prefix: the route prefix + * + * Sets the prefix property of this route object. + **/ +void +nm_ip_route_set_prefix (NMIPRoute *route, + guint prefix) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (valid_prefix (route->family, prefix, NULL, TRUE)); + + route->prefix = prefix; +} + +/** + * nm_ip_route_get_next_hop: + * @route: the #NMIPRoute + * + * Gets the IP address of the next hop of this route; this will be %NULL if the + * route has no next hop. + * + * Returns: the IP address of the next hop, or %NULL if this is a device route. + **/ +const char * +nm_ip_route_get_next_hop (NMIPRoute *route) +{ + g_return_val_if_fail (route != NULL, NULL); + g_return_val_if_fail (route->refcount > 0, NULL); + + return route->next_hop; +} + +/** + * nm_ip_route_set_next_hop: + * @route: the #NMIPRoute + * @next_hop: (allow-none): the route's next hop, as a string + * + * Sets the next-hop property of this route object. + * + * @next_hop (if non-%NULL) must be a valid address of @route's family. If you + * aren't sure you have a valid address, use nm_utils_ipaddr_valid() to check + * it. + **/ +void +nm_ip_route_set_next_hop (NMIPRoute *route, + const char *next_hop) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (!next_hop || nm_utils_ipaddr_valid (route->family, next_hop)); + + g_free (route->next_hop); + route->next_hop = canonicalize_ip (route->family, next_hop, TRUE); +} + +/** + * nm_ip_route_get_next_hop_binary: (skip) + * @route: the #NMIPRoute + * @next_hop: a buffer in which to store the next hop in binary format. + * + * Gets the next hop property of this route object. + * + * @next_hop must point to a buffer that is the correct size for @route's family. + * + * Returns: %TRUE if @route has a next hop, %FALSE if not (in which case + * @next_hop will be zeroed out) + **/ +gboolean +nm_ip_route_get_next_hop_binary (NMIPRoute *route, + gpointer next_hop) +{ + g_return_val_if_fail (route != NULL, FALSE); + g_return_val_if_fail (next_hop != NULL, FALSE); + + if (route->next_hop) { + inet_pton (route->family, route->next_hop, next_hop); + return TRUE; + } else { + memset (next_hop, 0, + route->family == AF_INET ? sizeof (struct in_addr) : sizeof (struct in6_addr)); + return FALSE; + } +} + +/** + * nm_ip_route_set_next_hop_binary: (skip) + * @route: the #NMIPRoute + * @next_hop: the route's next hop, in binary format + * + * Sets the destination property of this route object. + * + * @next_hop (if non-%NULL) must point to a buffer that is the correct size for + * @route's family. + **/ +void +nm_ip_route_set_next_hop_binary (NMIPRoute *route, + gconstpointer next_hop) +{ + char string[NM_UTILS_INET_ADDRSTRLEN]; + + g_return_if_fail (route != NULL); + + g_free (route->next_hop); + if (next_hop) + route->next_hop = g_strdup (inet_ntop (route->family, next_hop, string, sizeof (string))); + else + route->next_hop = NULL; +} + +/** + * nm_ip_route_get_metric: + * @route: the #NMIPRoute + * + * Gets the route metric property of this route object; lower values + * indicate "better" or more preferred routes; -1 indicates "default" + * (meaning NetworkManager will set it appropriately). + * + * Returns: the route metric + **/ +gint64 +nm_ip_route_get_metric (NMIPRoute *route) +{ + g_return_val_if_fail (route != NULL, 0); + g_return_val_if_fail (route->refcount > 0, 0); + + return route->metric; +} + +/** + * nm_ip_route_set_metric: + * @route: the #NMIPRoute + * @metric: the route metric (or -1 for "default") + * + * Sets the metric property of this route object. + **/ +void +nm_ip_route_set_metric (NMIPRoute *route, + gint64 metric) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (valid_metric (metric, NULL)); + + route->metric = metric; +} + +/** + * nm_ip_route_get_attribute_names: + * @route: the #NMIPRoute + * + * Gets an array of attribute names defined on @route. + * + * Returns: (transfer full): a %NULL-terminated array of attribute names + **/ +char ** +nm_ip_route_get_attribute_names (NMIPRoute *route) +{ + GHashTableIter iter; + const char *key; + GPtrArray *names; + + g_return_val_if_fail (route != NULL, NULL); + + names = g_ptr_array_new (); + + if (route->attributes) { + g_hash_table_iter_init (&iter, route->attributes); + while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) + g_ptr_array_add (names, g_strdup (key)); + } + g_ptr_array_add (names, NULL); + + return (char **) g_ptr_array_free (names, FALSE); +} + +/** + * nm_ip_route_get_attribute: + * @route: the #NMIPRoute + * @name: the name of an route attribute + * + * Gets the value of the attribute with name @name on @route + * + * Returns: (transfer none): the value of the attribute with name @name on + * @route, or %NULL if @route has no such attribute. + **/ +GVariant * +nm_ip_route_get_attribute (NMIPRoute *route, const char *name) +{ + g_return_val_if_fail (route != NULL, NULL); + g_return_val_if_fail (name != NULL && *name != '\0', NULL); + + if (route->attributes) + return g_hash_table_lookup (route->attributes, name); + else + return NULL; +} + +/** + * nm_ip_route_set_attribute: + * @route: the #NMIPRoute + * @name: the name of a route attribute + * @value: (transfer none) (allow-none): the value + * + * Sets the named attribute on @route to the given value. + **/ +void +nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value) +{ + g_return_if_fail (route != NULL); + g_return_if_fail (name != NULL && *name != '\0'); + g_return_if_fail ( strcmp (name, "dest") != 0 && strcmp (name, "prefix") != 0 + && strcmp (name, "next-hop") != 0 && strcmp (name, "metric") != 0); + + if (!route->attributes) { + route->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_variant_unref); + } + + if (value) + g_hash_table_insert (route->attributes, g_strdup (name), g_variant_ref_sink (value)); + else + g_hash_table_remove (route->attributes, name); +} + + +G_DEFINE_ABSTRACT_TYPE (NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING) + +#define NM_SETTING_IP_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigPrivate)) + +typedef struct { + char *method; + GPtrArray *dns; /* array of IP address strings */ + GPtrArray *dns_search; /* array of domain name strings */ + GPtrArray *addresses; /* array of NMIPAddress */ + GPtrArray *routes; /* array of NMIPRoute */ + gint64 route_metric; + char *gateway; + gboolean ignore_auto_routes; + gboolean ignore_auto_dns; + char *dhcp_hostname; + gboolean dhcp_send_hostname; + gboolean never_default; + gboolean may_fail; +} NMSettingIPConfigPrivate; + +enum { + PROP_0, + PROP_METHOD, + PROP_DNS, + PROP_DNS_SEARCH, + PROP_ADDRESSES, + PROP_GATEWAY, + PROP_ROUTES, + PROP_ROUTE_METRIC, + PROP_IGNORE_AUTO_ROUTES, + PROP_IGNORE_AUTO_DNS, + PROP_DHCP_HOSTNAME, + PROP_DHCP_SEND_HOSTNAME, + PROP_NEVER_DEFAULT, + PROP_MAY_FAIL, + + LAST_PROP +}; + +#define NM_SETTING_IP_CONFIG_GET_FAMILY(setting) (NM_IS_SETTING_IP4_CONFIG (setting) ? AF_INET : AF_INET6) + +/** + * nm_setting_ip_config_get_method: + * @setting: the #NMSettingIPConfig + * + * Returns: the #NMSettingIPConfig:method property of the setting; see + * #NMSettingIP4Config and #NMSettingIP6Config for details of the + * methods available with each type. + **/ +const char * +nm_setting_ip_config_get_method (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->method; +} + +/** + * nm_setting_ip_config_get_num_dns: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS servers + **/ +guint +nm_setting_ip_config_get_num_dns (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns->len; +} + +/** + * nm_setting_ip_config_get_dns: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS server to return + * + * Returns: the IP address of the DNS server at index @i + **/ +const char * +nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (i < priv->dns->len, NULL); + + return priv->dns->pdata[i]; +} + +/** + * nm_setting_ip_config_add_dns: + * @setting: the #NMSettingIPConfig + * @dns: the IP address of the DNS server to add + * + * Adds a new DNS server to the setting. + * + * Returns: %TRUE if the DNS server was added; %FALSE if the server was already + * known + **/ +gboolean +nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, const char *dns) +{ + NMSettingIPConfigPrivate *priv; + char *dns_canonical; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns != NULL, FALSE); + g_return_val_if_fail (nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + dns_canonical = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns, FALSE); + for (i = 0; i < priv->dns->len; i++) { + if (!strcmp (dns_canonical, priv->dns->pdata[i])) { + g_free (dns_canonical); + return FALSE; + } + } + + g_ptr_array_add (priv->dns, dns_canonical); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS server to remove + * + * Removes the DNS server at index @i. + **/ +void +nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (i < priv->dns->len); + + g_ptr_array_remove_index (priv->dns, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); +} + +/** + * nm_setting_ip_config_remove_dns_by_value: + * @setting: the #NMSettingIPConfig + * @dns: the DNS server to remove + * + * Removes the DNS server @dns. + * + * Returns: %TRUE if the DNS server was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_dns_by_value (NMSettingIPConfig *setting, const char *dns) +{ + NMSettingIPConfigPrivate *priv; + char *dns_canonical; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns != NULL, FALSE); + g_return_val_if_fail (nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + dns_canonical = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns, FALSE); + for (i = 0; i < priv->dns->len; i++) { + if (!strcmp (dns_canonical, priv->dns->pdata[i])) { + g_ptr_array_remove_index (priv->dns, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); + g_free (dns_canonical); + return TRUE; + } + } + g_free (dns_canonical); + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DNS servers. + **/ +void +nm_setting_ip_config_clear_dns (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_ptr_array_set_size (priv->dns, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS); +} + +/** + * nm_setting_ip_config_get_num_dns_searches: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured DNS search domains + **/ +guint +nm_setting_ip_config_get_num_dns_searches (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_search->len; +} + +/** + * nm_setting_ip_config_get_dns_search: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS search domain to return + * + * Returns: the DNS search domain at index @i + **/ +const char * +nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (i < priv->dns_search->len, NULL); + + return priv->dns_search->pdata[i]; +} + +/** + * nm_setting_ip_config_add_dns_search: + * @setting: the #NMSettingIPConfig + * @dns_search: the search domain to add + * + * Adds a new DNS search domain to the setting. + * + * Returns: %TRUE if the DNS search domain was added; %FALSE if the search + * domain was already known + **/ +gboolean +nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting, + const char *dns_search) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_search != NULL, FALSE); + g_return_val_if_fail (dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->dns_search->len; i++) { + if (!strcmp (dns_search, priv->dns_search->pdata[i])) + return FALSE; + } + + g_ptr_array_add (priv->dns_search, g_strdup (dns_search)); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_dns_search: + * @setting: the #NMSettingIPConfig + * @i: index number of the DNS search domain + * + * Removes the DNS search domain at index @i. + **/ +void +nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (i < priv->dns_search->len); + + g_ptr_array_remove_index (priv->dns_search, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); +} + +/** + * nm_setting_ip_config_remove_dns_search_by_value: + * @setting: the #NMSettingIPConfig + * @dns_search: the search domain to remove + * + * Removes the DNS search domain @dns_search. + * + * Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not. + * + * Since 0.9.10 + **/ +gboolean +nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting, + const char *dns_search) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (dns_search != NULL, FALSE); + g_return_val_if_fail (dns_search[0] != '\0', FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->dns_search->len; i++) { + if (!strcmp (dns_search, priv->dns_search->pdata[i])) { + g_ptr_array_remove_index (priv->dns_search, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_dns_searches: + * @setting: the #NMSettingIPConfig + * + * Removes all configured DNS search domains. + **/ +void +nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_ptr_array_set_size (priv->dns_search, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH); +} + +/** + * nm_setting_ip_config_get_num_addresses: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured addresses + **/ +guint +nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->addresses->len; +} + +/** + * nm_setting_ip_config_get_address: + * @setting: the #NMSettingIPConfig + * @i: index number of the address to return + * + * Returns: the address at index @i + **/ +NMIPAddress * +nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (i < priv->addresses->len, NULL); + + return priv->addresses->pdata[i]; +} + +/** + * nm_setting_ip_config_add_address: + * @setting: the #NMSettingIPConfig + * @address: the new address to add + * + * Adds a new IP address and associated information to the setting. The + * given address is duplicated internally and is not changed by this function. + * + * Returns: %TRUE if the address was added; %FALSE if the address was already + * known. + **/ +gboolean +nm_setting_ip_config_add_address (NMSettingIPConfig *setting, + NMIPAddress *address) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (address != NULL, FALSE); + g_return_val_if_fail (address->family == NM_SETTING_IP_CONFIG_GET_FAMILY (setting), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->addresses->len; i++) { + if (nm_ip_address_equal (priv->addresses->pdata[i], address)) + return FALSE; + } + + g_ptr_array_add (priv->addresses, nm_ip_address_dup (address)); + + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_address: + * @setting: the #NMSettingIPConfig + * @i: index number of the address to remove + * + * Removes the address at index @i. + **/ +void +nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (i < priv->addresses->len); + + g_ptr_array_remove_index (priv->addresses, i); + + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES); +} + +/** + * nm_setting_ip_config_remove_address_by_value: + * @setting: the #NMSettingIPConfig + * @address: the IP address to remove + * + * Removes the address @address. + * + * Returns: %TRUE if the address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig *setting, + NMIPAddress *address) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (address != NULL, FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->addresses->len; i++) { + if (nm_ip_address_equal (priv->addresses->pdata[i], address)) { + g_ptr_array_remove_index (priv->addresses, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_addresses: + * @setting: the #NMSettingIPConfig + * + * Removes all configured addresses. + **/ +void +nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + g_ptr_array_set_size (priv->addresses, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES); +} + +/** + * nm_setting_ip_config_get_gateway: + * @setting: the #NMSettingIPConfig + * + * Returns: the IP address of the gateway associated with this configuration, or + * %NULL. + **/ +const char * +nm_setting_ip_config_get_gateway (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->gateway; +} + +/** + * nm_setting_ip_config_get_num_routes: + * @setting: the #NMSettingIPConfig + * + * Returns: the number of configured routes + **/ +guint +nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->routes->len; +} + +/** + * nm_setting_ip_config_get_route: + * @setting: the #NMSettingIPConfig + * @i: index number of the route to return + * + * Returns: the route at index @i + **/ +NMIPRoute * +nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_val_if_fail (i < priv->routes->len, NULL); + + return priv->routes->pdata[i]; +} + +/** + * nm_setting_ip_config_add_route: + * @setting: the #NMSettingIPConfig + * @route: the route to add + * + * Adds a new route and associated information to the setting. The + * given route is duplicated internally and is not changed by this function. + * + * Returns: %TRUE if the route was added; %FALSE if the route was already known. + **/ +gboolean +nm_setting_ip_config_add_route (NMSettingIPConfig *setting, + NMIPRoute *route) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (route != NULL, FALSE); + g_return_val_if_fail (route->family == NM_SETTING_IP_CONFIG_GET_FAMILY (setting), FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->routes->len; i++) { + if (nm_ip_route_equal (priv->routes->pdata[i], route)) + return FALSE; + } + + g_ptr_array_add (priv->routes, nm_ip_route_dup (route)); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); + return TRUE; +} + +/** + * nm_setting_ip_config_remove_route: + * @setting: the #NMSettingIPConfig + * @i: index number of the route + * + * Removes the route at index @i. + **/ +void +nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int i) +{ + NMSettingIPConfigPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + g_return_if_fail (i < priv->routes->len); + + g_ptr_array_remove_index (priv->routes, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); +} + +/** + * nm_setting_ip_config_remove_route_by_value: + * @setting: the #NMSettingIPConfig + * @route: the route to remove + * + * Removes the route @route. + * + * Returns: %TRUE if the route was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, + NMIPRoute *route) +{ + NMSettingIPConfigPrivate *priv; + int i; + + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + g_return_val_if_fail (route != NULL, FALSE); + + priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + for (i = 0; i < priv->routes->len; i++) { + if (nm_ip_route_equal (priv->routes->pdata[i], route)) { + g_ptr_array_remove_index (priv->routes, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_ip_config_clear_routes: + * @setting: the #NMSettingIPConfig + * + * Removes all configured routes. + **/ +void +nm_setting_ip_config_clear_routes (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting)); + + g_ptr_array_set_size (priv->routes, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES); +} + +/** + * nm_setting_ip_config_get_route_metric: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:route-metric + * property. + * + * Returns: the route metric that is used for routes that don't explicitly + * specify a metric. See #NMSettingIPConfig:route-metric for more details. + **/ +gint64 +nm_setting_ip_config_get_route_metric (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), -1); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->route_metric; +} + + +/** + * nm_setting_ip_config_get_ignore_auto_routes: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:ignore-auto-routes + * property. + * + * Returns: %TRUE if automatically configured (ie via DHCP) routes should be + * ignored. + **/ +gboolean +nm_setting_ip_config_get_ignore_auto_routes (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->ignore_auto_routes; +} + +/** + * nm_setting_ip_config_get_ignore_auto_dns: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:ignore-auto-dns + * property. + * + * Returns: %TRUE if automatically configured (ie via DHCP) DNS information + * should be ignored. + **/ +gboolean +nm_setting_ip_config_get_ignore_auto_dns (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->ignore_auto_dns; +} + +/** + * nm_setting_ip_config_get_dhcp_hostname: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-hostname + * property. + * + * Returns: the configured hostname to send to the DHCP server + **/ +const char * +nm_setting_ip_config_get_dhcp_hostname (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dhcp_hostname; +} + +/** + * nm_setting_ip_config_get_dhcp_send_hostname: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-send-hostname + * property. + * + * Returns: %TRUE if NetworkManager should send the machine hostname to the + * DHCP server when requesting addresses to allow the server to automatically + * update DNS information for this machine. + **/ +gboolean +nm_setting_ip_config_get_dhcp_send_hostname (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dhcp_send_hostname; +} + +/** + * nm_setting_ip_config_get_never_default: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:never-default + * property. + * + * Returns: %TRUE if this connection should never be the default + * connection + **/ +gboolean +nm_setting_ip_config_get_never_default (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->never_default; +} + +/** + * nm_setting_ip_config_get_may_fail: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:may-fail + * property. + * + * Returns: %TRUE if this connection doesn't require this type of IP + * addressing to complete for the connection to succeed. + **/ +gboolean +nm_setting_ip_config_get_may_fail (NMSettingIPConfig *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->may_fail; +} + +static gboolean +verify_label (const char *label) +{ + const char *p; + char *iface; + + p = strchr (label, ':'); + if (!p) + return FALSE; + iface = g_strndup (label, p - label); + if (!nm_utils_iface_valid_name (iface)) { + g_free (iface); + return FALSE; + } + g_free (iface); + + for (p++; *p; p++) { + if (!g_ascii_isalnum (*p) && *p != '_') + return FALSE; + } + + return TRUE; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + int i; + + if (!priv->method) { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if (priv->dhcp_hostname && !*priv->dhcp_hostname) { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_DHCP_HOSTNAME); + return FALSE; + } + + /* Validate DNS */ + for (i = 0; i < priv->dns->len; i++) { + const char *dns = priv->dns->pdata[i]; + + if (!nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. DNS server address is invalid"), + i+1); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + } + + /* Validate addresses */ + for (i = 0; i < priv->addresses->len; i++) { + NMIPAddress *addr = (NMIPAddress *) priv->addresses->pdata[i]; + GVariant *label; + + if (nm_ip_address_get_family (addr) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address is invalid"), + i+1); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + + label = nm_ip_address_get_attribute (addr, "label"); + if (label) { + if (!g_variant_is_of_type (label, G_VARIANT_TYPE_STRING)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address has 'label' property with invalid type"), + i+1); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + if (!verify_label (g_variant_get_string (label, NULL))) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. IP address has invalid label '%s'"), + i+1, g_variant_get_string (label, NULL)); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } + } + + /* Validate gateway */ + if (priv->gateway) { + if (!priv->addresses->len) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("gateway cannot be set if there are no addresses configured")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY); + return FALSE; + } + + if (!nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), priv->gateway)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("gateway is invalid")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY); + return FALSE; + } + } + + /* Validate routes */ + for (i = 0; i < priv->routes->len; i++) { + NMIPRoute *route = (NMIPRoute *) priv->routes->pdata[i]; + + if (nm_ip_route_get_family (route) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. route is invalid"), + i+1); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } + if (nm_ip_route_get_prefix (route) == 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%d. route cannot be a default route"), + i+1); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } + } + + return TRUE; +} + + +static void +nm_setting_ip_config_init (NMSettingIPConfig *setting) +{ + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + priv->dns = g_ptr_array_new_with_free_func (g_free); + priv->dns_search = g_ptr_array_new_with_free_func (g_free); + priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); +} + +static void +finalize (GObject *object) +{ + NMSettingIPConfig *self = NM_SETTING_IP_CONFIG (object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (self); + + g_free (priv->method); + g_free (priv->gateway); + g_free (priv->dhcp_hostname); + + g_ptr_array_unref (priv->dns); + g_ptr_array_unref (priv->dns_search); + g_ptr_array_unref (priv->addresses); + g_ptr_array_unref (priv->routes); + + G_OBJECT_CLASS (nm_setting_ip_config_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + const char *gateway; + + switch (prop_id) { + case PROP_METHOD: + g_free (priv->method); + priv->method = g_value_dup_string (value); + break; + case PROP_DNS: + g_ptr_array_unref (priv->dns); + priv->dns = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); + break; + case PROP_DNS_SEARCH: + g_ptr_array_unref (priv->dns_search); + priv->dns_search = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value)); + break; + case PROP_ADDRESSES: + g_ptr_array_unref (priv->addresses); + priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value), + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref); + break; + case PROP_GATEWAY: + gateway = g_value_get_string (value); + g_return_if_fail (!gateway || nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway)); + g_free (priv->gateway); + priv->gateway = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway, TRUE); + break; + case PROP_ROUTES: + g_ptr_array_unref (priv->routes); + priv->routes = _nm_utils_copy_array (g_value_get_boxed (value), + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref); + break; + case PROP_ROUTE_METRIC: + priv->route_metric = g_value_get_int64 (value); + break; + case PROP_IGNORE_AUTO_ROUTES: + priv->ignore_auto_routes = g_value_get_boolean (value); + break; + case PROP_IGNORE_AUTO_DNS: + priv->ignore_auto_dns = g_value_get_boolean (value); + break; + case PROP_DHCP_HOSTNAME: + g_free (priv->dhcp_hostname); + priv->dhcp_hostname = g_value_dup_string (value); + break; + case PROP_DHCP_SEND_HOSTNAME: + priv->dhcp_send_hostname = g_value_get_boolean (value); + break; + case PROP_NEVER_DEFAULT: + priv->never_default = g_value_get_boolean (value); + break; + case PROP_MAY_FAIL: + priv->may_fail = g_value_get_boolean (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) +{ + NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object); + NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_METHOD: + g_value_set_string (value, nm_setting_ip_config_get_method (setting)); + break; + case PROP_DNS: + g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns)); + break; + case PROP_DNS_SEARCH: + g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_search)); + break; + case PROP_ADDRESSES: + g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses, + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref)); + break; + case PROP_GATEWAY: + g_value_set_string (value, nm_setting_ip_config_get_gateway (setting)); + break; + case PROP_ROUTES: + g_value_take_boxed (value, _nm_utils_copy_array (priv->routes, + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref)); + break; + case PROP_ROUTE_METRIC: + g_value_set_int64 (value, priv->route_metric); + break; + case PROP_IGNORE_AUTO_ROUTES: + g_value_set_boolean (value, nm_setting_ip_config_get_ignore_auto_routes (setting)); + break; + case PROP_IGNORE_AUTO_DNS: + g_value_set_boolean (value, nm_setting_ip_config_get_ignore_auto_dns (setting)); + break; + case PROP_DHCP_HOSTNAME: + g_value_set_string (value, nm_setting_ip_config_get_dhcp_hostname (setting)); + break; + case PROP_DHCP_SEND_HOSTNAME: + g_value_set_boolean (value, nm_setting_ip_config_get_dhcp_send_hostname (setting)); + break; + case PROP_NEVER_DEFAULT: + g_value_set_boolean (value, priv->never_default); + break; + case PROP_MAY_FAIL: + g_value_set_boolean (value, priv->may_fail); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ip_gateway_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + /* Don't set from 'gateway' if we're going to use the gateway in 'addresses' */ + if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "gateway")) + return; + + g_object_set (setting, property, g_variant_get_string (value, NULL), NULL); +} + +static void +nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingIPConfigPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingIPConfig:method: + * + * IP configuration method. + * + * #NMSettingIP4Config and #NMSettingIP6Config both support "auto", + * "manual", and "link-local". See the subclass-specific documentation for + * other values. + * + * In general, for the "auto" method, properties such as + * #NMSettingIPConfig:dns and #NMSettingIPConfig:routes specify information + * that is added on to the information returned from automatic + * configuration. The #NMSettingIPConfig:ignore-auto-routes and + * #NMSettingIPConfig:ignore-auto-dns properties modify this behavior. + * + * For methods that imply no upstream network, such as "shared" or + * "link-local", these properties must be empty. + **/ + g_object_class_install_property + (object_class, PROP_METHOD, + g_param_spec_string (NM_SETTING_IP_CONFIG_METHOD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:dns: + * + * Array of IP addresses of DNS servers. + **/ + g_object_class_install_property + (object_class, PROP_DNS, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:dns-search: + * + * Array of DNS search domains. + **/ + g_object_class_install_property + (object_class, PROP_DNS_SEARCH, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_SEARCH, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:addresses: + * + * Array of IP addresses. + * + * Element-Type: NMIPAddress + **/ + g_object_class_install_property + (object_class, PROP_ADDRESSES, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_ADDRESSES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + /* "addresses" is a legacy D-Bus property, because the + * "addresses" GObject property normally gets set from + * the "address-data" D-Bus property... + */ + NM_SETTING_PARAM_LEGACY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:gateway: + * + * The gateway associated with this configuration. This is only meaningful + * if #NMSettingIPConfig:addresses is also set. + **/ + g_object_class_install_property + (object_class, PROP_GATEWAY, + g_param_spec_string (NM_SETTING_IP_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + _nm_setting_class_override_property (parent_class, + NM_SETTING_IP_CONFIG_GATEWAY, + G_VARIANT_TYPE_STRING, + NULL, + ip_gateway_set, + NULL); + + /** + * NMSettingIPConfig:routes: + * + * Array of IP routes. + * + * Element-Type: NMIPRoute + **/ + g_object_class_install_property + (object_class, PROP_ROUTES, + g_param_spec_boxed (NM_SETTING_IP_CONFIG_ROUTES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + /* See :addresses above Re: LEGACY */ + NM_SETTING_PARAM_LEGACY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:route-metric: + * + * The default metric for routes that don't explicitly specify a metric. + * The default value -1 means that the metric is choosen automatically + * based on the device type. + * The metric applies to dynamic routes, manual (static) routes that + * don't have an explicit metric setting, address prefix routes, and + * the default route. + * Note that for IPv6, the kernel accepts zero (0) but coerces it to + * 1024 (user default). Hence, setting this property to zero effectively + * mean setting it to 1024. + * For IPv4, zero is a regular value for the metric. + **/ + g_object_class_install_property + (object_class, PROP_ROUTE_METRIC, + g_param_spec_int64 (NM_SETTING_IP_CONFIG_ROUTE_METRIC, "", "", + -1, G_MAXUINT32, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:ignore-auto-routes: + * + * When #NMSettingIPConfig:method is set to "auto" and this property to + * %TRUE, automatically configured routes are ignored and only routes + * specified in the #NMSettingIPConfig:routes property, if any, are used. + **/ + g_object_class_install_property + (object_class, PROP_IGNORE_AUTO_ROUTES, + g_param_spec_boolean (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:ignore-auto-dns: + * + * When #NMSettingIPConfig:method is set to "auto" and this property to + * %TRUE, automatically configured nameservers and search domains are + * ignored and only nameservers and search domains specified in the + * #NMSettingIPConfig:dns and #NMSettingIPConfig:dns-search properties, if + * any, are used. + **/ + g_object_class_install_property + (object_class, PROP_IGNORE_AUTO_DNS, + g_param_spec_boolean (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:dhcp-hostname: + * + * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the + * specified name will be sent to the DHCP server when acquiring a lease. + **/ + g_object_class_install_property + (object_class, PROP_DHCP_HOSTNAME, + g_param_spec_string (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:dhcp-send-hostname: + * + * If %TRUE, a hostname is sent to the DHCP server when acquiring a lease. + * Some DHCP servers use this hostname to update DNS databases, essentially + * providing a static hostname for the computer. If the + * #NMSettingIPConfig:dhcp-hostname property is %NULL and this property is + * %TRUE, the current persistent hostname of the computer is sent. + **/ + g_object_class_install_property + (object_class, PROP_DHCP_SEND_HOSTNAME, + g_param_spec_boolean (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:never-default: + * + * If %TRUE, this connection will never be the default connection for this + * IP type, meaning it will never be assigned the default route by + * NetworkManager. + **/ + g_object_class_install_property + (object_class, PROP_NEVER_DEFAULT, + g_param_spec_boolean (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPConfig:may-fail: + * + * If %TRUE, allow overall network configuration to proceed even if the + * configuration specified by this property times out. Note that at least + * one IP configuration must succeed or overall network configuration will + * still fail. For example, in IPv6-only networks, setting this property to + * %TRUE on the #NMSettingIP4Config allows the overall network configuration + * to succeed if IPv4 configuration fails but IPv6 configuration completes + * successfully. + **/ + g_object_class_install_property + (object_class, PROP_MAY_FAIL, + g_param_spec_boolean (NM_SETTING_IP_CONFIG_MAY_FAIL, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h new file mode 100644 index 00000000..12763fa8 --- /dev/null +++ b/libnm-core/nm-setting-ip-config.h @@ -0,0 +1,221 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef NM_SETTING_IP_CONFIG_H +#define NM_SETTING_IP_CONFIG_H + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +typedef struct NMIPAddress NMIPAddress; + +GType nm_ip_address_get_type (void); + +NMIPAddress *nm_ip_address_new (int family, + const char *addr, + guint prefix, + GError **error); +NMIPAddress *nm_ip_address_new_binary (int family, + gconstpointer addr, + guint prefix, + GError **error); + +void nm_ip_address_ref (NMIPAddress *address); +void nm_ip_address_unref (NMIPAddress *address); +gboolean nm_ip_address_equal (NMIPAddress *address, + NMIPAddress *other); +NMIPAddress *nm_ip_address_dup (NMIPAddress *address); + +int nm_ip_address_get_family (NMIPAddress *address); +const char *nm_ip_address_get_address (NMIPAddress *address); +void nm_ip_address_set_address (NMIPAddress *address, + const char *addr); +void nm_ip_address_get_address_binary (NMIPAddress *address, + gpointer addr); +void nm_ip_address_set_address_binary (NMIPAddress *address, + gconstpointer addr); +guint nm_ip_address_get_prefix (NMIPAddress *address); +void nm_ip_address_set_prefix (NMIPAddress *address, + guint prefix); + +char **nm_ip_address_get_attribute_names (NMIPAddress *address); +GVariant *nm_ip_address_get_attribute (NMIPAddress *address, + const char *name); +void nm_ip_address_set_attribute (NMIPAddress *address, + const char *name, + GVariant *value); + + +typedef struct NMIPRoute NMIPRoute; + +GType nm_ip_route_get_type (void); + +NMIPRoute *nm_ip_route_new (int family, + const char *dest, + guint prefix, + const char *next_hop, + gint64 metric, + GError **error); +NMIPRoute *nm_ip_route_new_binary (int family, + gconstpointer dest, + guint prefix, + gconstpointer next_hop, + gint64 metric, + GError **error); + +void nm_ip_route_ref (NMIPRoute *route); +void nm_ip_route_unref (NMIPRoute *route); +gboolean nm_ip_route_equal (NMIPRoute *route, + NMIPRoute *other); +NMIPRoute *nm_ip_route_dup (NMIPRoute *route); + +int nm_ip_route_get_family (NMIPRoute *route); +const char *nm_ip_route_get_dest (NMIPRoute *route); +void nm_ip_route_set_dest (NMIPRoute *route, + const char *dest); +void nm_ip_route_get_dest_binary (NMIPRoute *route, + gpointer dest); +void nm_ip_route_set_dest_binary (NMIPRoute *route, + gconstpointer dest); +guint nm_ip_route_get_prefix (NMIPRoute *route); +void nm_ip_route_set_prefix (NMIPRoute *route, + guint prefix); +const char *nm_ip_route_get_next_hop (NMIPRoute *route); +void nm_ip_route_set_next_hop (NMIPRoute *route, + const char *next_hop); +gboolean nm_ip_route_get_next_hop_binary (NMIPRoute *route, + gpointer next_hop); +void nm_ip_route_set_next_hop_binary (NMIPRoute *route, + gconstpointer next_hop); +gint64 nm_ip_route_get_metric (NMIPRoute *route); +void nm_ip_route_set_metric (NMIPRoute *route, + gint64 metric); + +char **nm_ip_route_get_attribute_names (NMIPRoute *route); +GVariant *nm_ip_route_get_attribute (NMIPRoute *route, + const char *name); +void nm_ip_route_set_attribute (NMIPRoute *route, + const char *name, + GVariant *value); + + +#define NM_TYPE_SETTING_IP_CONFIG (nm_setting_ip_config_get_type ()) +#define NM_SETTING_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfig)) +#define NM_SETTING_IP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IPCONFIG, NMSettingIPConfigClass)) +#define NM_IS_SETTING_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP_CONFIG)) +#define NM_IS_SETTING_IP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_IP_CONFIG)) +#define NM_SETTING_IP_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigClass)) + +#define NM_SETTING_IP_CONFIG_METHOD "method" +#define NM_SETTING_IP_CONFIG_DNS "dns" +#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" +#define NM_SETTING_IP_CONFIG_GATEWAY "gateway" +#define NM_SETTING_IP_CONFIG_ROUTES "routes" +#define NM_SETTING_IP_CONFIG_ROUTE_METRIC "route-metric" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" +#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME "dhcp-hostname" +#define NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME "dhcp-send-hostname" +#define NM_SETTING_IP_CONFIG_NEVER_DEFAULT "never-default" +#define NM_SETTING_IP_CONFIG_MAY_FAIL "may-fail" + +struct _NMSettingIPConfig { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /* Padding for future expansion */ + gpointer padding[8]; +} NMSettingIPConfigClass; + +GType nm_setting_ip_config_get_type (void); + +const char *nm_setting_ip_config_get_method (NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_dns (NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, + const char *dns); +void nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_remove_dns_by_value (NMSettingIPConfig *setting, + const char *dns); +void nm_setting_ip_config_clear_dns (NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_dns_searches (NMSettingIPConfig *setting); +const char *nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting, + const char *dns_search); +void nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting, + const char *dns_search); +void nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting); +NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_add_address (NMSettingIPConfig *setting, + NMIPAddress *address); +void nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig *setting, + NMIPAddress *address); +void nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting); + +const char *nm_setting_ip_config_get_gateway (NMSettingIPConfig *setting); + +guint nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting); +NMIPRoute *nm_setting_ip_config_get_route (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_add_route (NMSettingIPConfig *setting, + NMIPRoute *route); +void nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, + int i); +gboolean nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting, + NMIPRoute *route); +void nm_setting_ip_config_clear_routes (NMSettingIPConfig *setting); + +gint64 nm_setting_ip_config_get_route_metric (NMSettingIPConfig *setting); + +gboolean nm_setting_ip_config_get_ignore_auto_routes (NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_ignore_auto_dns (NMSettingIPConfig *setting); + +const char *nm_setting_ip_config_get_dhcp_hostname (NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_dhcp_send_hostname (NMSettingIPConfig *setting); + +gboolean nm_setting_ip_config_get_never_default (NMSettingIPConfig *setting); +gboolean nm_setting_ip_config_get_may_fail (NMSettingIPConfig *setting); + +G_END_DECLS + +#endif /* NM_SETTING_IP_CONFIG_H */ diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c new file mode 100644 index 00000000..68619267 --- /dev/null +++ b/libnm-core/nm-setting-ip4-config.c @@ -0,0 +1,695 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-ip4-config.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ip4-config + * @short_description: Describes IPv4 addressing, routing, and name service properties + * + * The #NMSettingIP4Config object is a #NMSetting subclass that describes + * properties related to IPv4 addressing, routing, and Domain Name Service. + * + * #NMSettingIP4Config has few properties or methods of its own; it inherits + * almost everything from #NMSettingIPConfig. + * + * NetworkManager supports 5 values for the #NMSettingIPConfig:method property + * for IPv4. If "auto" is specified then the appropriate automatic method + * (DHCP, PPP, etc) is used for the interface and most other properties can be + * left unset. If "link-local" is specified, then a link-local address in the + * 169.254/16 range will be assigned to the interface. If "manual" is + * specified, static IP addressing is used and at least one IP address must be + * given in the "addresses" property. If "shared" is specified (indicating that + * this connection will provide network access to other computers) then the + * interface is assigned an address in the 10.42.x.1/24 range and a DHCP and + * forwarding DNS server are started, and the interface is NAT-ed to the current + * default network connection. "disabled" means IPv4 will not be used on this + * connection. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG, + _nm_register_setting (IP4_CONFIG, 4)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP4_CONFIG) + +#define NM_SETTING_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigPrivate)) + +typedef struct { + char *dhcp_client_id; +} NMSettingIP4ConfigPrivate; + +enum { + PROP_0, + PROP_DHCP_CLIENT_ID, + + LAST_PROP +}; + +/** + * nm_setting_ip4_config_new: + * + * Creates a new #NMSettingIP4Config object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIP4Config object + **/ +NMSetting * +nm_setting_ip4_config_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP4_CONFIG, NULL); +} + +/** + * nm_setting_ip4_config_get_dhcp_client_id: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:dhcp-client-id + * property. + * + * Returns: the configured Client ID to send to the DHCP server when requesting + * addresses via DHCP. + **/ +const char * +nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_client_id; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); + NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); + NMSettingVerifyResult ret; + const char *method; + + ret = NM_SETTING_CLASS (nm_setting_ip4_config_parent_class)->verify (setting, connection, error); + if (ret != NM_SETTING_VERIFY_SUCCESS) + return ret; + + method = nm_setting_ip_config_get_method (s_ip); + /* Base class already checked that it exists */ + g_assert (method); + + if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + if (nm_setting_ip_config_get_num_addresses (s_ip) == 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("this property cannot be empty for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } else if ( !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) + || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) + || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + if (nm_setting_ip_config_get_num_dns (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + + if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH); + return FALSE; + } + + /* Shared allows IP addresses; link-local and disabled do not */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { + if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } + } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + /* nothing to do */ + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + if (priv->dhcp_client_id && !strlen (priv->dhcp_client_id)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_ip4_config_init (NMSettingIP4Config *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (object); + + g_free (priv->dhcp_client_id); + + G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_DHCP_CLIENT_ID: + g_free (priv->dhcp_client_id); + priv->dhcp_client_id = 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) +{ + NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG (object); + + switch (prop_id) { + case PROP_DHCP_CLIENT_ID: + g_value_set_string (value, nm_setting_ip4_config_get_dhcp_client_id (s_ip4)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GVariant * +ip4_dns_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_dns_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip4_dns_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_dns_from_variant (dbus_value)); +} + +static GVariant * +ip4_addresses_get (NMSetting *setting, + const char *property) +{ + GPtrArray *addrs; + const char *gateway; + GVariant *ret; + + g_object_get (setting, property, &addrs, NULL); + gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting)); + ret = nm_utils_ip4_addresses_to_variant (addrs, gateway); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip4_addresses_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + GVariant *s_ip4; + char **labels, *gateway = NULL; + int i; + + if (!_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data")) + return; + + addrs = nm_utils_ip4_addresses_from_variant (value, &gateway); + + s_ip4 = g_variant_lookup_value (connection_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + if (g_variant_lookup (s_ip4, "address-labels", "^as", &labels)) { + for (i = 0; i < addrs->len && labels[i]; i++) + if (*labels[i]) + nm_ip_address_set_attribute (addrs->pdata[i], "label", g_variant_new_string (labels[i])); + g_strfreev (labels); + } + g_variant_unref (s_ip4); + + g_object_set (setting, + NM_SETTING_IP_CONFIG_ADDRESSES, addrs, + NM_SETTING_IP_CONFIG_GATEWAY, gateway, + NULL); + g_ptr_array_unref (addrs); + g_free (gateway); +} + +static GVariant * +ip4_address_labels_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); + gboolean have_labels = FALSE; + GPtrArray *labels; + GVariant *ret; + int num_addrs, i; + + num_addrs = nm_setting_ip_config_get_num_addresses (s_ip); + for (i = 0; i < num_addrs; i++) { + NMIPAddress *addr = nm_setting_ip_config_get_address (s_ip, i); + GVariant *label = nm_ip_address_get_attribute (addr, "label"); + + if (label) { + have_labels = TRUE; + break; + } + } + if (!have_labels) + return NULL; + + labels = g_ptr_array_sized_new (num_addrs); + for (i = 0; i < num_addrs; i++) { + NMIPAddress *addr = nm_setting_ip_config_get_address (s_ip, i); + GVariant *label = nm_ip_address_get_attribute (addr, "label"); + + g_ptr_array_add (labels, (char *) (label ? g_variant_get_string (label, NULL) : "")); + } + + ret = g_variant_new_strv ((const char * const *) labels->pdata, labels->len); + g_ptr_array_unref (labels); + + return ret; +} + +static GVariant * +ip4_address_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *addrs; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + ret = nm_utils_ip_addresses_to_variant (addrs); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip4_address_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + + /* Ignore 'address-data' if we're going to process 'addresses' */ + if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data")) + return; + + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref (addrs); +} + +static GVariant * +ip4_routes_get (NMSetting *setting, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, property, &routes, NULL); + ret = nm_utils_ip4_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip4_routes_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + + if (!_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data")) + return; + + routes = nm_utils_ip4_routes_from_variant (value); + g_object_set (setting, property, routes, NULL); + g_ptr_array_unref (routes); +} + +static GVariant * +ip4_route_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + ret = nm_utils_ip_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip4_route_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + + /* Ignore 'route-data' if we're going to process 'routes' */ + if (_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data")) + return; + + routes = nm_utils_ip_routes_from_variant (value, AF_INET); + g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref (routes); +} + + +static void +nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) +{ + NMSettingClass *setting_class = NM_SETTING_CLASS (ip4_class); + GObjectClass *object_class = G_OBJECT_CLASS (ip4_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingIP4ConfigPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + setting_class->verify = verify; + + /* properties */ + + /* ---ifcfg-rh--- + * property: method + * variable: BOOTPROTO + * format: string + * values: none, dhcp (bootp), static, ibft, autoip, shared + * default: none + * description: Method used for IPv4 protocol configuration. + * ---end--- + */ + + /* ---keyfile--- + * property: dns + * format: list of DNS IP addresses + * description: List of DNS servers. + * example: dns=1.2.3.4;8.8.8.8;8.8.4.4; + * ---end--- + * ---ifcfg-rh--- + * property: dns + * variable: DNS1, DNS2, ... + * format: string + * description: List of DNS servers. Even if NetworkManager supports many DNS + * servers, initscripts and resolver only care about the first three, usually. + * example: DNS1=1.2.3.4 DNS2=10.0.0.254 DNS3=8.8.8.8 + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-search + * variable: DOMAIN + * format: string (space-separated domains) + * description: List of DNS search domains. + * ---end--- + */ + + /* ---keyfile--- + * property: addresses + * variable: address1, address2, ... + * format: address/plen + * description: List of static IP addresses. + * example: address1=192.168.100.100/24 address2=10.1.1.5/24 + * ---end--- + * ---ifcfg-rh--- + * property: addresses + * variable: IPADDR, PREFIX, IPADDR1, PREFIX1, ... + * description: List of static IP addresses. + * example: IPADDR=10.5.5.23 PREFIX=24 IPADDR1=1.1.1.2 PREFIX1=16 + * ---end--- + */ + + /* ---keyfile--- + * property: gateway + * variable: gateway + * format: string + * description: Gateway IP addresses as a string. + * example: gateway=192.168.100.1 + * ---end--- + * ---ifcfg-rh--- + * property: gateway + * variable: GATEWAY + * description: Gateway IP address. + * example: GATEWAY=10.5.5.1 + * ---end--- + */ + + /* ---keyfile--- + * property: routes + * variable: route1, route2, ... + * format: route/plen[,gateway,metric] + * description: List of IP routes. + * example: route1=8.8.8.0/24,10.1.1.1,77 + * route2=7.7.0.0/16 + * ---end--- + * ---ifcfg-rh--- + * property: routes + * variable: ADDRESS1, NETMASK1, GATEWAY1, METRIC1, ... + * description: List of static routes. They are not stored in ifcfg-* file, + * but in route-* file instead. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-routes + * variable: PEERROUTES(+) + * default: yes + * description: PEERROUTES has the opposite meaning as 'ignore-auto-routes' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-dns + * variable: PEERDNS + * default: yes + * description: PEERDNS has the opposite meaning as 'ignore-auto-dns' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-send-hostname + * variable: DHCP_SEND_HOSTNAME(+) + * default: yes + * description: Whether DHCP_HOSTNAME should be sent to the DHCP server. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname + * variable: DHCP_HOSTNAME + * description: Hostname to send to the DHCP server. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: never-default + * variable: DEFROUTE (GATEWAYDEV in /etc/sysconfig/network) + * default: yes + * description: DEFROUTE=no tells NetworkManager that this connection + * should not be assigned the default route. DEFROUTE has the opposite + * meaning as 'never-default' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: may-fail + * variable: IPV4_FAILURE_FATAL(+) + * default: no + * description: IPV4_FAILURE_FATAL has the opposite meaning as 'may-fail' property. + * ---end--- + */ + + /** + * NMSettingIP4Config:dhcp-client-id: + * + * A string sent to the DHCP server to identify the local machine which the + * DHCP server may use to customize the DHCP lease and options. + **/ + /* ---ifcfg-rh--- + * property: dhcp-client-id + * variable: DHCP_CLIENT_ID(+) + * description: A string sent to the DHCP server to identify the local machine. + * example: DHCP_CLIENT_ID=ax-srv-1 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_DHCP_CLIENT_ID, + g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* IP4-specific property overrides */ + + /* ---dbus--- + * property: dns + * format: array of uint32 + * description: Array of IP addresses of DNS servers (as network-byte-order + * integers) + * ---end--- + */ + _nm_setting_class_transform_property (setting_class, + NM_SETTING_IP_CONFIG_DNS, + G_VARIANT_TYPE ("au"), + ip4_dns_to_dbus, + ip4_dns_from_dbus); + + /* ---dbus--- + * property: addresses + * format: array of array of uint32 + * description: Deprecated in favor of the 'address-data' and 'gateway' + * properties, but this can be used for backward-compatibility with older + * daemons. Note that if you send this property the daemon will ignore + * 'address-data' and 'gateway'. + * + * Array of IPv4 address structures. Each IPv4 address structure is + * composed of 3 32-bit values; the first being the IPv4 address (network + * byte order), the second the prefix (1 - 32), and last the IPv4 gateway + * (network byte order). The gateway may be left as 0 if no gateway exists + * for that subnet. + * ---end--- + */ + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ADDRESSES, + G_VARIANT_TYPE ("aau"), + ip4_addresses_get, + ip4_addresses_set, + NULL); + + _nm_setting_class_add_dbus_only_property (setting_class, + "address-labels", + G_VARIANT_TYPE_STRING_ARRAY, + ip4_address_labels_get, + NULL); + + /* ---dbus--- + * property: address-data + * format: array of vardict + * description: Array of IPv4 addresses. Each address dictionary contains at + * least 'address' and 'prefix' entries, containing the IP address as a + * string, and the prefix length as a uint32. Additional attributes may + * also exist on some addresses. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (setting_class, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_address_data_get, + ip4_address_data_set); + + /* ---dbus--- + * property: routes + * format: array of array of uint32 + * description: Deprecated in favor of the 'route-data' property, but this + * can be used for backward-compatibility with older daemons. Note that if + * you send this property the daemon will ignore 'route-data'. + * + * Array of IPv4 route structures. Each IPv4 route structure is composed + * of 4 32-bit values; the first being the destination IPv4 network or + * address (network byte order), the second the destination network or + * address prefix (1 - 32), the third being the next-hop (network byte + * order) if any, and the fourth being the route metric. If the metric is + * 0, NM will choose an appropriate default metric for the device. (There + * is no way to explicitly specify an actual metric of 0 with this + * property.) + * ---end--- + */ + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ROUTES, + G_VARIANT_TYPE ("aau"), + ip4_routes_get, + ip4_routes_set, + NULL); + + /* ---dbus--- + * property: route-data + * format: array of vardict + * description: Array of IPv4 routes. Each route dictionary contains at + * least 'dest' and 'prefix' entries, containing the destination IP + * address as a string, and the prefix length as a uint32. Most routes + * will also have a 'gateway' entry, containing the gateway IP address as + * a string. If the route has a 'metric' entry (containing a uint32), that + * will be used as the metric for the route (otherwise NM will pick a + * default value appropriate to the device). Additional attributes may + * also exist on some routes. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (setting_class, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_route_data_get, + ip4_route_data_set); + +} diff --git a/libnm-core/nm-setting-ip4-config.h b/libnm-core/nm-setting-ip4-config.h new file mode 100644 index 00000000..e944dfe3 --- /dev/null +++ b/libnm-core/nm-setting-ip4-config.h @@ -0,0 +1,108 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_IP4_CONFIG_H__ +#define __NM_SETTING_IP4_CONFIG_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting-ip-config.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP4_CONFIG (nm_setting_ip4_config_get_type ()) +#define NM_SETTING_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4Config)) +#define NM_SETTING_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IP4CONFIG, NMSettingIP4ConfigClass)) +#define NM_IS_SETTING_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_IS_SETTING_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_IP4_CONFIG)) +#define NM_SETTING_IP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigClass)) + +#define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4" + +#define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_AUTO: + * + * IPv4 configuration should be automatically determined via a method appropriate + * for the hardware interface, ie DHCP or PPP or some other device-specific + * manner. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_AUTO "auto" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL: + * + * IPv4 configuration should be automatically configured for link-local-only + * operation. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_MANUAL: + * + * All necessary IPv4 configuration (addresses, prefix, DNS, etc) is specified + * in the setting's properties. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_MANUAL "manual" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_SHARED: + * + * This connection specifies configuration that allows other computers to + * connect through it to the default network (usually the Internet). The + * connection's interface will be assigned a private address, and a DHCP server, + * caching DNS server, and Network Address Translation (NAT) functionality will + * be started on this connection's interface to allow other devices to connect + * through that interface to the default network. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_SHARED "shared" + +/** + * NM_SETTING_IP4_CONFIG_METHOD_DISABLED: + * + * This connection does not use or require IPv4 address and it should be disabled. + */ +#define NM_SETTING_IP4_CONFIG_METHOD_DISABLED "disabled" + +struct _NMSettingIP4Config { + NMSettingIPConfig parent; +}; + +typedef struct { + NMSettingIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIP4ConfigClass; + +GType nm_setting_ip4_config_get_type (void); + +NMSetting *nm_setting_ip4_config_new (void); + +const char *nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP4_CONFIG_H__ */ diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c new file mode 100644 index 00000000..f5d90334 --- /dev/null +++ b/libnm-core/nm-setting-ip6-config.c @@ -0,0 +1,610 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-ip6-config.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-ip6-config + * @short_description: Describes IPv6 addressing, routing, and name service properties + * + * The #NMSettingIP6Config object is a #NMSetting subclass that describes + * properties related to IPv6 addressing, routing, and Domain Name Service + * + * #NMSettingIP6Config has few properties or methods of its own; it inherits + * almost everything from #NMSettingIPConfig. + * + * NetworkManager supports 6 values for the #NMSettingIPConfig:method property + * for IPv6. If "auto" is specified then the appropriate automatic method (PPP, + * router advertisement, etc) is used for the device and most other properties + * can be left unset. To force the use of DHCP only, specify "dhcp"; this + * method is only valid for Ethernet- based hardware. If "link-local" is + * specified, then an IPv6 link-local address will be assigned to the interface. + * If "manual" is specified, static IP addressing is used and at least one IP + * address must be given in the "addresses" property. If "ignore" is specified, + * IPv6 configuration is not done. Note: the "shared" method is not yet + * supported. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG, + _nm_register_setting (IP6_CONFIG, 4)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG) + +#define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate)) + +typedef struct { + NMSettingIP6ConfigPrivacy ip6_privacy; +} NMSettingIP6ConfigPrivate; + + +enum { + PROP_0, + PROP_IP6_PRIVACY, + + LAST_PROP +}; + +/** + * nm_setting_ip6_config_new: + * + * Creates a new #NMSettingIP6Config object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIP6Config object + **/ +NMSetting * +nm_setting_ip6_config_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP6_CONFIG, NULL); +} + +/** + * nm_setting_ip6_config_get_ip6_privacy: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:ip6-privacy + * property. + * + * Returns: IPv6 Privacy Extensions configuration value (#NMSettingIP6ConfigPrivacy). + **/ +NMSettingIP6ConfigPrivacy +nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ip6_privacy; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); + NMSettingVerifyResult ret; + const char *method; + + ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error); + if (ret != NM_SETTING_VERIFY_SUCCESS) + return ret; + + method = nm_setting_ip_config_get_method (s_ip); + /* Base class already checked that it exists */ + g_assert (method); + + if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + if (nm_setting_ip_config_get_num_addresses (s_ip) == 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("this property cannot be empty for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) + || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) + || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + if (nm_setting_ip_config_get_num_dns (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' not allowed for %s=%s"), + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } + + if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH); + return FALSE; + } + + if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } + } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) + || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + /* nothing to do */ + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD); + return FALSE; + } + + return TRUE; +} + + +static void +nm_setting_ip6_config_init (NMSettingIP6Config *setting) +{ +} + +static GVariant * +ip6_dns_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip6_dns_to_variant (g_value_get_boxed (prop_value)); +} + +static void +ip6_dns_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip6_dns_from_variant (dbus_value)); +} + +static GVariant * +ip6_addresses_get (NMSetting *setting, + const char *property) +{ + GPtrArray *addrs; + const char *gateway; + GVariant *ret; + + g_object_get (setting, property, &addrs, NULL); + gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting)); + ret = nm_utils_ip6_addresses_to_variant (addrs, gateway); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip6_addresses_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + char *gateway = NULL; + + if (!_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data")) + return; + + addrs = nm_utils_ip6_addresses_from_variant (value, &gateway); + + g_object_set (setting, + NM_SETTING_IP_CONFIG_ADDRESSES, addrs, + NM_SETTING_IP_CONFIG_GATEWAY, gateway, + NULL); + g_ptr_array_unref (addrs); + g_free (gateway); +} + +static GVariant * +ip6_address_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *addrs; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + ret = nm_utils_ip_addresses_to_variant (addrs); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip6_address_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + + /* Ignore 'address-data' if we're going to process 'addresses' */ + if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data")) + return; + + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET6); + g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref (addrs); +} + +static GVariant * +ip6_routes_get (NMSetting *setting, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, property, &routes, NULL); + ret = nm_utils_ip6_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip6_routes_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + + if (!_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data")) + return; + + routes = nm_utils_ip6_routes_from_variant (value); + g_object_set (setting, property, routes, NULL); + g_ptr_array_unref (routes); +} + +static GVariant * +ip6_route_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + ret = nm_utils_ip_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip6_route_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + + /* Ignore 'route-data' if we're going to process 'routes' */ + if (_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data")) + return; + + routes = nm_utils_ip_routes_from_variant (value, AF_INET6); + g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref (routes); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IP6_PRIVACY: + priv->ip6_privacy = g_value_get_enum (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) +{ + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IP6_PRIVACY: + g_value_set_enum (value, priv->ip6_privacy); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ip6_class); + NMSettingClass *setting_class = NM_SETTING_CLASS (ip6_class); + + g_type_class_add_private (ip6_class, sizeof (NMSettingIP6ConfigPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + setting_class->verify = verify; + + /* Properties */ + + /* ---ifcfg-rh--- + * property: method + * variable: IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C + * default: IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no + * description: Method used for IPv6 protocol configuration. + * ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yes + * ---end--- + */ + + /* ---keyfile--- + * property: dns + * format: list of DNS IP addresses + * description: List of DNS servers. + * example: dns=2001:4860:4860::8888;2001:4860:4860::8844; + * ---end--- + * ---ifcfg-rh--- + * property: dns + * variable: DNS1, DNS2, ... + * format: string + * description: List of DNS servers. NetworkManager uses the variables both + * for IPv4 and IPv6. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dns-search + * variable: DOMAIN + * format: string (space-separated domains) + * description: List of DNS search domains. + * ---end--- + */ + + /* ---keyfile--- + * property: addresses + * variable: address1, address2, ... + * format: address/plen + * description: List of static IP addresses. + * example: address1=abbe::cafe/96 address2=2001::1234 + * ---end--- + * ---ifcfg-rh--- + * property: addresses + * variable: IPV6ADDR, IPV6ADDR_SECONDARIES + * description: List of static IP addresses. + * example: IPV6ADDR=ab12:9876::1 + * IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3" + * ---end--- + */ + + /* ---keyfile--- + * property: gateway + * variable: gateway + * format: string + * description: Gateway IP addresses as a string. + * example: gateway=abbe::1 + * ---end--- + * ---ifcfg-rh--- + * property: gateway + * variable: IPV6_DEFAULTGW + * description: Gateway IP address. + * example: IPV6_DEFAULTGW=abbe::1 + * ---end--- + */ + + /* ---keyfile--- + * property: routes + * variable: route1, route2, ... + * format: route/plen[,gateway,metric] + * description: List of IP routes. + * example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403 + * ---end--- + * ---ifcfg-rh--- + * property: routes + * variable: (none) + * description: List of static routes. They are not stored in ifcfg-* file, + * but in route6-* file instead in the form of command line for 'ip route add'. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-routes + * variable: IPV6_PEERROUTES(+) + * default: yes + * description: IPV6_PEERROUTES has the opposite meaning as 'ignore-auto-routes' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: ignore-auto-dns + * variable: IPV6_PEERDNS(+) + * default: yes + * description: IPV6_PEERDNS has the opposite meaning as 'ignore-auto-dns' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: dhcp-hostname + * variable: DHCP_HOSTNAME + * description: Hostname to send the DHCP server. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: never-default + * variable: IPV6_DEFROUTE(+), (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network) + * default: IPV6_DEFROUTE=yes (when no variable specified) + * description: IPV6_DEFROUTE=no tells NetworkManager that this connection + * should not be assigned the default IPv6 route. IPV6_DEFROUTE has the opposite + * meaning as 'never-default' property. + * ---end--- + */ + + /* ---ifcfg-rh--- + * property: may-fail + * variable: IPV6_FAILURE_FATAL(+) + * default: no + * description: IPV6_FAILURE_FATAL has the opposite meaning as 'may-fail' property. + * ---end--- + */ + + /** + * NMSettingIP6Config:ip6-privacy: + * + * Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If + * enabled, it makes the kernel generate a temporary IPv6 address in + * addition to the public one generated from MAC address via modified + * EUI-64. This enhances privacy, but could cause problems in some + * applications, on the other hand. The permitted values are: 0: disabled, + * 1: enabled (prefer public address), 2: enabled (prefer temporary + * addresses). + **/ + /* ---ifcfg-rh--- + * property: ip6-privacy + * variable: IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+) + * values: IPV6_PRIVACY: no, yes (rfc3041 or rfc4941); + * IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no + * default: no + * description: Configure IPv6 Privacy Extensions for SLAAC (RFC4941). + * example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_IP6_PRIVACY, + g_param_spec_enum (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, "", "", + NM_TYPE_SETTING_IP6_CONFIG_PRIVACY, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /* IP6-specific property overrides */ + + /* ---dbus--- + * property: dns + * format: array of byte array + * description: Array of IP addresses of DNS servers (in network byte order) + * ---end--- + */ + _nm_setting_class_transform_property (setting_class, + NM_SETTING_IP_CONFIG_DNS, + G_VARIANT_TYPE ("aay"), + ip6_dns_to_dbus, + ip6_dns_from_dbus); + + /* ---dbus--- + * property: addresses + * format: array of legacy IPv6 address struct (a(ayuay)) + * description: Deprecated in favor of the 'address-data' and 'gateway' + * properties, but this can be used for backward-compatibility with older + * daemons. Note that if you send this property the daemon will ignore + * 'address-data' and 'gateway'. + * + * Array of IPv6 address structures. Each IPv6 address structure is + * composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 + * gateway address. The gateway may be zeroed out if no gateway exists for + * that subnet. + * ---end--- + */ + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ADDRESSES, + G_VARIANT_TYPE ("a(ayuay)"), + ip6_addresses_get, + ip6_addresses_set, + NULL); + + /* ---dbus--- + * property: address-data + * format: array of vardict + * description: Array of IPv6 addresses. Each address dictionary contains at + * least 'address' and 'prefix' entries, containing the IP address as a + * string, and the prefix length as a uint32. Additional attributes may + * also exist on some addresses. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (setting_class, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_address_data_get, + ip6_address_data_set); + + /* ---dbus--- + * property: routes + * format: array of legacy IPv6 route struct (a(ayuayu)) + * description: Deprecated in favor of the 'route-data' property, but this + * can be used for backward-compatibility with older daemons. Note that if + * you send this property the daemon will ignore 'route-data'. + * + * Array of IPv6 route structures. Each IPv6 route structure is + * composed of an IPv6 address, a prefix length (1 - 128), an IPv6 + * next hop address (which may be zeroed out if there is no next hop), + * and a metric. If the metric is 0, NM will choose an appropriate + * default metric for the device. + * ---end--- + */ + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ROUTES, + G_VARIANT_TYPE ("a(ayuayu)"), + ip6_routes_get, + ip6_routes_set, + NULL); + + /* ---dbus--- + * property: route-data + * format: array of vardict + * description: Array of IPv6 routes. Each route dictionary contains at + * least 'dest' and 'prefix' entries, containing the destination IP + * address as a string, and the prefix length as a uint32. Most routes + * will also have a 'next-hop' entry, containing the next hop IP address as + * a string. If the route has a 'metric' entry (containing a uint32), that + * will be used as the metric for the route (otherwise NM will pick a + * default value appropriate to the device). Additional attributes may + * also exist on some routes. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (setting_class, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_route_data_get, + ip6_route_data_set); +} diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h new file mode 100644 index 00000000..b791e937 --- /dev/null +++ b/libnm-core/nm-setting-ip6-config.h @@ -0,0 +1,136 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_IP6_CONFIG_H__ +#define __NM_SETTING_IP6_CONFIG_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting-ip-config.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP6_CONFIG (nm_setting_ip6_config_get_type ()) +#define NM_SETTING_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6Config)) +#define NM_SETTING_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IP6CONFIG, NMSettingIP6ConfigClass)) +#define NM_IS_SETTING_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_IS_SETTING_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_SETTING_IP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigClass)) + +#define NM_SETTING_IP6_CONFIG_SETTING_NAME "ipv6" + +#define NM_SETTING_IP6_CONFIG_IP6_PRIVACY "ip6-privacy" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_IGNORE: + * + * IPv6 is not required or is handled by some other mechanism, and NetworkManager + * should not configure IPv6 for this connection. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_IGNORE "ignore" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_AUTO: + * + * IPv6 configuration should be automatically determined via a method appropriate + * for the hardware interface, ie router advertisements, DHCP, or PPP or some + * other device-specific manner. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_DHCP: + * + * IPv6 configuration should be automatically determined via DHCPv6 only and + * router advertisements should be ignored. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_DHCP "dhcp" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL: + * + * IPv6 configuration should be automatically configured for link-local-only + * operation. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL "link-local" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_MANUAL: + * + * All necessary IPv6 configuration (addresses, prefix, DNS, etc) is specified + * in the setting's properties. + */ +#define NM_SETTING_IP6_CONFIG_METHOD_MANUAL "manual" + +/** + * NM_SETTING_IP6_CONFIG_METHOD_SHARED: + * + * This connection specifies configuration that allows other computers to + * connect through it to the default network (usually the Internet). The + * connection's interface will be assigned a private address, and router + * advertisements, a caching DNS server, and Network Address Translation (NAT) + * functionality will be started on this connection's interface to allow other + * devices to connect through that interface to the default network. (not yet + * supported for IPv6) + */ +#define NM_SETTING_IP6_CONFIG_METHOD_SHARED "shared" + +/** + * NMSettingIP6ConfigPrivacy: + * @NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: unknown or no value specified + * @NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: IPv6 Privacy Extensions are disabled + * @NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: IPv6 Privacy Extensions + * are enabled, but public addresses are preferred over temporary addresses + * @NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: IPv6 Privacy Extensions + * are enabled and temporary addresses are preferred over public addresses + * + * #NMSettingIP6ConfigPrivacy values indicate if and how IPv6 Privacy + * Extensions are used (RFC4941). + */ +typedef enum { + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN = -1, + NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED = 0, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR = 1, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR = 2 +} NMSettingIP6ConfigPrivacy; + +struct _NMSettingIP6Config { + NMSettingIPConfig parent; +}; + +typedef struct { + NMSettingIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingIP6ConfigClass; + +GType nm_setting_ip6_config_get_type (void); + +NMSetting *nm_setting_ip6_config_new (void); + +NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IP6_CONFIG_H__ */ diff --git a/libnm-core/nm-setting-olpc-mesh.c b/libnm-core/nm-setting-olpc-mesh.c new file mode 100644 index 00000000..c1d54bee --- /dev/null +++ b/libnm-core/nm-setting-olpc-mesh.c @@ -0,0 +1,268 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2009 One Laptop per Child + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-olpc-mesh.h" +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +static void nm_setting_olpc_mesh_init (NMSettingOlpcMesh *setting); + +G_DEFINE_TYPE_WITH_CODE (NMSettingOlpcMesh, nm_setting_olpc_mesh, NM_TYPE_SETTING, + _nm_register_setting (OLPC_MESH, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_OLPC_MESH) + +#define NM_SETTING_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshPrivate)) + +typedef struct { + GBytes *ssid; + guint32 channel; + char *dhcp_anycast_addr; +} NMSettingOlpcMeshPrivate; + +enum { + PROP_0, + PROP_SSID, + PROP_CHANNEL, + PROP_DHCP_ANYCAST_ADDRESS, + + LAST_PROP +}; + +/** + * nm_setting_olpc_mesh_new: + * + * Creates a new #NMSettingOlpcMesh object with default values. + * + * Returns: the new empty #NMSettingOlpcMesh object + **/ +NMSetting *nm_setting_olpc_mesh_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_OLPC_MESH, NULL); +} + +static void +nm_setting_olpc_mesh_init (NMSettingOlpcMesh *setting) +{ +} + +/** + * nm_setting_olpc_mesh_get_ssid: + * + * Returns: (transfer none): + */ +GBytes * +nm_setting_olpc_mesh_get_ssid (NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_OLPC_MESH (setting), NULL); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE (setting)->ssid; +} + +guint32 +nm_setting_olpc_mesh_get_channel (NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_OLPC_MESH (setting), 0); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE (setting)->channel; +} + +const char * +nm_setting_olpc_mesh_get_dhcp_anycast_address (NMSettingOlpcMesh *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_OLPC_MESH (setting), NULL); + + return NM_SETTING_OLPC_MESH_GET_PRIVATE (setting)->dhcp_anycast_addr; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE (setting); + gsize length; + + if (!priv->ssid) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_SSID); + return FALSE; + } + + length = g_bytes_get_size (priv->ssid); + if (length == 0 || length > 32) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("SSID length is out of range <1-32> bytes")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_SSID); + return FALSE; + } + + if (priv->channel == 0 || priv->channel > 13) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid channel"), + priv->channel); + g_prefix_error (error, "%s.%s: ", NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_CHANNEL); + return FALSE; + } + + if (priv->dhcp_anycast_addr && !nm_utils_hwaddr_valid (priv->dhcp_anycast_addr, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_OLPC_MESH_SETTING_NAME, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS); + return FALSE; + } + + return TRUE; +} + +static void +finalize (GObject *object) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE (object); + + if (priv->ssid) + g_bytes_unref (priv->ssid); + g_free (priv->dhcp_anycast_addr); + + G_OBJECT_CLASS (nm_setting_olpc_mesh_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SSID: + if (priv->ssid) + g_bytes_unref (priv->ssid); + priv->ssid = g_value_dup_boxed (value); + break; + case PROP_CHANNEL: + priv->channel = g_value_get_uint (value); + break; + case PROP_DHCP_ANYCAST_ADDRESS: + g_free (priv->dhcp_anycast_addr); + priv->dhcp_anycast_addr = 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) +{ + NMSettingOlpcMesh *setting = NM_SETTING_OLPC_MESH (object); + + switch (prop_id) { + case PROP_SSID: + g_value_set_boxed (value, nm_setting_olpc_mesh_get_ssid (setting)); + break; + case PROP_CHANNEL: + g_value_set_uint (value, nm_setting_olpc_mesh_get_channel (setting)); + break; + case PROP_DHCP_ANYCAST_ADDRESS: + g_value_set_string (value, nm_setting_olpc_mesh_get_dhcp_anycast_address (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingOlpcMeshPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingOlpcMesh:ssid: + * + * SSID of the mesh network to join. + **/ + g_object_class_install_property + (object_class, PROP_SSID, + g_param_spec_boxed (NM_SETTING_OLPC_MESH_SSID, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingOlpcMesh:channel: + * + * Channel on which the mesh network to join is located. + **/ + g_object_class_install_property + (object_class, PROP_CHANNEL, + g_param_spec_uint (NM_SETTING_OLPC_MESH_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingOlpcMesh:dhcp-anycast-address: + * + * Anycast DHCP MAC address used when requesting an IP address via DHCP. + * The specific anycast address used determines which DHCP server class + * answers the request. + **/ + g_object_class_install_property + (object_class, PROP_DHCP_ANYCAST_ADDRESS, + g_param_spec_string (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); +} diff --git a/libnm-core/nm-setting-olpc-mesh.h b/libnm-core/nm-setting-olpc-mesh.h new file mode 100644 index 00000000..6a165651 --- /dev/null +++ b/libnm-core/nm-setting-olpc-mesh.h @@ -0,0 +1,67 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2009 One Laptop per Child + */ + +#ifndef __NM_SETTING_OLPC_MESH_H__ +#define __NM_SETTING_OLPC_MESH_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_OLPC_MESH (nm_setting_olpc_mesh_get_type ()) +#define NM_SETTING_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMesh)) +#define NM_SETTING_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshClass)) +#define NM_IS_SETTING_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_OLPC_MESH)) +#define NM_IS_SETTING_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_OLPC_MESH)) +#define NM_SETTING_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_OLPC_MESH, NMSettingOlpcMeshClass)) + +#define NM_SETTING_OLPC_MESH_SETTING_NAME "802-11-olpc-mesh" + +#define NM_SETTING_OLPC_MESH_SSID "ssid" +#define NM_SETTING_OLPC_MESH_CHANNEL "channel" +#define NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS "dhcp-anycast-address" + +struct _NMSettingOlpcMesh { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingOlpcMeshClass; + +GType nm_setting_olpc_mesh_get_type (void); + +NMSetting * nm_setting_olpc_mesh_new (void); +GBytes * nm_setting_olpc_mesh_get_ssid (NMSettingOlpcMesh *setting); +guint32 nm_setting_olpc_mesh_get_channel (NMSettingOlpcMesh *setting); +const char * nm_setting_olpc_mesh_get_dhcp_anycast_address (NMSettingOlpcMesh *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_OLPC_MESH_H__ */ diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c new file mode 100644 index 00000000..01f798ea --- /dev/null +++ b/libnm-core/nm-setting-ppp.c @@ -0,0 +1,803 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include + +#include "nm-setting-ppp.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-ppp + * @short_description: Describes connection properties for devices/networks + * that require PPP to deliver IP capability + * + * The #NMSettingPpp object is a #NMSetting subclass that describes properties + * necessary for connection to networks that require PPP transport, like PPPoE + * cable and DSL modems and some mobile broadband devices. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING, + _nm_register_setting (PPP, 3)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PPP) + +#define NM_SETTING_PPP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPP, NMSettingPppPrivate)) + +typedef struct { + gboolean noauth; + gboolean refuse_eap; + gboolean refuse_pap; + gboolean refuse_chap; + gboolean refuse_mschap; + gboolean refuse_mschapv2; + gboolean nobsdcomp; + gboolean nodeflate; + gboolean no_vj_comp; + gboolean require_mppe; + gboolean require_mppe_128; + gboolean mppe_stateful; + gboolean crtscts; + guint32 baud; + guint32 mru; + guint32 mtu; + guint32 lcp_echo_failure; + guint32 lcp_echo_interval; +} NMSettingPppPrivate; + +enum { + PROP_0, + PROP_NOAUTH, + PROP_REFUSE_EAP, + PROP_REFUSE_PAP, + PROP_REFUSE_CHAP, + PROP_REFUSE_MSCHAP, + PROP_REFUSE_MSCHAPV2, + PROP_NOBSDCOMP, + PROP_NODEFLATE, + PROP_NO_VJ_COMP, + PROP_REQUIRE_MPPE, + PROP_REQUIRE_MPPE_128, + PROP_MPPE_STATEFUL, + PROP_CRTSCTS, + PROP_BAUD, + PROP_MRU, + PROP_MTU, + PROP_LCP_ECHO_FAILURE, + PROP_LCP_ECHO_INTERVAL, + + LAST_PROP +}; + +/** + * nm_setting_ppp_new: + * + * Creates a new #NMSettingPpp object with default values. + * + * Returns: (transfer full): the new empty #NMSettingPpp object + **/ +NMSetting * +nm_setting_ppp_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPP, NULL); +} + +/** + * nm_setting_ppp_get_noauth: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:noauth property of the setting + **/ +gboolean +nm_setting_ppp_get_noauth (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->noauth; +} + +/** + * nm_setting_ppp_get_refuse_eap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-eap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_eap (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_eap; +} + +/** + * nm_setting_ppp_get_refuse_pap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-pap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_pap (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_pap; +} + +/** + * nm_setting_ppp_get_refuse_chap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-chap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_chap (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_chap; +} + +/** + * nm_setting_ppp_get_refuse_mschap: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-mschap property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_mschap (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_mschap; +} + +/** + * nm_setting_ppp_get_refuse_mschapv2: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:refuse-mschapv2 property of the setting + **/ +gboolean +nm_setting_ppp_get_refuse_mschapv2 (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_mschapv2; +} + +/** + * nm_setting_ppp_get_nobsdcomp: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:nobsdcomp property of the setting + **/ +gboolean +nm_setting_ppp_get_nobsdcomp (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->nobsdcomp; +} + +/** + * nm_setting_ppp_get_nodeflate: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:nodeflate property of the setting + **/ +gboolean +nm_setting_ppp_get_nodeflate (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->nodeflate; +} + +/** + * nm_setting_ppp_get_no_vj_comp: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:no-vj-comp property of the setting + **/ +gboolean +nm_setting_ppp_get_no_vj_comp (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->no_vj_comp; +} + +/** + * nm_setting_ppp_get_require_mppe: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:require-mppe property of the setting + **/ +gboolean +nm_setting_ppp_get_require_mppe (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->require_mppe; +} + +/** + * nm_setting_ppp_get_require_mppe_128: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:require-mppe-128 property of the setting + **/ +gboolean +nm_setting_ppp_get_require_mppe_128 (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->require_mppe_128; +} + +/** + * nm_setting_ppp_get_mppe_stateful: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mppe-stateful property of the setting + **/ +gboolean +nm_setting_ppp_get_mppe_stateful (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->mppe_stateful; +} + +/** + * nm_setting_ppp_get_crtscts: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:crtscts property of the setting + **/ +gboolean +nm_setting_ppp_get_crtscts (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), FALSE); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->crtscts; +} + +/** + * nm_setting_ppp_get_baud: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:baud property of the setting + **/ +guint32 +nm_setting_ppp_get_baud (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->baud; +} + +/** + * nm_setting_ppp_get_mru: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mru property of the setting + **/ +guint32 +nm_setting_ppp_get_mru (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->mru; +} + +/** + * nm_setting_ppp_get_mtu: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:mtu property of the setting + **/ +guint32 +nm_setting_ppp_get_mtu (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->mtu; +} + +/** + * nm_setting_ppp_get_lcp_echo_failure: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:lcp-echo-failure property of the setting + **/ +guint32 +nm_setting_ppp_get_lcp_echo_failure (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->lcp_echo_failure; +} + +/** + * nm_setting_ppp_get_lcp_echo_interval: + * @setting: the #NMSettingPpp + * + * Returns: the #NMSettingPpp:lcp-echo-interval property of the setting + **/ +guint32 +nm_setting_ppp_get_lcp_echo_interval (NMSettingPpp *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPP (setting), 0); + + return NM_SETTING_PPP_GET_PRIVATE (setting)->lcp_echo_interval; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingPppPrivate *priv = NM_SETTING_PPP_GET_PRIVATE (setting); + + /* FIXME: Do we even want this or can we just let pppd evaluate the options? */ + if (priv->mru > 0) { + if (priv->mru < 128 || priv->mru > 16384) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is out of valid range <128-16384>"), + priv->mru); + g_prefix_error (error, "%s.%s: ", NM_SETTING_PPP_SETTING_NAME, NM_SETTING_PPP_MRU); + return FALSE; + } + } + + if (priv->lcp_echo_failure > 0) { + /* lcp_echo_interval must also be non-zero */ + if (priv->lcp_echo_interval == 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("setting this property requires non-zero '%s' property"), + NM_SETTING_PPP_LCP_ECHO_INTERVAL); + g_prefix_error (error, "%s.%s: ", NM_SETTING_PPP_SETTING_NAME, NM_SETTING_PPP_LCP_ECHO_FAILURE); + return FALSE; + } + } + + return TRUE; +} + +static void +nm_setting_ppp_init (NMSettingPpp *setting) +{ +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingPppPrivate *priv = NM_SETTING_PPP_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_NOAUTH: + priv->noauth = g_value_get_boolean (value); + break; + case PROP_REFUSE_EAP: + priv->refuse_eap = g_value_get_boolean (value); + break; + case PROP_REFUSE_PAP: + priv->refuse_pap = g_value_get_boolean (value); + break; + case PROP_REFUSE_CHAP: + priv->refuse_chap = g_value_get_boolean (value); + break; + case PROP_REFUSE_MSCHAP: + priv->refuse_mschap = g_value_get_boolean (value); + break; + case PROP_REFUSE_MSCHAPV2: + priv->refuse_mschapv2 = g_value_get_boolean (value); + break; + case PROP_NOBSDCOMP: + priv->nobsdcomp = g_value_get_boolean (value); + break; + case PROP_NODEFLATE: + priv->nodeflate = g_value_get_boolean (value); + break; + case PROP_NO_VJ_COMP: + priv->no_vj_comp = g_value_get_boolean (value); + break; + case PROP_REQUIRE_MPPE: + priv->require_mppe = g_value_get_boolean (value); + break; + case PROP_REQUIRE_MPPE_128: + priv->require_mppe_128 = g_value_get_boolean (value); + break; + case PROP_MPPE_STATEFUL: + priv->mppe_stateful = g_value_get_boolean (value); + break; + case PROP_CRTSCTS: + priv->crtscts = g_value_get_boolean (value); + break; + case PROP_BAUD: + priv->baud = g_value_get_uint (value); + break; + case PROP_MRU: + priv->mru = g_value_get_uint (value); + break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; + case PROP_LCP_ECHO_FAILURE: + priv->lcp_echo_failure = g_value_get_uint (value); + break; + case PROP_LCP_ECHO_INTERVAL: + priv->lcp_echo_interval = g_value_get_uint (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) +{ + NMSettingPpp *setting = NM_SETTING_PPP (object); + + switch (prop_id) { + case PROP_NOAUTH: + g_value_set_boolean (value, nm_setting_ppp_get_noauth (setting)); + break; + case PROP_REFUSE_EAP: + g_value_set_boolean (value, nm_setting_ppp_get_refuse_eap (setting)); + break; + case PROP_REFUSE_PAP: + g_value_set_boolean (value, nm_setting_ppp_get_refuse_pap (setting)); + break; + case PROP_REFUSE_CHAP: + g_value_set_boolean (value, nm_setting_ppp_get_refuse_chap (setting)); + break; + case PROP_REFUSE_MSCHAP: + g_value_set_boolean (value, nm_setting_ppp_get_refuse_mschap (setting)); + break; + case PROP_REFUSE_MSCHAPV2: + g_value_set_boolean (value, nm_setting_ppp_get_refuse_mschapv2 (setting)); + break; + case PROP_NOBSDCOMP: + g_value_set_boolean (value, nm_setting_ppp_get_nobsdcomp (setting)); + break; + case PROP_NODEFLATE: + g_value_set_boolean (value, nm_setting_ppp_get_nodeflate (setting)); + break; + case PROP_NO_VJ_COMP: + g_value_set_boolean (value, nm_setting_ppp_get_no_vj_comp (setting)); + break; + case PROP_REQUIRE_MPPE: + g_value_set_boolean (value, nm_setting_ppp_get_require_mppe (setting)); + break; + case PROP_REQUIRE_MPPE_128: + g_value_set_boolean (value, nm_setting_ppp_get_require_mppe_128 (setting)); + break; + case PROP_MPPE_STATEFUL: + g_value_set_boolean (value, nm_setting_ppp_get_mppe_stateful (setting)); + break; + case PROP_CRTSCTS: + g_value_set_boolean (value, nm_setting_ppp_get_crtscts (setting)); + break; + case PROP_BAUD: + g_value_set_uint (value, nm_setting_ppp_get_baud (setting)); + break; + case PROP_MRU: + g_value_set_uint (value, nm_setting_ppp_get_mru (setting)); + break; + case PROP_MTU: + g_value_set_uint (value, nm_setting_ppp_get_mtu (setting)); + break; + case PROP_LCP_ECHO_FAILURE: + g_value_set_uint (value, nm_setting_ppp_get_lcp_echo_failure (setting)); + break; + case PROP_LCP_ECHO_INTERVAL: + g_value_set_uint (value, nm_setting_ppp_get_lcp_echo_interval (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_ppp_class_init (NMSettingPppClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingPppPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingPpp:noauth: + * + * If %TRUE, do not require the other side (usually the PPP server) to + * authenticate itself to the client. If %FALSE, require authentication + * from the remote side. In almost all cases, this should be %TRUE. + **/ + g_object_class_install_property + (object_class, PROP_NOAUTH, + g_param_spec_boolean (NM_SETTING_PPP_NOAUTH, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:refuse-eap: + * + * If %TRUE, the EAP authentication method will not be used. + **/ + g_object_class_install_property + (object_class, PROP_REFUSE_EAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_EAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:refuse-pap: + * + * If %TRUE, the PAP authentication method will not be used. + **/ + g_object_class_install_property + (object_class, PROP_REFUSE_PAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_PAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:refuse-chap: + * + * If %TRUE, the CHAP authentication method will not be used. + **/ + g_object_class_install_property + (object_class, PROP_REFUSE_CHAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_CHAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:refuse-mschap: + * + * If %TRUE, the MSCHAP authentication method will not be used. + **/ + g_object_class_install_property + (object_class, PROP_REFUSE_MSCHAP, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:refuse-mschapv2: + * + * If %TRUE, the MSCHAPv2 authentication method will not be used. + **/ + g_object_class_install_property + (object_class, PROP_REFUSE_MSCHAPV2, + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAPV2, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:nobsdcomp: + * + * If %TRUE, BSD compression will not be requested. + **/ + g_object_class_install_property + (object_class, PROP_NOBSDCOMP, + g_param_spec_boolean (NM_SETTING_PPP_NOBSDCOMP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:nodeflate: + * + * If %TRUE, "deflate" compression will not be requested. + **/ + g_object_class_install_property + (object_class, PROP_NODEFLATE, + g_param_spec_boolean (NM_SETTING_PPP_NODEFLATE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:no-vj-comp: + * + * If %TRUE, Van Jacobsen TCP header compression will not be requested. + **/ + g_object_class_install_property + (object_class, PROP_NO_VJ_COMP, + g_param_spec_boolean (NM_SETTING_PPP_NO_VJ_COMP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:require-mppe: + * + * If %TRUE, MPPE (Microsoft Point-to-Point Encrpytion) will be required for + * the PPP session. If either 64-bit or 128-bit MPPE is not available the + * session will fail. Note that MPPE is not used on mobile broadband + * connections. + **/ + g_object_class_install_property + (object_class, PROP_REQUIRE_MPPE, + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:require-mppe-128: + * + * If %TRUE, 128-bit MPPE (Microsoft Point-to-Point Encrpytion) will be + * required for the PPP session, and the "require-mppe" property must also + * be set to %TRUE. If 128-bit MPPE is not available the session will fail. + **/ + g_object_class_install_property + (object_class, PROP_REQUIRE_MPPE_128, + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE_128, "", "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:mppe-stateful: + * + * If %TRUE, stateful MPPE is used. See pppd documentation for more + * information on stateful MPPE. + **/ + g_object_class_install_property + (object_class, PROP_MPPE_STATEFUL, + g_param_spec_boolean (NM_SETTING_PPP_MPPE_STATEFUL, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:crtscts: + * + * If %TRUE, specify that pppd should set the serial port to use hardware + * flow control with RTS and CTS signals. This value should normally be set + * to %FALSE. + **/ + g_object_class_install_property + (object_class, PROP_CRTSCTS, + g_param_spec_boolean (NM_SETTING_PPP_CRTSCTS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:baud: + * + * If non-zero, instruct pppd to set the serial port to the specified + * baudrate. This value should normally be left as 0 to automatically + * choose the speed. + **/ + g_object_class_install_property + (object_class, PROP_BAUD, + g_param_spec_uint (NM_SETTING_PPP_BAUD, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:mru: + * + * If non-zero, instruct pppd to request that the peer send packets no + * larger than the specified size. If non-zero, the MRU should be between + * 128 and 16384. + */ + g_object_class_install_property + (object_class, PROP_MRU, + g_param_spec_uint (NM_SETTING_PPP_MRU, "", "", + 0, 16384, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:mtu: + * + * If non-zero, instruct pppd to send packets no larger than the specified + * size. + **/ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_PPP_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:lcp-echo-failure: + * + * If non-zero, instruct pppd to presume the connection to the peer has + * failed if the specified number of LCP echo-requests go unanswered by the + * peer. The "lcp-echo-interval" property must also be set to a non-zero + * value if this property is used. + **/ + g_object_class_install_property + (object_class, PROP_LCP_ECHO_FAILURE, + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_FAILURE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPpp:lcp-echo-interval: + * + * If non-zero, instruct pppd to send an LCP echo-request frame to the peer + * every n seconds (where n is the specified value). Note that some PPP + * peers will respond to echo requests and some will not, and it is not + * possible to autodetect this. + **/ + g_object_class_install_property + (object_class, PROP_LCP_ECHO_INTERVAL, + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_INTERVAL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-ppp.h b/libnm-core/nm-setting-ppp.h new file mode 100644 index 00000000..2e0162cc --- /dev/null +++ b/libnm-core/nm-setting-ppp.h @@ -0,0 +1,97 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_PPP_H__ +#define __NM_SETTING_PPP_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_PPP (nm_setting_ppp_get_type ()) +#define NM_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_PPP, NMSettingPpp)) +#define NM_SETTING_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_PPP, NMSettingPppClass)) +#define NM_IS_SETTING_PPP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_PPP)) +#define NM_IS_SETTING_PPP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_PPP)) +#define NM_SETTING_PPP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_PPP, NMSettingPppClass)) + +#define NM_SETTING_PPP_SETTING_NAME "ppp" + +#define NM_SETTING_PPP_NOAUTH "noauth" +#define NM_SETTING_PPP_REFUSE_EAP "refuse-eap" +#define NM_SETTING_PPP_REFUSE_PAP "refuse-pap" +#define NM_SETTING_PPP_REFUSE_CHAP "refuse-chap" +#define NM_SETTING_PPP_REFUSE_MSCHAP "refuse-mschap" +#define NM_SETTING_PPP_REFUSE_MSCHAPV2 "refuse-mschapv2" +#define NM_SETTING_PPP_NOBSDCOMP "nobsdcomp" +#define NM_SETTING_PPP_NODEFLATE "nodeflate" +#define NM_SETTING_PPP_NO_VJ_COMP "no-vj-comp" +#define NM_SETTING_PPP_REQUIRE_MPPE "require-mppe" +#define NM_SETTING_PPP_REQUIRE_MPPE_128 "require-mppe-128" +#define NM_SETTING_PPP_MPPE_STATEFUL "mppe-stateful" +#define NM_SETTING_PPP_CRTSCTS "crtscts" +#define NM_SETTING_PPP_BAUD "baud" +#define NM_SETTING_PPP_MRU "mru" +#define NM_SETTING_PPP_MTU "mtu" +#define NM_SETTING_PPP_LCP_ECHO_FAILURE "lcp-echo-failure" +#define NM_SETTING_PPP_LCP_ECHO_INTERVAL "lcp-echo-interval" + +struct _NMSettingPpp { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingPppClass; + +GType nm_setting_ppp_get_type (void); + +NMSetting *nm_setting_ppp_new (void); +gboolean nm_setting_ppp_get_noauth (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_eap (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_pap (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_chap (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_mschap (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_refuse_mschapv2 (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_nobsdcomp (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_nodeflate (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_no_vj_comp (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_require_mppe (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_require_mppe_128 (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_mppe_stateful (NMSettingPpp *setting); +gboolean nm_setting_ppp_get_crtscts (NMSettingPpp *setting); +guint32 nm_setting_ppp_get_baud (NMSettingPpp *setting); +guint32 nm_setting_ppp_get_mru (NMSettingPpp *setting); +guint32 nm_setting_ppp_get_mtu (NMSettingPpp *setting); +guint32 nm_setting_ppp_get_lcp_echo_failure (NMSettingPpp *setting); +guint32 nm_setting_ppp_get_lcp_echo_interval (NMSettingPpp *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_PPP_H__ */ diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c new file mode 100644 index 00000000..ac6764d0 --- /dev/null +++ b/libnm-core/nm-setting-pppoe.c @@ -0,0 +1,322 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-pppoe.h" +#include "nm-setting-ppp.h" +#include "nm-setting-private.h" +#include "nm-core-enum-types.h" + +/** + * SECTION:nm-setting-pppoe + * @short_description: Describes PPPoE connection properties + * + * The #NMSettingPppoe object is a #NMSetting subclass that describes + * properties necessary for connection to networks that require PPPoE connections + * to provide IP transport, for example cable or DSL modems. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING, + _nm_register_setting (PPPOE, 3)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PPPOE) + +#define NM_SETTING_PPPOE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate)) + +typedef struct { + char *service; + char *username; + char *password; + NMSettingSecretFlags password_flags; +} NMSettingPppoePrivate; + +enum { + PROP_0, + PROP_SERVICE, + PROP_USERNAME, + PROP_PASSWORD, + PROP_PASSWORD_FLAGS, + + LAST_PROP +}; + +/** + * nm_setting_pppoe_new: + * + * Creates a new #NMSettingPppoe object with default values. + * + * Returns: (transfer full): the new empty #NMSettingPppoe object + **/ +NMSetting * +nm_setting_pppoe_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPPOE, NULL); +} + +/** + * nm_setting_pppoe_get_service: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:service property of the setting + **/ +const char * +nm_setting_pppoe_get_service (NMSettingPppoe *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->service; +} + +/** + * nm_setting_pppoe_get_username: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:username property of the setting + **/ +const char * +nm_setting_pppoe_get_username (NMSettingPppoe *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->username; +} + +/** + * nm_setting_pppoe_get_password: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingPppoe:password property of the setting + **/ +const char * +nm_setting_pppoe_get_password (NMSettingPppoe *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NULL); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password; +} + +/** + * nm_setting_pppoe_get_password_flags: + * @setting: the #NMSettingPppoe + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingPppoe:password + **/ +NMSettingSecretFlags +nm_setting_pppoe_get_password_flags (NMSettingPppoe *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password_flags; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (setting); + + if (!priv->username) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME); + return FALSE; + } else if (!strlen (priv->username)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_USERNAME); + return FALSE; + } + + if (priv->service && !strlen (priv->service)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_PPPOE_SETTING_NAME, NM_SETTING_PPPOE_SERVICE); + return FALSE; + } + + return TRUE; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (setting); + GPtrArray *secrets = NULL; + + if (priv->password) + return NULL; + + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_PPPOE_PASSWORD); + } + + return secrets; +} + +static void +nm_setting_pppoe_init (NMSettingPppoe *setting) +{ +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SERVICE: + g_free (priv->service); + priv->service = g_value_dup_string (value); + break; + case PROP_USERNAME: + g_free (priv->username); + priv->username = g_value_dup_string (value); + break; + case PROP_PASSWORD: + g_free (priv->password); + priv->password = g_value_dup_string (value); + break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_flags (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) +{ + NMSettingPppoe *setting = NM_SETTING_PPPOE (object); + + switch (prop_id) { + case PROP_SERVICE: + g_value_set_string (value, nm_setting_pppoe_get_service (setting)); + break; + case PROP_USERNAME: + g_value_set_string (value, nm_setting_pppoe_get_username (setting)); + break; + case PROP_PASSWORD: + g_value_set_string (value, nm_setting_pppoe_get_password (setting)); + break; + case PROP_PASSWORD_FLAGS: + g_value_set_flags (value, nm_setting_pppoe_get_password_flags (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingPppoePrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (object); + + g_free (priv->username); + g_free (priv->password); + g_free (priv->service); + + G_OBJECT_CLASS (nm_setting_pppoe_parent_class)->finalize (object); +} + +static void +nm_setting_pppoe_class_init (NMSettingPppoeClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingPppoePrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + + /* Properties */ + /** + * NMSettingPppoe:service: + * + * If specified, instruct PPPoE to only initiate sessions with access + * concentrators that provide the specified service. For most providers, + * this should be left blank. It is only required if there are multiple + * access concentrators or a specific service is known to be required. + **/ + g_object_class_install_property + (object_class, PROP_SERVICE, + g_param_spec_string (NM_SETTING_PPPOE_SERVICE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPppoe:username: + * + * Username used to authenticate with the PPPoE service. + **/ + g_object_class_install_property + (object_class, PROP_USERNAME, + g_param_spec_string (NM_SETTING_PPPOE_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPppoe:password: + * + * Password used to authenticate with the PPPoE service. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD, + g_param_spec_string (NM_SETTING_PPPOE_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingPppoe:password-flags: + * + * Flags indicating how to handle the #NMSettingPppoe:password property. + **/ + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_PPPOE_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-pppoe.h b/libnm-core/nm-setting-pppoe.h new file mode 100644 index 00000000..b1e0d92f --- /dev/null +++ b/libnm-core/nm-setting-pppoe.h @@ -0,0 +1,69 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_PPPOE_H__ +#define __NM_SETTING_PPPOE_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_PPPOE (nm_setting_pppoe_get_type ()) +#define NM_SETTING_PPPOE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_PPPOE, NMSettingPppoe)) +#define NM_SETTING_PPPOE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_PPPOE, NMSettingPppoeClass)) +#define NM_IS_SETTING_PPPOE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_PPPOE)) +#define NM_IS_SETTING_PPPOE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_PPPOE)) +#define NM_SETTING_PPPOE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_PPPOE, NMSettingPppoeClass)) + +#define NM_SETTING_PPPOE_SETTING_NAME "pppoe" + +#define NM_SETTING_PPPOE_SERVICE "service" +#define NM_SETTING_PPPOE_USERNAME "username" +#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_PASSWORD_FLAGS "password-flags" + +struct _NMSettingPppoe { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingPppoeClass; + +GType nm_setting_pppoe_get_type (void); + +NMSetting *nm_setting_pppoe_new (void); +const char *nm_setting_pppoe_get_service (NMSettingPppoe *setting); +const char *nm_setting_pppoe_get_username (NMSettingPppoe *setting); +const char *nm_setting_pppoe_get_password (NMSettingPppoe *setting); +NMSettingSecretFlags nm_setting_pppoe_get_password_flags (NMSettingPppoe *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_PPPOE_H__ */ diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h new file mode 100644 index 00000000..2d34d509 --- /dev/null +++ b/libnm-core/nm-setting-private.h @@ -0,0 +1,158 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_PRIVATE_H__ +#define __NM_SETTING_PRIVATE_H__ + +#include "nm-setting.h" +#include "nm-connection.h" +#include "nm-core-enum-types.h" +#include "nm-glib-compat.h" + +#include "nm-core-internal.h" + +/** + * NMSettingVerifyResult: + * @NM_SETTING_VERIFY_SUCCESS: the setting verifies successfully + * @NM_SETTING_VERIFY_ERROR: the setting has a serious misconfiguration + * @NM_SETTING_VERIFY_NORMALIZABLE: the setting is valid but has properties + * that should be normalized + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR: the setting is invalid but the + * errors can be fixed by nm_connection_normalize(). + */ +typedef enum { + NM_SETTING_VERIFY_SUCCESS = TRUE, + NM_SETTING_VERIFY_ERROR = FALSE, + NM_SETTING_VERIFY_NORMALIZABLE = 2, + NM_SETTING_VERIFY_NORMALIZABLE_ERROR = 3, +} NMSettingVerifyResult; + +void _nm_register_setting (const char *name, + const GType type, + const guint32 priority); + +#define _nm_register_setting(name, priority) \ + G_STMT_START { \ + _nm_register_setting (NM_SETTING_ ## name ## _SETTING_NAME "", g_define_type_id, priority); \ + } G_STMT_END + +gboolean _nm_setting_is_base_type (NMSetting *setting); +gboolean _nm_setting_type_is_base_type (GType type); +gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b); + +typedef enum NMSettingUpdateSecretResult { + NM_SETTING_UPDATE_SECRET_ERROR = FALSE, + NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE, + NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED = 2, +} NMSettingUpdateSecretResult; + +NMSettingUpdateSecretResult _nm_setting_update_secrets (NMSetting *setting, + GVariant *secrets, + GError **error); +gboolean _nm_setting_clear_secrets (NMSetting *setting); +gboolean _nm_setting_clear_secrets_with_flags (NMSetting *setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + + +/* The property of the #NMSetting should be considered during comparisons that + * use the %NM_SETTING_COMPARE_FLAG_INFERRABLE flag. Properties that don't have + * this flag, are ignored when doing an infrerrable comparison. This flag should + * be set on all properties that are read from the kernel or the system when a + * connection is generated. eg, IP addresses/routes can be read from the + * kernel, but the 'autoconnect' property cannot, so + * %NM_SETTING_IP4_CONFIG_ADDRESSES gets the INFERRABLE flag, but + * %NM_SETTING_CONNECTION_AUTOCONNECT would not. + * + * This flag should not be used with properties where the default cannot be + * read separately from the current value, like MTU or wired duplex mode. + */ +#define NM_SETTING_PARAM_INFERRABLE (1 << (4 + G_PARAM_USER_SHIFT)) + +/* This is a legacy property, which clients should not send to the daemon. */ +#define NM_SETTING_PARAM_LEGACY (1 << (5 + G_PARAM_USER_SHIFT)) + +/* Ensure the setting's GType is registered at library load time */ +#define NM_SETTING_REGISTER_TYPE(x) \ +static void __attribute__((constructor)) register_setting (void) \ +{ g_type_init (); g_type_ensure (x); } + +GVariant *_nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, + NMConnection *connection, + const char *property); + +NMSettingVerifyResult _nm_setting_verify (NMSetting *setting, + NMConnection *connection, + GError **error); + +gboolean _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type); + +GVariant *_nm_setting_to_dbus (NMSetting *setting, + NMConnection *connection, + NMConnectionSerializationFlags flags); + +NMSetting *_nm_setting_new_from_dbus (GType setting_type, + GVariant *setting_dict, + GVariant *connection_dict, + GError **error); + +typedef GVariant * (*NMSettingPropertyGetFunc) (NMSetting *setting, + const char *property); +typedef GVariant * (*NMSettingPropertySynthFunc) (NMSetting *setting, + NMConnection *connection, + const char *property); +typedef void (*NMSettingPropertySetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value); +typedef void (*NMSettingPropertyNotSetFunc) (NMSetting *setting, + GVariant *connection_dict, + const char *property); + +void _nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertySynthFunc synth_func, + NMSettingPropertySetFunc set_func); + +void _nm_setting_class_override_property (NMSettingClass *setting_class, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertyGetFunc get_func, + NMSettingPropertySetFunc set_func, + NMSettingPropertyNotSetFunc not_set_func); + +typedef GVariant * (*NMSettingPropertyTransformToFunc) (const GValue *from); +typedef void (*NMSettingPropertyTransformFromFunc) (GVariant *from, GValue *to); + +void _nm_setting_class_transform_property (NMSettingClass *setting_class, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus); + +gboolean _nm_setting_use_legacy_property (NMSetting *setting, + GVariant *connection_dict, + const char *legacy_property, + const char *new_property); + +GPtrArray *_nm_setting_need_secrets (NMSetting *setting); + +#endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c new file mode 100644 index 00000000..3fd780c8 --- /dev/null +++ b/libnm-core/nm-setting-serial.c @@ -0,0 +1,351 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include + +#include "nm-setting-serial.h" +#include "nm-glib-compat.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-serial + * @short_description: Describes connection properties for devices that use + * serial communications + * + * The #NMSettingSerial object is a #NMSetting subclass that describes + * properties necessary for connections that may use serial communications, + * such as mobile broadband or analog telephone connections. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING, + _nm_register_setting (SERIAL, 2)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_SERIAL) + +#define NM_SETTING_SERIAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_SERIAL, NMSettingSerialPrivate)) + +typedef struct { + guint baud; + guint bits; + char parity; + guint stopbits; + guint64 send_delay; +} NMSettingSerialPrivate; + + +enum { + PROP_0, + PROP_BAUD, + PROP_BITS, + PROP_PARITY, + PROP_STOPBITS, + PROP_SEND_DELAY, + + LAST_PROP +}; + +/** + * nm_setting_serial_new: + * + * Creates a new #NMSettingSerial object with default values. + * + * Returns: (transfer full): the new empty #NMSettingSerial object + **/ +NMSetting * +nm_setting_serial_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_SERIAL, NULL); +} + +/** + * nm_setting_serial_get_baud: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:baud property of the setting + **/ +guint +nm_setting_serial_get_baud (NMSettingSerial *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE (setting)->baud; +} + +/** + * nm_setting_serial_get_bits: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:bits property of the setting + **/ +guint +nm_setting_serial_get_bits (NMSettingSerial *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE (setting)->bits; +} + +/** + * nm_setting_serial_get_parity: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:parity property of the setting + **/ +NMSettingSerialParity +nm_setting_serial_get_parity (NMSettingSerial *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE (setting)->parity; +} + +/** + * nm_setting_serial_get_stopbits: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:stopbits property of the setting + **/ +guint +nm_setting_serial_get_stopbits (NMSettingSerial *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE (setting)->stopbits; +} + +/** + * nm_setting_serial_get_send_delay: + * @setting: the #NMSettingSerial + * + * Returns: the #NMSettingSerial:send-delay property of the setting + **/ +guint64 +nm_setting_serial_get_send_delay (NMSettingSerial *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_SERIAL (setting), 0); + + return NM_SETTING_SERIAL_GET_PRIVATE (setting)->send_delay; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + return TRUE; +} + +static void +nm_setting_serial_init (NMSettingSerial *setting) +{ +} + +static GVariant * +parity_to_dbus (const GValue *from) +{ + switch (g_value_get_enum (from)) { + case NM_SETTING_SERIAL_PARITY_EVEN: + return g_variant_new_byte ('E'); + case NM_SETTING_SERIAL_PARITY_ODD: + return g_variant_new_byte ('o'); + case NM_SETTING_SERIAL_PARITY_NONE: + default: + return g_variant_new_byte ('n'); + } +} + +static void +parity_from_dbus (GVariant *from, GValue *to) +{ + switch (g_variant_get_byte (from)) { + case 'E': + g_value_set_enum (to, NM_SETTING_SERIAL_PARITY_EVEN); + break; + case 'o': + g_value_set_enum (to, NM_SETTING_SERIAL_PARITY_ODD); + break; + case 'n': + default: + g_value_set_enum (to, NM_SETTING_SERIAL_PARITY_NONE); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingSerialPrivate *priv = NM_SETTING_SERIAL_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_BAUD: + priv->baud = g_value_get_uint (value); + break; + case PROP_BITS: + priv->bits = g_value_get_uint (value); + break; + case PROP_PARITY: + priv->parity = g_value_get_enum (value); + break; + case PROP_STOPBITS: + priv->stopbits = g_value_get_uint (value); + break; + case PROP_SEND_DELAY: + priv->send_delay = g_value_get_uint64 (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) +{ + NMSettingSerial *setting = NM_SETTING_SERIAL (object); + + switch (prop_id) { + case PROP_BAUD: + g_value_set_uint (value, nm_setting_serial_get_baud (setting)); + break; + case PROP_BITS: + g_value_set_uint (value, nm_setting_serial_get_bits (setting)); + break; + case PROP_PARITY: + g_value_set_enum (value, nm_setting_serial_get_parity (setting)); + break; + case PROP_STOPBITS: + g_value_set_uint (value, nm_setting_serial_get_stopbits (setting)); + break; + case PROP_SEND_DELAY: + g_value_set_uint64 (value, nm_setting_serial_get_send_delay (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_serial_class_init (NMSettingSerialClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingSerialPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingSerial:baud: + * + * Speed to use for communication over the serial port. Note that this + * value usually has no effect for mobile broadband modems as they generally + * ignore speed settings and use the highest available speed. + **/ + g_object_class_install_property + (object_class, PROP_BAUD, + g_param_spec_uint (NM_SETTING_SERIAL_BAUD, "", "", + 0, G_MAXUINT, 57600, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingSerial:bits: + * + * Byte-width of the serial communication. The 8 in "8n1" for example. + **/ + g_object_class_install_property + (object_class, PROP_BITS, + g_param_spec_uint (NM_SETTING_SERIAL_BITS, "", "", + 5, 8, 8, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingSerial:parity: + * + * Parity setting of the serial port. + **/ + /* ---keyfile--- + * property: parity + * format: 'e', 'o', or 'n' + * description: The connection parity; even, odd, or none. Note that older + * versions of NetworkManager stored this as an integer: 69 ('E') for even, + * 111 ('o') for odd, or 110 ('n') for none. + * example: parity=n + * ---end--- + * ---dbus--- + * property: parity + * format: byte + * description: The connection parity: 69 (ASCII 'E') for even parity, + * 111 (ASCII 'o') for odd, 110 (ASCII 'n') for none. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PARITY, + g_param_spec_enum (NM_SETTING_SERIAL_PARITY, "", "", + NM_TYPE_SETTING_SERIAL_PARITY, + NM_SETTING_SERIAL_PARITY_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, + NM_SETTING_SERIAL_PARITY, + G_VARIANT_TYPE_BYTE, + parity_to_dbus, + parity_from_dbus); + + /** + * NMSettingSerial:stopbits: + * + * Number of stop bits for communication on the serial port. Either 1 or 2. + * The 1 in "8n1" for example. + **/ + g_object_class_install_property + (object_class, PROP_STOPBITS, + g_param_spec_uint (NM_SETTING_SERIAL_STOPBITS, "", "", + 1, 2, 1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingSerial:send-delay: + * + * Time to delay between each byte sent to the modem, in microseconds. + **/ + g_object_class_install_property + (object_class, PROP_SEND_DELAY, + g_param_spec_uint64 (NM_SETTING_SERIAL_SEND_DELAY, "", "", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-serial.h b/libnm-core/nm-setting-serial.h new file mode 100644 index 00000000..58289227 --- /dev/null +++ b/libnm-core/nm-setting-serial.h @@ -0,0 +1,85 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_SERIAL_H__ +#define __NM_SETTING_SERIAL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_SERIAL (nm_setting_serial_get_type ()) +#define NM_SETTING_SERIAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerial)) +#define NM_SETTING_SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) +#define NM_IS_SETTING_SERIAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_SERIAL)) +#define NM_IS_SETTING_SERIAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_SERIAL)) +#define NM_SETTING_SERIAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_SERIAL, NMSettingSerialClass)) + +#define NM_SETTING_SERIAL_SETTING_NAME "serial" + +/** + * NMSettingSerialParity: + * @NM_SETTING_SERIAL_PARITY_NONE: No parity bits (default) + * @NM_SETTING_SERIAL_PARITY_EVEN: Even parity + * @NM_SETTING_SERIAL_PARITY_ODD: Odd parity + * + * The parity setting of a serial port. + */ +typedef enum { + NM_SETTING_SERIAL_PARITY_NONE = 0, + NM_SETTING_SERIAL_PARITY_EVEN, + NM_SETTING_SERIAL_PARITY_ODD +} NMSettingSerialParity; + +#define NM_SETTING_SERIAL_BAUD "baud" +#define NM_SETTING_SERIAL_BITS "bits" +#define NM_SETTING_SERIAL_PARITY "parity" +#define NM_SETTING_SERIAL_STOPBITS "stopbits" +#define NM_SETTING_SERIAL_SEND_DELAY "send-delay" + +struct _NMSettingSerial { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingSerialClass; + +GType nm_setting_serial_get_type (void); + +NMSetting *nm_setting_serial_new (void); +guint nm_setting_serial_get_baud (NMSettingSerial *setting); +guint nm_setting_serial_get_bits (NMSettingSerial *setting); +NMSettingSerialParity nm_setting_serial_get_parity (NMSettingSerial *setting); +guint nm_setting_serial_get_stopbits (NMSettingSerial *setting); +guint64 nm_setting_serial_get_send_delay (NMSettingSerial *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_SERIAL_H__ */ diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c new file mode 100644 index 00000000..b5125753 --- /dev/null +++ b/libnm-core/nm-setting-team-port.c @@ -0,0 +1,192 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-setting-team-port.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" +#include "nm-setting-connection.h" +#include "nm-setting-team.h" + +/** + * SECTION:nm-setting-team-port + * @short_description: Describes connection properties for team ports + * + * The #NMSettingTeamPort object is a #NMSetting subclass that describes + * optional properties that apply to team ports. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING, + _nm_register_setting (TEAM_PORT, 3)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM_PORT) + +#define NM_SETTING_TEAM_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortPrivate)) + +typedef struct { + char *config; +} NMSettingTeamPortPrivate; + +enum { + PROP_0, + PROP_CONFIG, + LAST_PROP +}; + +/** + * nm_setting_team_port_new: + * + * Creates a new #NMSettingTeamPort object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTeamPort object + **/ +NMSetting * +nm_setting_team_port_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_TEAM_PORT, NULL); +} + +/** + * nm_setting_team_port_get_config: + * @setting: the #NMSettingTeamPort + * + * Returns: the #NMSettingTeamPort:config property of the setting + **/ +const char * +nm_setting_team_port_get_config (NMSettingTeamPort *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), NULL); + + return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->config; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + if (connection) { + NMSettingConnection *s_con; + const char *slave_type; + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("missing setting")); + g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME); + return FALSE; + } + + slave_type = nm_setting_connection_get_slave_type (s_con); + if ( slave_type + && strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"), + NM_SETTING_TEAM_PORT_SETTING_NAME, + NM_SETTING_TEAM_SETTING_NAME, + slave_type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return FALSE; + } + } + return TRUE; +} + +static void +nm_setting_team_port_init (NMSettingTeamPort *setting) +{ +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_CONFIG: + priv->config = 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) +{ + NMSettingTeamPort *setting = NM_SETTING_TEAM_PORT (object); + + switch (prop_id) { + case PROP_CONFIG: + g_value_set_string (value, nm_setting_team_port_get_config (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingTeamPortPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingTeamPort:config: + * + * The JSON configuration for the team port. The property should contain raw + * JSON configuration data suitable for teamd, because the value is passed + * directly to teamd. If not specified, the default configuration is + * used. See man teamd.conf for the format details. + **/ + /* ---ifcfg-rh--- + * property: config + * variable: TEAM_PORT_CONFIG + * description: Team port configuration in JSON. See man teamd.conf for details. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CONFIG, + g_param_spec_string (NM_SETTING_TEAM_PORT_CONFIG, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting-team-port.h b/libnm-core/nm-setting-team-port.h new file mode 100644 index 00000000..86efb97c --- /dev/null +++ b/libnm-core/nm-setting-team-port.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#ifndef __NM_SETTING_TEAM_PORT_H__ +#define __NM_SETTING_TEAM_PORT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TEAM_PORT (nm_setting_team_port_get_type ()) +#define NM_SETTING_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPort)) +#define NM_SETTING_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortClass)) +#define NM_IS_SETTING_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_TEAM_PORT)) +#define NM_IS_SETTING_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_TEAM_PORT)) +#define NM_SETTING_TEAM_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortClass)) + +#define NM_SETTING_TEAM_PORT_SETTING_NAME "team-port" + +#define NM_SETTING_TEAM_PORT_CONFIG "config" + +struct _NMSettingTeamPort { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTeamPortClass; + +GType nm_setting_team_port_get_type (void); + +NMSetting * nm_setting_team_port_new (void); + +const char * nm_setting_team_port_get_config (NMSettingTeamPort *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_TEAM_PORT_H__ */ diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c new file mode 100644 index 00000000..04b98243 --- /dev/null +++ b/libnm-core/nm-setting-team.c @@ -0,0 +1,186 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-team.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-team + * @short_description: Describes connection properties for teams + * + * The #NMSettingTeam object is a #NMSetting subclass that describes properties + * necessary for team connections. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingTeam, nm_setting_team, NM_TYPE_SETTING, + _nm_register_setting (TEAM, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM) + +#define NM_SETTING_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TEAM, NMSettingTeamPrivate)) + +typedef struct { + char *config; +} NMSettingTeamPrivate; + +enum { + PROP_0, + PROP_CONFIG, + LAST_PROP +}; + +/** + * nm_setting_team_new: + * + * Creates a new #NMSettingTeam object with default values. + * + * Returns: (transfer full): the new empty #NMSettingTeam object + **/ +NMSetting * +nm_setting_team_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_TEAM, NULL); +} + +/** + * nm_setting_team_get_config: + * @setting: the #NMSettingTeam + * + * Returns: the #NMSettingTeam:config property of the setting + **/ +const char * +nm_setting_team_get_config (NMSettingTeam *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL); + + return NM_SETTING_TEAM_GET_PRIVATE (setting)->config; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + return _nm_connection_verify_required_interface_name (connection, error); +} + +static void +nm_setting_team_init (NMSettingTeam *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object); + + g_free (priv->config); + + G_OBJECT_CLASS (nm_setting_team_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_CONFIG: + g_free (priv->config); + priv->config = 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) +{ + NMSettingTeam *setting = NM_SETTING_TEAM (object); + + switch (prop_id) { + case PROP_CONFIG: + g_value_set_string (value, nm_setting_team_get_config (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_team_class_init (NMSettingTeamClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingTeamPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingTeam:config: + * + * The JSON configuration for the team network interface. The property + * should contain raw JSON configuration data suitable for teamd, because + * the value is passed directly to teamd. If not specified, the default + * configuration is used. See man teamd.conf for the format details. + **/ + /* ---ifcfg-rh--- + * property: config + * variable: TEAM_CONFIG + * description: Team configuration in JSON. See man teamd.conf for details. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CONFIG, + g_param_spec_string (NM_SETTING_TEAM_CONFIG, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /* ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * team's interface name. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); +} diff --git a/libnm-core/nm-setting-team.h b/libnm-core/nm-setting-team.h new file mode 100644 index 00000000..d66eb685 --- /dev/null +++ b/libnm-core/nm-setting-team.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#ifndef __NM_SETTING_TEAM_H__ +#define __NM_SETTING_TEAM_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_TEAM (nm_setting_team_get_type ()) +#define NM_SETTING_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_TEAM, NMSettingTeam)) +#define NM_SETTING_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_TEAM, NMSettingTeamClass)) +#define NM_IS_SETTING_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_TEAM)) +#define NM_IS_SETTING_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_TEAM)) +#define NM_SETTING_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_TEAM, NMSettingTeamClass)) + +#define NM_SETTING_TEAM_SETTING_NAME "team" + +#define NM_SETTING_TEAM_CONFIG "config" + +struct _NMSettingTeam { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingTeamClass; + +GType nm_setting_team_get_type (void); + +NMSetting * nm_setting_team_new (void); + +const char * nm_setting_team_get_config (NMSettingTeam *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_TEAM_H__ */ diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c new file mode 100644 index 00000000..f622ddcb --- /dev/null +++ b/libnm-core/nm-setting-vlan.c @@ -0,0 +1,822 @@ +/* -*- 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. + * + * Copyright 2011 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-vlan.h" +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-setting-wired.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-vlan + * @short_description: Describes connection properties for VLAN interfaces + * + * The #NMSettingVlan object is a #NMSetting subclass that describes properties + * necessary for connection to VLAN interfaces. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING, + _nm_register_setting (VLAN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VLAN) + +#define NM_SETTING_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VLAN, NMSettingVlanPrivate)) + +typedef struct { + char *parent; + guint32 id; + guint32 flags; + GSList *ingress_priority_map; + GSList *egress_priority_map; +} NMSettingVlanPrivate; + +enum { + PROP_0, + PROP_PARENT, + PROP_ID, + PROP_FLAGS, + PROP_INGRESS_PRIORITY_MAP, + PROP_EGRESS_PRIORITY_MAP, + LAST_PROP +}; + +#define MAX_SKB_PRIO G_MAXUINT32 +#define MAX_8021P_PRIO 7 /* Max 802.1p priority */ + +typedef struct { + guint32 from; + guint32 to; +} PriorityMap; + +/** + * nm_setting_vlan_new: + * + * Creates a new #NMSettingVlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVlan object + **/ +NMSetting * +nm_setting_vlan_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_VLAN, NULL); +} + +/** + * nm_setting_vlan_get_parent: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:parent property of the setting + **/ +const char * +nm_setting_vlan_get_parent (NMSettingVlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), NULL); + return NM_SETTING_VLAN_GET_PRIVATE (setting)->parent; +} + +/** + * nm_setting_vlan_get_id: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:id property of the setting + **/ +guint32 +nm_setting_vlan_get_id (NMSettingVlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), 0); + return NM_SETTING_VLAN_GET_PRIVATE (setting)->id; +} + +/** + * nm_setting_vlan_get_flags: + * @setting: the #NMSettingVlan + * + * Returns: the #NMSettingVlan:flags property of the setting + **/ +guint32 +nm_setting_vlan_get_flags (NMSettingVlan *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), 0); + return NM_SETTING_VLAN_GET_PRIVATE (setting)->flags; +} + +static guint32 +get_max_prio (NMVlanPriorityMap map, gboolean from) +{ + if (map == NM_VLAN_INGRESS_MAP) + return from ? MAX_8021P_PRIO : MAX_SKB_PRIO; + else if (map == NM_VLAN_EGRESS_MAP) + return from ? MAX_SKB_PRIO : MAX_8021P_PRIO; + g_assert_not_reached (); +} + +static PriorityMap * +priority_map_new_from_str (NMVlanPriorityMap map, const char *str) +{ + PriorityMap *p = NULL; + gchar **t = NULL; + guint32 len; + guint64 from, to; + + g_return_val_if_fail (str && str[0], NULL); + + t = g_strsplit (str, ":", 0); + len = g_strv_length (t); + if (len == 2) { + from = g_ascii_strtoull (t[0], NULL, 10); + to = g_ascii_strtoull (t[1], NULL, 10); + + if ((from <= get_max_prio (map, TRUE)) && (to <= get_max_prio (map, FALSE))) { + p = g_malloc0 (sizeof (PriorityMap)); + p->from = from; + p->to = to; + } + } else { + /* Warn */ + g_warn_if_fail (len == 2); + } + + g_strfreev (t); + return p; +} + +static void +priority_map_free (PriorityMap *map) +{ + g_return_if_fail (map != NULL); + g_free (map); +} + +static GSList * +get_map (NMSettingVlan *self, NMVlanPriorityMap map) +{ + if (map == NM_VLAN_INGRESS_MAP) + return NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map; + else if (map == NM_VLAN_EGRESS_MAP) + return NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map; + g_assert_not_reached (); + return NULL; +} + +static void +set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) +{ + if (map == NM_VLAN_INGRESS_MAP) { + NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map = list; + g_object_notify (G_OBJECT (self), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + } else if (map == NM_VLAN_EGRESS_MAP) { + NM_SETTING_VLAN_GET_PRIVATE (self)->egress_priority_map = list; + g_object_notify (G_OBJECT (self), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + } else + g_assert_not_reached (); +} + +/** + * nm_setting_vlan_add_priority_str: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @str: the string which contains a priority map, like "3:7" + * + * Adds a priority map entry into either the #NMSettingVlan:ingress_priority_map + * or the #NMSettingVlan:egress_priority_map properties. The priority map maps + * the Linux SKB priorities to 802.1p priorities. + * + * Returns: %TRUE if the entry was successfully added to the list, or it + * overwrote the old value, %FALSE if error + */ +gboolean +nm_setting_vlan_add_priority_str (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str) +{ + GSList *list = NULL, *iter = NULL; + PriorityMap *item = NULL; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + g_return_val_if_fail (str && str[0], FALSE); + + list = get_map (setting, map); + + item = priority_map_new_from_str (map, str); + if (!item) + g_return_val_if_reached (FALSE); + + /* Duplicates get replaced */ + for (iter = list; iter; iter = g_slist_next (iter)) { + PriorityMap *p = iter->data; + + if (p->from == item->from) { + p->to = item->to; + g_free (item); + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; + } + } + + set_map (setting, map, g_slist_append (list, item)); + return TRUE; +} + +/** + * nm_setting_vlan_get_num_priorities: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * + * Returns the number of entires in the + * #NMSettingVlan:ingress_priority_map or #NMSettingVlan:egress_priority_map + * properties of this setting. + * + * Returns: return the number of ingress/egress priority entries, -1 if error + **/ +gint32 +nm_setting_vlan_get_num_priorities (NMSettingVlan *setting, NMVlanPriorityMap map) +{ + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), -1); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, -1); + + return g_slist_length (get_map (setting, map)); +} + +/** + * nm_setting_vlan_get_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @idx: the zero-based index of the ingress/egress priority map entry + * @out_from: (out): on return the value of the priority map's 'from' item + * @out_to: (out): on return the value of priority map's 'to' item + * + * Retrieve one of the entries of the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map properties of this setting. + * + * Returns: %TRUE if a priority map was returned, %FALSE if error + **/ +gboolean +nm_setting_vlan_get_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 idx, + guint32 *out_from, + guint32 *out_to) +{ + GSList *list = NULL; + PriorityMap *item = NULL; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + g_return_val_if_fail (out_from != NULL, FALSE); + g_return_val_if_fail (out_to != NULL, FALSE); + + list = get_map (setting, map); + g_return_val_if_fail (idx < g_slist_length (list), FALSE); + + item = g_slist_nth_data (list, idx); + g_assert (item); + *out_from = item->from; + *out_to = item->to; + return TRUE; +} + +/** + * nm_setting_vlan_add_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @from: the priority to map to @to + * @to: the priority to map @from to + * + * Adds a priority mapping to the #NMSettingVlan:ingress_priority_map or + * #NMSettingVlan:egress_priority_map properties of the setting. If @from is + * already in the given priority map, this function will overwrite the + * existing entry with the new @to. + * + * If @map is #NM_VLAN_INGRESS_MAP then @from is the incoming 802.1q VLAN + * Priority Code Point (PCP) value, and @to is the Linux SKB priority value. + * + * If @map is #NM_VLAN_EGRESS_MAP then @from is the Linux SKB priority value and + * @to is the outgoing 802.1q VLAN Priority Code Point (PCP) value. + * + * Returns: %TRUE if the new priority mapping was successfully added to the + * list, %FALSE if error + */ +gboolean +nm_setting_vlan_add_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to) +{ + GSList *list = NULL, *iter = NULL; + PriorityMap *item; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + list = get_map (setting, map); + for (iter = list; iter; iter = g_slist_next (iter)) { + item = iter->data; + if (item->from == from) { + item->to = to; + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; + } + } + + item = g_malloc0 (sizeof (PriorityMap)); + item->from = from; + item->to = to; + set_map (setting, map, g_slist_append (list, item)); + + return TRUE; +} + +/** + * nm_setting_vlan_remove_priority: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @idx: the zero-based index of the priority map to remove + * + * Removes the priority map at index @idx from the + * #NMSettingVlan:ingress_priority_map or #NMSettingVlan:egress_priority_map + * properties. + */ +void +nm_setting_vlan_remove_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 idx) +{ + GSList *list = NULL, *item = NULL; + + g_return_if_fail (NM_IS_SETTING_VLAN (setting)); + g_return_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP); + + list = get_map (setting, map); + g_return_if_fail (idx < g_slist_length (list)); + + item = g_slist_nth (list, idx); + priority_map_free ((PriorityMap *) (item->data)); + set_map (setting, map, g_slist_delete_link (list, item)); +} + +/** + * nm_setting_vlan_remove_priority_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @from: the priority to map to @to + * @to: the priority to map @from to + * + * Removes the priority map @form:@to from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to) +{ + GSList *list = NULL, *iter = NULL; + PriorityMap *item; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + list = get_map (setting, map); + for (iter = list; iter; iter = g_slist_next (iter)) { + item = iter->data; + if (item->from == from && item->to == to) { + priority_map_free ((PriorityMap *) (iter->data)); + set_map (setting, map, g_slist_delete_link (list, iter)); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_vlan_remove_priority_str_by_value: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * @str: the string which contains a priority map, like "3:7" + * + * Removes the priority map @str from the #NMSettingVlan:ingress_priority_map + * or #NMSettingVlan:egress_priority_map (according to @map argument) + * properties. + * + * Returns: %TRUE if the priority mapping was found and removed; %FALSE if it was not. + */ +gboolean +nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str) +{ + PriorityMap *item; + gboolean found; + + g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); + g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); + + item = priority_map_new_from_str (map, str); + if (!item) + return FALSE; + + found = nm_setting_vlan_remove_priority_by_value (setting, map, item->from, item->to); + g_free (item); + return found; +} + +/** + * nm_setting_vlan_clear_priorities: + * @setting: the #NMSettingVlan + * @map: the type of priority map + * + * Clear all the entires from #NMSettingVlan:ingress_priority_map or + * #NMSettingVlan:egress_priority_map properties. + */ +void +nm_setting_vlan_clear_priorities (NMSettingVlan *setting, NMVlanPriorityMap map) +{ + GSList *list = NULL; + + g_return_if_fail (NM_IS_SETTING_VLAN (setting)); + g_return_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP); + + list = get_map (setting, map); + g_slist_free_full (list, g_free); + set_map (setting, map, NULL); +} + +/*********************************************************************/ + +static void +nm_setting_vlan_init (NMSettingVlan *setting) +{ +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting); + NMSettingConnection *s_con; + NMSettingWired *s_wired; + + if (connection) { + s_con = nm_connection_get_setting_connection (connection); + s_wired = nm_connection_get_setting_wired (connection); + } else { + s_con = NULL; + s_wired = NULL; + } + + if (priv->parent) { + if (nm_utils_is_uuid (priv->parent)) { + /* If we have an NMSettingConnection:master with slave-type="vlan", + * then it must be the same UUID. + */ + if (s_con) { + const char *master = NULL, *slave_type = NULL; + + slave_type = nm_setting_connection_get_slave_type (s_con); + if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME)) + master = nm_setting_connection_get_master (s_con); + + if (master && g_strcmp0 (priv->parent, master) != 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' value doesn't match '%s=%s'"), + priv->parent, NM_SETTING_CONNECTION_MASTER, master); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); + return FALSE; + } + } + } else if (!nm_utils_iface_valid_name (priv->parent)) { + /* parent must be either a UUID or an interface name */ + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via + * NMSettingWired:mac-address. + */ + if ( connection + && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); + return FALSE; + } + } + + if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS | + NM_VLAN_FLAG_GVRP | + NM_VLAN_FLAG_LOOSE_BINDING)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("flags are invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS); + return FALSE; + } + + return TRUE; +} + +static GSList * +priority_strv_to_maplist (NMVlanPriorityMap map, char **strv) +{ + GSList *list = NULL; + int i; + + for (i = 0; strv[i]; i++) { + PriorityMap *item; + + item = priority_map_new_from_str (map, strv[i]); + if (item) + list = g_slist_prepend (list, item); + } + return g_slist_reverse (list); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingVlan *setting = NM_SETTING_VLAN (object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_free (priv->parent); + priv->parent = g_value_dup_string (value); + break; + case PROP_ID: + priv->id = g_value_get_uint (value); + break; + case PROP_FLAGS: + priv->flags = g_value_get_flags (value); + break; + case PROP_INGRESS_PRIORITY_MAP: + g_slist_free_full (priv->ingress_priority_map, g_free); + priv->ingress_priority_map = + priority_strv_to_maplist (NM_VLAN_INGRESS_MAP, g_value_get_boxed (value)); + break; + case PROP_EGRESS_PRIORITY_MAP: + g_slist_free_full (priv->egress_priority_map, g_free); + priv->egress_priority_map = + priority_strv_to_maplist (NM_VLAN_EGRESS_MAP, g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static char ** +priority_maplist_to_strv (GSList *list) +{ + GSList *iter; + GPtrArray *strv; + + strv = g_ptr_array_new (); + + for (iter = list; iter; iter = g_slist_next (iter)) { + PriorityMap *item = iter->data; + + g_ptr_array_add (strv, g_strdup_printf ("%d:%d", item->from, item->to)); + } + g_ptr_array_add (strv, NULL); + + return (char **) g_ptr_array_free (strv, FALSE); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingVlan *setting = NM_SETTING_VLAN (object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_string (value, priv->parent); + break; + case PROP_ID: + g_value_set_uint (value, priv->id); + break; + case PROP_FLAGS: + g_value_set_flags (value, priv->flags); + break; + case PROP_INGRESS_PRIORITY_MAP: + g_value_take_boxed (value, priority_maplist_to_strv (priv->ingress_priority_map)); + break; + case PROP_EGRESS_PRIORITY_MAP: + g_value_take_boxed (value, priority_maplist_to_strv (priv->egress_priority_map)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +finalize (GObject *object) +{ + NMSettingVlan *setting = NM_SETTING_VLAN (object); + NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting); + + g_free (priv->parent); + g_slist_free_full (priv->ingress_priority_map, g_free); + g_slist_free_full (priv->egress_priority_map, g_free); + + G_OBJECT_CLASS (nm_setting_vlan_parent_class)->finalize (object); +} + +static void +nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingVlanPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + + /** + * NMSettingVlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this VLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + **/ + /* ---ifcfg-rh--- + * property: parent + * variable: DEVICE or PHYSDEV + * description: Parent interface of the VLAN. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_string (NM_SETTING_VLAN_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVlan:id: + * + * The VLAN identifier that the interface created by this connection should + * be assigned. + **/ + /* ---ifcfg-rh--- + * property: id + * variable: VLAN_ID or DEVICE + * description: VLAN identifier. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_uint (NM_SETTING_VLAN_ID, "", "", + 0, 4095, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVlan:flags: + * + * One or more flags which control the behavior and features of the VLAN + * interface. Flags include %NM_VLAN_FLAG_REORDER_HEADERS (reordering of + * output packet headers), %NM_VLAN_FLAG_GVRP (use of the GVRP protocol), + * and %NM_VLAN_FLAG_LOOSE_BINDING (loose binding of the interface to its + * master device's operating state). + **/ + /* ---ifcfg-rh--- + * property: flags + * variable: VLAN_FLAGS, REORDER_HDR + * values: "GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDR + * description: Parent interface of the VLAN. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_FLAGS, + g_param_spec_flags (NM_SETTING_VLAN_FLAGS, "", "", + NM_TYPE_VLAN_FLAGS, + 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVlan:ingress-priority-map: + * + * For incoming packets, a list of mappings from 802.1p priorities to Linux + * SKB priorities. The mapping is given in the format "from:to" where both + * "from" and "to" are unsigned integers, ie "7:3". + **/ + /* ---ifcfg-rh--- + * property: ingress-property-map + * variable: VLAN_INGRESS_PRIORITY_MAP + * description: Ingress priority mapping. + * example: VLAN_INGRESS_PRIORITY_MAP=4:2,3:5 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_INGRESS_PRIORITY_MAP, + g_param_spec_boxed (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVlan:egress-priority-map: + * + * For outgoing packets, a list of mappings from Linux SKB priorities to + * 802.1p priorities. The mapping is given in the format "from:to" where + * both "from" and "to" are unsigned integers, ie "7:3". + **/ + /* ---ifcfg-rh--- + * property: egress-property-map + * variable: VLAN_EGRESS_PRIORITY_MAP + * description: Egress priority mapping. + * example: VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_EGRESS_PRIORITY_MAP, + g_param_spec_boxed (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /* ---ifcfg-rh--- + * property: interface-name + * variable: PHYSDEV and VLAN_ID, or DEVICE + * description: VLAN interface name. + * If all variables are set, parent device from PHYSDEV takes precedence over DEVICE, + * but VLAN id from DEVICE takes precedence over VLAN_ID. + * example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12 + * ---end--- + * ---dbus--- + * property: interface-name + * format: string + * description: Deprecated in favor of connection.interface-name, but can + * be used for backward-compatibility with older daemons, to set the + * vlan's interface name. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (parent_class, "interface-name", + G_VARIANT_TYPE_STRING, + _nm_setting_get_deprecated_virtual_interface_name, + NULL); +} diff --git a/libnm-core/nm-setting-vlan.h b/libnm-core/nm-setting-vlan.h new file mode 100644 index 00000000..30305d32 --- /dev/null +++ b/libnm-core/nm-setting-vlan.h @@ -0,0 +1,134 @@ +/* -*- 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. + * + * Copyright 2011 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VLAN_H__ +#define __NM_SETTING_VLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-setting.h" +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VLAN (nm_setting_vlan_get_type ()) +#define NM_SETTING_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VLAN, NMSettingVlan)) +#define NM_SETTING_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VLANCONFIG, NMSettingVlanClass)) +#define NM_IS_SETTING_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VLAN)) +#define NM_IS_SETTING_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_VLAN)) +#define NM_SETTING_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VLAN, NMSettingVlanClass)) + +#define NM_SETTING_VLAN_SETTING_NAME "vlan" + +#define NM_SETTING_VLAN_PARENT "parent" +#define NM_SETTING_VLAN_ID "id" +#define NM_SETTING_VLAN_FLAGS "flags" +#define NM_SETTING_VLAN_INGRESS_PRIORITY_MAP "ingress-priority-map" +#define NM_SETTING_VLAN_EGRESS_PRIORITY_MAP "egress-priority-map" + +struct _NMSettingVlan { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVlanClass; + +/** + * NMVlanPriorityMap: + * @NM_VLAN_INGRESS_MAP: map for incoming data + * @NM_VLAN_EGRESS_MAP: map for outgoing data + * + * A selector for traffic priority maps; these map Linux SKB priorities + * to 802.1p priorities used in VLANs. + **/ +typedef enum { + NM_VLAN_INGRESS_MAP, + NM_VLAN_EGRESS_MAP +} NMVlanPriorityMap; + +/** + * NMVlanFlags: + * @NM_VLAN_FLAG_REORDER_HEADERS: indicates that this interface should reorder + * outgoing packet headers to look more like a non-VLAN Ethernet interface + * @NM_VLAN_FLAG_GVRP: indicates that this interface should use GVRP to register + * itself with it's switch + * @NM_VLAN_FLAG_LOOSE_BINDING: indicates that this interface's operating + * state is tied to the underlying network interface but other details + * (like routing) are not. + * + * #NMVlanFlags values control the behavior of the VLAN interface. + **/ +typedef enum { /*< flags >*/ + NM_VLAN_FLAG_REORDER_HEADERS = 0x1, + NM_VLAN_FLAG_GVRP = 0x2, + NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + + /* NOTE: if adding flags update nm-setting-vlan.c::verify() */ +} NMVlanFlags; + +GType nm_setting_vlan_get_type (void); +NMSetting *nm_setting_vlan_new (void); + +const char *nm_setting_vlan_get_parent (NMSettingVlan *setting); +guint32 nm_setting_vlan_get_id (NMSettingVlan *setting); +guint32 nm_setting_vlan_get_flags (NMSettingVlan *setting); + +gint32 nm_setting_vlan_get_num_priorities (NMSettingVlan *setting, NMVlanPriorityMap map); + +gboolean nm_setting_vlan_get_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 idx, + guint32 *out_from, + guint32 *out_to); + +gboolean nm_setting_vlan_add_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to); + +void nm_setting_vlan_remove_priority (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 idx); + +gboolean nm_setting_vlan_remove_priority_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + guint32 from, + guint32 to); + +gboolean nm_setting_vlan_remove_priority_str_by_value (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str); + +void nm_setting_vlan_clear_priorities (NMSettingVlan *setting, NMVlanPriorityMap map); + +gboolean nm_setting_vlan_add_priority_str (NMSettingVlan *setting, + NMVlanPriorityMap map, + const char *str); + +G_END_DECLS + +#endif /* __NM_SETTING_VLAN_H__ */ diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c new file mode 100644 index 00000000..e6fffa87 --- /dev/null +++ b/libnm-core/nm-setting-vpn.c @@ -0,0 +1,913 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-setting-vpn.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-vpn + * @short_description: Describes connection properties for Virtual Private Networks + * + * The #NMSettingVpn object is a #NMSetting subclass that describes properties + * necessary for connection to Virtual Private Networks. NetworkManager uses + * a plugin architecture to allow easier use of new VPN types, and this + * setting abstracts the configuration for those plugins. Since the configuration + * options are only known to the VPN plugins themselves, the VPN configuration + * options are stored as key/value pairs of strings rather than GObject + * properties. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingVpn, nm_setting_vpn, NM_TYPE_SETTING, + _nm_register_setting (VPN, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VPN) + +#define NM_SETTING_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VPN, NMSettingVpnPrivate)) + +typedef struct { + char *service_type; + + /* username of the user requesting this connection, thus + * it's really only valid for user connections, and it also + * should never be saved out to persistent config. + */ + char *user_name; + + /* Whether the VPN stays up across link changes, until the user + * explicitly disconnects it. + */ + gboolean persistent; + + /* The hash table is created at setting object + * init time and should not be replaced. It is + * a char * -> char * mapping, and both the key + * and value are owned by the hash table, and should + * be allocated with functions whose value can be + * freed with g_free(). Should not contain secrets. + */ + GHashTable *data; + + /* The hash table is created at setting object + * init time and should not be replaced. It is + * a char * -> char * mapping, and both the key + * and value are owned by the hash table, and should + * be allocated with functions whose value can be + * freed with g_free(). Should contain secrets only. + */ + GHashTable *secrets; +} NMSettingVpnPrivate; + +enum { + PROP_0, + PROP_SERVICE_TYPE, + PROP_USER_NAME, + PROP_PERSISTENT, + PROP_DATA, + PROP_SECRETS, + + LAST_PROP +}; + +/** + * nm_setting_vpn_new: + * + * Creates a new #NMSettingVpn object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVpn object + **/ +NMSetting * +nm_setting_vpn_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_VPN, NULL); +} + +/** + * nm_setting_vpn_get_service_type: + * @setting: the #NMSettingVpn + * + * Returns the service name of the VPN, which identifies the specific VPN + * plugin that should be used to connect to this VPN. + * + * Returns: the VPN plugin's service name + **/ +const char * +nm_setting_vpn_get_service_type (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); + + return NM_SETTING_VPN_GET_PRIVATE (setting)->service_type; +} + +/** + * nm_setting_vpn_get_user_name: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:user-name property of the setting + **/ +const char * +nm_setting_vpn_get_user_name (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); + + return NM_SETTING_VPN_GET_PRIVATE (setting)->user_name; +} + +/** + * nm_setting_vpn_get_persistent: + * @setting: the #NMSettingVpn + * + * Returns: the #NMSettingVpn:persistent property of the setting + **/ +gboolean +nm_setting_vpn_get_persistent (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); + + return NM_SETTING_VPN_GET_PRIVATE (setting)->persistent; +} + +/** + * nm_setting_vpn_get_num_data_items: + * @setting: the #NMSettingVpn + * + * Gets number of key/value pairs of VPN configuration data. + * + * Returns: the number of VPN plugin specific configuration data items + **/ +guint32 +nm_setting_vpn_get_num_data_items (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); + + return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->data); +} + +/** + * nm_setting_vpn_add_data_item: + * @setting: the #NMSettingVpn + * @key: a name that uniquely identifies the given value @item + * @item: the value to be referenced by @key + * + * Establishes a relationship between @key and @item internally in the + * setting which may be retrieved later. Should not be used to store passwords + * or other secrets, which is what nm_setting_vpn_add_secret() is for. + **/ +void +nm_setting_vpn_add_data_item (NMSettingVpn *setting, + const char *key, + const char *item) +{ + g_return_if_fail (NM_IS_SETTING_VPN (setting)); + g_return_if_fail (key != NULL); + g_return_if_fail (strlen (key) > 0); + g_return_if_fail (item != NULL); + g_return_if_fail (strlen (item) > 0); + + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + g_strdup (key), g_strdup (item)); + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA); +} + +/** + * nm_setting_vpn_get_data_item: + * @setting: the #NMSettingVpn + * @key: the name of the data item to retrieve + * + * Retrieves the data item of a key/value relationship previously established + * by nm_setting_vpn_add_data_item(). + * + * Returns: the data item, if any + **/ +const char * +nm_setting_vpn_get_data_item (NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); + + return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); +} + +/** + * nm_setting_vpn_remove_data_item: + * @setting: the #NMSettingVpn + * @key: the name of the data item to remove + * + * Deletes a key/value relationship previously established by + * nm_setting_vpn_add_data_item(). + * + * Returns: %TRUE if the data item was found and removed from the internal list, + * %FALSE if it was not. + **/ +gboolean +nm_setting_vpn_remove_data_item (NMSettingVpn *setting, const char *key) +{ + gboolean found; + + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); + + found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); + if (found) + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_DATA); + return found; +} + +static void +foreach_item_helper (GHashTable *hash, + NMVpnIterFunc func, + gpointer user_data) +{ + GList *keys, *liter; + GSList *copied = NULL, *siter; + + g_return_if_fail (hash != NULL); + + /* Grab keys and copy them so that the callback func can modify + * the hash table items if it wants to. + */ + keys = g_hash_table_get_keys (hash); + for (liter = keys; liter; liter = g_list_next (liter)) + copied = g_slist_prepend (copied, g_strdup (liter->data)); + copied = g_slist_reverse (copied); + g_list_free (keys); + + for (siter = copied; siter; siter = g_slist_next (siter)) { + gpointer value; + + value = g_hash_table_lookup (hash, siter->data); + func (siter->data, value, user_data); + } + + g_slist_free_full (copied, g_free); +} + +/** + * nm_setting_vpn_foreach_data_item: + * @setting: a #NMSettingVpn + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all data items stored in this setting. It is safe to add, remove, + * and modify data items inside @func, though any additions or removals made + * during iteration will not be part of the iteration. + */ +void +nm_setting_vpn_foreach_data_item (NMSettingVpn *setting, + NMVpnIterFunc func, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SETTING_VPN (setting)); + + foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->data, func, user_data); +} + +/** + * nm_setting_vpn_get_num_secrets: + * @setting: the #NMSettingVpn + * + * Gets number of VPN plugin specific secrets in the setting. + * + * Returns: the number of VPN plugin specific secrets + **/ +guint32 +nm_setting_vpn_get_num_secrets (NMSettingVpn *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), 0); + + return g_hash_table_size (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets); +} + +/** + * nm_setting_vpn_add_secret: + * @setting: the #NMSettingVpn + * @key: a name that uniquely identifies the given secret @secret + * @secret: the secret to be referenced by @key + * + * Establishes a relationship between @key and @secret internally in the + * setting which may be retrieved later. + **/ +void +nm_setting_vpn_add_secret (NMSettingVpn *setting, + const char *key, + const char *secret) +{ + g_return_if_fail (NM_IS_SETTING_VPN (setting)); + g_return_if_fail (key != NULL); + g_return_if_fail (strlen (key) > 0); + g_return_if_fail (secret != NULL); + g_return_if_fail (strlen (secret) > 0); + + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, + g_strdup (key), g_strdup (secret)); + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); +} + +/** + * nm_setting_vpn_get_secret: + * @setting: the #NMSettingVpn + * @key: the name of the secret to retrieve + * + * Retrieves the secret of a key/value relationship previously established + * by nm_setting_vpn_add_secret(). + * + * Returns: the secret, if any + **/ +const char * +nm_setting_vpn_get_secret (NMSettingVpn *setting, const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), NULL); + + return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); +} + +/** + * nm_setting_vpn_remove_secret: + * @setting: the #NMSettingVpn + * @key: the name of the secret to remove + * + * Deletes a key/value relationship previously established by + * nm_setting_vpn_add_secret(). + * + * Returns: %TRUE if the secret was found and removed from the internal list, + * %FALSE if it was not. + **/ +gboolean +nm_setting_vpn_remove_secret (NMSettingVpn *setting, const char *key) +{ + gboolean found; + + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); + + found = g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); + if (found) + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); + return found; +} + +/** + * nm_setting_vpn_foreach_secret: + * @setting: a #NMSettingVpn + * @func: (scope call): an user provided function + * @user_data: data to be passed to @func + * + * Iterates all secrets stored in this setting. It is safe to add, remove, + * and modify secrets inside @func, though any additions or removals made during + * iteration will not be part of the iteration. + */ +void +nm_setting_vpn_foreach_secret (NMSettingVpn *setting, + NMVpnIterFunc func, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SETTING_VPN (setting)); + + foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, func, user_data); +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + + if (!priv->service_type) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); + return FALSE; + } + + if (!strlen (priv->service_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_SERVICE_TYPE); + return FALSE; + } + + /* default username can be NULL, but can't be zero-length */ + if (priv->user_name && !strlen (priv->user_name)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, NM_SETTING_VPN_USER_NAME); + return FALSE; + } + + return TRUE; +} + +static NMSettingUpdateSecretResult +update_secret_string (NMSetting *setting, + const char *key, + const char *value, + GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + + g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + if (!value || !strlen (value)) { + g_set_error (error, NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("secret was empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, key); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + if (g_strcmp0 (g_hash_table_lookup (priv->secrets, key), value) == 0) + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value)); + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; +} + +static NMSettingUpdateSecretResult +update_secret_dict (NMSetting *setting, + GVariant *secrets, + GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + GVariantIter iter; + const char *name, *value; + NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_return_val_if_fail (secrets != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + /* Make sure the items are valid */ + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { + if (!name || !strlen (name)) { + g_set_error_literal (error, NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting contained a secret with an empty name")); + g_prefix_error (error, "%s: ", NM_SETTING_VPN_SETTING_NAME); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + if (!value || !strlen (value)) { + g_set_error (error, NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("secret value was empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, name); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + } + + /* Now add the items to the settings' secrets list */ + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&s&s}", &name, &value)) { + if (value == NULL) { + g_warn_if_fail (value != NULL); + continue; + } + if (strlen (value) == 0) { + g_warn_if_fail (strlen (value) > 0); + continue; + } + + if (g_strcmp0 (g_hash_table_lookup (priv->secrets, name), value) == 0) + continue; + + g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); + result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + } + + return result; +} + +static int +update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error) +{ + NMSettingUpdateSecretResult success = NM_SETTING_UPDATE_SECRET_ERROR; + + g_return_val_if_fail (key != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail (value != NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { + /* Passing the string properties individually isn't correct, and won't + * produce the correct result, but for some reason that's how it used + * to be done. So even though it's not correct, keep the code around + * for compatibility's sake. + */ + success = update_secret_string (setting, key, g_variant_get_string (value, NULL), error); + } else if (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{ss}"))) { + if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) { + g_set_error_literal (error, NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("not a secret property")); + g_prefix_error (error, "%s.%s ", NM_SETTING_VPN_SETTING_NAME, key); + } else + success = update_secret_dict (setting, value, error); + } else { + g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("secret is not of correct type")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, key); + } + + if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); + + return success; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + gboolean success = FALSE; + char *flags_key; + gpointer val; + unsigned long tmp; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + flags_key = g_strdup_printf ("%s-flags", secret_name); + if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { + errno = 0; + tmp = strtoul ((const char *) val, NULL, 10); + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { + flags = (NMSettingSecretFlags) tmp; + success = TRUE; + } else { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("failed to convert value '%s' to uint"), + (const char *) val); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, flags_key); + } + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("secret flags property not found")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_VPN_SETTING_NAME, flags_key); + } + g_free (flags_key); + if (out_flags) + *out_flags = flags; + return success; +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + g_strdup_printf ("%s-flags", secret_name), + g_strdup_printf ("%u", flags)); + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); + return TRUE; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + /* Assume that VPN connections need secrets since they almost always will */ + return g_ptr_array_sized_new (1); +} + +static gboolean +compare_one_secret (NMSettingVpn *a, + NMSettingVpn *b, + NMSettingCompareFlags flags) +{ + GHashTable *a_secrets, *b_secrets; + GHashTableIter iter; + const char *key, *val; + + a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets; + b_secrets = NM_SETTING_VPN_GET_PRIVATE (b)->secrets; + + g_hash_table_iter_init (&iter, a_secrets); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) { + NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL); + nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL); + + /* If the secret flags aren't the same, the settings aren't the same */ + if (a_secret_flags != b_secret_flags) + return FALSE; + + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) + && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + continue; + + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) + continue; + + /* Now compare the values themselves */ + if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0) + return FALSE; + } + + return TRUE; +} + +static gboolean +compare_property (NMSetting *setting, + NMSetting *other, + const GParamSpec *prop_spec, + NMSettingCompareFlags flags) +{ + gboolean same; + + /* We only need to treat the 'secrets' property specially */ + if (g_strcmp0 (prop_spec->name, NM_SETTING_VPN_SECRETS) != 0) + return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (setting, other, prop_spec, flags); + + /* Compare A to B to ensure everything in A is found in B */ + same = compare_one_secret (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags); + if (same) { + /* And then B to A to ensure everything in B is also found in A */ + same = compare_one_secret (NM_SETTING_VPN (other), NM_SETTING_VPN (setting), flags); + } + + return same; +} + +static gboolean +clear_secrets_with_flags (NMSetting *setting, + GParamSpec *pspec, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + GHashTableIter iter; + const char *secret; + gboolean changed = TRUE; + + if (priv->secrets == NULL) + return FALSE; + + /* Iterate through secrets hash and check each entry */ + g_hash_table_iter_init (&iter, priv->secrets); + while (g_hash_table_iter_next (&iter, (gpointer) &secret, NULL)) { + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (setting, secret, &flags, NULL); + if (func (setting, pspec->name, flags, user_data) == TRUE) { + g_hash_table_iter_remove (&iter); + changed = TRUE; + } + } + + if (changed) + g_object_notify (G_OBJECT (setting), NM_SETTING_VPN_SECRETS); + + return changed; +} + +static void +destroy_one_secret (gpointer data) +{ + char *secret = (char *) data; + + /* Don't leave the secret lying around in memory */ + memset (secret, 0, strlen (secret)); + g_free (secret); +} + +static void +nm_setting_vpn_init (NMSettingVpn *setting) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + + priv->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_one_secret); +} + +static void +finalize (GObject *object) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); + + g_free (priv->service_type); + g_free (priv->user_name); + g_hash_table_destroy (priv->data); + g_hash_table_destroy (priv->secrets); + + G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_free (priv->service_type); + priv->service_type = g_value_dup_string (value); + break; + case PROP_USER_NAME: + g_free (priv->user_name); + priv->user_name = g_value_dup_string (value); + break; + case PROP_PERSISTENT: + priv->persistent = g_value_get_boolean (value); + break; + case PROP_DATA: + g_hash_table_unref (priv->data); + priv->data = _nm_utils_copy_strdict (g_value_get_boxed (value)); + break; + case PROP_SECRETS: + g_hash_table_unref (priv->secrets); + priv->secrets = _nm_utils_copy_strdict (g_value_get_boxed (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) +{ + NMSettingVpn *setting = NM_SETTING_VPN (object); + NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_SERVICE_TYPE: + g_value_set_string (value, nm_setting_vpn_get_service_type (setting)); + break; + case PROP_USER_NAME: + g_value_set_string (value, nm_setting_vpn_get_user_name (setting)); + break; + case PROP_PERSISTENT: + g_value_set_boolean (value, priv->persistent); + break; + case PROP_DATA: + g_value_take_boxed (value, _nm_utils_copy_strdict (priv->data)); + break; + case PROP_SECRETS: + g_value_take_boxed (value, _nm_utils_copy_strdict (priv->secrets)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_vpn_class_init (NMSettingVpnClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingVpnPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + parent_class->verify = verify; + parent_class->update_one_secret = update_one_secret; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; + parent_class->need_secrets = need_secrets; + parent_class->compare_property = compare_property; + parent_class->clear_secrets_with_flags = clear_secrets_with_flags; + + /* Properties */ + /** + * NMSettingVpn:service-type: + * + * D-Bus service name of the VPN plugin that this setting uses to connect to + * its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc + * plugin. + **/ + g_object_class_install_property + (object_class, PROP_SERVICE_TYPE, + g_param_spec_string (NM_SETTING_VPN_SERVICE_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVpn:user-name: + * + * If the VPN connection requires a user name for authentication, that name + * should be provided here. If the connection is available to more than one + * user, and the VPN requires each user to supply a different name, then + * leave this property empty. If this property is empty, NetworkManager + * will automatically supply the username of the user which requested the + * VPN connection. + **/ + g_object_class_install_property + (object_class, PROP_USER_NAME, + g_param_spec_string (NM_SETTING_VPN_USER_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVpn:persistent: + * + * If the VPN service supports persistence, and this property is %TRUE, + * the VPN will attempt to stay connected across link changes and outages, + * until explicitly disconnected. + **/ + g_object_class_install_property + (object_class, PROP_PERSISTENT, + g_param_spec_boolean (NM_SETTING_VPN_PERSISTENT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVpn:data: + * + * Dictionary of key/value pairs of VPN plugin specific data. Both keys and + * values must be strings. + * + * Type: GHashTable(utf8,utf8) + **/ + /* ---keyfile--- + * property: data + * variable: separate variables named after keys of the dictionary + * description: The keys of the data dictionary are used as variable names directly + * under [vpn] section. + * example: remote=ovpn.corp.com cipher=AES-256-CBC username=joe + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_DATA, + g_param_spec_boxed (NM_SETTING_VPN_DATA, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_DATA, + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); + + /** + * NMSettingVpn:secrets: + * + * Dictionary of key/value pairs of VPN plugin specific secrets like + * passwords or private keys. Both keys and values must be strings. + * + * Type: GHashTable(utf8,utf8) + **/ + /* ---keyfile--- + * property: secrets + * variable: separate variables named after keys of the dictionary + * description: The keys of the secrets dictionary are used as variable names directly + * under [vpn-secrets] section. + * example: password=Popocatepetl + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SECRETS, + g_param_spec_boxed (NM_SETTING_VPN_SECRETS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_VPN_SECRETS, + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); +} diff --git a/libnm-core/nm-setting-vpn.h b/libnm-core/nm-setting-vpn.h new file mode 100644 index 00000000..487549af --- /dev/null +++ b/libnm-core/nm-setting-vpn.h @@ -0,0 +1,102 @@ +/* -*- 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. + * + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_VPN_H__ +#define __NM_SETTING_VPN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_VPN (nm_setting_vpn_get_type ()) +#define NM_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_VPN, NMSettingVpn)) +#define NM_SETTING_VPN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_VPN, NMSettingVpnClass)) +#define NM_IS_SETTING_VPN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_VPN)) +#define NM_IS_SETTING_VPN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_VPN)) +#define NM_SETTING_VPN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_VPN, NMSettingVpnClass)) + +#define NM_SETTING_VPN_SETTING_NAME "vpn" + +#define NM_SETTING_VPN_SERVICE_TYPE "service-type" +#define NM_SETTING_VPN_USER_NAME "user-name" +#define NM_SETTING_VPN_PERSISTENT "persistent" +#define NM_SETTING_VPN_DATA "data" +#define NM_SETTING_VPN_SECRETS "secrets" + +struct _NMSettingVpn { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingVpnClass; + +/** + * NMVpnIterFunc: + * @key: the name of the data or secret item + * @value: the value of the data or secret item + * @user_data: User data passed to nm_setting_vpn_foreach_data_item() or + * nm_setting_vpn_foreach_secret() + **/ +typedef void (*NMVpnIterFunc) (const char *key, const char *value, gpointer user_data); + +GType nm_setting_vpn_get_type (void); + +NMSetting *nm_setting_vpn_new (void); +const char *nm_setting_vpn_get_service_type (NMSettingVpn *setting); +const char *nm_setting_vpn_get_user_name (NMSettingVpn *setting); +gboolean nm_setting_vpn_get_persistent (NMSettingVpn *setting); + +guint32 nm_setting_vpn_get_num_data_items (NMSettingVpn *setting); +void nm_setting_vpn_add_data_item (NMSettingVpn *setting, + const char *key, + const char *item); +const char * nm_setting_vpn_get_data_item (NMSettingVpn *setting, + const char *key); +gboolean nm_setting_vpn_remove_data_item (NMSettingVpn *setting, + const char *key); +void nm_setting_vpn_foreach_data_item (NMSettingVpn *setting, + NMVpnIterFunc func, + gpointer user_data); + +guint32 nm_setting_vpn_get_num_secrets (NMSettingVpn *setting); +void nm_setting_vpn_add_secret (NMSettingVpn *setting, + const char *key, + const char *secret); +const char * nm_setting_vpn_get_secret (NMSettingVpn *setting, + const char *key); +gboolean nm_setting_vpn_remove_secret (NMSettingVpn *setting, + const char *key); +void nm_setting_vpn_foreach_secret (NMSettingVpn *setting, + NMVpnIterFunc func, + gpointer user_data); + +G_END_DECLS + +#endif /* __NM_SETTING_VPN_H__ */ diff --git a/libnm-core/nm-setting-wimax.c b/libnm-core/nm-setting-wimax.c new file mode 100644 index 00000000..541c0bbf --- /dev/null +++ b/libnm-core/nm-setting-wimax.c @@ -0,0 +1,245 @@ +/* -*- 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. + * + * Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2009 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-wimax.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-wimax + * @short_description: Describes 802.16e Mobile WiMAX connection properties + * + * The #NMSettingWimax object is a #NMSetting subclass that describes properties + * necessary for connection to 802.16e Mobile WiMAX networks. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING, + _nm_register_setting (WIMAX, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIMAX) + +#define NM_SETTING_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate)) + +typedef struct { + char *network_name; + char *mac_address; +} NMSettingWimaxPrivate; + +enum { + PROP_0, + PROP_NETWORK_NAME, + PROP_MAC_ADDRESS, + + LAST_PROP +}; + +/** + * nm_setting_wimax_new: + * + * Creates a new #NMSettingWimax object with default values. + * + * Returns: the new empty #NMSettingWimax object + **/ +NMSetting * +nm_setting_wimax_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIMAX, NULL); +} + +/** + * nm_setting_wimax_get_network_name: + * @setting: the #NMSettingWimax + * + * Returns the WiMAX NSP name (ex "Sprint" or "CLEAR") which identifies the + * specific WiMAX network this setting describes a connection to. + * + * Returns: the WiMAX NSP name + **/ +const char * +nm_setting_wimax_get_network_name (NMSettingWimax *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE (setting)->network_name; +} + +/** + * nm_setting_wimax_get_mac_address: + * @setting: the #NMSettingWimax + * + * Returns the MAC address of a WiMAX device which this connection is locked + * to. + * + * Returns: the MAC address + **/ +const char * +nm_setting_wimax_get_mac_address (NMSettingWimax *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL); + + return NM_SETTING_WIMAX_GET_PRIVATE (setting)->mac_address; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (setting); + + if (!priv->network_name) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_NETWORK_NAME); + return FALSE; + } + + if (!strlen (priv->network_name)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_NETWORK_NAME); + return FALSE; + } + + if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS); + return FALSE; + } + + return TRUE; +} + +static void +nm_setting_wimax_init (NMSettingWimax *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object); + + g_free (priv->network_name); + g_free (priv->mac_address); + + G_OBJECT_CLASS (nm_setting_wimax_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_free (priv->network_name); + priv->network_name = g_value_dup_string (value); + break; + case PROP_MAC_ADDRESS: + g_free (priv->mac_address); + priv->mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + 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) +{ + NMSettingWimax *setting = NM_SETTING_WIMAX (object); + + switch (prop_id) { + case PROP_NETWORK_NAME: + g_value_set_string (value, nm_setting_wimax_get_network_name (setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string (value, nm_setting_wimax_get_mac_address (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingWimaxPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingWimax:network-name: + * + * Network Service Provider (NSP) name of the WiMAX network this connection + * should use. + **/ + g_object_class_install_property + (object_class, PROP_NETWORK_NAME, + g_param_spec_string (NM_SETTING_WIMAX_NETWORK_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWimax:mac-address: + * + * If specified, this connection will only apply to the WiMAX device whose + * MAC address matches. This property does not change the MAC address of the + * device (known as MAC spoofing). + **/ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_WIMAX_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIMAX_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); +} diff --git a/libnm-core/nm-setting-wimax.h b/libnm-core/nm-setting-wimax.h new file mode 100644 index 00000000..0a585046 --- /dev/null +++ b/libnm-core/nm-setting-wimax.h @@ -0,0 +1,64 @@ +/* -*- 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. + * + * Copyright 2009 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIMAX_H__ +#define __NM_SETTING_WIMAX_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIMAX (nm_setting_wimax_get_type ()) +#define NM_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimax)) +#define NM_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) +#define NM_IS_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIMAX)) +#define NM_IS_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_WIMAX)) +#define NM_SETTING_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass)) + +#define NM_SETTING_WIMAX_SETTING_NAME "wimax" + +#define NM_SETTING_WIMAX_NETWORK_NAME "network-name" +#define NM_SETTING_WIMAX_MAC_ADDRESS "mac-address" + +struct _NMSettingWimax { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWimaxClass; + +GType nm_setting_wimax_get_type (void); + +NMSetting *nm_setting_wimax_new (void); +const char *nm_setting_wimax_get_network_name (NMSettingWimax *setting); +const char *nm_setting_wimax_get_mac_address (NMSettingWimax *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIMAX_H__ */ diff --git a/libnm-core/nm-setting-wired.c b/libnm-core/nm-setting-wired.c new file mode 100644 index 00000000..ac143e45 --- /dev/null +++ b/libnm-core/nm-setting-wired.c @@ -0,0 +1,1103 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-wired.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-wired + * @short_description: Describes connection properties for Ethernet-based networks + * + * The #NMSettingWired object is a #NMSetting subclass that describes properties + * necessary for connection to Ethernet networks. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingWired, nm_setting_wired, NM_TYPE_SETTING, + _nm_register_setting (WIRED, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRED) + +#define NM_SETTING_WIRED_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRED, NMSettingWiredPrivate)) + +typedef struct { + char *port; + guint32 speed; + char *duplex; + gboolean auto_negotiate; + char *device_mac_address; + char *cloned_mac_address; + GArray *mac_address_blacklist; + guint32 mtu; + char **s390_subchannels; + char *s390_nettype; + GHashTable *s390_options; +} NMSettingWiredPrivate; + +enum { + PROP_0, + PROP_PORT, + PROP_SPEED, + PROP_DUPLEX, + PROP_AUTO_NEGOTIATE, + PROP_MAC_ADDRESS, + PROP_CLONED_MAC_ADDRESS, + PROP_MAC_ADDRESS_BLACKLIST, + PROP_MTU, + PROP_S390_SUBCHANNELS, + PROP_S390_NETTYPE, + PROP_S390_OPTIONS, + + LAST_PROP +}; + +static const char *valid_s390_opts[] = { + "portno", "layer2", "portname", "protocol", "priority_queueing", + "buffer_count", "isolation", "total", "inter", "inter_jumbo", "route4", + "route6", "fake_broadcast", "broadcast_mode", "canonical_macaddr", + "checksumming", "sniffer", "large_send", "ipato_enable", "ipato_invert4", + "ipato_add4", "ipato_invert6", "ipato_add6", "vipa_add4", "vipa_add6", + "rxip_add4", "rxip_add6", "lancmd_timeout", "ctcprot", + NULL +}; + +/** + * nm_setting_wired_new: + * + * Creates a new #NMSettingWired object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWired object + **/ +NMSetting * +nm_setting_wired_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRED, NULL); +} + +/** + * nm_setting_wired_get_port: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:port property of the setting + **/ +const char * +nm_setting_wired_get_port (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->port; +} + +/** + * nm_setting_wired_get_speed: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:speed property of the setting + **/ +guint32 +nm_setting_wired_get_speed (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->speed; +} + +/** + * nm_setting_wired_get_duplex: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:duplex property of the setting + **/ +const char * +nm_setting_wired_get_duplex (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->duplex; +} + +/** + * nm_setting_wired_get_auto_negotiate: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:auto-negotiate property of the setting + **/ +gboolean +nm_setting_wired_get_auto_negotiate (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->auto_negotiate; +} + +/** + * nm_setting_wired_get_mac_address: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mac-address property of the setting + **/ +const char * +nm_setting_wired_get_mac_address (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->device_mac_address; +} + +/** + * nm_setting_wired_get_cloned_mac_address: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:cloned-mac-address property of the setting + **/ +const char * +nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address; +} + +/** + * nm_setting_wired_get_mac_address_blacklist: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mac-address-blacklist property of the setting + **/ +const char * const * +nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting) +{ + NMSettingWiredPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + return (const char * const *) priv->mac_address_blacklist->data; +} + +/** + * nm_setting_wired_get_num_mac_blacklist_items: + * @setting: the #NMSettingWired + * + * Returns: the number of blacklisted MAC addresses + **/ +guint32 +nm_setting_wired_get_num_mac_blacklist_items (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist->len; +} + +/** + * nm_setting_wired_get_mac_blacklist_item: + * @setting: the #NMSettingWired + * @idx: the zero-based index of the MAC address entry + * + * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) + * at index @idx + **/ +const char * +nm_setting_wired_get_mac_blacklist_item (NMSettingWired *setting, guint32 idx) +{ + NMSettingWiredPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + g_return_val_if_fail (idx <= priv->mac_address_blacklist->len, NULL); + + return g_array_index (priv->mac_address_blacklist, const char *, idx); +} + +/** + * nm_setting_wired_add_mac_blacklist_item: + * @setting: the #NMSettingWired + * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist + * + * Adds a new MAC address to the #NMSettingWired:mac-address-blacklist property. + * + * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address + * is invalid or was already present + **/ +gboolean +nm_setting_wired_add_mac_blacklist_item (NMSettingWired *setting, const char *mac) +{ + NMSettingWiredPrivate *priv; + const char *candidate; + int i; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + if (!nm_utils_hwaddr_valid (mac, ETH_ALEN)) + return FALSE; + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index (priv->mac_address_blacklist, char *, i); + if (nm_utils_hwaddr_matches (mac, -1, candidate, -1)) + return FALSE; + } + + mac = nm_utils_hwaddr_canonical (mac, ETH_ALEN); + g_array_append_val (priv->mac_address_blacklist, mac); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return TRUE; +} + +/** + * nm_setting_wired_remove_mac_blacklist_item: + * @setting: the #NMSettingWired + * @idx: index number of the MAC address + * + * Removes the MAC address at index @idx from the blacklist. + **/ +void +nm_setting_wired_remove_mac_blacklist_item (NMSettingWired *setting, guint32 idx) +{ + NMSettingWiredPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRED (setting)); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + g_return_if_fail (idx < priv->mac_address_blacklist->len); + + g_array_remove_index (priv->mac_address_blacklist, idx); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wired_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWired + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_mac_blacklist_item_by_value (NMSettingWired *setting, const char *mac) +{ + NMSettingWiredPrivate *priv; + const char *candidate; + int i; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index (priv->mac_address_blacklist, char *, i); + if (!nm_utils_hwaddr_matches (mac, -1, candidate, -1)) { + g_array_remove_index (priv->mac_address_blacklist, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wired_clear_mac_blacklist_items: + * @setting: the #NMSettingWired + * + * Removes all blacklisted MAC addresses. + **/ +void +nm_setting_wired_clear_mac_blacklist_items (NMSettingWired *setting) +{ + g_return_if_fail (NM_IS_SETTING_WIRED (setting)); + + g_array_set_size (NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address_blacklist, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wired_get_mtu: + * @setting: the #NMSettingWired + * + * Returns: the #NMSettingWired:mtu property of the setting + **/ +guint32 +nm_setting_wired_get_mtu (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->mtu; +} + +/** + * nm_setting_wired_get_s390_subchannels: + * @setting: the #NMSettingWired + * + * Return the list of s390 subchannels that identify the device that this + * connection is applicable to. The connection should only be used in + * conjunction with that device. + * + * Returns: (transfer none) (element-type utf8): array of strings, each specifying + * one subchannel the s390 device uses to communicate to the host. + **/ +const char * const * +nm_setting_wired_get_s390_subchannels (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return (const char * const *) NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_subchannels; +} + +/** + * nm_setting_wired_get_s390_nettype: + * @setting: the #NMSettingWired + * + * Returns the s390 device type this connection should apply to. Will be one + * of 'qeth', 'lcs', or 'ctc'. + * + * Returns: the s390 device type + **/ +const char * +nm_setting_wired_get_s390_nettype (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + + return NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_nettype; +} + +/** + * nm_setting_wired_get_num_s390_options: + * @setting: the #NMSettingWired + * + * Returns the number of s390-specific options that should be set for this + * device when it is activated. This can be used to retrieve each s390 + * option individually using nm_setting_wired_get_s390_option(). + * + * Returns: the number of s390-specific device options + **/ +guint32 +nm_setting_wired_get_num_s390_options (NMSettingWired *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), 0); + + return g_hash_table_size (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options); +} + +/** + * nm_setting_wired_get_s390_option: + * @setting: the #NMSettingWired + * @idx: index of the desired option, from 0 to + * nm_setting_wired_get_num_s390_options() - 1 + * @out_key: (out) (transfer none): on return, the key name of the s390 specific + * option; this value is owned by the setting and should not be modified + * @out_value: (out) (transfer none): on return, the value of the key of the + * s390 specific option; this value is owned by the setting and should not be + * modified + * + * Given an index, return the value of the s390 option at that index. indexes + * are *not* guaranteed to be static across modifications to options done by + * nm_setting_wired_add_s390_option() and nm_setting_wired_remove_s390_option(), + * and should not be used to refer to options except for short periods of time + * such as during option iteration. + * + * Returns: %TRUE on success if the index was valid and an option was found, + * %FALSE if the index was invalid (ie, greater than the number of options + * currently held by the setting) + **/ +gboolean +nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value) +{ + NMSettingWiredPrivate *priv; + guint32 num_keys; + GList *keys; + const char *_key = NULL, *_value = NULL; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + + priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + + num_keys = nm_setting_wired_get_num_s390_options (setting); + g_return_val_if_fail (idx < num_keys, FALSE); + + keys = g_hash_table_get_keys (priv->s390_options); + _key = g_list_nth_data (keys, idx); + _value = g_hash_table_lookup (priv->s390_options, _key); + + if (out_key) + *out_key = _key; + if (out_value) + *out_value = _value; + return TRUE; +} + +/** + * nm_setting_wired_get_s390_option_by_key: + * @setting: the #NMSettingWired + * @key: the key for which to retrieve the value + * + * Returns the value associated with the s390-specific option specified by + * @key, if it exists. + * + * Returns: the value, or %NULL if the key/value pair was never added to the + * setting; the value is owned by the setting and must not be modified + **/ +const char * +nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL); + g_return_val_if_fail (key != NULL, NULL); + g_return_val_if_fail (strlen (key), NULL); + + return g_hash_table_lookup (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); +} + +/** + * nm_setting_wired_add_s390_option: + * @setting: the #NMSettingWired + * @key: key name for the option + * @value: value for the option + * + * Add an option to the table. The option is compared to an internal list + * of allowed options. Key names may contain only alphanumeric characters + * (ie [a-zA-Z0-9]). Adding a new key replaces any existing key/value pair that + * may already exist. + * + * Returns: %TRUE if the option was valid and was added to the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *value) +{ + size_t value_len; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + g_return_val_if_fail (_nm_utils_string_in_list (key, valid_s390_opts), FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + value_len = strlen (value); + g_return_val_if_fail (value_len > 0 && value_len < 200, FALSE); + + g_hash_table_insert (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, + g_strdup (key), + g_strdup (value)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_S390_OPTIONS); + return TRUE; +} + +/** + * nm_setting_wired_remove_s390_option: + * @setting: the #NMSettingWired + * @key: key name for the option to remove + * + * Remove the s390-specific option referenced by @key from the internal option + * list. + * + * Returns: %TRUE if the option was found and removed from the internal option + * list, %FALSE if it was not. + **/ +gboolean +nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key) +{ + gboolean found; + + g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (strlen (key), FALSE); + + found = g_hash_table_remove (NM_SETTING_WIRED_GET_PRIVATE (setting)->s390_options, key); + if (found) + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRED_S390_OPTIONS); + return found; +} + +/** + * nm_setting_wired_get_valid_s390_options: + * @setting: the #NMSettingWired + * + * Returns a list of valid s390 options. + * + * Returns: (transfer none): a %NULL-terminated array of strings of valid s390 options. + **/ +const char ** +nm_setting_wired_get_valid_s390_options (NMSettingWired *setting) +{ + return valid_s390_opts; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + const char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; + const char *valid_duplex[] = { "half", "full", NULL }; + const char *valid_nettype[] = { "qeth", "lcs", "ctc", NULL }; + GHashTableIter iter; + const char *key, *value; + int i; + + if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid Ethernet port value"), + priv->port); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_PORT); + return FALSE; + } + + if (priv->duplex && !_nm_utils_string_in_list (priv->duplex, valid_duplex)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid duplex value"), + priv->duplex); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_DUPLEX); + return FALSE; + } + + if (priv->device_mac_address && !nm_utils_hwaddr_valid (priv->device_mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid MAC address")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); + return FALSE; + } + + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + const char *mac = g_array_index (priv->mac_address_blacklist, const char *, i); + + if (!nm_utils_hwaddr_valid (mac, ETH_ALEN)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + mac); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + + if (priv->s390_subchannels) { + int len = g_strv_length (priv->s390_subchannels); + + if (len != 2 && len != 3) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_SUBCHANNELS); + return FALSE; + } + } + + if (priv->s390_nettype && !_nm_utils_string_in_list (priv->s390_nettype, valid_nettype)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_NETTYPE); + return FALSE; + } + + g_hash_table_iter_init (&iter, priv->s390_options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { + if ( !_nm_utils_string_in_list (key, valid_s390_opts) + || !strlen (value) + || (strlen (value) > 200)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid '%s' or its value '%s'"), + key, value); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_OPTIONS); + return FALSE; + } + } + + if (priv->cloned_mac_address && !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a valid MAC address")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS); + return FALSE; + } + + return TRUE; +} + +static void +clear_blacklist_item (char **item_p) +{ + g_free (*item_p); +} + +static void +nm_setting_wired_init (NMSettingWired *setting) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + + priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */ + priv->mac_address_blacklist = g_array_new (TRUE, FALSE, sizeof (char *)); + g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); +} + +static void +finalize (GObject *object) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (object); + + g_free (priv->port); + g_free (priv->duplex); + g_free (priv->s390_nettype); + + g_hash_table_destroy (priv->s390_options); + + g_free (priv->device_mac_address); + g_free (priv->cloned_mac_address); + g_array_unref (priv->mac_address_blacklist); + + if (priv->s390_subchannels) + g_strfreev (priv->s390_subchannels); + + G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (object); + const char * const *blacklist; + const char *mac; + int i; + + switch (prop_id) { + case PROP_PORT: + g_free (priv->port); + priv->port = g_value_dup_string (value); + break; + case PROP_SPEED: + priv->speed = g_value_get_uint (value); + break; + case PROP_DUPLEX: + g_free (priv->duplex); + priv->duplex = g_value_dup_string (value); + break; + case PROP_AUTO_NEGOTIATE: + priv->auto_negotiate = g_value_get_boolean (value); + break; + case PROP_MAC_ADDRESS: + g_free (priv->device_mac_address); + priv->device_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + break; + case PROP_CLONED_MAC_ADDRESS: + g_free (priv->cloned_mac_address); + priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + blacklist = g_value_get_boxed (value); + g_array_set_size (priv->mac_address_blacklist, 0); + if (blacklist && *blacklist) { + for (i = 0; blacklist[i]; i++) { + mac = _nm_utils_hwaddr_canonical_or_invalid (blacklist[i], ETH_ALEN); + g_array_append_val (priv->mac_address_blacklist, mac); + } + } + break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; + case PROP_S390_SUBCHANNELS: + if (priv->s390_subchannels) + g_strfreev (priv->s390_subchannels); + priv->s390_subchannels = g_value_dup_boxed (value); + break; + case PROP_S390_NETTYPE: + g_free (priv->s390_nettype); + priv->s390_nettype = g_value_dup_string (value); + break; + case PROP_S390_OPTIONS: + g_hash_table_unref (priv->s390_options); + priv->s390_options = _nm_utils_copy_strdict (g_value_get_boxed (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) +{ + NMSettingWired *setting = NM_SETTING_WIRED (object); + NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_PORT: + g_value_set_string (value, nm_setting_wired_get_port (setting)); + break; + case PROP_SPEED: + g_value_set_uint (value, nm_setting_wired_get_speed (setting)); + break; + case PROP_DUPLEX: + g_value_set_string (value, nm_setting_wired_get_duplex (setting)); + break; + case PROP_AUTO_NEGOTIATE: + g_value_set_boolean (value, nm_setting_wired_get_auto_negotiate (setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string (value, nm_setting_wired_get_mac_address (setting)); + break; + case PROP_CLONED_MAC_ADDRESS: + g_value_set_string (value, nm_setting_wired_get_cloned_mac_address (setting)); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data); + break; + case PROP_MTU: + g_value_set_uint (value, nm_setting_wired_get_mtu (setting)); + break; + case PROP_S390_SUBCHANNELS: + g_value_set_boxed (value, priv->s390_subchannels); + break; + case PROP_S390_NETTYPE: + g_value_set_string (value, nm_setting_wired_get_s390_nettype (setting)); + break; + case PROP_S390_OPTIONS: + g_value_take_boxed (value, _nm_utils_copy_strdict (priv->s390_options)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wired_class_init (NMSettingWiredClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingWiredPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingWired:port: + * + * Specific port type to use if multiple the device supports multiple + * attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit + * Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface. + * If the device supports only one port type, this setting is ignored. + **/ + /* ---ifcfg-rh--- + * property: port + * variable: (none) + * description: The property is not saved by the plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PORT, + g_param_spec_string (NM_SETTING_WIRED_PORT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:speed: + * + * If non-zero, request that the device use only the specified speed. In + * Mbit/s, ie 100 == 100Mbit/s. + **/ + /* ---ifcfg-rh--- + * property: speed + * variable: (none) + * description: The property is not saved by the plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SPEED, + g_param_spec_uint (NM_SETTING_WIRED_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:duplex: + * + * If specified, request that the device only use the specified duplex mode. + * Either "half" or "full". + **/ + /* ---ifcfg-rh--- + * property: duplex + * variable: (none) + * description: The property is not saved by the plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_DUPLEX, + g_param_spec_string (NM_SETTING_WIRED_DUPLEX, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:auto-negotiate: + * + * If %TRUE, allow auto-negotiation of port speed and duplex mode. If + * %FALSE, do not allow auto-negotiation, in which case the "speed" and + * "duplex" properties should be set. + **/ + /* ---ifcfg-rh--- + * property: auto-negotiate + * variable: (none) + * description: The property is not saved by the plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_AUTO_NEGOTIATE, + g_param_spec_boolean (NM_SETTING_WIRED_AUTO_NEGOTIATE, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:mac-address: + * + * If specified, this connection will only apply to the Ethernet device + * whose permanent MAC address matches. This property does not change the + * MAC address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: ususal hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;162) + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: Hardware address of the device in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:05). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_WIRED_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingWired:cloned-mac-address: + * + * If specified, request that the device use this MAC address instead of its + * permanent MAC address. This is known as MAC cloning or spoofing. + **/ + /* ---keyfile--- + * property: cloned-mac-address + * format: ususal hex-digits-and-colons notation + * description: Cloned MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;178). + * ---end--- + * ---ifcfg-rh--- + * property: cloned-mac-address + * variable: MACADDR + * description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:99). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CLONED_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingWired:mac-address-blacklist: + * + * If specified, this connection will never apply to the Ethernet device + * whose permanent MAC address matches an address in the list. Each MAC + * address is in the standard hex-digits-and-colons notation + * (00:11:22:33:44:55). + **/ + /* ---keyfile--- + * property: mac-address-blacklist + * format: list of MACs (separated with semicolons) + * description: MAC address blacklist. + * example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address-blacklist + * variable: HWADDR_BLACKLIST(+) + * description: It denies usage of the connection for any device whose address + * is listed. + * example: HWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS_BLACKLIST, + g_param_spec_boxed (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple Ethernet frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the interface. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_WIRED_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:s390-subchannels: + * + * Identifies specific subchannels that this network device uses for + * communication with z/VM or s390 host. Like the + * #NMSettingWired:mac-address property for non-z/VM devices, this property + * can be used to ensure this connection only applies to the network device + * that uses these subchannels. The list should contain exactly 3 strings, + * and each string may only be composed of hexadecimal characters and the + * period (.) character. + **/ + /* ---ifcfg-rh--- + * property: s390-subchannels + * variable: SUBCHANNELS + * description: Subchannels for IBM S390 hosts. + * example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00c + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_S390_SUBCHANNELS, + g_param_spec_boxed (NM_SETTING_WIRED_S390_SUBCHANNELS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:s390-nettype: + * + * s390 network device type; one of "qeth", "lcs", or "ctc", representing + * the different types of virtual network devices available on s390 systems. + **/ + /* ---ifcfg-rh--- + * property: s390-nettype + * variable: NETTYPE + * values: "qeth", "lcs" or "ctc" + * description: Network type of the S390 host. + * example: NETTYPE=qeth + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_S390_NETTYPE, + g_param_spec_string (NM_SETTING_WIRED_S390_NETTYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWired:s390-options: + * + * Dictionary of key/value pairs of s390-specific device options. Both keys + * and values must be strings. Allowed keys include "portno", "layer2", + * "portname", "protocol", among others. Key names must contain only + * alphanumeric characters (ie, [a-zA-Z0-9]). + * + * Type: GHashTable(utf8,utf8) + **/ + /* ---ifcfg-rh--- + * property: s390-options + * variable: OPTIONS and PORTNAME, CTCPROTO, + * description: S390 device options. All options go to OPTIONS, except for + * "portname" and "ctcprot" that have their own variables. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_S390_OPTIONS, + g_param_spec_boxed (NM_SETTING_WIRED_S390_OPTIONS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRED_S390_OPTIONS, + G_VARIANT_TYPE ("a{ss}"), + _nm_utils_strdict_to_dbus, + _nm_utils_strdict_from_dbus); +} diff --git a/libnm-core/nm-setting-wired.h b/libnm-core/nm-setting-wired.h new file mode 100644 index 00000000..4189b689 --- /dev/null +++ b/libnm-core/nm-setting-wired.h @@ -0,0 +1,109 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRED_H__ +#define __NM_SETTING_WIRED_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRED (nm_setting_wired_get_type ()) +#define NM_SETTING_WIRED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRED, NMSettingWired)) +#define NM_SETTING_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) +#define NM_IS_SETTING_WIRED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRED)) +#define NM_IS_SETTING_WIRED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_WIRED)) +#define NM_SETTING_WIRED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRED, NMSettingWiredClass)) + +#define NM_SETTING_WIRED_SETTING_NAME "802-3-ethernet" + +#define NM_SETTING_WIRED_PORT "port" +#define NM_SETTING_WIRED_SPEED "speed" +#define NM_SETTING_WIRED_DUPLEX "duplex" +#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate" +#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address" +#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist" +#define NM_SETTING_WIRED_MTU "mtu" +#define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels" +#define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype" +#define NM_SETTING_WIRED_S390_OPTIONS "s390-options" + +struct _NMSettingWired { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWiredClass; + +GType nm_setting_wired_get_type (void); + +NMSetting * nm_setting_wired_new (void); +const char * nm_setting_wired_get_port (NMSettingWired *setting); +guint32 nm_setting_wired_get_speed (NMSettingWired *setting); +const char * nm_setting_wired_get_duplex (NMSettingWired *setting); +gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting); +const char * nm_setting_wired_get_mac_address (NMSettingWired *setting); +const char * nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting); + +const char * const *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting); +guint32 nm_setting_wired_get_num_mac_blacklist_items (NMSettingWired *setting); +const char * nm_setting_wired_get_mac_blacklist_item (NMSettingWired *setting, + guint32 idx); +gboolean nm_setting_wired_add_mac_blacklist_item (NMSettingWired *setting, + const char *mac); +void nm_setting_wired_remove_mac_blacklist_item (NMSettingWired *setting, + guint32 idx); +gboolean nm_setting_wired_remove_mac_blacklist_item_by_value (NMSettingWired *setting, + const char *mac); +void nm_setting_wired_clear_mac_blacklist_items (NMSettingWired *setting); + +guint32 nm_setting_wired_get_mtu (NMSettingWired *setting); + +const char * const *nm_setting_wired_get_s390_subchannels (NMSettingWired *setting); +const char * nm_setting_wired_get_s390_nettype (NMSettingWired *setting); + +guint32 nm_setting_wired_get_num_s390_options (NMSettingWired *setting); +gboolean nm_setting_wired_get_s390_option (NMSettingWired *setting, + guint32 idx, + const char **out_key, + const char **out_value); +const char * nm_setting_wired_get_s390_option_by_key (NMSettingWired *setting, + const char *key); +gboolean nm_setting_wired_add_s390_option (NMSettingWired *setting, + const char *key, + const char *value); +gboolean nm_setting_wired_remove_s390_option (NMSettingWired *setting, + const char *key); +const char ** nm_setting_wired_get_valid_s390_options (NMSettingWired *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRED_H__ */ diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c new file mode 100644 index 00000000..c95f9243 --- /dev/null +++ b/libnm-core/nm-setting-wireless-security.c @@ -0,0 +1,1704 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-wireless-security.h" +#include "nm-setting-8021x.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" +#include "nm-setting-wireless.h" + +/** + * SECTION:nm-setting-wireless-security + * @short_description: Describes connection properties for Wi-Fi networks that + * use WEP, LEAP, WPA or WPA2/RSN security + * + * The #NMSettingWirelessSecurity object is a #NMSetting subclass that describes + * properties necessary for connection to encrypted Wi-Fi networks. + * + * It's a good idea to read up on wpa_supplicant configuration before using this + * setting extensively, since most of the options here correspond closely with + * the relevant wpa_supplicant configuration options. To get a better overview + * of how Wi-Fi security works, you may want to get copies of the following books. + * + * 802.11 Wireless Networks: The Definitive Guide, Second Edition + * Author: Matthew Gast + * ISBN: 978-0596100520 + * + * Cisco Wireless LAN Security + * Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky + * ISBN: 978-1587051548 + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING, + _nm_register_setting (WIRELESS_SECURITY, 2)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRELESS_SECURITY) + +#define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate)) + +typedef struct { + char *key_mgmt; + char *auth_alg; + GSList *proto; /* GSList of strings */ + GSList *pairwise; /* GSList of strings */ + GSList *group; /* GSList of strings */ + + /* LEAP */ + char *leap_username; + char *leap_password; + NMSettingSecretFlags leap_password_flags; + + /* WEP */ + char *wep_key0; + char *wep_key1; + char *wep_key2; + char *wep_key3; + NMSettingSecretFlags wep_key_flags; + NMWepKeyType wep_key_type; + guint32 wep_tx_keyidx; + + /* WPA-PSK */ + char *psk; + NMSettingSecretFlags psk_flags; +} NMSettingWirelessSecurityPrivate; + +enum { + PROP_0, + PROP_KEY_MGMT, + PROP_WEP_TX_KEYIDX, + PROP_AUTH_ALG, + PROP_PROTO, + PROP_PAIRWISE, + PROP_GROUP, + PROP_LEAP_USERNAME, + PROP_WEP_KEY0, + PROP_WEP_KEY1, + PROP_WEP_KEY2, + PROP_WEP_KEY3, + PROP_WEP_KEY_FLAGS, + PROP_WEP_KEY_TYPE, + PROP_PSK, + PROP_PSK_FLAGS, + PROP_LEAP_PASSWORD, + PROP_LEAP_PASSWORD_FLAGS, + + LAST_PROP +}; + +/** + * nm_setting_wireless_security_new: + * + * Creates a new #NMSettingWirelessSecurity object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object + **/ +NMSetting * +nm_setting_wireless_security_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL); +} + +/** + * nm_setting_wireless_security_get_key_mgmt: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:key-mgmt property of the setting + **/ +const char * +nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->key_mgmt; +} + +/** + * nm_setting_wireless_security_get_num_protos: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of security protocols this connection allows when + * connecting to secure Wi-Fi networks + **/ +guint32 +nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->proto); +} + +/** + * nm_setting_wireless_security_get_proto: + * @setting: the #NMSettingWirelessSecurity + * @i: an index into the protocol list + * + * Returns: the protocol at index @i + **/ +const char * +nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->proto), NULL); + + return (const char *) g_slist_nth_data (priv->proto, i); +} + +/** + * nm_setting_wireless_security_add_proto: + * @setting: the #NMSettingWirelessSecurity + * @proto: the protocol to add, one of "wpa" or "rsn" + * + * Adds a Wi-Fi security protocol (one of "wpa" or "rsn") to the allowed list; + * only protocols in this list will be used when finding and connecting to + * the Wi-Fi network specified by this connection. For example, if the + * protocol list contains only "wpa" but the access point for the SSID specified + * by this connection only supports WPA2/RSN, the connection cannot be used + * with the access point. + * + * Returns: %TRUE if the protocol was new and and was added to the allowed + * protocol list, or %FALSE if it was already in the list + **/ +gboolean +nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (proto != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->proto; iter; iter = g_slist_next (iter)) { + if (strcasecmp (proto, (char *) iter->data) == 0) + return FALSE; + } + + priv->proto = g_slist_append (priv->proto, g_ascii_strdown (proto, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_proto: + * @setting: the #NMSettingWirelessSecurity + * @i: index of the protocol to remove + * + * Removes a protocol from the allowed protocol list. + **/ +void +nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + elt = g_slist_nth (priv->proto, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->proto = g_slist_delete_link (priv->proto, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); +} + +/** + * nm_setting_wireless_security_remove_proto_by_value: + * @setting: the #NMSettingWirelessSecurity + * @proto: the protocol to remove, one of "wpa" or "rsn" + * + * Removes a protocol from the allowed protocol list. + * + * Returns: %TRUE if the protocol was found and removed; %FALSE it it was not. + **/ +gboolean +nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *setting, + const char *proto) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (proto != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->proto; iter; iter = g_slist_next (iter)) { + if (strcasecmp (proto, (char *) iter->data) == 0) { + priv->proto = g_slist_delete_link (priv->proto, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_protos: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all protocols from the allowed list. If there are no protocols + * specified then all protocols are allowed. + **/ +void +nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_slist_free_full (priv->proto, g_free); + priv->proto = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO); +} + +/** + * nm_setting_wireless_security_get_num_pairwise: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of pairwise encryption algorithms in the allowed list + **/ +guint32 +nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->pairwise); +} + +/** + * nm_setting_wireless_security_get_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @i: index of an item in the allowed pairwise encryption algorithm list + * + * Returns the allowed pairwise encryption algorithm from allowed algorithm + * list. + * + * Returns: the pairwise encryption algorithm at index @i + **/ +const char * +nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->pairwise), NULL); + + return (const char *) g_slist_nth_data (priv->pairwise, i); +} + +/** + * nm_setting_wireless_security_add_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @pairwise: the encryption algorithm to add, one of "tkip" or "ccmp" + * + * Adds an encryption algorithm to the list of allowed pairwise encryption + * algorithms. If the list is not empty, then only access points that support + * one or more of the encryption algorithms in the list will be considered + * compatible with this connection. + * + * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was + * already in the list + **/ +gboolean +nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (pairwise != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) { + if (strcasecmp (pairwise, (char *) iter->data) == 0) + return FALSE; + } + + priv->pairwise = g_slist_append (priv->pairwise, g_ascii_strdown (pairwise, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_pairwise: + * @setting: the #NMSettingWirelessSecurity + * @i: the index of an item in the allowed pairwise encryption algorithm list + * + * Removes an encryption algorithm from the allowed pairwise encryption + * algorithm list. + **/ +void +nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + elt = g_slist_nth (priv->pairwise, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->pairwise = g_slist_delete_link (priv->pairwise, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); +} + +/** + * nm_setting_wireless_security_remove_pairwise_by_value: + * @setting: the #NMSettingWirelessSecurity + * @pairwise: the encryption algorithm to remove, one of "tkip" or "ccmp" + * + * Removes an encryption algorithm from the allowed pairwise encryption + * algorithm list. + * + * Returns: %TRUE if the encryption algorith was found and removed; %FALSE it it was not. + **/ +gboolean +nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting, + const char *pairwise) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (pairwise != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) { + if (strcasecmp (pairwise, (char *) iter->data) == 0) { + priv->pairwise = g_slist_delete_link (priv->pairwise, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_pairwise: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all algorithms from the allowed list. If there are no algorithms + * specified then all pairwise encryption algorithms are allowed. + **/ +void +nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_slist_free_full (priv->pairwise, g_free); + priv->pairwise = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE); +} + +/** + * nm_setting_wireless_security_get_num_groups: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the number of groupwise encryption algorithms in the allowed list + **/ +guint32 +nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->group); +} + +/** + * nm_setting_wireless_security_get_group: + * @setting: the #NMSettingWirelessSecurity + * @i: index of an item in the allowed groupwise encryption algorithm list + * + * Returns the allowed groupwise encryption algorithm from allowed algorithm + * list. + * + * Returns: the groupwise encryption algorithm at index @i + **/ +const char * +nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_return_val_if_fail (i <= g_slist_length (priv->group), NULL); + + return (const char *) g_slist_nth_data (priv->group, i); +} + +/** + * nm_setting_wireless_security_add_group: + * @setting: the #NMSettingWirelessSecurity + * @group: the encryption algorithm to add, one of "wep40", "wep104", + * "tkip", or "ccmp" + * + * Adds an encryption algorithm to the list of allowed groupwise encryption + * algorithms. If the list is not empty, then only access points that support + * one or more of the encryption algorithms in the list will be considered + * compatible with this connection. + * + * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was + * already in the list + **/ +gboolean +nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (group != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->group; iter; iter = g_slist_next (iter)) { + if (strcasecmp (group, (char *) iter->data) == 0) + return FALSE; + } + + priv->group = g_slist_append (priv->group, g_ascii_strdown (group, -1)); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); + return TRUE; +} + +/** + * nm_setting_wireless_security_remove_group: + * @setting: the #NMSettingWirelessSecurity + * @i: the index of an item in the allowed groupwise encryption algorithm list + * + * Removes an encryption algorithm from the allowed groupwise encryption + * algorithm list. + **/ +void +nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *elt; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + elt = g_slist_nth (priv->group, i); + g_return_if_fail (elt != NULL); + + g_free (elt->data); + priv->group = g_slist_delete_link (priv->group, elt); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); +} + +/** + * nm_setting_wireless_security_remove_group_by_value: + * @setting: the #NMSettingWirelessSecurity + * @group: the encryption algorithm to remove, one of "wep40", "wep104", + * "tkip", or "ccmp" + * + * Removes an encryption algorithm from the allowed groupwise encryption + * algorithm list. + * + * Returns: %TRUE if the algorithm was found and removed; %FALSE it it was not. + **/ +gboolean +nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting, + const char *group) +{ + NMSettingWirelessSecurityPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE); + g_return_val_if_fail (group != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + for (iter = priv->group; iter; iter = g_slist_next (iter)) { + if (strcasecmp (group, (char *) iter->data) == 0) { + priv->group = g_slist_delete_link (priv->group, iter); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_security_clear_groups: + * @setting: the #NMSettingWirelessSecurity + * + * Removes all algorithms from the allowed list. If there are no algorithms + * specified then all groupwise encryption algorithms are allowed. + **/ +void +nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + g_slist_free_full (priv->group, g_free); + priv->group = NULL; + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP); +} + +/** + * nm_setting_wireless_security_get_psk: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:psk property of the setting + **/ +const char * +nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk; +} + +/** + * nm_setting_wireless_security_get_psk_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:psk + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags; +} + +/** + * nm_setting_wireless_security_get_leap_username: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:leap-username property of the setting + **/ +const char * +nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_username; +} + +/** + * nm_setting_wireless_security_get_leap_password: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:leap-password property of the setting + **/ +const char * +nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password; +} + +/** + * nm_setting_wireless_security_get_leap_password_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:leap-password + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags; +} + +/** + * nm_setting_wireless_security_get_wep_key: + * @setting: the #NMSettingWirelessSecurity + * @idx: the WEP key index (0..3 inclusive) + * + * Returns: the WEP key at the given index + **/ +const char * +nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + g_return_val_if_fail (idx < 4, NULL); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + if (idx == 0) + return priv->wep_key0; + else if (idx == 1) + return priv->wep_key1; + else if (idx == 2) + return priv->wep_key2; + else if (idx == 3) + return priv->wep_key3; + + g_assert_not_reached (); + return NULL; +} + +/** + * nm_setting_wireless_security_set_wep_key: + * @setting: the #NMSettingWirelessSecurity + * @idx: the index of the key (0..3 inclusive) + * @key: the WEP key as a string, in either hexadecimal, ASCII, or passphrase + * form as determiend by the value of the #NMSettingWirelessSecurity:wep-key-type + * property. + * + * Sets a WEP key in the given index. + **/ +void +nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key) +{ + NMSettingWirelessSecurityPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting)); + g_return_if_fail (idx < 4); + + priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + switch (idx) { + case 0: + g_free (priv->wep_key0); + priv->wep_key0 = g_strdup (key); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + break; + case 1: + g_free (priv->wep_key1); + priv->wep_key1 = g_strdup (key); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + break; + case 2: + g_free (priv->wep_key2); + priv->wep_key2 = g_strdup (key); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + break; + case 3: + g_free (priv->wep_key3); + priv->wep_key3 = g_strdup (key); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + break; + default: + g_assert_not_reached (); + } +} + +/** + * nm_setting_wireless_security_get_wep_tx_keyidx: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:wep-tx-keyidx property of the setting + **/ +guint32 +nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_tx_keyidx; +} + +/** + * nm_setting_wireless_security_get_auth_alg: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:auth-alg property of the setting + **/ +const char * +nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->auth_alg; +} + +/** + * nm_setting_wireless_security_get_wep_key_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the all WEP keys + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags; +} + +/** + * nm_setting_wireless_security_get_wep_key_type: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingWirelessSecurity:wep-key-type property of the setting + **/ +NMWepKeyType +nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_type; +} + +static GPtrArray * +need_secrets (NMSetting *setting) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self); + GPtrArray *secrets; + + secrets = g_ptr_array_sized_new (4); + + g_assert (priv->key_mgmt); + + /* Static WEP */ + if (strcmp (priv->key_mgmt, "none") == 0) { + if ((priv->wep_tx_keyidx == 0) && !nm_utils_wep_key_valid (priv->wep_key0, priv->wep_key_type)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + return secrets; + } + if ((priv->wep_tx_keyidx == 1) && !nm_utils_wep_key_valid (priv->wep_key1, priv->wep_key_type)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + return secrets; + } + if ((priv->wep_tx_keyidx == 2) && !nm_utils_wep_key_valid (priv->wep_key2, priv->wep_key_type)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + return secrets; + } + if ((priv->wep_tx_keyidx == 3) && !nm_utils_wep_key_valid (priv->wep_key3, priv->wep_key_type)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + return secrets; + } + goto no_secrets; + } + + /* WPA-PSK infrastructure and adhoc */ + if ( (strcmp (priv->key_mgmt, "wpa-none") == 0) + || (strcmp (priv->key_mgmt, "wpa-psk") == 0)) { + if (!nm_utils_wpa_psk_valid (priv->psk)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PSK); + return secrets; + } + goto no_secrets; + } + + /* LEAP */ + if ( priv->auth_alg + && !strcmp (priv->auth_alg, "leap") + && !strcmp (priv->key_mgmt, "ieee8021x")) { + if (!priv->leap_password || !strlen (priv->leap_password)) { + g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + return secrets; + } + goto no_secrets; + } + + if ( (strcmp (priv->key_mgmt, "ieee8021x") == 0) + || (strcmp (priv->key_mgmt, "wpa-eap") == 0)) { + /* Let caller check the 802.1x setting for secrets */ + goto no_secrets; + } + + g_assert_not_reached (); + return secrets; + +no_secrets: + if (secrets) + g_ptr_array_free (secrets, TRUE); + return NULL; +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self); + const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL }; + const char *valid_auth_algs[] = { "open", "shared", "leap", NULL }; + const char *valid_protos[] = { "wpa", "rsn", NULL }; + const char *valid_pairwise[] = { "tkip", "ccmp", NULL }; + const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL }; + + if (!priv->key_mgmt) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (!_nm_utils_string_in_list (priv->key_mgmt, valid_key_mgmt)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid value for the property"), + priv->key_mgmt); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + return FALSE; + } + + if (priv->auth_alg && !strcmp (priv->auth_alg, "leap")) { + /* LEAP must use ieee8021x key management */ + if (strcmp (priv->key_mgmt, "ieee8021x")) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' security requires '%s=%s'"), + "leap", NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + if (!priv->leap_username) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + if (priv->leap_password && !strlen (priv->leap_password)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD); + return FALSE; + } + } else { + if ( (strcmp (priv->key_mgmt, "ieee8021x") == 0) + || (strcmp (priv->key_mgmt, "wpa-eap") == 0)) { + /* Need an 802.1x setting too */ + if (connection && !nm_connection_get_setting_802_1x (connection)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("'%s' security requires '%s' setting presence"), + priv->key_mgmt, NM_SETTING_802_1X_SETTING_NAME); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); + return FALSE; + } + } + } + + if (priv->leap_username && !strlen (priv->leap_username)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is empty")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + return FALSE; + } + + if (priv->wep_tx_keyidx > 3) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' value is out of range <0-3>"), + priv->wep_tx_keyidx); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + return FALSE; + } + + if (priv->wep_key_type > NM_WEP_KEY_TYPE_LAST) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE); + return FALSE; + } + + if (priv->wep_key0 && !nm_utils_wep_key_valid (priv->wep_key0, priv->wep_key_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + return FALSE; + } + if (priv->wep_key1 && !nm_utils_wep_key_valid (priv->wep_key1, priv->wep_key_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1); + return FALSE; + } + if (priv->wep_key2 && !nm_utils_wep_key_valid (priv->wep_key2, priv->wep_key_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2); + return FALSE; + } + if (priv->wep_key3 && !nm_utils_wep_key_valid (priv->wep_key3, priv->wep_key_type)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3); + return FALSE; + } + + if (priv->auth_alg && !_nm_utils_string_in_list (priv->auth_alg, valid_auth_algs)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + + if (priv->psk && !nm_utils_wpa_psk_valid (priv->psk)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PSK); + return FALSE; + } + + if (priv->proto && !_nm_utils_string_slist_validate (priv->proto, valid_protos)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PROTO); + return FALSE; + } + + if (priv->pairwise) { + const char *wpa_none[] = { "wpa-none", NULL }; + + /* For ad-hoc connections, pairwise must be "none" */ + if (_nm_utils_string_in_list (priv->key_mgmt, wpa_none)) { + GSList *iter; + gboolean found = FALSE; + + for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) { + if (!strcmp ((char *) iter->data, "none")) { + found = TRUE; + break; + } + } + + /* pairwise cipher list didn't contain "none", which is invalid + * for WPA adhoc connections. + */ + if (!found) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' connections require '%s' in this property"), + NM_SETTING_WIRELESS_MODE_ADHOC, "none"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + } else if (!_nm_utils_string_slist_validate (priv->pairwise, valid_pairwise)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PAIRWISE); + return FALSE; + } + } + + if (priv->group && !_nm_utils_string_slist_validate (priv->group, valid_groups)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_GROUP); + return FALSE; + } + + /* Shared Key auth can only be used with WEP */ + if (priv->auth_alg && !strcmp (priv->auth_alg, "shared")) { + if (priv->key_mgmt && strcmp (priv->key_mgmt, "none")) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' can only be used with '%s=%s' (WEP)"), + "shared", NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->get_secret_flags (setting, secret_name, verify_override, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->set_secret_flags (setting, secret_name, verify_override, flags, error); +} + +static void +nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting) +{ +} + +static void +finalize (GObject *object) +{ + NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self); + + /* Strings first. g_free() already checks for NULLs so we don't have to */ + + g_free (priv->key_mgmt); + g_free (priv->auth_alg); + g_free (priv->leap_username); + g_free (priv->wep_key0); + g_free (priv->wep_key1); + g_free (priv->wep_key2); + g_free (priv->wep_key3); + g_free (priv->psk); + g_free (priv->leap_password); + + g_slist_free_full (priv->proto, g_free); + g_slist_free_full (priv->pairwise, g_free); + g_slist_free_full (priv->group, g_free); + + G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object); +} + +/* NMSettingWirelessSecurity:wep-key-type is an enum, but needs to be marshalled + * as 'u', not 'i', for backward-compatibility. + */ +static GVariant * +wep_key_type_to_dbus (const GValue *from) +{ + return g_variant_new_uint32 (g_value_get_enum (from)); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + const char *str; + + switch (prop_id) { + case PROP_KEY_MGMT: + g_free (priv->key_mgmt); + str = g_value_get_string (value); + priv->key_mgmt = str ? g_ascii_strdown (str, -1) : NULL; + break; + case PROP_WEP_TX_KEYIDX: + priv->wep_tx_keyidx = g_value_get_uint (value); + break; + case PROP_AUTH_ALG: + g_free (priv->auth_alg); + str = g_value_get_string (value); + priv->auth_alg = str ? g_ascii_strdown (str, -1) : NULL; + break; + case PROP_PROTO: + g_slist_free_full (priv->proto, g_free); + priv->proto = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_PAIRWISE: + g_slist_free_full (priv->pairwise, g_free); + priv->pairwise = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_GROUP: + g_slist_free_full (priv->group, g_free); + priv->group = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_LEAP_USERNAME: + g_free (priv->leap_username); + priv->leap_username = g_value_dup_string (value); + break; + case PROP_WEP_KEY0: + g_free (priv->wep_key0); + priv->wep_key0 = g_value_dup_string (value); + break; + case PROP_WEP_KEY1: + g_free (priv->wep_key1); + priv->wep_key1 = g_value_dup_string (value); + break; + case PROP_WEP_KEY2: + g_free (priv->wep_key2); + priv->wep_key2 = g_value_dup_string (value); + break; + case PROP_WEP_KEY3: + g_free (priv->wep_key3); + priv->wep_key3 = g_value_dup_string (value); + break; + case PROP_WEP_KEY_FLAGS: + priv->wep_key_flags = g_value_get_flags (value); + break; + case PROP_PSK: + g_free (priv->psk); + priv->psk = g_value_dup_string (value); + break; + case PROP_PSK_FLAGS: + priv->psk_flags = g_value_get_flags (value); + break; + case PROP_LEAP_PASSWORD: + g_free (priv->leap_password); + priv->leap_password = g_value_dup_string (value); + break; + case PROP_LEAP_PASSWORD_FLAGS: + priv->leap_password_flags = g_value_get_flags (value); + break; + case PROP_WEP_KEY_TYPE: + priv->wep_key_type = g_value_get_enum (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) +{ + NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); + NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); + + switch (prop_id) { + case PROP_KEY_MGMT: + g_value_set_string (value, priv->key_mgmt); + break; + case PROP_WEP_TX_KEYIDX: + g_value_set_uint (value, priv->wep_tx_keyidx); + break; + case PROP_AUTH_ALG: + g_value_set_string (value, priv->auth_alg); + break; + case PROP_PROTO: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->proto)); + break; + case PROP_PAIRWISE: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->pairwise)); + break; + case PROP_GROUP: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->group)); + break; + case PROP_LEAP_USERNAME: + g_value_set_string (value, priv->leap_username); + break; + case PROP_WEP_KEY0: + g_value_set_string (value, priv->wep_key0); + break; + case PROP_WEP_KEY1: + g_value_set_string (value, priv->wep_key1); + break; + case PROP_WEP_KEY2: + g_value_set_string (value, priv->wep_key2); + break; + case PROP_WEP_KEY3: + g_value_set_string (value, priv->wep_key3); + break; + case PROP_WEP_KEY_FLAGS: + g_value_set_flags (value, priv->wep_key_flags); + break; + case PROP_PSK: + g_value_set_string (value, priv->psk); + break; + case PROP_PSK_FLAGS: + g_value_set_flags (value, priv->psk_flags); + break; + case PROP_LEAP_PASSWORD: + g_value_set_string (value, priv->leap_password); + break; + case PROP_LEAP_PASSWORD_FLAGS: + g_value_set_flags (value, priv->leap_password_flags); + break; + case PROP_WEP_KEY_TYPE: + g_value_set_enum (value, priv->wep_key_type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingWirelessSecurityPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; + + /* Properties */ + /** + * NMSettingWirelessSecurity:key-mgmt: + * + * Key management used for the connection. One of "none" (WEP), "ieee8021x" + * (Dynamic WEP), "wpa-none" (Ad-Hoc WPA-PSK), "wpa-psk" (infrastructure + * WPA-PSK), or "wpa-eap" (WPA-Enterprise). This property must be set for + * any Wi-Fi connection that uses security. + **/ + /* ---ifcfg-rh--- + * property: key-mgmt + * variable: KEY_MGMT(+) + * values: IEEE8021X, WPA-PSK, WPA-EAP + * description: Key management menthod. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_KEY_MGMT, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_REQUIRED | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-tx-keyidx: + * + * When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key + * index is used by the AP, put that WEP key index here. Valid values are 0 + * (default key) through 3. Note that some consumer access points (like the + * Linksys WRT54G) number the keys 1 - 4. + **/ + /* ---ifcfg-rh--- + * property: wep-tx-keyidx + * variable: DEFAULTKEY + * values: 1, 2, 3, 4 + * default: 1 + * description: Index of active WEP key. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_TX_KEYIDX, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, "", "", + 0, 3, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:auth-alg: + * + * When WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the + * 802.11 authentication algorithm required by the AP here. One of "open" + * for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP. When + * using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the + * "leap-username" and "leap-password" properties must be specified. + **/ + /* ---ifcfg-rh--- + * property: auth-alg + * variable: SECURITYMODE(+) + * values: restricted, open, leap + * description: Authentication algorithm for WEP. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_AUTH_ALG, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:proto: + * + * List of strings specifying the allowed WPA protocol versions to use. + * Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN). If + * not specified, both WPA and RSN connections are allowed. + **/ + /* ---ifcfg-rh--- + * property: proto + * variable: WPA_ALLOW_WPA(+), WPA_ALLOW_WPA2(+) + * values: yes, no + * default: no + * description: Allowed WPA protocols, WPA and WPA2 (RSN). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PROTO, + g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PROTO, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:pairwise: + * + * A list of pairwise encryption algorithms which prevents connections to + * Wi-Fi networks that do not utilize one of the algorithms in the list. + * For maximum compatibility leave this property empty. Each list element + * may be one of "tkip" or "ccmp". + **/ + /* ---ifcfg-rh--- + * property: pairwise + * variable: CIPHER_PAIRWISE(+) + * values: CCMP, TKIP + * description: Restrict pairwise encryption algorithms, specified as a space + * separated list. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PAIRWISE, + g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:group: + * + * A list of group/broadcast encryption algorithms which prevents + * connections to Wi-Fi networks that do not utilize one of the algorithms + * in the list. For maximum compatibility leave this property empty. Each + * list element may be one of "wep40", "wep104", "tkip", or "ccmp". + **/ + /* ---ifcfg-rh--- + * property: group + * variable: CIPHER_GROUP(+) + * values: CCMP, TKIP, WEP40, WEP104 + * description: Restrict group/broadcast encryption algorithms, specified as a space + * separated list. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_GROUP, + g_param_spec_boxed (NM_SETTING_WIRELESS_SECURITY_GROUP, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:leap-username: + * + * The login username for legacy LEAP connections (ie, key-mgmt = + * "ieee8021x" and auth-alg = "leap"). + **/ + /* ---ifcfg-rh--- + * property: leap-username + * variable: IEEE_8021X_IDENTITY(+) + * description: Login name for LEAP. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_LEAP_USERNAME, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key0: + * + * Index 0 WEP key. This is the WEP key used in most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key0 + * variable: KEY1, KEY_PASSPHRASE1(+) + * description: The first WEP key (used in most networks). See also DEFAULTKEY for key index. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY0, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key1: + * + * Index 1 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key1 + * variable: KEY2, KEY_PASSPHRASE2(+) + * description: WEP key with index 1. See also DEFAULTKEY for key index. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY1, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key2: + * + * Index 2 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key2 + * variable: KEY3, KEY_PASSPHRASE3(+) + * description: WEP key with index 2. See also DEFAULTKEY for key index. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY2, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key3: + * + * Index 3 WEP key. This WEP index is not used by most networks. See the + * "wep-key-type" property for a description of how this key is interpreted. + **/ + /* ---ifcfg-rh--- + * property: wep-key3 + * variable: KEY4, KEY_PASSPHRASE4(+) + * description: WEP key with index 3. See also DEFAULTKEY for key index. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY3, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key-flags: + * + * Flags indicating how to handle the #NMSettingWirelessSecurity:wep-key0, + * #NMSettingWirelessSecurity:wep-key1, #NMSettingWirelessSecurity:wep-key2, + * and #NMSettingWirelessSecurity:wep-key3 properties. + **/ + /* ---ifcfg-rh--- + * property: wep-key-flags + * variable: WEP_KEY_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for KEY, KEY_PASSPHRASE password. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY_FLAGS, + g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:psk: + * + * Pre-Shared-Key for WPA networks. If the key is 64-characters long, it + * must contain only hexadecimal characters and is interpreted as a + * hexadecimal WPA key. Otherwise, the key must be between 8 and 63 ASCII + * characters (as specified in the 802.11i standard) and is interpreted as a + * WPA passphrase, and is hashed to derive the actual WPA-PSK used when + * connecting to the Wi-Fi network. + **/ + /* ---ifcfg-rh--- + * property: psk + * variable: WPA_PSK + * description: Pre-Shared-Key for WPA networks. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PSK, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:psk-flags: + * + * Flags indicating how to handle the #NMSettingWirelessSecurity:psk + * property. + **/ + /* ---ifcfg-rh--- + * property: psk-flags + * variable: WPA_PSK_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for WPA_PSK_FLAGS. + * example: WPA_PSK_FLAGS=user + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_PSK_FLAGS, + g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:leap-password: + * + * The login password for legacy LEAP connections (ie, key-mgmt = + * "ieee8021x" and auth-alg = "leap"). + **/ + /* ---ifcfg-rh--- + * property: leap-password + * variable: IEEE_8021X_PASSWORD(+) + * description: Password for LEAP. It can also go to "key-" + * lookaside file, or it can be owned by a secret agent. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_LEAP_PASSWORD, + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:leap-password-flags: + * + * Flags indicating how to handle the + * #NMSettingWirelessSecurity:leap-password property. + **/ + /* ---ifcfg-rh--- + * property: leap-password-flags + * variable: IEEE_8021X_PASSWORD_FLAGS(+) + * format: NMSettingSecretFlags + * description: Password flags for IEEE_8021X_PASSWORD_FLAGS. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_LEAP_PASSWORD_FLAGS, + g_param_spec_flags (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "", "", + NM_TYPE_SETTING_SECRET_FLAGS, + NM_SETTING_SECRET_FLAG_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWirelessSecurity:wep-key-type: + * + * Controls the interpretation of WEP keys. Allowed values are + * %NM_WEP_KEY_TYPE_KEY, in which case the key is either a 10- or + * 26-character hexadecimal string, or a 5- or 13-character ASCII password; + * or %NM_WEP_KEY_TYPE_PASSPHRASE, in which case the passphrase is provided + * as a string and will be hashed using the de-facto MD5 method to derive + * the actual WEP key. + **/ + /* ---ifcfg-rh--- + * property: wep-key-type + * variable: KEY or KEY_PASSPHRASE(+) + * description: KEY is used for "key" type (10 or 26 hexadecimal characters, + * or 5 or 13 character string prefixed with "s:"). KEY_PASSPHRASE is used + * for WEP passphrases. + * example: KEY1=s:ahoj, KEY1=0a1c45bc02, KEY_PASSPHRASE1=mysupersecretkey + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_WEP_KEY_TYPE, + g_param_spec_enum (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, "", "", + NM_TYPE_WEP_KEY_TYPE, + NM_WEP_KEY_TYPE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + G_VARIANT_TYPE_UINT32, + wep_key_type_to_dbus, + NULL); +} diff --git a/libnm-core/nm-setting-wireless-security.h b/libnm-core/nm-setting-wireless-security.h new file mode 100644 index 00000000..8c4e1f03 --- /dev/null +++ b/libnm-core/nm-setting-wireless-security.h @@ -0,0 +1,147 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRELESS_SECURITY_H__ +#define __NM_SETTING_WIRELESS_SECURITY_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_get_type ()) +#define NM_SETTING_WIRELESS_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurity)) +#define NM_SETTING_WIRELESS_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityClass)) +#define NM_IS_SETTING_WIRELESS_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_IS_SETTING_WIRELESS_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_WIRELESS_SECURITY)) +#define NM_SETTING_WIRELESS_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityClass)) + +#define NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "802-11-wireless-security" + +/** + * NMWepKeyType: + * @NM_WEP_KEY_TYPE_UNKNOWN: unknown WEP key type + * @NM_WEP_KEY_TYPE_KEY: indicates a hexadecimal or ASCII formatted WEP key. + * Hex keys are either 10 or 26 hexadecimal characters (ie "5f782f2f5f" or + * "732f2d712e4a394a375d366931"), while ASCII keys are either 5 or 13 ASCII + * characters (ie "abcde" or "blahblah99$*1"). + * @NM_WEP_KEY_TYPE_PASSPHRASE: indicates a WEP passphrase (ex "I bought a duck + * on my way back from the market 235Q&^%^*%") instead of a hexadecimal or ASCII + * key. Passphrases are between 8 and 64 characters inclusive and are hashed + * the actual WEP key using the MD5 hash algorithm. + * @NM_WEP_KEY_TYPE_LAST: placeholder value for bounds-checking + * + * The #NMWepKeyType values specify how any WEP keys present in the setting + * are intepreted. There are no standards governing how to hash the various WEP + * key/passphrase formats into the actual WEP key. Unfortunately some WEP keys + * can be interpreted in multiple ways, requring the setting to specify how to + * interpret the any WEP keys. For example, the key "732f2d712e4a394a375d366931" + * is both a valid Hexadecimal WEP key and a WEP passphrase. Further, many + * ASCII keys are also valid WEP passphrases, but since passphrases and ASCII + * keys are hashed differently to determine the actual WEP key the type must be + * specified. + */ +typedef enum { + NM_WEP_KEY_TYPE_UNKNOWN = 0, + NM_WEP_KEY_TYPE_KEY = 1, /* Hex or ASCII */ + NM_WEP_KEY_TYPE_PASSPHRASE = 2, /* 104/128-bit Passphrase */ + + NM_WEP_KEY_TYPE_LAST = NM_WEP_KEY_TYPE_PASSPHRASE +} NMWepKeyType; + +#define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt" +#define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx" +#define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg" +#define NM_SETTING_WIRELESS_SECURITY_PROTO "proto" +#define NM_SETTING_WIRELESS_SECURITY_PAIRWISE "pairwise" +#define NM_SETTING_WIRELESS_SECURITY_GROUP "group" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME "leap-username" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY0 "wep-key0" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS "wep-key-flags" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type" +#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" +#define NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS "psk-flags" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags" + +struct _NMSettingWirelessSecurity { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWirelessSecurityClass; + +GType nm_setting_wireless_security_get_type (void); + +NMSetting * nm_setting_wireless_security_new (void); + +const char *nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *setting, const char *proto); +void nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise); +void nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting, const char *pairwise); +void nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting); + +guint32 nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group); +void nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i); +gboolean nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting, const char *group); +void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); + +const char *nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting); + +const char *nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting); + +const char *nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx); +void nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key); +guint32 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting); +const char *nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting); + +NMSettingSecretFlags nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting); +NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRELESS_SECURITY_H__ */ diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c new file mode 100644 index 00000000..f8d22c2d --- /dev/null +++ b/libnm-core/nm-setting-wireless.c @@ -0,0 +1,1335 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting-wireless.h" +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-setting-private.h" + +/** + * SECTION:nm-setting-wireless + * @short_description: Describes connection properties for 802.11 Wi-Fi networks + * + * The #NMSettingWireless object is a #NMSetting subclass that describes properties + * necessary for connection to 802.11 Wi-Fi networks. + **/ + +G_DEFINE_TYPE_WITH_CODE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING, + _nm_register_setting (WIRELESS, 1)) +NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRELESS) + +#define NM_SETTING_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessPrivate)) + +typedef struct { + GBytes *ssid; + char *mode; + char *band; + guint32 channel; + char *bssid; + guint32 rate; + guint32 tx_power; + char *device_mac_address; + char *cloned_mac_address; + GArray *mac_address_blacklist; + guint32 mtu; + GSList *seen_bssids; + gboolean hidden; +} NMSettingWirelessPrivate; + +enum { + PROP_0, + PROP_SSID, + PROP_MODE, + PROP_BAND, + PROP_CHANNEL, + PROP_BSSID, + PROP_RATE, + PROP_TX_POWER, + PROP_MAC_ADDRESS, + PROP_CLONED_MAC_ADDRESS, + PROP_MAC_ADDRESS_BLACKLIST, + PROP_MTU, + PROP_SEEN_BSSIDS, + PROP_HIDDEN, + + LAST_PROP +}; + +static gboolean +match_cipher (const char *cipher, + const char *expected, + guint32 wpa_flags, + guint32 rsn_flags, + guint32 flag) +{ + if (strcmp (cipher, expected) != 0) + return FALSE; + + if (!(wpa_flags & flag) && !(rsn_flags & flag)) + return FALSE; + + return TRUE; +} + +/** + * nm_setting_wireless_ap_security_compatible: + * @s_wireless: a #NMSettingWireless + * @s_wireless_sec: a #NMSettingWirelessSecurity or %NULL + * @ap_flags: the %NM80211ApFlags of the given access point + * @ap_wpa: the %NM80211ApSecurityFlags of the given access point's WPA + * capabilities + * @ap_rsn: the %NM80211ApSecurityFlags of the given access point's WPA2/RSN + * capabilities + * @ap_mode: the 802.11 mode of the AP, either Ad-Hoc or Infrastructure + * + * Given a #NMSettingWireless and an optional #NMSettingWirelessSecurity, + * determine if the configuration given by the settings is compatible with + * the security of an access point using that access point's capability flags + * and mode. Useful for clients that wish to filter a set of connections + * against a set of access points and determine which connections are + * compatible with which access points. + * + * Returns: %TRUE if the given settings are compatible with the access point's + * security flags and mode, %FALSE if they are not. + */ +gboolean +nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode) +{ + const char *key_mgmt = NULL, *cipher; + guint32 num, i; + gboolean found = FALSE; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (s_wireless), FALSE); + + if (!s_wireless_sec) { + if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); + if (!key_mgmt) + return FALSE; + + /* Static WEP */ + if (!strcmp (key_mgmt, "none")) { + if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + || (ap_wpa != NM_802_11_AP_SEC_NONE) + || (ap_rsn != NM_802_11_AP_SEC_NONE)) + return FALSE; + return TRUE; + } + + /* Adhoc WPA */ + if (!strcmp (key_mgmt, "wpa-none")) { + if (ap_mode != NM_802_11_MODE_ADHOC) + return FALSE; + /* FIXME: validate ciphers if they're in the beacon */ + return TRUE; + } + + /* Adhoc WPA2 (ie, RSN IBSS) */ + if (ap_mode == NM_802_11_MODE_ADHOC) { + if (strcmp (key_mgmt, "wpa-psk")) + return FALSE; + + /* Ensure the AP has RSN PSK capability */ + if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + return FALSE; + + /* Fall through and check ciphers in generic WPA-PSK code */ + } + + /* Dynamic WEP or LEAP */ + if (!strcmp (key_mgmt, "ieee8021x")) { + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + + /* If the AP is advertising a WPA IE, make sure it supports WEP ciphers */ + if (ap_wpa != NM_802_11_AP_SEC_NONE) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + + /* quick check; can't use AP if it doesn't support at least one + * WEP cipher in both pairwise and group suites. + */ + if ( !(ap_wpa & (NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104)) + || !(ap_wpa & (NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104))) + return FALSE; + + /* Match at least one pairwise cipher with AP's capability if the + * wireless-security setting explicitly lists pairwise ciphers + */ + num = nm_setting_wireless_security_get_num_pairwise (s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_pairwise (s_wireless_sec, i); + if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP40))) + break; + if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP104))) + break; + } + if (!found && num) + return FALSE; + + /* Match at least one group cipher with AP's capability if the + * wireless-security setting explicitly lists group ciphers + */ + num = nm_setting_wireless_security_get_num_groups (s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_group (s_wireless_sec, i); + if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP104))) + break; + } + if (!found && num) + return FALSE; + } + return TRUE; + } + + /* WPA[2]-PSK and WPA[2] Enterprise */ + if ( !strcmp (key_mgmt, "wpa-psk") + || !strcmp (key_mgmt, "wpa-eap")) { + + if (!strcmp (key_mgmt, "wpa-psk")) { + if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK)) + return FALSE; + } else if (!strcmp (key_mgmt, "wpa-eap")) { + if ( !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + } + + // FIXME: should handle WPA and RSN separately here to ensure that + // if the Connection only uses WPA we don't match a cipher against + // the AP's RSN IE instead + + /* Match at least one pairwise cipher with AP's capability if the + * wireless-security setting explicitly lists pairwise ciphers + */ + num = nm_setting_wireless_security_get_num_pairwise (s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_pairwise (s_wireless_sec, i); + if ((found = match_cipher (cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_TKIP))) + break; + if ((found = match_cipher (cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_CCMP))) + break; + } + if (!found && num) + return FALSE; + + /* Match at least one group cipher with AP's capability if the + * wireless-security setting explicitly lists group ciphers + */ + num = nm_setting_wireless_security_get_num_groups (s_wireless_sec); + for (i = 0, found = FALSE; i < num; i++) { + cipher = nm_setting_wireless_security_get_group (s_wireless_sec, i); + + if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP40))) + break; + if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP104))) + break; + if ((found = match_cipher (cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_TKIP))) + break; + if ((found = match_cipher (cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_CCMP))) + break; + } + if (!found && num) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +/** + * nm_setting_wireless_new: + * + * Creates a new #NMSettingWireless object with default values. + * + * Returns: (transfer full): the new empty #NMSettingWireless object + **/ +NMSetting * +nm_setting_wireless_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS, NULL); +} + +/** + * nm_setting_wireless_get_ssid: + * @setting: the #NMSettingWireless + * + * Returns: (transfer none): the #NMSettingWireless:ssid property of the setting + **/ +GBytes * +nm_setting_wireless_get_ssid (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ssid; +} + +/** + * nm_setting_wireless_get_mode: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mode property of the setting + **/ +const char * +nm_setting_wireless_get_mode (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mode; +} + +/** + * nm_setting_wireless_get_band: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:band property of the setting + **/ +const char * +nm_setting_wireless_get_band (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->band; +} + +/** + * nm_setting_wireless_get_channel: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:channel property of the setting + **/ +guint32 +nm_setting_wireless_get_channel (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->channel; +} + +/** + * nm_setting_wireless_get_bssid: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:bssid property of the setting + **/ +const char * +nm_setting_wireless_get_bssid (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->bssid; +} + +/** + * nm_setting_wireless_get_rate: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:rate property of the setting + **/ +guint32 +nm_setting_wireless_get_rate (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->rate; +} + +/** + * nm_setting_wireless_get_tx_power: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:tx-power property of the setting + **/ +guint32 +nm_setting_wireless_get_tx_power (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->tx_power; +} + +/** + * nm_setting_wireless_get_mac_address: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address property of the setting + **/ +const char * +nm_setting_wireless_get_mac_address (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->device_mac_address; +} + +/** + * nm_setting_wireless_get_cloned_mac_address: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:cloned-mac-address property of the setting + **/ +const char * +nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address; +} + +/** + * nm_setting_wireless_get_mac_address_blacklist: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mac-address-blacklist property of the setting + **/ +const char * const * +nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + return (const char * const *) priv->mac_address_blacklist->data; +} + +/** + * nm_setting_wireless_get_num_mac_blacklist_items: + * @setting: the #NMSettingWireless + * + * Returns: the number of blacklisted MAC addresses + **/ +guint32 +nm_setting_wireless_get_num_mac_blacklist_items (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist->len; +} + +/** + * nm_setting_wireless_get_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @idx: the zero-based index of the MAC address entry + * + * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) + * at index @idx + **/ +const char * +nm_setting_wireless_get_mac_blacklist_item (NMSettingWireless *setting, guint32 idx) +{ + NMSettingWirelessPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + g_return_val_if_fail (idx <= priv->mac_address_blacklist->len, NULL); + + return g_array_index (priv->mac_address_blacklist, const char *, idx); +} + +/** + * nm_setting_wireless_add_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist + * + * Adds a new MAC address to the #NMSettingWireless:mac-address-blacklist property. + * + * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address + * is invalid or was already present + **/ +gboolean +nm_setting_wireless_add_mac_blacklist_item (NMSettingWireless *setting, const char *mac) +{ + NMSettingWirelessPrivate *priv; + const char *candidate; + int i; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + if (!nm_utils_hwaddr_valid (mac, ETH_ALEN)) + return FALSE; + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index (priv->mac_address_blacklist, char *, i); + if (nm_utils_hwaddr_matches (mac, -1, candidate, -1)) + return FALSE; + } + + mac = nm_utils_hwaddr_canonical (mac, ETH_ALEN); + g_array_append_val (priv->mac_address_blacklist, mac); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return TRUE; +} + +/** + * nm_setting_wireless_remove_mac_blacklist_item: + * @setting: the #NMSettingWireless + * @idx: index number of the MAC address + * + * Removes the MAC address at index @idx from the blacklist. + **/ +void +nm_setting_wireless_remove_mac_blacklist_item (NMSettingWireless *setting, guint32 idx) +{ + NMSettingWirelessPrivate *priv; + + g_return_if_fail (NM_IS_SETTING_WIRELESS (setting)); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + g_return_if_fail (idx < priv->mac_address_blacklist->len); + + g_array_remove_index (priv->mac_address_blacklist, idx); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wireless_remove_mac_blacklist_item_by_value: + * @setting: the #NMSettingWireless + * @mac: the MAC address string (hex-digits-and-colons notation) to remove from + * the blacklist + * + * Removes the MAC address @mac from the blacklist. + * + * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. + **/ +gboolean +nm_setting_wireless_remove_mac_blacklist_item_by_value (NMSettingWireless *setting, const char *mac) +{ + NMSettingWirelessPrivate *priv; + const char *candidate; + int i; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + candidate = g_array_index (priv->mac_address_blacklist, char *, i); + if (!nm_utils_hwaddr_matches (mac, -1, candidate, -1)) { + g_array_remove_index (priv->mac_address_blacklist, i); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return TRUE; + } + } + return FALSE; +} + +/** + * nm_setting_wireless_clear_mac_blacklist_items: + * @setting: the #NMSettingWireless + * + * Removes all blacklisted MAC addresses. + **/ +void +nm_setting_wireless_clear_mac_blacklist_items (NMSettingWireless *setting) +{ + g_return_if_fail (NM_IS_SETTING_WIRELESS (setting)); + + g_array_set_size (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist, 0); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); +} + +/** + * nm_setting_wireless_get_mtu: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:mtu property of the setting + **/ +guint32 +nm_setting_wireless_get_mtu (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mtu; +} + +/** + * nm_setting_wireless_get_hidden: + * @setting: the #NMSettingWireless + * + * Returns: the #NMSettingWireless:hidden property of the setting + **/ +gboolean +nm_setting_wireless_get_hidden (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); + + return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->hidden; +} + +/** + * nm_setting_wireless_add_seen_bssid: + * @setting: the #NMSettingWireless + * @bssid: the new BSSID to add to the list + * + * Adds a new Wi-Fi AP's BSSID to the previously seen BSSID list of the setting. + * NetworkManager now tracks previously seen BSSIDs internally so this function + * no longer has much use. Actually, changes you make using this function will + * not be preserved. + * + * Returns: %TRUE if @bssid was already known, %FALSE if not + **/ +gboolean +nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, + const char *bssid) +{ + NMSettingWirelessPrivate *priv; + char *lower_bssid; + GSList *iter; + gboolean found = FALSE; + + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE); + g_return_val_if_fail (bssid != NULL, FALSE); + + lower_bssid = g_ascii_strdown (bssid, -1); + if (!lower_bssid) + return FALSE; + + priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + + for (iter = priv->seen_bssids; iter; iter = iter->next) { + if (!strcmp ((char *) iter->data, lower_bssid)) { + found = TRUE; + break; + } + } + + if (!found) { + priv->seen_bssids = g_slist_prepend (priv->seen_bssids, lower_bssid); + g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SEEN_BSSIDS); + } else + g_free (lower_bssid); + + return !found; +} + +/** + * nm_setting_wireless_get_num_seen_bssids: + * @setting: the #NMSettingWireless + * + * Returns: the number of BSSIDs in the previously seen BSSID list + **/ +guint32 +nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0); + + return g_slist_length (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids); +} + +/** + * nm_setting_wireless_get_seen_bssid: + * @setting: the #NMSettingWireless + * @i: index of a BSSID in the previously seen BSSID list + * + * Returns: the BSSID at index @i + **/ +const char * +nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, + guint32 i) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); + + return (const char *) g_slist_nth_data (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids, i); +} + +static gboolean +verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + const char *valid_modes[] = { NM_SETTING_WIRELESS_MODE_INFRA, NM_SETTING_WIRELESS_MODE_ADHOC, NM_SETTING_WIRELESS_MODE_AP, NULL }; + const char *valid_bands[] = { "a", "bg", NULL }; + GSList *iter; + int i; + gsize length; + + if (!priv->ssid) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + length = g_bytes_get_size (priv->ssid); + if (length == 0 || length > 32) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("SSID length is out of range <1-32> bytes")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); + return FALSE; + } + + if (priv->mode && !_nm_utils_string_in_list (priv->mode, valid_modes)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid Wi-Fi mode"), + priv->mode); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); + return FALSE; + } + + if (priv->band && !_nm_utils_string_in_list (priv->band, valid_bands)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid band"), + priv->band); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BAND); + return FALSE; + } + + if (priv->channel && !priv->band) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("'%s' requires setting '%s' property"), + NM_SETTING_WIRELESS_CHANNEL, NM_SETTING_WIRELESS_BAND); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BAND); + return FALSE; + } + + if (priv->channel) { + if (!nm_utils_wifi_is_channel_valid (priv->channel, priv->band)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%d' is not a valid channel"), + priv->channel); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CHANNEL); + return FALSE; + } + } + + if (priv->bssid && !nm_utils_hwaddr_valid (priv->bssid, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BSSID); + return FALSE; + } + + if (priv->device_mac_address && !nm_utils_hwaddr_valid (priv->device_mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); + return FALSE; + } + + if (priv->cloned_mac_address && !nm_utils_hwaddr_valid (priv->cloned_mac_address, ETH_ALEN)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS); + return FALSE; + } + + for (i = 0; i < priv->mac_address_blacklist->len; i++) { + const char *mac = g_array_index (priv->mac_address_blacklist, const char *, i); + + if (!nm_utils_hwaddr_valid (mac, ETH_ALEN)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + mac); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST); + return FALSE; + } + } + + for (iter = priv->seen_bssids; iter; iter = iter->next) { + if (!nm_utils_hwaddr_valid (iter->data, ETH_ALEN)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid MAC address"), + (const char *) iter->data); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SEEN_BSSIDS); + return FALSE; + } + } + + return TRUE; +} + +static GVariant * +nm_setting_wireless_get_security (NMSetting *setting, + NMConnection *connection, + const char *property_name) +{ + if (nm_connection_get_setting_wireless_security (connection)) + return g_variant_new_string (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + else + return NULL; +} + +static void +clear_blacklist_item (char **item_p) +{ + g_free (*item_p); +} + +static void +nm_setting_wireless_init (NMSettingWireless *setting) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); + + /* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */ + priv->mac_address_blacklist = g_array_new (TRUE, FALSE, sizeof (char *)); + g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); +} + +static void +finalize (GObject *object) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object); + + g_free (priv->mode); + g_free (priv->band); + + if (priv->ssid) + g_bytes_unref (priv->ssid); + g_free (priv->bssid); + g_free (priv->device_mac_address); + g_free (priv->cloned_mac_address); + g_array_unref (priv->mac_address_blacklist); + g_slist_free_full (priv->seen_bssids, g_free); + + G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object); + const char * const *blacklist; + const char *mac; + int i; + + switch (prop_id) { + case PROP_SSID: + if (priv->ssid) + g_bytes_unref (priv->ssid); + priv->ssid = g_value_dup_boxed (value); + break; + case PROP_MODE: + g_free (priv->mode); + priv->mode = g_value_dup_string (value); + break; + case PROP_BAND: + g_free (priv->band); + priv->band = g_value_dup_string (value); + break; + case PROP_CHANNEL: + priv->channel = g_value_get_uint (value); + break; + case PROP_BSSID: + g_free (priv->bssid); + priv->bssid = g_value_dup_string (value); + break; + case PROP_RATE: + priv->rate = g_value_get_uint (value); + break; + case PROP_TX_POWER: + priv->tx_power = g_value_get_uint (value); + break; + case PROP_MAC_ADDRESS: + g_free (priv->device_mac_address); + priv->device_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + break; + case PROP_CLONED_MAC_ADDRESS: + g_free (priv->cloned_mac_address); + priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), + ETH_ALEN); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + blacklist = g_value_get_boxed (value); + g_array_set_size (priv->mac_address_blacklist, 0); + if (blacklist && *blacklist) { + for (i = 0; blacklist[i]; i++) { + mac = _nm_utils_hwaddr_canonical_or_invalid (blacklist[i], ETH_ALEN); + g_array_append_val (priv->mac_address_blacklist, mac); + } + } + break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; + case PROP_SEEN_BSSIDS: + g_slist_free_full (priv->seen_bssids, g_free); + priv->seen_bssids = _nm_utils_strv_to_slist (g_value_get_boxed (value)); + break; + case PROP_HIDDEN: + priv->hidden = g_value_get_boolean (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) +{ + NMSettingWireless *setting = NM_SETTING_WIRELESS (object); + NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_SSID: + g_value_set_boxed (value, nm_setting_wireless_get_ssid (setting)); + break; + case PROP_MODE: + g_value_set_string (value, nm_setting_wireless_get_mode (setting)); + break; + case PROP_BAND: + g_value_set_string (value, nm_setting_wireless_get_band (setting)); + break; + case PROP_CHANNEL: + g_value_set_uint (value, nm_setting_wireless_get_channel (setting)); + break; + case PROP_BSSID: + g_value_set_string (value, nm_setting_wireless_get_bssid (setting)); + break; + case PROP_RATE: + g_value_set_uint (value, nm_setting_wireless_get_rate (setting)); + break; + case PROP_TX_POWER: + g_value_set_uint (value, nm_setting_wireless_get_tx_power (setting)); + break; + case PROP_MAC_ADDRESS: + g_value_set_string (value, nm_setting_wireless_get_mac_address (setting)); + break; + case PROP_CLONED_MAC_ADDRESS: + g_value_set_string (value, nm_setting_wireless_get_cloned_mac_address (setting)); + break; + case PROP_MAC_ADDRESS_BLACKLIST: + g_value_set_boxed (value, (char **) priv->mac_address_blacklist->data); + break; + case PROP_MTU: + g_value_set_uint (value, nm_setting_wireless_get_mtu (setting)); + break; + case PROP_SEEN_BSSIDS: + g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->seen_bssids)); + break; + case PROP_HIDDEN: + g_value_set_boolean (value, nm_setting_wireless_get_hidden (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + g_type_class_add_private (setting_class, sizeof (NMSettingWirelessPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + /** + * NMSettingWireless:ssid: + * + * SSID of the Wi-Fi network. Must be specified. + **/ + /* ---keyfile--- + * property: ssid + * format: string (or decimal-byte list - obsolete) + * description: SSID of Wi-Fi network. + * example: ssid=Quick Net + * ---end--- + * ---ifcfg-rh--- + * property: ssid + * variable: ESSID + * description: SSID of Wi-Fi network. + * example: ESSID="Quick Net" + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SSID, + g_param_spec_boxed (NM_SETTING_WIRELESS_SSID, "", "", + G_TYPE_BYTES, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:mode: + * + * Wi-Fi network mode; one of "infrastructure", "adhoc" or "ap". If blank, + * infrastructure is assumed. + **/ + /* ---ifcfg-rh--- + * property: mode + * variable: MODE + * values: Ad-Hoc, Managed (Auto) [case insensitive] + * description: Wi-Fi network mode. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_string (NM_SETTING_WIRELESS_MODE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:band: + * + * 802.11 frequency band of the network. One of "a" for 5GHz 802.11a or + * "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network + * to the specific band, i.e. if "a" is specified, the device will not + * associate with the same network in the 2.4GHz band even if the network's + * settings are compatible. This setting depends on specific driver + * capability and may not work with all drivers. + **/ + /* ---ifcfg-rh--- + * property: band + * variable: BAND(+) + * values: a, bg + * description: BAND alone is honored, but CHANNEL overrides BAND since it + * implies a band. + * example: BAND=bg + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_BAND, + g_param_spec_string (NM_SETTING_WIRELESS_BAND, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:channel: + * + * Wireless channel to use for the Wi-Fi connection. The device will only + * join (or create for Ad-Hoc networks) a Wi-Fi network on the specified + * channel. Because channel numbers overlap between bands, this property + * also requires the "band" property to be set. + **/ + /* ---ifcfg-rh--- + * property: channel + * variable: CHANNEL + * description: Channel used for the Wi-Fi communication. + * Channels greater than 14 mean "a" band, otherwise the + * band is "bg". + * example: CHANNEL=6 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CHANNEL, + g_param_spec_uint (NM_SETTING_WIRELESS_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:bssid: + * + * If specified, directs the device to only associate with the given access + * point. This capability is highly driver dependent and not supported by + * all devices. Note: this property does not control the BSSID used when + * creating an Ad-Hoc network and is unlikely to in the future. + **/ + /* ---ifcfg-rh--- + * property: bssid + * variable: BSSID(+) + * description: Restricts association only to a single AP. + * example: BSSID=00:1E:BD:64:83:21 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_BSSID, + g_param_spec_string (NM_SETTING_WIRELESS_BSSID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_BSSID, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingWireless:rate: + * + * If non-zero, directs the device to only use the specified bitrate for + * communication with the access point. Units are in Kb/s, ie 5500 = 5.5 + * Mbit/s. This property is highly driver dependent and not all devices + * support setting a static bitrate. + **/ + /* ---ifcfg-rh--- + * property: rate + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_RATE, + g_param_spec_uint (NM_SETTING_WIRELESS_RATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:tx-power: + * + * If non-zero, directs the device to use the specified transmit power. + * Units are dBm. This property is highly driver dependent and not all + * devices support setting a static transmit power. + **/ + /* ---ifcfg-rh--- + * property: tx-power + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_TX_POWER, + g_param_spec_uint (NM_SETTING_WIRELESS_TX_POWER, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:mac-address: + * + * If specified, this connection will only apply to the Wi-Fi device whose + * permanent MAC address matches. This property does not change the MAC + * address of the device (i.e. MAC spoofing). + **/ + /* ---keyfile--- + * property: mac-address + * format: ususal hex-digits-and-colons notation + * description: MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;162). + * ---end--- + * ---ifcfg-rh--- + * property: mac-address + * variable: HWADDR + * description: Hardware address of the device in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:05). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_WIRELESS_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingWireless:cloned-mac-address: + * + * If specified, request that the Wi-Fi device use this MAC address instead + * of its permanent MAC address. This is known as MAC cloning or spoofing. + **/ + /* ---keyfile--- + * property: cloned-mac-address + * format: ususal hex-digits-and-colons notation + * description: Cloned MAC address in traditional hex-digits-and-colons notation + * (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) + * (e.g. 0;34;104;18;121;178). + * ---end--- + * ---ifcfg-rh--- + * property: cloned-mac-address + * variable: MACADDR + * description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons + * notation (e.g. 00:22:68:14:5A:99). + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_CLONED_MAC_ADDRESS, + g_param_spec_string (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + _nm_setting_class_transform_property (parent_class, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, + G_VARIANT_TYPE_BYTESTRING, + _nm_utils_hwaddr_to_dbus, + _nm_utils_hwaddr_from_dbus); + + /** + * NMSettingWireless:mac-address-blacklist: + * + * A list of permanent MAC addresses of Wi-Fi devices to which this + * connection should never apply. Each MAC address should be given in the + * standard hex-digits-and-colons notation (eg "00:11:22:33:44:55"). + **/ + /* ---keyfile--- + * property: mac-address-blacklist + * format: list of MACs (separated with semicolons) + * description: MAC address blacklist. + * example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 + * ---end--- + * ---ifcfg-rh--- + * property: mac-address-blacklist + * variable: HWADDR_BLACKLIST(+) + * description: It denies usage of the connection for any device whose address + * is listed. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MAC_ADDRESS_BLACKLIST, + g_param_spec_boxed (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:seen-bssids: + * + * A list of BSSIDs (each BSSID formatted as a MAC address like + * "00:11:22:33:44:55") that have been detected as part of the Wi-Fi + * network. NetworkManager internally tracks previously seen BSSIDs. The + * property is only meant for reading and reflects the BSSID list of + * NetworkManager. The changes you make to this property will not be + * preserved. + **/ + /* ---ifcfg-rh--- + * property: seen-bssids + * variable: (none) + * description: This property is not handled by ifcfg-rh plugin. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_SEEN_BSSIDS, + g_param_spec_boxed (NM_SETTING_WIRELESS_SEEN_BSSIDS, "", "", + G_TYPE_STRV, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple Ethernet frames. + **/ + /* ---ifcfg-rh--- + * property: mtu + * variable: MTU + * description: MTU of the wireless interface. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_WIRELESS_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingWireless:hidden: + * + * If %TRUE, indicates this network is a non-broadcasting network that hides + * its SSID. In this case various workarounds may take place, such as + * probe-scanning the SSID for more reliable network discovery. However, + * these workarounds expose inherent insecurities with hidden SSID networks, + * and thus hidden SSID networks should be used with caution. + **/ + /* ---ifcfg-rh--- + * property: hidden + * variable: SSID_HIDDEN(+) + * description: Whether the network hides the SSID. + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_HIDDEN, + g_param_spec_boolean (NM_SETTING_WIRELESS_HIDDEN, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* Compatibility for deprecated property */ + /* ---ifcfg-rh--- + * property: security + * variable: (none) + * description: This property is deprecated and not handled by ifcfg-rh-plugin. + * ---end--- + * ---dbus--- + * property: security + * description: This property is deprecated, but can be set to the value + * '802-11-wireless-security' when a wireless security setting is also + * present in the connection dictionary, for compatibility with very old + * NetworkManager daemons. + * ---end--- + */ + _nm_setting_class_add_dbus_only_property (parent_class, "security", + G_VARIANT_TYPE_STRING, + nm_setting_wireless_get_security, NULL); +} diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h new file mode 100644 index 00000000..98fa98dc --- /dev/null +++ b/libnm-core/nm-setting-wireless.h @@ -0,0 +1,138 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_WIRELESS_H__ +#define __NM_SETTING_WIRELESS_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_WIRELESS (nm_setting_wireless_get_type ()) +#define NM_SETTING_WIRELESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWireless)) +#define NM_SETTING_WIRELESS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) +#define NM_IS_SETTING_WIRELESS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIRELESS)) +#define NM_IS_SETTING_WIRELESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_WIRELESS)) +#define NM_SETTING_WIRELESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessClass)) + +#define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless" + +#define NM_SETTING_WIRELESS_SSID "ssid" +#define NM_SETTING_WIRELESS_MODE "mode" +#define NM_SETTING_WIRELESS_BAND "band" +#define NM_SETTING_WIRELESS_CHANNEL "channel" +#define NM_SETTING_WIRELESS_BSSID "bssid" +#define NM_SETTING_WIRELESS_RATE "rate" +#define NM_SETTING_WIRELESS_TX_POWER "tx-power" +#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address" +#define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address" +#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist" +#define NM_SETTING_WIRELESS_MTU "mtu" +#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" +#define NM_SETTING_WIRELESS_HIDDEN "hidden" + +/** + * NM_SETTING_WIRELESS_MODE_ADHOC: + * + * Indicates Ad-Hoc mode where no access point is expected to be present. + */ +#define NM_SETTING_WIRELESS_MODE_ADHOC "adhoc" + +/** + * NM_SETTING_WIRELESS_MODE_AP: + * + * Indicates AP/master mode where the wireless device is started as an access + * point/hotspot. + */ +#define NM_SETTING_WIRELESS_MODE_AP "ap" + +/** + * NM_SETTING_WIRELESS_MODE_INFRA: + * + * Indicates infrastructure mode where an access point is expected to be present + * for this connection. + */ +#define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure" + +struct _NMSettingWireless { + NMSetting parent; +}; + +typedef struct { + NMSettingClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMSettingWirelessClass; + +GType nm_setting_wireless_get_type (void); + +NMSetting *nm_setting_wireless_new (void); + +GBytes *nm_setting_wireless_get_ssid (NMSettingWireless *setting); +const char *nm_setting_wireless_get_mode (NMSettingWireless *setting); +const char *nm_setting_wireless_get_band (NMSettingWireless *setting); +guint32 nm_setting_wireless_get_channel (NMSettingWireless *setting); +const char *nm_setting_wireless_get_bssid (NMSettingWireless *setting); +guint32 nm_setting_wireless_get_rate (NMSettingWireless *setting); +guint32 nm_setting_wireless_get_tx_power (NMSettingWireless *setting); +const char *nm_setting_wireless_get_mac_address (NMSettingWireless *setting); +const char *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting); + +const char * const *nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting); +guint32 nm_setting_wireless_get_num_mac_blacklist_items (NMSettingWireless *setting); +const char * nm_setting_wireless_get_mac_blacklist_item (NMSettingWireless *setting, + guint32 idx); +gboolean nm_setting_wireless_add_mac_blacklist_item (NMSettingWireless *setting, + const char *mac); +void nm_setting_wireless_remove_mac_blacklist_item (NMSettingWireless *setting, + guint32 idx); +gboolean nm_setting_wireless_remove_mac_blacklist_item_by_value (NMSettingWireless *setting, + const char *mac); +void nm_setting_wireless_clear_mac_blacklist_items (NMSettingWireless *setting); + +guint32 nm_setting_wireless_get_mtu (NMSettingWireless *setting); +gboolean nm_setting_wireless_get_hidden (NMSettingWireless *setting); + +gboolean nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, + const char *bssid); + +guint32 nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting); +const char *nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, + guint32 i); + +gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, + NMSettingWirelessSecurity *s_wireless_sec, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn, + NM80211Mode ap_mode); + +G_END_DECLS + +#endif /* __NM_SETTING_WIRELESS_H__ */ diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c new file mode 100644 index 00000000..037baa6b --- /dev/null +++ b/libnm-core/nm-setting.c @@ -0,0 +1,1818 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-setting.h" +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-core-internal.h" +#include "nm-utils-private.h" +#include "nm-property-compare.h" + +#include "nm-setting-connection.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-vpn.h" + +/** + * SECTION:nm-setting + * @short_description: Describes related configuration information + * + * Each #NMSetting contains properties that describe configuration that applies + * to a specific network layer (like IPv4 or IPv6 configuration) or device type + * (like Ethernet, or Wi-Fi). A collection of individual settings together + * make up an #NMConnection. Each property is strongly typed and usually has + * a number of allowed values. See each #NMSetting subclass for a description + * of properties and allowed values. + */ + +G_DEFINE_ABSTRACT_TYPE (NMSetting, nm_setting, G_TYPE_OBJECT) + +#define NM_SETTING_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING, NMSettingPrivate)) + +typedef struct { + const char *name; + GType type; + guint32 priority; +} SettingInfo; + +typedef struct { + const SettingInfo *info; +} NMSettingPrivate; + +enum { + PROP_0, + PROP_NAME, + + PROP_LAST +}; + +/*************************************************************/ + +static GHashTable *registered_settings = NULL; +static GHashTable *registered_settings_by_type = NULL; + +static gboolean +_nm_gtype_equal (gconstpointer v1, gconstpointer v2) +{ + return *((const GType *) v1) == *((const GType *) v2); +} +static guint +_nm_gtype_hash (gconstpointer v) +{ + return *((const GType *) v); +} + +static void __attribute__((constructor)) +_ensure_registered (void) +{ + if (G_UNLIKELY (registered_settings == NULL)) { +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + registered_settings = g_hash_table_new (g_str_hash, g_str_equal); + registered_settings_by_type = g_hash_table_new (_nm_gtype_hash, _nm_gtype_equal); + } +} + +#define _ensure_setting_info(self, priv) \ + G_STMT_START { \ + NMSettingPrivate *_priv_esi = (priv); \ + if (G_UNLIKELY (!_priv_esi->info)) { \ + _priv_esi->info = _nm_setting_lookup_setting_by_type (G_OBJECT_TYPE (self)); \ + g_assert (_priv_esi->info); \ + } \ + } G_STMT_END + +/*************************************************************/ + +/* + * _nm_register_setting: + * @name: the name of the #NMSetting object to register + * @type: the #GType of the #NMSetting + * @priority: the sort priority of the setting, see below + * + * INTERNAL ONLY: registers a setting's internal properties with libnm. + * + * A setting's priority should roughly follow the OSI layer model, but it also + * controls which settings get asked for secrets first. Thus settings which + * relate to things that must be working first, like hardware, should get a + * higher priority than things which layer on top of the hardware. For example, + * the GSM/CDMA settings should provide secrets before the PPP setting does, + * because a PIN is required to unlock the device before PPP can even start. + * Even settings without secrets should be assigned the right priority. + * + * 0: reserved for the Connection setting + * + * 1: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. + * These priority 1 settings are also "base types", which means that at least + * one of them is required for the connection to be valid, and their name is + * valid in the 'type' property of the Connection setting. + * + * 2: hardware-related auxiliary settings that require a base setting to be + * successful first, like Wi-Fi security, 802.1x, etc. + * + * 3: hardware-independent settings that are required before IP connectivity + * can be established, like PPP, PPPoE, etc. + * + * 4: IP-level stuff + */ +void +(_nm_register_setting) (const char *name, + const GType type, + const guint32 priority) +{ + SettingInfo *info; + + g_return_if_fail (name != NULL && *name); + g_return_if_fail (type != G_TYPE_INVALID); + g_return_if_fail (type != G_TYPE_NONE); + g_return_if_fail (priority <= 4); + + _ensure_registered (); + + if (G_LIKELY ((info = g_hash_table_lookup (registered_settings, name)))) { + g_return_if_fail (info->type == type); + g_return_if_fail (info->priority == priority); + g_return_if_fail (g_strcmp0 (info->name, name) == 0); + return; + } + g_return_if_fail (g_hash_table_lookup (registered_settings_by_type, &type) == NULL); + + if (priority == 0) + g_assert_cmpstr (name, ==, NM_SETTING_CONNECTION_SETTING_NAME); + + info = g_slice_new0 (SettingInfo); + info->type = type; + info->priority = priority; + info->name = name; + g_hash_table_insert (registered_settings, (void *) info->name, info); + g_hash_table_insert (registered_settings_by_type, &info->type, info); +} + +static const SettingInfo * +_nm_setting_lookup_setting_by_type (GType type) +{ + _ensure_registered (); + return g_hash_table_lookup (registered_settings_by_type, &type); +} + +static guint32 +_get_setting_type_priority (GType type) +{ + const SettingInfo *info; + + g_return_val_if_fail (g_type_is_a (type, NM_TYPE_SETTING), G_MAXUINT32); + + info = _nm_setting_lookup_setting_by_type (type); + return info->priority; +} + +guint32 +_nm_setting_get_setting_priority (NMSetting *setting) +{ + NMSettingPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING (setting), G_MAXUINT32); + priv = NM_SETTING_GET_PRIVATE (setting); + _ensure_setting_info (setting, priv); + return priv->info->priority; +} + +gboolean +_nm_setting_type_is_base_type (GType type) +{ + /* Historical oddity: PPPoE is a base-type even though it's not + * priority 1. It needs to be sorted *after* lower-level stuff like + * Wi-Fi security or 802.1x for secrets, but it's still allowed as a + * base type. + */ + return _get_setting_type_priority (type) == 1 || (type == NM_TYPE_SETTING_PPPOE); +} + +gboolean +_nm_setting_is_base_type (NMSetting *setting) +{ + return _nm_setting_type_is_base_type (G_OBJECT_TYPE (setting)); +} + +/** + * nm_setting_lookup_type: + * @name: a setting name + * + * Returns the #GType of the setting's class for a given setting name. + * + * Returns: the #GType of the setting's class, or %G_TYPE_INVALID if + * @name is not recognized. + **/ +GType +nm_setting_lookup_type (const char *name) +{ + SettingInfo *info; + + g_return_val_if_fail (name != NULL, G_TYPE_INVALID); + + _ensure_registered (); + + info = g_hash_table_lookup (registered_settings, name); + return info ? info->type : G_TYPE_INVALID; +} + +gint +_nm_setting_compare_priority (gconstpointer a, gconstpointer b) +{ + guint32 prio_a, prio_b; + + prio_a = _nm_setting_get_setting_priority ((NMSetting *) a); + prio_b = _nm_setting_get_setting_priority ((NMSetting *) b); + + if (prio_a < prio_b) + return -1; + else if (prio_a == prio_b) + return 0; + return 1; +} + +/*************************************************************/ + +gboolean +_nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_type) +{ + const char *port_type = NULL; + gboolean found = TRUE; + + if (!slave_type) + found = FALSE; + else if (!strcmp (slave_type, NM_SETTING_BOND_SETTING_NAME)) + ; + else if (!strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) + port_type = NM_SETTING_BRIDGE_PORT_SETTING_NAME; + else if (!strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME)) + port_type = NM_SETTING_TEAM_PORT_SETTING_NAME; + else + found = FALSE; + + if (out_port_type) + *out_port_type = port_type; + return found; +} + +/*************************************************************/ + +typedef struct { + const char *name; + GParamSpec *param_spec; + const GVariantType *dbus_type; + + NMSettingPropertyGetFunc get_func; + NMSettingPropertySynthFunc synth_func; + NMSettingPropertySetFunc set_func; + NMSettingPropertyNotSetFunc not_set_func; + + NMSettingPropertyTransformToFunc to_dbus; + NMSettingPropertyTransformFromFunc from_dbus; +} NMSettingProperty; + +static GQuark setting_property_overrides_quark; +static GQuark setting_properties_quark; + +static NMSettingProperty * +find_property (GArray *properties, const char *name) +{ + NMSettingProperty *property; + int i; + + if (!properties) + return NULL; + + for (i = 0; i < properties->len; i++) { + property = &g_array_index (properties, NMSettingProperty, i); + if (strcmp (name, property->name) == 0) + return property; + } + + return NULL; +} + +static void +add_property_override (NMSettingClass *setting_class, + const char *property_name, + GParamSpec *param_spec, + const GVariantType *dbus_type, + NMSettingPropertyGetFunc get_func, + NMSettingPropertySynthFunc synth_func, + NMSettingPropertySetFunc set_func, + NMSettingPropertyNotSetFunc not_set_func, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus) +{ + GType setting_type = G_TYPE_FROM_CLASS (setting_class); + GArray *overrides; + NMSettingProperty override; + + g_return_if_fail (g_type_get_qdata (setting_type, setting_properties_quark) == NULL); + + memset (&override, 0, sizeof (override)); + override.name = property_name; + override.param_spec = param_spec; + override.dbus_type = dbus_type; + override.get_func = get_func; + override.synth_func = synth_func; + override.set_func = set_func; + override.not_set_func = not_set_func; + override.to_dbus = to_dbus; + override.from_dbus = from_dbus; + + overrides = g_type_get_qdata (setting_type, setting_property_overrides_quark); + if (!overrides) { + overrides = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); + g_type_set_qdata (setting_type, setting_property_overrides_quark, overrides); + } + g_return_if_fail (find_property (overrides, property_name) == NULL); + + g_array_append_val (overrides, override); +} + +/** + * _nm_setting_class_add_dbus_only_property: + * @setting_class: the setting class + * @property_name: the name of the property to override + * @dbus_type: the type of the property (in its D-Bus representation) + * @synth_func: (allow-none): function to call to synthesize a value for the property + * @set_func: (allow-none): function to call to set the value of the property + * + * Registers a property named @property_name, which will be used in the D-Bus + * serialization of objects of @setting_class, but which does not correspond to + * a #GObject property. + * + * When serializing a setting to D-Bus, @synth_func will be called to synthesize + * a value for the property. (If it returns %NULL, no value will be added to the + * serialization. If @synth_func is %NULL, the property will always be omitted + * in the serialization.) + * + * When deserializing a D-Bus representation into a setting, if @property_name + * is present, then @set_func will be called to set it. (If @set_func is %NULL + * then the property will be ignored when deserializing.) + */ +void +_nm_setting_class_add_dbus_only_property (NMSettingClass *setting_class, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertySynthFunc synth_func, + NMSettingPropertySetFunc set_func) +{ + g_return_if_fail (NM_IS_SETTING_CLASS (setting_class)); + g_return_if_fail (property_name != NULL); + + /* Must not match any GObject property. */ + g_return_if_fail (!g_object_class_find_property (G_OBJECT_CLASS (setting_class), property_name)); + + add_property_override (setting_class, + property_name, NULL, dbus_type, + NULL, synth_func, set_func, NULL, + NULL, NULL); +} + +/** + * _nm_setting_class_override_property: + * @setting_class: the setting class + * @property_name: the name of the property to override + * @dbus_type: the type of the property (in its D-Bus representation) + * @get_func: (allow-none): function to call to get the value of the property + * @set_func: (allow-none): function to call to set the value of the property + * @not_set_func: (allow-none): function to call to indicate the property was not set + * + * Overrides the D-Bus representation of the #GObject property named + * @property_name on @setting_class. + * + * When serializing a setting to D-Bus, if @get_func is non-%NULL, then it will + * be called to get the property's value. If it returns a #GVariant, the + * property will be added to the hash, and if it returns %NULL, the property + * will be omitted. (If @get_func is %NULL, the property will be read normally + * with g_object_get_property(), and added to the hash if it is not the default + * value.) + * + * When deserializing a D-Bus representation into a setting, if @property_name + * is present, then @set_func will be called to set it. (If @set_func is %NULL + * then the property will be set normally with g_object_set_property().) + * + * If @not_set_func is non-%NULL, then it will be called when deserializing a + * representation that does NOT contain @property_name. This can be used, eg, if + * a new property needs to be initialized from some older deprecated property + * when it is not present. + */ +void +_nm_setting_class_override_property (NMSettingClass *setting_class, + const char *property_name, + const GVariantType *dbus_type, + NMSettingPropertyGetFunc get_func, + NMSettingPropertySetFunc set_func, + NMSettingPropertyNotSetFunc not_set_func) +{ + GParamSpec *param_spec; + + param_spec = g_object_class_find_property (G_OBJECT_CLASS (setting_class), property_name); + g_return_if_fail (param_spec != NULL); + + add_property_override (setting_class, + property_name, param_spec, dbus_type, + get_func, NULL, set_func, not_set_func, + NULL, NULL); +} + +/** + * _nm_setting_class_transform_property: + * @setting_class: the setting class + * @property: the name of the property to transform + * @dbus_type: the type of the property (in its D-Bus representation) + * @to_dbus: function to convert from object to D-Bus format + * @from_dbus: function to convert from D-Bus to object format + * + * Indicates that @property on @setting_class does not have the same format as + * its corresponding D-Bus representation, and so must be transformed when + * serializing/deserializing. + * + * The transformation will also be used by nm_setting_compare(), meaning that + * the underlying object property does not need to be of a type that + * nm_property_compare() recognizes, as long as it recognizes @dbus_type. + */ +void +_nm_setting_class_transform_property (NMSettingClass *setting_class, + const char *property, + const GVariantType *dbus_type, + NMSettingPropertyTransformToFunc to_dbus, + NMSettingPropertyTransformFromFunc from_dbus) +{ + GParamSpec *param_spec; + + param_spec = g_object_class_find_property (G_OBJECT_CLASS (setting_class), property); + g_return_if_fail (param_spec != NULL); + + add_property_override (setting_class, + property, param_spec, dbus_type, + NULL, NULL, NULL, NULL, + to_dbus, from_dbus); +} + +gboolean +_nm_setting_use_legacy_property (NMSetting *setting, + GVariant *connection_dict, + const char *legacy_property, + const char *new_property) +{ + GVariant *setting_dict, *value; + + setting_dict = g_variant_lookup_value (connection_dict, nm_setting_get_name (NM_SETTING (setting)), NM_VARIANT_TYPE_SETTING); + g_return_val_if_fail (setting_dict != NULL, FALSE); + + /* If the new property isn't set, we have to use the legacy property. */ + value = g_variant_lookup_value (setting_dict, new_property, NULL); + if (!value) { + g_variant_unref (setting_dict); + return TRUE; + } + g_variant_unref (value); + + /* Otherwise, clients always prefer new properties sent from the daemon. */ + if (!_nm_utils_is_manager_process) { + g_variant_unref (setting_dict); + return FALSE; + } + + /* The daemon prefers the legacy property if it exists. */ + value = g_variant_lookup_value (setting_dict, legacy_property, NULL); + g_variant_unref (setting_dict); + + if (value) { + g_variant_unref (value); + return TRUE; + } else + return FALSE; +} + +static GArray * +nm_setting_class_ensure_properties (NMSettingClass *setting_class) +{ + GType type = G_TYPE_FROM_CLASS (setting_class), otype; + NMSettingProperty property, *override; + GArray *overrides, *type_overrides, *properties; + GParamSpec **property_specs; + guint n_property_specs, i; + + properties = g_type_get_qdata (type, setting_properties_quark); + if (properties) + return properties; + + /* Build overrides array from @setting_class and its superclasses */ + overrides = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); + for (otype = type; otype != G_TYPE_OBJECT; otype = g_type_parent (otype)) { + type_overrides = g_type_get_qdata (otype, setting_property_overrides_quark); + if (type_overrides) + g_array_append_vals (overrides, (NMSettingProperty *)type_overrides->data, type_overrides->len); + } + + /* Build the properties array from the GParamSpecs, obeying overrides */ + properties = g_array_new (FALSE, FALSE, sizeof (NMSettingProperty)); + + property_specs = g_object_class_list_properties (G_OBJECT_CLASS (setting_class), + &n_property_specs); + for (i = 0; i < n_property_specs; i++) { + override = find_property (overrides, property_specs[i]->name); + if (override) + property = *override; + else { + memset (&property, 0, sizeof (property)); + property.name = property_specs[i]->name; + property.param_spec = property_specs[i]; + } + g_array_append_val (properties, property); + } + g_free (property_specs); + + /* Add any remaining overrides not corresponding to GObject properties */ + for (i = 0; i < overrides->len; i++) { + override = &g_array_index (overrides, NMSettingProperty, i); + if (!g_object_class_find_property (G_OBJECT_CLASS (setting_class), override->name)) + g_array_append_val (properties, *override); + } + g_array_unref (overrides); + + g_type_set_qdata (type, setting_properties_quark, properties); + return properties; +} + +static const NMSettingProperty * +nm_setting_class_get_properties (NMSettingClass *setting_class, guint *n_properties) +{ + GArray *properties; + + properties = nm_setting_class_ensure_properties (setting_class); + + *n_properties = properties->len; + return (NMSettingProperty *) properties->data; +} + +static const NMSettingProperty * +nm_setting_class_find_property (NMSettingClass *setting_class, const char *property_name) +{ + GArray *properties; + + properties = nm_setting_class_ensure_properties (setting_class); + return find_property (properties, property_name); +} + +/*************************************************************/ + +static const GVariantType * +variant_type_for_gtype (GType type) +{ + if (type == G_TYPE_BOOLEAN) + return G_VARIANT_TYPE_BOOLEAN; + else if (type == G_TYPE_UCHAR) + return G_VARIANT_TYPE_BYTE; + else if (type == G_TYPE_INT) + return G_VARIANT_TYPE_INT32; + else if (type == G_TYPE_UINT) + return G_VARIANT_TYPE_UINT32; + else if (type == G_TYPE_INT64) + return G_VARIANT_TYPE_INT64; + else if (type == G_TYPE_UINT64) + return G_VARIANT_TYPE_UINT64; + else if (type == G_TYPE_STRING) + return G_VARIANT_TYPE_STRING; + else if (type == G_TYPE_DOUBLE) + return G_VARIANT_TYPE_DOUBLE; + else if (type == G_TYPE_STRV) + return G_VARIANT_TYPE_STRING_ARRAY; + else if (type == G_TYPE_BYTES) + return G_VARIANT_TYPE_BYTESTRING; + else if (g_type_is_a (type, G_TYPE_ENUM)) + return G_VARIANT_TYPE_INT32; + else if (g_type_is_a (type, G_TYPE_FLAGS)) + return G_VARIANT_TYPE_UINT32; + else + g_assert_not_reached (); +} + +static GVariant * +get_property_for_dbus (NMSetting *setting, + const NMSettingProperty *property, + gboolean ignore_default) +{ + GValue prop_value = { 0, }; + GVariant *dbus_value; + + if (property->get_func) + return property->get_func (setting, property->name); + else + g_return_val_if_fail (property->param_spec != NULL, NULL); + + g_value_init (&prop_value, property->param_spec->value_type); + g_object_get_property (G_OBJECT (setting), property->param_spec->name, &prop_value); + + if (ignore_default && g_param_value_defaults (property->param_spec, &prop_value)) { + g_value_unset (&prop_value); + return NULL; + } + + if (property->to_dbus) + dbus_value = property->to_dbus (&prop_value); + else if (property->dbus_type) + dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, property->dbus_type); + else if (g_type_is_a (prop_value.g_type, G_TYPE_ENUM)) + dbus_value = g_variant_new_int32 (g_value_get_enum (&prop_value)); + else if (g_type_is_a (prop_value.g_type, G_TYPE_FLAGS)) + dbus_value = g_variant_new_uint32 (g_value_get_flags (&prop_value)); + else if (prop_value.g_type == G_TYPE_BYTES) + dbus_value = _nm_utils_bytes_to_dbus (&prop_value); + else + dbus_value = g_dbus_gvalue_to_gvariant (&prop_value, variant_type_for_gtype (prop_value.g_type)); + g_value_unset (&prop_value); + + return dbus_value; +} + +static void +set_property_from_dbus (const NMSettingProperty *property, GVariant *src_value, GValue *dst_value) +{ + g_return_if_fail (property->param_spec != NULL); + + if (property->from_dbus) + property->from_dbus (src_value, dst_value); + else if (dst_value->g_type == G_TYPE_BYTES) + _nm_utils_bytes_from_dbus (src_value, dst_value); + else + g_dbus_gvariant_to_gvalue (src_value, dst_value); +} + + +/** + * _nm_setting_to_dbus: + * @setting: the #NMSetting + * @connection: the #NMConnection containing @setting + * @flags: hash flags, e.g. %NM_CONNECTION_SERIALIZE_ALL + * + * Converts the #NMSetting into a #GVariant of type #NM_VARIANT_TYPE_SETTING + * mapping each setting property name to a value describing that property, + * suitable for marshalling over D-Bus or serializing. + * + * Returns: (transfer none): a new floating #GVariant describing the setting's + * properties + **/ +GVariant * +_nm_setting_to_dbus (NMSetting *setting, NMConnection *connection, NMConnectionSerializationFlags flags) +{ + GVariantBuilder builder; + GVariant *dbus_value; + const NMSettingProperty *properties; + guint n_properties, i; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + properties = nm_setting_class_get_properties (NM_SETTING_GET_CLASS (setting), &n_properties); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + + for (i = 0; i < n_properties; i++) { + const NMSettingProperty *property = &properties[i]; + GParamSpec *prop_spec = property->param_spec; + + if (!prop_spec && !property->synth_func) { + /* D-Bus-only property with no synth_func, so we skip it. */ + continue; + } + + if (prop_spec && !(prop_spec->flags & G_PARAM_WRITABLE)) + continue; + + if ( prop_spec && (prop_spec->flags & NM_SETTING_PARAM_LEGACY) + && !_nm_utils_is_manager_process) + continue; + + if ( (flags & NM_CONNECTION_SERIALIZE_NO_SECRETS) + && (prop_spec && (prop_spec->flags & NM_SETTING_PARAM_SECRET))) + continue; + + if ( (flags & NM_CONNECTION_SERIALIZE_ONLY_SECRETS) + && !(prop_spec && (prop_spec->flags & NM_SETTING_PARAM_SECRET))) + continue; + + if (property->synth_func) + dbus_value = property->synth_func (setting, connection, property->name); + else + dbus_value = get_property_for_dbus (setting, property, TRUE); + if (dbus_value) { + /* Allow dbus_value to be either floating or not. */ + g_variant_take_ref (dbus_value); + + g_variant_builder_add (&builder, "{sv}", property->name, dbus_value); + g_variant_unref (dbus_value); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * _nm_setting_new_from_dbus: + * @setting_type: the #NMSetting type which the hash contains properties for + * @setting_dict: the #GVariant containing an %NM_VARIANT_TYPE_SETTING dictionary + * mapping property names to values + * @connection_dict: the #GVariant containing an %NM_VARIANT_TYPE_CONNECTION + * dictionary mapping setting names to dictionaries. + * @error: location to store error, or %NULL + * + * Creates a new #NMSetting object and populates that object with the properties + * contained in @setting_dict, using each key as the property to set, and each + * value as the value to set that property to. Setting properties are strongly + * typed, thus the #GVariantType of the dict value must be correct. See the + * documentation on each #NMSetting object subclass for the correct property + * names and value types. + * + * Returns: a new #NMSetting object populated with the properties from the + * hash table, or %NULL if @setting_hash could not be deserialized. + **/ +NMSetting * +_nm_setting_new_from_dbus (GType setting_type, + GVariant *setting_dict, + GVariant *connection_dict, + GError **error) +{ + NMSettingClass *class; + NMSetting *setting; + const NMSettingProperty *properties; + guint n_properties; + guint i; + + g_return_val_if_fail (G_TYPE_IS_INSTANTIATABLE (setting_type), NULL); + g_return_val_if_fail (g_variant_is_of_type (setting_dict, NM_VARIANT_TYPE_SETTING), NULL); + + /* connection_dict is not technically optional, but some tests in test-general + * don't bother with it in cases where they know it's not needed. + */ + if (connection_dict) + g_return_val_if_fail (g_variant_is_of_type (connection_dict, NM_VARIANT_TYPE_CONNECTION), NULL); + + /* g_type_class_ref() ensures the setting class is created if it hasn't + * already been used. + */ + class = g_type_class_ref (setting_type); + + /* Build the setting object from the properties we know about; we assume + * that any propreties in @setting_dict that we don't know about can + * either be ignored or else has a backward-compatibility equivalent + * that we do know about. + */ + setting = (NMSetting *) g_object_new (setting_type, NULL); + + properties = nm_setting_class_get_properties (class, &n_properties); + for (i = 0; i < n_properties; i++) { + const NMSettingProperty *property = &properties[i]; + GVariant *value = g_variant_lookup_value (setting_dict, property->name, NULL); + + if (value && property->set_func) { + property->set_func (setting, + connection_dict, + property->name, + value); + } else if (!value && property->not_set_func) { + property->not_set_func (setting, + connection_dict, + property->name); + } else if (value && property->param_spec) { + GValue object_value = { 0, }; + + if (!(property->param_spec->flags & G_PARAM_WRITABLE)) + continue; + + g_value_init (&object_value, property->param_spec->value_type); + set_property_from_dbus (property, value, &object_value); + g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value); + g_value_unset (&object_value); + } + + if (value) + g_variant_unref (value); + } + + g_type_class_unref (class); + + return setting; +} + +/** + * nm_setting_get_dbus_property_type: + * @setting: an #NMSetting + * @property_name: the property of @setting to get the type of + * + * Gets the D-Bus marshalling type of a property. @property_name is a D-Bus + * property name, which may not necessarily be a #GObject property. + * + * Returns: the D-Bus marshalling type of @property on @setting. + */ +const GVariantType * +nm_setting_get_dbus_property_type (NMSetting *setting, + const char *property_name) +{ + const NMSettingProperty *property; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + + property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), property_name); + g_return_val_if_fail (property != NULL, NULL); + + if (property->dbus_type) + return property->dbus_type; + else + return variant_type_for_gtype (property->param_spec->value_type); +} + +gboolean +_nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value) +{ + GParamSpec *prop_spec; + + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (property_name, FALSE); + g_return_val_if_fail (value, FALSE); + + prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); + + if (!prop_spec) { + g_value_unset (value); + return FALSE; + } + + g_value_init (value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), property_name, value); + return TRUE; +} + +static void +duplicate_setting (NMSetting *setting, + const char *name, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + if ((flags & (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)) == G_PARAM_WRITABLE) + g_object_set_property (G_OBJECT (user_data), name, value); +} + +/** + * nm_setting_duplicate: + * @setting: the #NMSetting to duplicate + * + * Duplicates a #NMSetting. + * + * Returns: (transfer full): a new #NMSetting containing the same properties and values as the + * source #NMSetting + **/ +NMSetting * +nm_setting_duplicate (NMSetting *setting) +{ + GObject *dup; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + dup = g_object_new (G_OBJECT_TYPE (setting), NULL); + + g_object_freeze_notify (dup); + nm_setting_enumerate_values (setting, duplicate_setting, dup); + g_object_thaw_notify (dup); + + return NM_SETTING (dup); +} + +/** + * nm_setting_get_name: + * @setting: the #NMSetting + * + * Returns the type name of the #NMSetting object + * + * Returns: a string containing the type name of the #NMSetting object, + * like 'ppp' or 'wireless' or 'wired'. + **/ +const char * +nm_setting_get_name (NMSetting *setting) +{ + NMSettingPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + priv = NM_SETTING_GET_PRIVATE (setting); + _ensure_setting_info (setting, priv); + return priv->info->name; +} + +/** + * nm_setting_verify: + * @setting: the #NMSetting to verify + * @connection: (allow-none): the #NMConnection that @setting came from, or + * %NULL if @setting is being verified in isolation. + * @error: location to store error, or %NULL + * + * Validates the setting. Each setting's properties have allowed values, and + * some are dependent on other values (hence the need for @connection). The + * returned #GError contains information about which property of the setting + * failed validation, and in what way that property failed validation. + * + * Returns: %TRUE if the setting is valid, %FALSE if it is not + **/ +gboolean +nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVerifyResult result = _nm_setting_verify (setting, connection, error); + + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error (error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +NMSettingVerifyResult +_nm_setting_verify (NMSetting *setting, NMConnection *connection, GError **error) +{ + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!error || *error == NULL, NM_SETTING_VERIFY_ERROR); + + if (NM_SETTING_GET_CLASS (setting)->verify) + return NM_SETTING_GET_CLASS (setting)->verify (setting, connection, error); + + return NM_SETTING_VERIFY_SUCCESS; +} + +static gboolean +compare_property (NMSetting *setting, + NMSetting *other, + const GParamSpec *prop_spec, + NMSettingCompareFlags flags) +{ + const NMSettingProperty *property; + GVariant *value1, *value2; + int cmp; + + /* Handle compare flags */ + if (prop_spec->flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE); + + if (!nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL)) + g_return_val_if_reached (FALSE); + if (!nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL)) + g_return_val_if_reached (FALSE); + + /* If the secret flags aren't the same the settings aren't the same */ + if (a_secret_flags != b_secret_flags) + return FALSE; + + /* Check for various secret flags that might cause us to ignore comparing + * this property. + */ + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) + && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + return TRUE; + + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) + return TRUE; + } + + property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), prop_spec->name); + g_return_val_if_fail (property != NULL, FALSE); + + value1 = get_property_for_dbus (setting, property, FALSE); + value2 = get_property_for_dbus (other, property, FALSE); + + cmp = nm_property_compare (value1, value2); + + g_variant_unref (value1); + g_variant_unref (value2); + + return cmp == 0; +} + +/** + * nm_setting_compare: + * @a: a #NMSetting + * @b: a second #NMSetting to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * + * Compares two #NMSetting objects for similarity, with comparison behavior + * modified by a set of flags. See the documentation for #NMSettingCompareFlags + * for a description of each flag's behavior. + * + * Returns: %TRUE if the comparison succeeds, %FALSE if it does not + **/ +gboolean +nm_setting_compare (NMSetting *a, + NMSetting *b, + NMSettingCompareFlags flags) +{ + GParamSpec **property_specs; + guint n_property_specs; + gint same = TRUE; + guint i; + + g_return_val_if_fail (NM_IS_SETTING (a), FALSE); + g_return_val_if_fail (NM_IS_SETTING (b), FALSE); + + /* First check that both have the same type */ + if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) + return FALSE; + + /* And now all properties */ + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs); + for (i = 0; i < n_property_specs && same; i++) { + GParamSpec *prop_spec = property_specs[i]; + + /* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */ + if ( (flags & NM_SETTING_COMPARE_FLAG_FUZZY) + && (prop_spec->flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))) + continue; + + if ((flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_spec->flags & NM_SETTING_PARAM_INFERRABLE)) + continue; + + if ( (flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) + && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; + + same = NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); + } + g_free (property_specs); + + return same; +} + +static inline gboolean +should_compare_prop (NMSetting *setting, + const char *prop_name, + NMSettingCompareFlags comp_flags, + GParamFlags prop_flags) +{ + /* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */ + if ( (comp_flags & NM_SETTING_COMPARE_FLAG_FUZZY) + && (prop_flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))) + return FALSE; + + if ((comp_flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_flags & NM_SETTING_PARAM_INFERRABLE)) + return FALSE; + + if (prop_flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) + return FALSE; + + if ( NM_IS_SETTING_VPN (setting) + && g_strcmp0 (prop_name, NM_SETTING_VPN_SECRETS) == 0) { + /* FIXME: NMSettingVPN:NM_SETTING_VPN_SECRETS has NM_SETTING_PARAM_SECRET. + * nm_setting_get_secret_flags() quite possibly fails, but it might succeed if the + * setting accidently uses a key "secrets". */ + return TRUE; + } + + if (!nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL)) + g_return_val_if_reached (FALSE); + + if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) + && (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) + return FALSE; + + if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS) + && (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)) + return FALSE; + } + + if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID) + && NM_IS_SETTING_CONNECTION (setting) + && !strcmp (prop_name, NM_SETTING_CONNECTION_ID)) + return FALSE; + + if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP) + && NM_IS_SETTING_CONNECTION (setting) + && !strcmp (prop_name, NM_SETTING_CONNECTION_TIMESTAMP)) + return FALSE; + + return TRUE; +} + +/** + * nm_setting_diff: + * @a: a #NMSetting + * @b: a second #NMSetting to compare with the first + * @flags: compare flags, e.g. %NM_SETTING_COMPARE_FLAG_EXACT + * @invert_results: this parameter is used internally by libnm and should + * be set to %FALSE. If %TRUE inverts the meaning of the #NMSettingDiffResult. + * @results: (inout) (transfer full) (element-type utf8 guint32): if the + * settings differ, on return a hash table mapping the differing keys to one or + * more %NMSettingDiffResult values OR-ed together. If the settings do not + * differ, any hash table passed in is unmodified. If no hash table is passed + * in and the settings differ, a new one is created and returned. + * + * Compares two #NMSetting objects for similarity, with comparison behavior + * modified by a set of flags. See the documentation for #NMSettingCompareFlags + * for a description of each flag's behavior. If the settings differ, the keys + * of each setting that differ from the other are added to @results, mapped to + * one or more #NMSettingDiffResult values. + * + * Returns: %TRUE if the settings contain the same values, %FALSE if they do not + **/ +gboolean +nm_setting_diff (NMSetting *a, + NMSetting *b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable **results) +{ + GParamSpec **property_specs; + guint n_property_specs; + guint i; + NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A; + NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B; + NMSettingDiffResult a_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; + NMSettingDiffResult b_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; + gboolean results_created = FALSE; + + g_return_val_if_fail (results != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (a), FALSE); + if (b) { + g_return_val_if_fail (NM_IS_SETTING (b), FALSE); + g_return_val_if_fail (G_OBJECT_TYPE (a) == G_OBJECT_TYPE (b), FALSE); + } + + if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == + (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) { + /* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */ + flags &= ~NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT; + } + + /* If the caller is calling this function in a pattern like this to get + * complete diffs: + * + * nm_setting_diff (A, B, FALSE, &results); + * nm_setting_diff (B, A, TRUE, &results); + * + * and wants us to invert the results so that the second invocation comes + * out correctly, do that here. + */ + if (invert_results) { + a_result = NM_SETTING_DIFF_RESULT_IN_B; + b_result = NM_SETTING_DIFF_RESULT_IN_A; + a_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; + b_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; + } + + if (*results == NULL) { + *results = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + results_created = TRUE; + } + + /* And now all properties */ + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; + + /* Handle compare flags */ + if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags)) + continue; + if (strcmp (prop_spec->name, NM_SETTING_NAME) == 0) + continue; + + if (b) { + gboolean different; + + different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); + if (different) { + gboolean a_is_default, b_is_default; + GValue value = G_VALUE_INIT; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (a), prop_spec->name, &value); + a_is_default = g_param_value_defaults (prop_spec, &value); + + g_value_reset (&value); + g_object_get_property (G_OBJECT (b), prop_spec->name, &value); + b_is_default = g_param_value_defaults (prop_spec, &value); + + g_value_unset (&value); + if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) { + if (!a_is_default) + r |= a_result; + if (!b_is_default) + r |= b_result; + } else { + r |= a_result | b_result; + if (a_is_default) + r |= a_result_default; + if (b_is_default) + r |= b_result_default; + } + } + } else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0) + r = a_result; /* only in A */ + else { + GValue value = G_VALUE_INIT; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (a), prop_spec->name, &value); + if (!g_param_value_defaults (prop_spec, &value)) + r |= a_result; + else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) + r |= a_result | a_result_default; + + g_value_unset (&value); + } + + if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) { + void *p; + + if (g_hash_table_lookup_extended (*results, prop_spec->name, NULL, &p)) { + if ((r & GPOINTER_TO_UINT (p)) != r) + g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r | GPOINTER_TO_UINT (p))); + } else + g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r)); + } + } + g_free (property_specs); + + /* Don't return an empty hash table */ + if (results_created && !g_hash_table_size (*results)) { + g_hash_table_destroy (*results); + *results = NULL; + } + + return !(*results); +} + +/** + * nm_setting_enumerate_values: + * @setting: the #NMSetting + * @func: (scope call): user-supplied function called for each property of the setting + * @user_data: user data passed to @func at each invocation + * + * Iterates over each property of the #NMSetting object, calling the supplied + * user function for each property. + **/ +void +nm_setting_enumerate_values (NMSetting *setting, + NMSettingValueIterFn func, + gpointer user_data) +{ + GParamSpec **property_specs; + guint n_property_specs; + int i; + + g_return_if_fail (NM_IS_SETTING (setting)); + g_return_if_fail (func != NULL); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = G_VALUE_INIT; + + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (prop_spec)); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + func (setting, prop_spec->name, &value, prop_spec->flags, user_data); + g_value_unset (&value); + } + + g_free (property_specs); +} + +/** + * _nm_setting_clear_secrets: + * @setting: the #NMSetting + * + * Resets and clears any secrets in the setting. Secrets should be added to the + * setting only when needed, and cleared immediately after use to prevent + * leakage of information. + * + * Returns: %TRUE if the setting changed at all + **/ +gboolean +_nm_setting_clear_secrets (NMSetting *setting) +{ + GParamSpec **property_specs; + guint n_property_specs; + guint i; + gboolean changed = FALSE; + + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + + if (prop_spec->flags & NM_SETTING_PARAM_SECRET) { + GValue value = G_VALUE_INIT; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + if (!g_param_value_defaults (prop_spec, &value)) { + g_param_value_set_default (prop_spec, &value); + g_object_set_property (G_OBJECT (setting), prop_spec->name, &value); + changed = TRUE; + } + g_value_unset (&value); + } + } + + g_free (property_specs); + + return changed; +} + +static gboolean +clear_secrets_with_flags (NMSetting *setting, + GParamSpec *pspec, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + gboolean changed = FALSE; + + g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE); + + /* Clear the secret if the user function says to do so */ + if (!nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL)) + g_return_val_if_reached (FALSE); + + if (func (setting, pspec->name, flags, user_data) == TRUE) { + GValue value = G_VALUE_INIT; + + g_value_init (&value, pspec->value_type); + g_object_get_property (G_OBJECT (setting), pspec->name, &value); + if (!g_param_value_defaults (pspec, &value)) { + g_param_value_set_default (pspec, &value); + g_object_set_property (G_OBJECT (setting), pspec->name, &value); + changed = TRUE; + } + g_value_unset (&value); + } + + return changed; +} + +/** + * _nm_setting_clear_secrets_with_flags: + * @setting: the #NMSetting + * @func: (scope call): function to be called to determine whether a + * specific secret should be cleared or not + * @user_data: caller-supplied data passed to @func + * + * Clears and frees secrets determined by @func. + * + * Returns: %TRUE if the setting changed at all + **/ +gboolean +_nm_setting_clear_secrets_with_flags (NMSetting *setting, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) +{ + GParamSpec **property_specs; + guint n_property_specs; + guint i; + gboolean changed = FALSE; + + g_return_val_if_fail (setting, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (func != NULL, FALSE); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + for (i = 0; i < n_property_specs; i++) { + if (property_specs[i]->flags & NM_SETTING_PARAM_SECRET) { + changed |= NM_SETTING_GET_CLASS (setting)->clear_secrets_with_flags (setting, + property_specs[i], + func, + user_data); + } + } + + g_free (property_specs); + return changed; +} + +/** + * _nm_setting_need_secrets: + * @setting: the #NMSetting + * + * Returns an array of property names for each secret which may be required + * to make a successful connection. The returned hints are only intended as a + * guide to what secrets may be required, because in some circumstances, there + * is no way to conclusively determine exactly which secrets are needed. + * + * Returns: (transfer container) (element-type utf8): a #GPtrArray containing + * the property names of secrets of the #NMSetting which may be required; the + * caller owns the array and must free it with g_ptr_array_free(), but must not + * free the elements. + **/ +GPtrArray * +_nm_setting_need_secrets (NMSetting *setting) +{ + GPtrArray *secrets = NULL; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + if (NM_SETTING_GET_CLASS (setting)->need_secrets) + secrets = NM_SETTING_GET_CLASS (setting)->need_secrets (setting); + + return secrets; +} + +static int +update_one_secret (NMSetting *setting, const char *key, GVariant *value, GError **error) +{ + const NMSettingProperty *property; + GParamSpec *prop_spec; + GValue prop_value = { 0, }; + + property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), key); + if (!property) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, + _("secret not found")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), key); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + /* Silently ignore non-secrets */ + prop_spec = property->param_spec; + if (!prop_spec || !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + if ( g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) + && G_IS_PARAM_SPEC_STRING (prop_spec)) { + /* String is expected to be a common case. Handle it specially and check + * whether the value is already set. Otherwise, we just reset the + * property and assume the value got modified. + */ + char *v; + + g_object_get (G_OBJECT (setting), prop_spec->name, &v, NULL); + if (g_strcmp0 (v, g_variant_get_string (value, NULL)) == 0) { + g_free (v); + return NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + } + g_free (v); + } + + g_value_init (&prop_value, prop_spec->value_type); + set_property_from_dbus (property, value, &prop_value); + g_object_set_property (G_OBJECT (setting), prop_spec->name, &prop_value); + g_value_unset (&prop_value); + + return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; +} + +/** + * _nm_setting_update_secrets: + * @setting: the #NMSetting + * @secrets: a #GVariant of type #NM_VARIANT_TYPE_SETTING, mapping property + * names to secrets. + * @error: location to store error, or %NULL + * + * Update the setting's secrets, given a dictionary of secrets intended for that + * setting (deserialized from D-Bus for example). + * + * Returns: an #NMSettingUpdateSecretResult + **/ +NMSettingUpdateSecretResult +_nm_setting_update_secrets (NMSetting *setting, GVariant *secrets, GError **error) +{ + GVariantIter iter; + const char *secret_key; + GVariant *secret_value; + GError *tmp_error = NULL; + NMSettingUpdateSecretResult result = NM_SETTING_UPDATE_SECRET_SUCCESS_UNCHANGED; + + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_UPDATE_SECRET_ERROR); + g_return_val_if_fail (g_variant_is_of_type (secrets, NM_VARIANT_TYPE_SETTING), NM_SETTING_UPDATE_SECRET_ERROR); + if (error) + g_return_val_if_fail (*error == NULL, NM_SETTING_UPDATE_SECRET_ERROR); + + g_variant_iter_init (&iter, secrets); + while (g_variant_iter_next (&iter, "{&sv}", &secret_key, &secret_value)) { + int success; + + success = NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error); + g_assert (!((success == NM_SETTING_UPDATE_SECRET_ERROR) ^ (!!tmp_error))); + + g_variant_unref (secret_value); + + if (success == NM_SETTING_UPDATE_SECRET_ERROR) { + g_propagate_error (error, tmp_error); + return NM_SETTING_UPDATE_SECRET_ERROR; + } + + if (success == NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED) + result = NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; + } + + return result; +} + +static gboolean +is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) +{ + const NMSettingProperty *property; + GParamSpec *pspec; + + property = nm_setting_class_find_property (NM_SETTING_GET_CLASS (setting), secret_name); + if (!property) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_FOUND, + _("secret is not set")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), secret_name); + return FALSE; + } + + pspec = property->param_spec; + if (!pspec || !(pspec->flags & NM_SETTING_PARAM_SECRET)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_PROPERTY_NOT_SECRET, + _("not a secret property")); + g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), secret_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + char *flags_prop; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + if (verify_secret && !is_secret_prop (setting, secret_name, error)) { + if (out_flags) + *out_flags = NM_SETTING_SECRET_FLAG_NONE; + return FALSE; + } + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL); + g_free (flags_prop); + + if (out_flags) + *out_flags = flags; + return TRUE; +} + +/** + * nm_setting_get_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to get flags for + * @out_flags: on success, the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: %TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), %FALSE if not + **/ +gboolean +nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error) +{ + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->get_secret_flags (setting, secret_name, TRUE, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + char *flags_prop; + + if (verify_secret) + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_set (G_OBJECT (setting), flags_prop, flags, NULL); + g_free (flags_prop); + return TRUE; +} + +/** + * nm_setting_set_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to set flags for + * @flags: the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, stores the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: %TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), %FALSE if not + **/ +gboolean +nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error) +{ + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (flags <= NM_SETTING_SECRET_FLAGS_ALL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, TRUE, flags, error); +} + +/** + * nm_setting_to_string: + * @setting: the #NMSetting + * + * Convert the setting into a string. For debugging purposes ONLY, should NOT + * be used for serialization of the setting, or machine-parsed in any way. The + * output format is not guaranteed to be stable and may change at any time. + * + * Returns: an allocated string containing a textual representation of the + * setting's properties and values (including secrets!), which the caller should + * free with g_free() + **/ +char * +nm_setting_to_string (NMSetting *setting) +{ + GString *string; + GParamSpec **property_specs; + guint n_property_specs; + guint i; + + g_return_val_if_fail (NM_IS_SETTING (setting), NULL); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + + string = g_string_new (nm_setting_get_name (setting)); + g_string_append_c (string, '\n'); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = G_VALUE_INIT; + char *value_str; + gboolean is_default; + + if (strcmp (prop_spec->name, NM_SETTING_NAME) == 0) + continue; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + + value_str = g_strdup_value_contents (&value); + g_string_append_printf (string, "\t%s : %s", prop_spec->name, value_str); + g_free (value_str); + + is_default = g_param_value_defaults (prop_spec, &value); + g_value_unset (&value); + + g_string_append (string, " ("); + g_string_append_c (string, 's'); + if (is_default) + g_string_append_c (string, 'd'); + g_string_append_c (string, ')'); + g_string_append_c (string, '\n'); + } + + g_free (property_specs); + g_string_append_c (string, '\n'); + + return g_string_free (string, FALSE); +} + +GVariant * +_nm_setting_get_deprecated_virtual_interface_name (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_return_val_if_fail (s_con != NULL, NULL); + + if (nm_setting_connection_get_interface_name (s_con)) + return g_variant_new_string (nm_setting_connection_get_interface_name (s_con)); + else + return NULL; +} + +/*****************************************************************************/ + +static void +nm_setting_init (NMSetting *setting) +{ +} + +static void +constructed (GObject *object) +{ + _ensure_setting_info (object, NM_SETTING_GET_PRIVATE (object)); + + G_OBJECT_CLASS (nm_setting_parent_class)->constructed (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSetting *setting = NM_SETTING (object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, nm_setting_get_name (setting)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_class_init (NMSettingClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + + if (!setting_property_overrides_quark) + setting_property_overrides_quark = g_quark_from_static_string ("nm-setting-property-overrides"); + if (!setting_properties_quark) + setting_properties_quark = g_quark_from_static_string ("nm-setting-properties"); + + g_type_class_add_private (setting_class, sizeof (NMSettingPrivate)); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + + setting_class->update_one_secret = update_one_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; + setting_class->compare_property = compare_property; + setting_class->clear_secrets_with_flags = clear_secrets_with_flags; + + /* Properties */ + + /** + * NMSetting:name: + * + * The setting's name, which uniquely identifies the setting within the + * connection. Each setting type has a name unique to that type, for + * example "ppp" or "wireless" or "wired". + **/ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_SETTING_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm-core/nm-setting.h b/libnm-core/nm-setting.h new file mode 100644 index 00000000..3601fce3 --- /dev/null +++ b/libnm-core/nm-setting.h @@ -0,0 +1,282 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#ifndef __NM_SETTING_H__ +#define __NM_SETTING_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING (nm_setting_get_type ()) +#define NM_SETTING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING, NMSetting)) +#define NM_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING, NMSettingClass)) +#define NM_IS_SETTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING)) +#define NM_IS_SETTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING)) +#define NM_SETTING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING, NMSettingClass)) + +/* The property of the #NMSetting is required for the setting to be valid */ +#define NM_SETTING_PARAM_REQUIRED (1 << (1 + G_PARAM_USER_SHIFT)) + +/* The property of the #NMSetting is a secret */ +#define NM_SETTING_PARAM_SECRET (1 << (2 + G_PARAM_USER_SHIFT)) + +/* The property of the #NMSetting should be ignored during comparisons that + * use the %NM_SETTING_COMPARE_FLAG_FUZZY flag. + */ +#define NM_SETTING_PARAM_FUZZY_IGNORE (1 << (3 + G_PARAM_USER_SHIFT)) + +/* Note: all non-glib GParamFlags bits are reserved by NetworkManager */ + + +#define NM_SETTING_NAME "name" + +/** + * NMSettingSecretFlags: + * @NM_SETTING_SECRET_FLAG_NONE: the system is responsible for providing and + * storing this secret (default) + * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible + * for providing and storing this secret; when it is required agents will be + * asked to retrieve it + * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but + * should be requested from the user each time it is needed + * @NM_SETTING_SECRET_FLAG_NOT_REQUIRED: in situations where it cannot be + * automatically determined that the secret is required (some VPNs and PPP + * providers dont require all secrets) this flag indicates that the specific + * secret is not required + * + * These flags indicate specific behavior related to handling of a secret. Each + * secret has a corresponding set of these flags which indicate how the secret + * is to be stored and/or requested when it is needed. + * + **/ +typedef enum { /*< flags >*/ + NM_SETTING_SECRET_FLAG_NONE = 0x00000000, + NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 0x00000004 + + /* NOTE: if adding flags, update nm-core-internal.h as well */ +} NMSettingSecretFlags; + +/** + * NMSettingCompareFlags: + * @NM_SETTING_COMPARE_FLAG_EXACT: match all properties exactly + * @NM_SETTING_COMPARE_FLAG_FUZZY: match only important attributes, like SSID, + * type, security settings, etc. Does not match, for example, connection ID + * or UUID. + * @NM_SETTING_COMPARE_FLAG_IGNORE_ID: ignore the connection's ID + * @NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS: ignore all secrets + * @NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS: ignore secrets for which + * the secret's flags indicate the secret is owned by a user secret agent + * (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_AGENT_OWNED) + * @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which + * the secret's flags indicate the secret should not be saved to persistent + * storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED) + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will also include properties that + * are set to their default value. See also @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT. + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will not include properties that + * are set to their default value. This is the opposite of + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. If both flags are set together, + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT wins. If both flags are unset, + * this means to exclude default properties if there is a setting to compare, + * but include all properties, if the setting 'b' is missing. This is the legacy + * behaviour of libnm-util, where nm_setting_diff() behaved differently depending + * on whether the setting 'b' was available. If @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + * is set, nm_setting_diff() will also set the flags @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT + * and @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, if the values are default values. + * @NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP: ignore the connection's timestamp + * + * These flags modify the comparison behavior when comparing two settings or + * two connections. + * + **/ +typedef enum { + NM_SETTING_COMPARE_FLAG_EXACT = 0x00000000, + NM_SETTING_COMPARE_FLAG_FUZZY = 0x00000001, + NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002, + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004, + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008, + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT = 0x00000020, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040, + NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP = 0x00000080, + + /* 0x80000000 is used for a private flag */ +} NMSettingCompareFlags; + + +/** + * NMSetting: + * + * The NMSetting struct contains only private data. + * It should only be accessed through the functions described below. + */ +struct _NMSetting { + GObject parent; +}; + + +/** + * NMSettingClearSecretsWithFlagsFn: + * @setting: The setting for which secrets are being iterated + * @secret: The secret's name + * @flags: The secret's flags, eg %NM_SETTING_SECRET_FLAG_AGENT_OWNED + * @user_data: User data passed to nm_connection_clear_secrets_with_flags() + * + * Returns: %TRUE to clear the secret, %FALSE to not clear the secret + */ +typedef gboolean (*NMSettingClearSecretsWithFlagsFn) (NMSetting *setting, + const char *secret, + NMSettingSecretFlags flags, + gpointer user_data); + +typedef struct { + GObjectClass parent; + + /* Virtual functions */ + gint (*verify) (NMSetting *setting, + NMConnection *connection, + GError **error); + + GPtrArray *(*need_secrets) (NMSetting *setting); + + int (*update_one_secret) (NMSetting *setting, + const char *key, + GVariant *value, + GError **error); + + gboolean (*get_secret_flags) (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error); + + gboolean (*set_secret_flags) (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error); + + gboolean (*clear_secrets_with_flags) (NMSetting *setting, + GParamSpec *pspec, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data); + + /* Returns TRUE if the given property contains the same value in both settings */ + gboolean (*compare_property) (NMSetting *setting, + NMSetting *other, + const GParamSpec *prop_spec, + NMSettingCompareFlags flags); + + /*< private >*/ + gpointer padding[8]; +} NMSettingClass; + +/** + * NMSettingValueIterFn: + * @setting: The setting for which properties are being iterated, given to + * nm_setting_enumerate_values() + * @key: The value/property name + * @value: The property's value + * @flags: The property's flags, like %NM_SETTING_PARAM_SECRET + * @user_data: User data passed to nm_setting_enumerate_values() + */ +typedef void (*NMSettingValueIterFn) (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data); + + +GType nm_setting_get_type (void); + +GType nm_setting_lookup_type (const char *name); + +NMSetting *nm_setting_duplicate (NMSetting *setting); + +const char *nm_setting_get_name (NMSetting *setting); + +gboolean nm_setting_verify (NMSetting *setting, + NMConnection *connection, + GError **error); + +gboolean nm_setting_compare (NMSetting *a, + NMSetting *b, + NMSettingCompareFlags flags); + +/** + * NMSettingDiffResult: + * @NM_SETTING_DIFF_RESULT_UNKNOWN: unknown result + * @NM_SETTING_DIFF_RESULT_IN_A: the property is present in setting A + * @NM_SETTING_DIFF_RESULT_IN_B: the property is present in setting B + * @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT: the property is present in + * setting A but is set to the default value. This flag is only set, + * if you specify @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. + * @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT: analog to @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT. + * + * These values indicate the result of a setting difference operation. + **/ +typedef enum { + NM_SETTING_DIFF_RESULT_UNKNOWN = 0x00000000, + NM_SETTING_DIFF_RESULT_IN_A = 0x00000001, + NM_SETTING_DIFF_RESULT_IN_B = 0x00000002, + NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004, + NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000004, +} NMSettingDiffResult; + +gboolean nm_setting_diff (NMSetting *a, + NMSetting *b, + NMSettingCompareFlags flags, + gboolean invert_results, + GHashTable **results); + +void nm_setting_enumerate_values (NMSetting *setting, + NMSettingValueIterFn func, + gpointer user_data); + +char *nm_setting_to_string (NMSetting *setting); + +/* Secrets */ +gboolean nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error); + +gboolean nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error); + +/* Properties */ +const GVariantType *nm_setting_get_dbus_property_type (NMSetting *setting, + const char *property_name); + +G_END_DECLS + +#endif /* __NM_SETTING_H__ */ diff --git a/libnm-core/nm-simple-connection.c b/libnm-core/nm-simple-connection.c new file mode 100644 index 00000000..c67f6244 --- /dev/null +++ b/libnm-core/nm-simple-connection.c @@ -0,0 +1,123 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-simple-connection.h" +#include "nm-setting-private.h" + +static void nm_simple_connection_interface_init (NMConnectionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMSimpleConnection, nm_simple_connection, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_simple_connection_interface_init); + ) + +static void +nm_simple_connection_init (NMSimpleConnection *self) +{ +} + +/** + * nm_simple_connection_new: + * + * Creates a new #NMSimpleConnection object with no #NMSetting objects. An + * #NMSimpleConnection does not directly represent a D-Bus-exported connection, + * but might be used in the process of creating a new one. + * + * Returns: (transfer full): the new empty #NMConnection object + **/ +NMConnection * +nm_simple_connection_new (void) +{ + return (NMConnection *) g_object_new (NM_TYPE_SIMPLE_CONNECTION, NULL); +} + +/** + * nm_simple_connection_new_from_dbus: + * @dict: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION describing the connection + * @error: on unsuccessful return, an error + * + * Creates a new #NMSimpleConnection from a hash table describing the + * connection. See nm_connection_to_dbus() for a description of the expected + * hash table. + * + * Returns: (transfer full): the new #NMSimpleConnection object, populated with + * settings created from the values in the hash table, or %NULL if the + * connection failed to validate + **/ +NMConnection * +nm_simple_connection_new_from_dbus (GVariant *dict, GError **error) +{ + NMConnection *connection; + + g_return_val_if_fail (dict != NULL, NULL); + g_return_val_if_fail (g_variant_is_of_type (dict, NM_VARIANT_TYPE_CONNECTION), NULL); + + connection = nm_simple_connection_new (); + if ( !nm_connection_replace_settings (connection, dict, error) + || !nm_connection_normalize (connection, NULL, NULL, error)) + g_clear_object (&connection); + return connection; +} + +/** + * nm_simple_connection_new_clone: + * @connection: the #NMConnection to clone + * + * Clones an #NMConnection as an #NMSimpleConnection. + * + * Returns: (transfer full): a new #NMConnection containing the same settings + * and properties as the source #NMConnection + **/ +NMConnection * +nm_simple_connection_new_clone (NMConnection *connection) +{ + NMConnection *clone; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + clone = nm_simple_connection_new (); + nm_connection_set_path (clone, nm_connection_get_path (connection)); + nm_connection_replace_settings_from_connection (clone, connection); + + return clone; +} + +static void +dispose (GObject *object) +{ + nm_connection_clear_secrets (NM_CONNECTION (object)); + + G_OBJECT_CLASS (nm_simple_connection_parent_class)->dispose (object); +} + +static void +nm_simple_connection_class_init (NMSimpleConnectionClass *simple_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (simple_class); + + object_class->dispose = dispose; +} + +static void +nm_simple_connection_interface_init (NMConnectionInterface *iface) +{ +} diff --git a/libnm-core/nm-simple-connection.h b/libnm-core/nm-simple-connection.h new file mode 100644 index 00000000..da6030a8 --- /dev/null +++ b/libnm-core/nm-simple-connection.h @@ -0,0 +1,61 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NM_SIMPLE_CONNECTION_H__ +#define __NM_SIMPLE_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SIMPLE_CONNECTION (nm_simple_connection_get_type ()) +#define NM_SIMPLE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnection)) +#define NM_SIMPLE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnectionClass)) +#define NM_IS_SIMPLE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SIMPLE_CONNECTION)) +#define NM_IS_SIMPLE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SIMPLE_CONNECTION)) +#define NM_SIMPLE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SIMPLE_CONNECTION, NMSimpleConnectionClass)) + +struct _NMSimpleConnection { + GObject parent; +}; + +typedef struct { + GObjectClass parent_class; + + /*< private >*/ + gpointer padding[4]; +} NMSimpleConnectionClass; + +GType nm_simple_connection_get_type (void); + +NMConnection *nm_simple_connection_new (void); + +NMConnection *nm_simple_connection_new_from_dbus (GVariant *dict, + GError **error); + +NMConnection *nm_simple_connection_new_clone (NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_SIMPLE_CONNECTION__ */ diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h new file mode 100644 index 00000000..3854d679 --- /dev/null +++ b/libnm-core/nm-utils-private.h @@ -0,0 +1,51 @@ +/* -*- 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. + * + * Copyright 2005 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_UTILS_PRIVATE_H__ +#define __NM_UTILS_PRIVATE_H__ + +#include "nm-setting-private.h" + +gboolean _nm_utils_string_slist_validate (GSList *list, + const char **valid_values); + +/* D-Bus transform funcs */ + +GVariant * _nm_utils_hwaddr_to_dbus (const GValue *prop_value); +void _nm_utils_hwaddr_from_dbus (GVariant *dbus_value, + GValue *prop_value); + +GVariant * _nm_utils_strdict_to_dbus (const GValue *prop_value); +void _nm_utils_strdict_from_dbus (GVariant *dbus_value, + GValue *prop_value); + +GVariant * _nm_utils_bytes_to_dbus (const GValue *prop_value); +void _nm_utils_bytes_from_dbus (GVariant *dbus_value, + GValue *prop_value); + +GSList * _nm_utils_strv_to_slist (char **strv); +char ** _nm_utils_slist_to_strv (GSList *slist); + +GPtrArray * _nm_utils_strv_to_ptrarray (char **strv); +char ** _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray); + +char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length); + +#endif diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c new file mode 100644 index 00000000..e14775ff --- /dev/null +++ b/libnm-core/nm-utils.c @@ -0,0 +1,3215 @@ +/* -*- 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. + * + * Copyright 2005 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-glib-compat.h" +#include "nm-setting-private.h" +#include "crypto.h" +#include "gsystem-local-alloc.h" +#include "nm-utils-internal.h" + +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-infiniband.h" +#include "nm-setting-ip6-config.h" +#include "nm-setting-team.h" +#include "nm-setting-vlan.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" + +/* Embed the commit id in the build binary */ +static const char *const __nm_git_sha = STRLEN (NM_GIT_SHA) > 0 ? "NM_GIT_SHA:"NM_GIT_SHA : ""; + +/** + * SECTION:nm-utils + * @short_description: Utility functions + * + * A collection of utility functions for working with SSIDs, IP addresses, Wi-Fi + * access points and devices, among other things. + */ + +struct EncodingTriplet +{ + const char *encoding1; + const char *encoding2; + const char *encoding3; +}; + +struct IsoLangToEncodings +{ + const char * lang; + struct EncodingTriplet encodings; +}; + +/* 5-letter language codes */ +static const struct IsoLangToEncodings isoLangEntries5[] = +{ + /* Simplified Chinese */ + { "zh_cn", {"euc-cn", "gb2312", "gb18030"} }, /* PRC */ + { "zh_sg", {"euc-cn", "gb2312", "gb18030"} }, /* Singapore */ + + /* Traditional Chinese */ + { "zh_tw", {"big5", "euc-tw", NULL} }, /* Taiwan */ + { "zh_hk", {"big5", "euc-tw", "big5-hkcs"} },/* Hong Kong */ + { "zh_mo", {"big5", "euc-tw", NULL} }, /* Macau */ + + /* Table end */ + { NULL, {NULL, NULL, NULL} } +}; + +/* 2-letter language codes; we don't care about the other 3 in this table */ +static const struct IsoLangToEncodings isoLangEntries2[] = +{ + /* Japanese */ + { "ja", {"euc-jp", "shift_jis", "iso-2022-jp"} }, + + /* Korean */ + { "ko", {"euc-kr", "iso-2022-kr", "johab"} }, + + /* Thai */ + { "th", {"iso-8859-11","windows-874", NULL} }, + + /* Central European */ + { "hu", {"iso-8859-2", "windows-1250", NULL} }, /* Hungarian */ + { "cs", {"iso-8859-2", "windows-1250", NULL} }, /* Czech */ + { "hr", {"iso-8859-2", "windows-1250", NULL} }, /* Croatian */ + { "pl", {"iso-8859-2", "windows-1250", NULL} }, /* Polish */ + { "ro", {"iso-8859-2", "windows-1250", NULL} }, /* Romanian */ + { "sk", {"iso-8859-2", "windows-1250", NULL} }, /* Slovakian */ + { "sl", {"iso-8859-2", "windows-1250", NULL} }, /* Slovenian */ + { "sh", {"iso-8859-2", "windows-1250", NULL} }, /* Serbo-Croatian */ + + /* Cyrillic */ + { "ru", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Russian */ + { "be", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Belorussian */ + { "bg", {"windows-1251","koi8-r", "iso-8859-5"} }, /* Bulgarian */ + { "mk", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Macedonian */ + { "sr", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Serbian */ + { "uk", {"koi8-u", "koi8-r", "windows-1251"} }, /* Ukranian */ + + /* Arabic */ + { "ar", {"iso-8859-6", "windows-1256", NULL} }, + + /* Baltic */ + { "et", {"iso-8859-4", "windows-1257", NULL} }, /* Estonian */ + { "lt", {"iso-8859-4", "windows-1257", NULL} }, /* Lithuanian */ + { "lv", {"iso-8859-4", "windows-1257", NULL} }, /* Latvian */ + + /* Greek */ + { "el", {"iso-8859-7", "windows-1253", NULL} }, + + /* Hebrew */ + { "he", {"iso-8859-8", "windows-1255", NULL} }, + { "iw", {"iso-8859-8", "windows-1255", NULL} }, + + /* Turkish */ + { "tr", {"iso-8859-9", "windows-1254", NULL} }, + + /* Table end */ + { NULL, {NULL, NULL, NULL} } +}; + + +static GHashTable * langToEncodings5 = NULL; +static GHashTable * langToEncodings2 = NULL; + +static void +init_lang_to_encodings_hash (void) +{ + struct IsoLangToEncodings *enc; + + if (G_UNLIKELY (langToEncodings5 == NULL)) { + /* Five-letter codes */ + enc = (struct IsoLangToEncodings *) &isoLangEntries5[0]; + langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal); + while (enc->lang) { + g_hash_table_insert (langToEncodings5, (gpointer) enc->lang, + (gpointer) &enc->encodings); + enc++; + } + } + + if (G_UNLIKELY (langToEncodings2 == NULL)) { + /* Two-letter codes */ + enc = (struct IsoLangToEncodings *) &isoLangEntries2[0]; + langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal); + while (enc->lang) { + g_hash_table_insert (langToEncodings2, (gpointer) enc->lang, + (gpointer) &enc->encodings); + enc++; + } + } +} + + +static gboolean +get_encodings_for_lang (const char *lang, + char **encoding1, + char **encoding2, + char **encoding3) +{ + struct EncodingTriplet * encodings; + gboolean success = FALSE; + char * tmp_lang; + + g_return_val_if_fail (lang != NULL, FALSE); + g_return_val_if_fail (encoding1 != NULL, FALSE); + g_return_val_if_fail (encoding2 != NULL, FALSE); + g_return_val_if_fail (encoding3 != NULL, FALSE); + + *encoding1 = "iso-8859-1"; + *encoding2 = "windows-1251"; + *encoding3 = NULL; + + init_lang_to_encodings_hash (); + + tmp_lang = g_strdup (lang); + if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang))) { + *encoding1 = (char *) encodings->encoding1; + *encoding2 = (char *) encodings->encoding2; + *encoding3 = (char *) encodings->encoding3; + success = TRUE; + } + + /* Truncate tmp_lang to length of 2 */ + if (strlen (tmp_lang) > 2) + tmp_lang[2] = '\0'; + if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang))) { + *encoding1 = (char *) encodings->encoding1; + *encoding2 = (char *) encodings->encoding2; + *encoding3 = (char *) encodings->encoding3; + success = TRUE; + } + + g_free (tmp_lang); + return success; +} + +/* init libnm */ + +static gboolean initialized = FALSE; + +static void __attribute__((constructor)) +_nm_utils_init (void) +{ + GModule *self; + gpointer func; + + (void) __nm_git_sha; + + if (initialized) + return; + initialized = TRUE; + + self = g_module_open (NULL, 0); + if (g_module_symbol (self, "nm_util_get_private", &func)) + g_error ("libnm-util symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); + g_module_close (self); + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + + g_type_init (); + + _nm_dbus_errors_init (); +} + +gboolean _nm_utils_is_manager_process; + +/* ssid helpers */ + +/** + * nm_utils_ssid_to_utf8: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * Wi-Fi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID may + * contain embedded NULLs and other unprintable characters. Often it is + * useful to print the SSID out for debugging purposes, but that should be the + * _only_ use of this function. Do not use this function for any persistent + * storage of the SSID, since the printable SSID returned from this function + * cannot be converted back into the real SSID of the access point. + * + * This function does almost everything humanly possible to convert the input + * into a printable UTF-8 string, using roughly the following procedure: + * + * 1) if the input data is already UTF-8 safe, no conversion is performed + * 2) attempts to get the current system language from the LANG environment + * variable, and depending on the language, uses a table of alternative + * encodings to try. For example, if LANG=hu_HU, the table may first try + * the ISO-8859-2 encoding, and if that fails, try the Windows-1250 encoding. + * If all fallback encodings fail, replaces non-UTF-8 characters with '?'. + * 3) If the system language was unable to be determined, falls back to the + * ISO-8859-1 encoding, then to the Windows-1251 encoding. + * 4) If step 3 fails, replaces non-UTF-8 characters with '?'. + * + * Again, this function should be used for debugging and display purposes + * _only_. + * + * Returns: (transfer full): an allocated string containing a UTF-8 + * representation of the SSID, which must be freed by the caller using g_free(). + * Returns %NULL on errors. + **/ +char * +nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len) +{ + char *converted = NULL; + char *lang, *e1 = NULL, *e2 = NULL, *e3 = NULL; + + g_return_val_if_fail (ssid != NULL, NULL); + + if (g_utf8_validate ((const gchar *) ssid, len, NULL)) + return g_strndup ((const gchar *) ssid, len); + + /* LANG may be a good encoding hint */ + g_get_charset ((const char **)(&e1)); + if ((lang = getenv ("LANG"))) { + char * dot; + + lang = g_ascii_strdown (lang, -1); + if ((dot = strchr (lang, '.'))) + *dot = '\0'; + + get_encodings_for_lang (lang, &e1, &e2, &e3); + g_free (lang); + } + + converted = g_convert ((const gchar *) ssid, len, "UTF-8", e1, NULL, NULL, NULL); + if (!converted && e2) + converted = g_convert ((const gchar *) ssid, len, "UTF-8", e2, NULL, NULL, NULL); + + if (!converted && e3) + converted = g_convert ((const gchar *) ssid, len, "UTF-8", e3, NULL, NULL, NULL); + + if (!converted) { + converted = g_convert_with_fallback ((const gchar *) ssid, len, + "UTF-8", e1, "?", NULL, NULL, NULL); + } + + return converted; +} + +/* Shamelessly ripped from the Linux kernel ieee80211 stack */ +/** + * nm_utils_is_empty_ssid: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * Different manufacturers use different mechanisms for not broadcasting the + * AP's SSID. This function attempts to detect blank/empty SSIDs using a + * number of known SSID-cloaking methods. + * + * Returns: %TRUE if the SSID is "empty", %FALSE if it is not + **/ +gboolean +nm_utils_is_empty_ssid (const guint8 *ssid, gsize len) +{ + /* Single white space is for Linksys APs */ + if (len == 1 && ssid[0] == ' ') + return TRUE; + + /* Otherwise, if the entire ssid is 0, we assume it is hidden */ + while (len--) { + if (ssid[len] != '\0') + return FALSE; + } + return TRUE; +} + +#define ESSID_MAX_SIZE 32 + +/** + * nm_utils_escape_ssid: + * @ssid: (array length=len): pointer to a buffer containing the SSID data + * @len: length of the SSID data in @ssid + * + * This function does a quick printable character conversion of the SSID, simply + * replacing embedded NULLs and non-printable characters with the hexadecimal + * representation of that character. Intended for debugging only, should not + * be used for display of SSIDs. + * + * Returns: pointer to the escaped SSID, which uses an internal static buffer + * and will be overwritten by subsequent calls to this function + **/ +const char * +nm_utils_escape_ssid (const guint8 *ssid, gsize len) +{ + static char escaped[ESSID_MAX_SIZE * 2 + 1]; + const guint8 *s = ssid; + char *d = escaped; + + if (nm_utils_is_empty_ssid (ssid, len)) { + memcpy (escaped, "", sizeof ("")); + return escaped; + } + + len = MIN (len, (guint32) ESSID_MAX_SIZE); + while (len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +/** + * nm_utils_same_ssid: + * @ssid1: (array length=len1): the first SSID to compare + * @len1: length of the SSID data in @ssid1 + * @ssid2: (array length=len2): the second SSID to compare + * @len2: length of the SSID data in @ssid2 + * @ignore_trailing_null: %TRUE to ignore one trailing NULL byte + * + * Earlier versions of the Linux kernel added a NULL byte to the end of the + * SSID to enable easy printing of the SSID on the console or in a terminal, + * but this behavior was problematic (SSIDs are simply byte arrays, not strings) + * and thus was changed. This function compensates for that behavior at the + * cost of some compatibility with odd SSIDs that may legitimately have trailing + * NULLs, even though that is functionally pointless. + * + * Returns: %TRUE if the SSIDs are the same, %FALSE if they are not + **/ +gboolean +nm_utils_same_ssid (const guint8 *ssid1, gsize len1, + const guint8 *ssid2, gsize len2, + gboolean ignore_trailing_null) +{ + g_return_val_if_fail (ssid1 != NULL || len1 == 0, FALSE); + g_return_val_if_fail (ssid2 != NULL || len2 == 0, FALSE); + + if (ssid1 == ssid2 && len1 == len2) + return TRUE; + if (!ssid1 || !ssid2) + return FALSE; + + if (ignore_trailing_null) { + if (len1 && ssid1[len1 - 1] == '\0') + len1--; + if (len2 && ssid2[len2 - 1] == '\0') + len2--; + } + + if (len1 != len2) + return FALSE; + + return memcmp (ssid1, ssid2, len1) == 0 ? TRUE : FALSE; +} + +gboolean +_nm_utils_string_in_list (const char *str, const char **valid_strings) +{ + int i; + + for (i = 0; valid_strings[i]; i++) + if (strcmp (str, valid_strings[i]) == 0) + break; + + return valid_strings[i] != NULL; +} + +gboolean +_nm_utils_string_slist_validate (GSList *list, const char **valid_values) +{ + GSList *iter; + + for (iter = list; iter; iter = iter->next) { + if (!_nm_utils_string_in_list ((char *) iter->data, valid_values)) + return FALSE; + } + + return TRUE; +} + +/** + * _nm_utils_hash_values_to_slist: + * @hash: a #GHashTable + * + * Utility function to iterate over a hash table and return + * it's values as a #GSList. + * + * Returns: (element-type gpointer) (transfer container): a newly allocated #GSList + * containing the values of the hash table. The caller must free the + * returned list with g_slist_free(). The hash values are not owned + * by the returned list. + **/ +GSList * +_nm_utils_hash_values_to_slist (GHashTable *hash) +{ + GSList *list = NULL; + GHashTableIter iter; + void *value; + + g_return_val_if_fail (hash, NULL); + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, NULL, &value)) + list = g_slist_prepend (list, value); + + return list; +} + +GVariant * +_nm_utils_strdict_to_dbus (const GValue *prop_value) +{ + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + hash = g_value_get_boxed (prop_value); + if (hash) { + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) + g_variant_builder_add (&builder, "{ss}", key, value); + } + + return g_variant_builder_end (&builder); +} + +void +_nm_utils_strdict_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + GVariantIter iter; + const char *key, *value; + GHashTable *hash; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_variant_iter_init (&iter, dbus_value); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) + g_hash_table_insert (hash, g_strdup (key), g_strdup (value)); + + g_value_take_boxed (prop_value, hash); +} + +GHashTable * +_nm_utils_copy_strdict (GHashTable *strdict) +{ + GHashTable *copy; + GHashTableIter iter; + gpointer key, value; + + copy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + if (strdict) { + g_hash_table_iter_init (&iter, strdict); + while (g_hash_table_iter_next (&iter, &key, &value)) + g_hash_table_insert (copy, g_strdup (key), g_strdup (value)); + } + return copy; +} + +GPtrArray * +_nm_utils_copy_slist_to_array (const GSList *list, + NMUtilsCopyFunc copy_func, + GDestroyNotify unref_func) +{ + const GSList *iter; + GPtrArray *array; + + array = g_ptr_array_new_with_free_func (unref_func); + for (iter = list; iter; iter = iter->next) + g_ptr_array_add (array, copy_func ? copy_func (iter->data) : iter->data); + return array; +} + +GSList * +_nm_utils_copy_array_to_slist (const GPtrArray *array, + NMUtilsCopyFunc copy_func) +{ + GSList *slist = NULL; + gpointer item; + int i; + + if (!array) + return NULL; + + for (i = 0; i < array->len; i++) { + item = array->pdata[i]; + slist = g_slist_prepend (slist, copy_func (item)); + } + + return g_slist_reverse (slist); +} + +GPtrArray * +_nm_utils_copy_array (const GPtrArray *array, + NMUtilsCopyFunc copy_func, + GDestroyNotify free_func) +{ + GPtrArray *copy; + int i; + + if (!array) + return g_ptr_array_new_with_free_func (free_func); + + copy = g_ptr_array_new_full (array->len, free_func); + for (i = 0; i < array->len; i++) + g_ptr_array_add (copy, copy_func (array->pdata[i])); + return copy; +} + +GPtrArray * +_nm_utils_copy_object_array (const GPtrArray *array) +{ + return _nm_utils_copy_array (array, g_object_ref, g_object_unref); +} + +GVariant * +_nm_utils_bytes_to_dbus (const GValue *prop_value) +{ + GBytes *bytes = g_value_get_boxed (prop_value); + + if (bytes) { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + 1); + } else { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + NULL, 0, + 1); + } +} + +void +_nm_utils_bytes_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + GBytes *bytes; + + if (g_variant_n_children (dbus_value)) { + gconstpointer data; + gsize length; + + data = g_variant_get_fixed_array (dbus_value, &length, 1); + bytes = g_bytes_new (data, length); + } else + bytes = NULL; + g_value_take_boxed (prop_value, bytes); +} + +GSList * +_nm_utils_strv_to_slist (char **strv) +{ + int i; + GSList *list = NULL; + + if (strv) { + for (i = 0; strv[i]; i++) + list = g_slist_prepend (list, g_strdup (strv[i])); + } + + return g_slist_reverse (list); +} + +char ** +_nm_utils_slist_to_strv (GSList *slist) +{ + GSList *iter; + char **strv; + int len, i; + + len = g_slist_length (slist); + strv = g_new (char *, len + 1); + + for (i = 0, iter = slist; iter; iter = iter->next, i++) + strv[i] = g_strdup (iter->data); + strv[i] = NULL; + + return strv; +} + +GPtrArray * +_nm_utils_strv_to_ptrarray (char **strv) +{ + GPtrArray *ptrarray; + int i; + + ptrarray = g_ptr_array_new_with_free_func (g_free); + + if (strv) { + for (i = 0; strv[i]; i++) + g_ptr_array_add (ptrarray, g_strdup (strv[i])); + } + + return ptrarray; +} + +char ** +_nm_utils_ptrarray_to_strv (GPtrArray *ptrarray) +{ + char **strv; + int i; + + if (!ptrarray) + return g_new0 (char *, 1); + + strv = g_new (char *, ptrarray->len + 1); + + for (i = 0; i < ptrarray->len; i++) + strv[i] = g_strdup (ptrarray->pdata[i]); + strv[i] = NULL; + + return strv; +} + +/** + * _nm_utils_strsplit_set: + * @str: string to split + * @delimiters: string of delimiter characters + * @max_tokens: the maximum number of tokens to split string into. When it is + * less than 1, the @str is split completely. + * + * Utility function for splitting string into a string array. It is a wrapper + * for g_strsplit_set(), but it also removes empty strings from the vector as + * they are not useful in most cases. + * + * Returns: (transfer full): a newly allocated NULL-terminated array of strings. + * The caller must free the returned array with g_strfreev(). + **/ +char ** +_nm_utils_strsplit_set (const char *str, const char *delimiters, int max_tokens) +{ + char **result; + uint i; + uint j; + + result = g_strsplit_set (str, delimiters, max_tokens); + + /* remove empty strings */ + for (i = 0; result && result[i]; i++) { + if (*result[i] == '\0') { + g_free (result[i]); + for (j = i; result[j]; j++) + result[j] = result[j + 1]; + i--; + } + } + return result; +} + +static gboolean +device_supports_ap_ciphers (guint32 dev_caps, + guint32 ap_flags, + gboolean static_wep) +{ + gboolean have_pair = FALSE; + gboolean have_group = FALSE; + /* Device needs to support at least one pairwise and one group cipher */ + + /* Pairwise */ + if (static_wep) { + /* Static WEP only uses group ciphers */ + have_pair = TRUE; + } else { + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40) + if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP40) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104) + if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP104) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) + if (ap_flags & NM_802_11_AP_SEC_PAIR_TKIP) + have_pair = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + if (ap_flags & NM_802_11_AP_SEC_PAIR_CCMP) + have_pair = TRUE; + } + + /* Group */ + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40) + if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP40) + have_group = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104) + if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP104) + have_group = TRUE; + if (!static_wep) { + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) + if (ap_flags & NM_802_11_AP_SEC_GROUP_TKIP) + have_group = TRUE; + if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + if (ap_flags & NM_802_11_AP_SEC_GROUP_CCMP) + have_group = TRUE; + } + + return (have_pair && have_group); +} + +/** + * nm_utils_ap_mode_security_valid: + * @type: the security type to check device capabilties against, + * e.g. #NMU_SEC_STATIC_WEP + * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g. + * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + * + * Given a set of device capabilities, and a desired security type to check + * against, determines whether the combination of device capabilities and + * desired security type are valid for AP/Hotspot connections. + * + * Returns: %TRUE if the device capabilities are compatible with the desired + * @type, %FALSE if they are not. + **/ +gboolean +nm_utils_ap_mode_security_valid (NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps) +{ + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_AP)) + return FALSE; + + /* Return TRUE for any security that wpa_supplicant's lightweight AP + * mode can handle: which is open, WEP, and WPA/WPA2 PSK. + */ + switch (type) { + case NMU_SEC_NONE: + case NMU_SEC_STATIC_WEP: + case NMU_SEC_WPA_PSK: + case NMU_SEC_WPA2_PSK: + return TRUE; + default: + break; + } + return FALSE; +} + +/** + * nm_utils_security_valid: + * @type: the security type to check AP flags and device capabilties against, + * e.g. #NMU_SEC_STATIC_WEP + * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g. + * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + * @have_ap: whether the @ap_flags, @ap_wpa, and @ap_rsn arguments are valid + * @adhoc: whether the capabilities being tested are from an Ad-Hoc AP (IBSS) + * @ap_flags: bitfield of AP capabilities, e.g. #NM_802_11_AP_FLAGS_PRIVACY + * @ap_wpa: bitfield of AP capabilties derived from the AP's WPA beacon, + * e.g. (#NM_802_11_AP_SEC_PAIR_TKIP | #NM_802_11_AP_SEC_KEY_MGMT_PSK) + * @ap_rsn: bitfield of AP capabilties derived from the AP's RSN/WPA2 beacon, + * e.g. (#NM_802_11_AP_SEC_PAIR_CCMP | #NM_802_11_AP_SEC_PAIR_TKIP) + * + * Given a set of device capabilities, and a desired security type to check + * against, determines whether the combination of device, desired security + * type, and AP capabilities intersect. + * + * NOTE: this function cannot handle checking security for AP/Hotspot mode; + * use nm_utils_ap_mode_security_valid() instead. + * + * Returns: %TRUE if the device capabilities and AP capabilties intersect and are + * compatible with the desired @type, %FALSE if they are not + **/ +gboolean +nm_utils_security_valid (NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps, + gboolean have_ap, + gboolean adhoc, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn) +{ + gboolean good = TRUE; + + if (!have_ap) { + if (type == NMU_SEC_NONE) + return TRUE; + if ( (type == NMU_SEC_STATIC_WEP) + || ((type == NMU_SEC_DYNAMIC_WEP) && !adhoc) + || ((type == NMU_SEC_LEAP) && !adhoc)) { + if (wifi_caps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) + return TRUE; + else + return FALSE; + } + } + + switch (type) { + case NMU_SEC_NONE: + g_assert (have_ap); + if (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + return FALSE; + if (ap_wpa || ap_rsn) + return FALSE; + break; + case NMU_SEC_LEAP: /* require PRIVACY bit for LEAP? */ + if (adhoc) + return FALSE; + /* Fall through */ + case NMU_SEC_STATIC_WEP: + g_assert (have_ap); + if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + if (ap_wpa || ap_rsn) { + if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, TRUE)) + if (!device_supports_ap_ciphers (wifi_caps, ap_rsn, TRUE)) + return FALSE; + } + break; + case NMU_SEC_DYNAMIC_WEP: + if (adhoc) + return FALSE; + g_assert (have_ap); + if (ap_rsn || !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)) + return FALSE; + /* Some APs broadcast minimal WPA-enabled beacons that must be handled */ + if (ap_wpa) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, FALSE)) + return FALSE; + } + break; + case NMU_SEC_WPA_PSK: + if (adhoc) + return FALSE; /* FIXME: Kernel WPA Ad-Hoc support is buggy */ + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) + return FALSE; + if (have_ap) { + /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and + * they don't have any pairwise ciphers. */ + if (adhoc) { + /* coverity[dead_error_line] */ + if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } else { + if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } + } + return FALSE; + } + break; + case NMU_SEC_WPA2_PSK: + if (adhoc) + return FALSE; /* FIXME: Kernel WPA Ad-Hoc support is buggy */ + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (have_ap) { + /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and + * they don't have any pairwise ciphers, nor any RSA flags yet. */ + if (adhoc) { + /* coverity[dead_error_line] */ + if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) + return TRUE; + if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) + return TRUE; + } else { + if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } + } + return FALSE; + } + break; + case NMU_SEC_WPA_ENTERPRISE: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) + return FALSE; + if (have_ap) { + if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + /* Ensure at least one WPA cipher is supported */ + if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, FALSE)) + return FALSE; + } + break; + case NMU_SEC_WPA2_ENTERPRISE: + if (adhoc) + return FALSE; + if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) + return FALSE; + if (have_ap) { + if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + return FALSE; + /* Ensure at least one WPA cipher is supported */ + if (!device_supports_ap_ciphers (wifi_caps, ap_rsn, FALSE)) + return FALSE; + } + break; + default: + good = FALSE; + break; + } + + return good; +} + +/** + * nm_utils_wep_key_valid: + * @key: a string that might be a WEP key + * @wep_type: the #NMWepKeyType type of the WEP key + * + * Checks if @key is a valid WEP key + * + * Returns: %TRUE if @key is a WEP key, %FALSE if not + */ +gboolean +nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type) +{ + int keylen, i; + + if (!key) + return FALSE; + + keylen = strlen (key); + if ( wep_type == NM_WEP_KEY_TYPE_KEY + || wep_type == NM_WEP_KEY_TYPE_UNKNOWN) { + if (keylen == 10 || keylen == 26) { + /* Hex key */ + for (i = 0; i < keylen; i++) { + if (!g_ascii_isxdigit (key[i])) + return FALSE; + } + } else if (keylen == 5 || keylen == 13) { + /* ASCII key */ + for (i = 0; i < keylen; i++) { + if (!g_ascii_isprint (key[i])) + return FALSE; + } + } else + return FALSE; + + } else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) { + if (!keylen || keylen > 64) + return FALSE; + } + + return TRUE; +} + +/** + * nm_utils_wpa_psk_valid: + * @psk: a string that might be a WPA PSK + * + * Checks if @psk is a valid WPA PSK + * + * Returns: %TRUE if @psk is a WPA PSK, %FALSE if not + */ +gboolean +nm_utils_wpa_psk_valid (const char *psk) +{ + int psklen, i; + + if (!psk) + return FALSE; + + psklen = strlen (psk); + if (psklen < 8 || psklen > 64) + return FALSE; + + if (psklen == 64) { + /* Hex PSK */ + for (i = 0; i < psklen; i++) { + if (!g_ascii_isxdigit (psk[i])) + return FALSE; + } + } + + return TRUE; +} + +/** + * nm_utils_ip4_dns_to_variant: + * @dns: (type utf8): an array of IP address strings + * + * Utility function to convert an array of IP address strings int a #GVariant of + * type 'au' representing an array of IPv4 addresses. + * + * Returns: (transfer none): a new floating #GVariant representing @dns. + **/ +GVariant * +nm_utils_ip4_dns_to_variant (char **dns) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("au")); + + if (dns) { + for (i = 0; dns[i]; i++) { + guint32 ip = 0; + + inet_pton (AF_INET, dns[i], &ip); + g_variant_builder_add (&builder, "u", ip); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip4_dns_from_variant: + * @value: a #GVariant of type 'au' + * + * Utility function to convert a #GVariant of type 'au' representing a list of + * IPv4 addresses into an array of IP address strings. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. + **/ +char ** +nm_utils_ip4_dns_from_variant (GVariant *value) +{ + const guint32 *array; + gsize length; + char **dns; + int i; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("au")), NULL); + + array = g_variant_get_fixed_array (value, &length, sizeof (guint32)); + dns = g_new (char *, length + 1); + + for (i = 0; i < length; i++) + dns[i] = g_strdup (nm_utils_inet4_ntop (array[i], NULL)); + dns[i] = NULL; + + return dns; +} + +/** + * nm_utils_ip4_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * @gateway: (allow-none): the gateway IP address + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv4 addresses into a #GVariant of type 'aau' representing an array of + * NetworkManager IPv4 addresses (which are tuples of address, prefix, and + * gateway). The "gateway" field of the first address will get the value of + * @gateway (if non-%NULL). In all of the other addresses, that field will be 0. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip4_addresses_to_variant (GPtrArray *addresses, const char *gateway) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + guint32 array[3]; + + if (nm_ip_address_get_family (addr) != AF_INET) + continue; + + nm_ip_address_get_address_binary (addr, &array[0]); + array[1] = nm_ip_address_get_prefix (addr); + if (i == 0 && gateway) + inet_pton (AF_INET, gateway, &array[2]); + else + array[2] = 0; + + g_variant_builder_add (&builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, 3, sizeof (guint32))); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip4_addresses_from_variant: + * @value: a #GVariant of type 'aau' + * @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway + * + * Utility function to convert a #GVariant of type 'aau' representing a list of + * NetworkManager IPv4 addresses (which are tuples of address, prefix, and + * gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field of + * the first address (if set) will be returned in @out_gateway; the "gateway" fields + * of the other addresses are ignored. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip4_addresses_from_variant (GVariant *value, char **out_gateway) +{ + GPtrArray *addresses; + GVariantIter iter; + GVariant *addr_var; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL); + + if (out_gateway) + *out_gateway = NULL; + + g_variant_iter_init (&iter, value); + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next (&iter, "@au", &addr_var)) { + const guint32 *addr_array; + gsize length; + NMIPAddress *addr; + GError *error = NULL; + + addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32)); + if (length < 3) { + g_warning ("Ignoring invalid IP4 address"); + g_variant_unref (addr_var); + continue; + } + + addr = nm_ip_address_new_binary (AF_INET, &addr_array[0], addr_array[1], &error); + if (addr) { + g_ptr_array_add (addresses, addr); + + if (addr_array[2] && out_gateway && !*out_gateway) + *out_gateway = g_strdup (nm_utils_inet4_ntop (addr_array[2], NULL)); + } else { + g_warning ("Ignoring invalid IP4 address: %s", error->message); + g_clear_error (&error); + } + + g_variant_unref (addr_var); + } + + return addresses; +} + +/** + * nm_utils_ip4_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIP4Route objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv4 routes into a #GVariant of type 'aau' representing an array of + * NetworkManager IPv4 routes (which are tuples of route, prefix, next hop, and + * metric). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip4_routes_to_variant (GPtrArray *routes) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + guint32 array[4]; + + if (nm_ip_route_get_family (route) != AF_INET) + continue; + + nm_ip_route_get_dest_binary (route, &array[0]); + array[1] = nm_ip_route_get_prefix (route); + nm_ip_route_get_next_hop_binary (route, &array[2]); + /* The old routes format uses "0" for default, not "-1" */ + array[3] = MAX (0, nm_ip_route_get_metric (route)); + + g_variant_builder_add (&builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, 4, sizeof (guint32))); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip4_routes_from_variant: + * @value: #GVariant of type 'aau' + * + * Utility function to convert a #GVariant of type 'aau' representing an array + * of NetworkManager IPv4 routes (which are tuples of route, prefix, next hop, + * and metric) into a #GPtrArray of #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip4_routes_from_variant (GVariant *value) +{ + GVariantIter iter; + GVariant *route_var; + GPtrArray *routes; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL); + + g_variant_iter_init (&iter, value); + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + + while (g_variant_iter_next (&iter, "@au", &route_var)) { + const guint32 *route_array; + gsize length; + NMIPRoute *route; + GError *error = NULL; + + route_array = g_variant_get_fixed_array (route_var, &length, sizeof (guint32)); + if (length < 4) { + g_warning ("Ignoring invalid IP4 route"); + g_variant_unref (route_var); + continue; + } + + route = nm_ip_route_new_binary (AF_INET, + &route_array[0], + route_array[1], + &route_array[2], + /* The old routes format uses "0" for default, not "-1" */ + route_array[3] ? (gint64) route_array[3] : -1, + &error); + if (route) + g_ptr_array_add (routes, route); + else { + g_warning ("Ignoring invalid IP4 route: %s", error->message); + g_clear_error (&error); + } + g_variant_unref (route_var); + } + + return routes; +} + +/** + * nm_utils_ip4_netmask_to_prefix: + * @netmask: an IPv4 netmask in network byte order + * + * Returns: the CIDR prefix represented by the netmask + **/ +guint32 +nm_utils_ip4_netmask_to_prefix (guint32 netmask) +{ + guint32 prefix; + guint8 v; + const guint8 *p = (guint8 *) &netmask; + + if (p[3]) { + prefix = 24; + v = p[3]; + } else if (p[2]) { + prefix = 16; + v = p[2]; + } else if (p[1]) { + prefix = 8; + v = p[1]; + } else { + prefix = 0; + v = p[0]; + } + + while (v) { + prefix++; + v <<= 1; + } + + return prefix; +} + +/** + * nm_utils_ip4_prefix_to_netmask: + * @prefix: a CIDR prefix + * + * Returns: the netmask represented by the prefix, in network byte order + **/ +guint32 +nm_utils_ip4_prefix_to_netmask (guint32 prefix) +{ + return prefix < 32 ? ~htonl(0xFFFFFFFF >> prefix) : 0xFFFFFFFF; +} + + +/** + * nm_utils_ip4_get_default_prefix: + * @ip: an IPv4 address (in network byte order) + * + * When the Internet was originally set up, various ranges of IP addresses were + * segmented into three network classes: A, B, and C. This function will return + * a prefix that is associated with the IP address specified defining where it + * falls in the predefined classes. + * + * Returns: the default class prefix for the given IP + **/ +/* The function is originally from ipcalc.c of Red Hat's initscripts. */ +guint32 +nm_utils_ip4_get_default_prefix (guint32 ip) +{ + if (((ntohl (ip) & 0xFF000000) >> 24) <= 127) + return 8; /* Class A - 255.0.0.0 */ + else if (((ntohl (ip) & 0xFF000000) >> 24) <= 191) + return 16; /* Class B - 255.255.0.0 */ + + return 24; /* Class C - 255.255.255.0 */ +} + +/** + * nm_utils_ip6_dns_to_variant: + * @dns: (type utf8): an array of IP address strings + * + * Utility function to convert an array of IP address strings int a #GVariant of + * type 'aay' representing an array of IPv6 addresses. + * + * Returns: (transfer none): a new floating #GVariant representing @dns. + **/ +GVariant * +nm_utils_ip6_dns_to_variant (char **dns) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); + + if (dns) { + for (i = 0; dns[i]; i++) { + struct in6_addr ip; + + inet_pton (AF_INET6, dns[i], &ip); + g_variant_builder_add (&builder, "@ay", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &ip, sizeof (ip), 1)); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip6_dns_from_variant: + * @value: a #GVariant of type 'aay' + * + * Utility function to convert a #GVariant of type 'aay' representing a list of + * IPv6 addresses into an array of IP address strings. + * + * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings. + **/ +char ** +nm_utils_ip6_dns_from_variant (GVariant *value) +{ + GVariantIter iter; + GVariant *ip_var; + char **dns; + int i; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aay")), NULL); + + dns = g_new (char *, g_variant_n_children (value) + 1); + + g_variant_iter_init (&iter, value); + i = 0; + while (g_variant_iter_next (&iter, "@ay", &ip_var)) { + gsize length; + const struct in6_addr *ip = g_variant_get_fixed_array (ip_var, &length, 1); + + if (length != sizeof (struct in6_addr)) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) length); + g_variant_unref (ip_var); + continue; + } + + dns[i++] = g_strdup (nm_utils_inet6_ntop (ip, NULL)); + g_variant_unref (ip_var); + } + dns[i] = NULL; + + return dns; +} + +/** + * nm_utils_ip6_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * @gateway: (allow-none): the gateway IP address + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv6 addresses into a #GVariant of type 'a(ayuay)' representing an array of + * NetworkManager IPv6 addresses (which are tuples of address, prefix, and + * gateway). The "gateway" field of the first address will get the value of + * @gateway (if non-%NULL). In all of the other addresses, that field will be + * all 0s. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip6_addresses_to_variant (GPtrArray *addresses, const char *gateway) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuay)")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + struct in6_addr ip_bytes, gateway_bytes; + GVariant *ip_var, *gateway_var; + guint32 prefix; + + if (nm_ip_address_get_family (addr) != AF_INET6) + continue; + + nm_ip_address_get_address_binary (addr, &ip_bytes); + ip_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &ip_bytes, 16, 1); + + prefix = nm_ip_address_get_prefix (addr); + + if (i == 0 && gateway) + inet_pton (AF_INET6, gateway, &gateway_bytes); + else + memset (&gateway_bytes, 0, sizeof (gateway_bytes)); + gateway_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &gateway_bytes, 16, 1); + + g_variant_builder_add (&builder, "(@ayu@ay)", ip_var, prefix, gateway_var); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip6_addresses_from_variant: + * @value: a #GVariant of type 'a(ayuay)' + * @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway + * + * Utility function to convert a #GVariant of type 'a(ayuay)' representing a + * list of NetworkManager IPv6 addresses (which are tuples of address, prefix, + * and gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field + * of the first address (if set) will be returned in @out_gateway; the "gateway" + * fields of the other addresses are ignored. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip6_addresses_from_variant (GVariant *value, char **out_gateway) +{ + GVariantIter iter; + GVariant *addr_var, *gateway_var; + guint32 prefix; + GPtrArray *addresses; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuay)")), NULL); + + if (out_gateway) + *out_gateway = NULL; + + g_variant_iter_init (&iter, value); + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next (&iter, "(@ayu@ay)", &addr_var, &prefix, &gateway_var)) { + NMIPAddress *addr; + const struct in6_addr *addr_bytes, *gateway_bytes; + gsize addr_len, gateway_len; + GError *error = NULL; + + if ( !g_variant_is_of_type (addr_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (gateway_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } + + addr_bytes = g_variant_get_fixed_array (addr_var, &addr_len, 1); + if (addr_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) addr_len); + goto next; + } + + addr = nm_ip_address_new_binary (AF_INET6, addr_bytes, prefix, &error); + if (addr) { + g_ptr_array_add (addresses, addr); + + if (out_gateway && !*out_gateway) { + gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1); + if (gateway_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) gateway_len); + goto next; + } + if (!IN6_IS_ADDR_UNSPECIFIED (gateway_bytes)) + *out_gateway = g_strdup (nm_utils_inet6_ntop (gateway_bytes, NULL)); + } + } else { + g_warning ("Ignoring invalid IP4 address: %s", error->message); + g_clear_error (&error); + } + + next: + g_variant_unref (addr_var); + g_variant_unref (gateway_var); + } + + return addresses; +} + +/** + * nm_utils_ip6_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIPRoute objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv6 routes into a #GVariant of type 'a(ayuayu)' representing an array of + * NetworkManager IPv6 routes (which are tuples of route, prefix, next hop, and + * metric). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip6_routes_to_variant (GPtrArray *routes) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuayu)")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + struct in6_addr dest_bytes, next_hop_bytes; + GVariant *dest, *next_hop; + guint32 prefix, metric; + + if (nm_ip_route_get_family (route) != AF_INET6) + continue; + + nm_ip_route_get_dest_binary (route, &dest_bytes); + dest = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &dest_bytes, 16, 1); + prefix = nm_ip_route_get_prefix (route); + nm_ip_route_get_next_hop_binary (route, &next_hop_bytes); + next_hop = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &next_hop_bytes, 16, 1); + /* The old routes format uses "0" for default, not "-1" */ + metric = MAX (0, nm_ip_route_get_metric (route)); + + g_variant_builder_add (&builder, "(@ayu@ayu)", dest, prefix, next_hop, metric); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip6_routes_from_variant: + * @value: #GVariant of type 'a(ayuayu)' + * + * Utility function to convert a #GVariant of type 'a(ayuayu)' representing an + * array of NetworkManager IPv6 routes (which are tuples of route, prefix, next + * hop, and metric) into a #GPtrArray of #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip6_routes_from_variant (GVariant *value) +{ + GPtrArray *routes; + GVariantIter iter; + GVariant *dest_var, *next_hop_var; + const struct in6_addr *dest, *next_hop; + gsize dest_len, next_hop_len; + guint32 prefix, metric; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuayu)")), NULL); + + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "(@ayu@ayu)", &dest_var, &prefix, &next_hop_var, &metric)) { + NMIPRoute *route; + GError *error = NULL; + + if ( !g_variant_is_of_type (dest_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (next_hop_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } + + dest = g_variant_get_fixed_array (dest_var, &dest_len, 1); + if (dest_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) dest_len); + goto next; + } + + next_hop = g_variant_get_fixed_array (next_hop_var, &next_hop_len, 1); + if (next_hop_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) next_hop_len); + goto next; + } + + route = nm_ip_route_new_binary (AF_INET6, dest, prefix, next_hop, + metric ? (gint64) metric : -1, + &error); + if (route) + g_ptr_array_add (routes, route); + else { + g_warning ("Ignoring invalid IP6 route: %s", error->message); + g_clear_error (&error); + } + + next: + g_variant_unref (dest_var); + g_variant_unref (next_hop_var); + } + + return routes; +} + +/** + * nm_utils_ip_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv4 or IPv6 addresses into a #GVariant of type 'aa{sv}' representing an + * array of new-style NetworkManager IP addresses. All addresses will include + * "address" (an IP address string), and "prefix" (a uint). Some addresses may + * include additional attributes. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip_addresses_to_variant (GPtrArray *addresses) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + GVariantBuilder addr_builder; + char **names; + int n; + + g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&addr_builder, "{sv}", + "address", + g_variant_new_string (nm_ip_address_get_address (addr))); + g_variant_builder_add (&addr_builder, "{sv}", + "prefix", + g_variant_new_uint32 (nm_ip_address_get_prefix (addr))); + + names = nm_ip_address_get_attribute_names (addr); + for (n = 0; names[n]; n++) { + g_variant_builder_add (&addr_builder, "{sv}", + names[n], + nm_ip_address_get_attribute (addr, names[n])); + } + g_strfreev (names); + + g_variant_builder_add (&builder, "a{sv}", &addr_builder); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip_addresses_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (as described in the documentation for + * nm_utils_ip_addresses_to_variant()) into a #GPtrArray of #NMIPAddress + * objects. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip_addresses_from_variant (GVariant *value, + int family) +{ + GPtrArray *addresses; + GVariantIter iter, attrs_iter; + GVariant *addr_var; + const char *ip; + guint32 prefix; + const char *attr_name; + GVariant *attr_val; + NMIPAddress *addr; + GError *error = NULL; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL); + + g_variant_iter_init (&iter, value); + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next (&iter, "@a{sv}", &addr_var)) { + if ( !g_variant_lookup (addr_var, "address", "&s", &ip) + || !g_variant_lookup (addr_var, "prefix", "u", &prefix)) { + g_warning ("Ignoring invalid address"); + g_variant_unref (addr_var); + continue; + } + + addr = nm_ip_address_new (family, ip, prefix, &error); + if (!addr) { + g_warning ("Ignoring invalid address: %s", error->message); + g_clear_error (&error); + g_variant_unref (addr_var); + continue; + } + + g_variant_iter_init (&attrs_iter, addr_var); + while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if ( strcmp (attr_name, "address") != 0 + && strcmp (attr_name, "prefix") != 0) + nm_ip_address_set_attribute (addr, attr_name, attr_val); + g_variant_unref (attr_val); + } + + g_ptr_array_add (addresses, addr); + } + + return addresses; +} + +/** + * nm_utils_ip_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIPRoute objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv4 or IPv6 routes into a #GVariant of type 'aa{sv}' representing an array + * of new-style NetworkManager IP routes (which are tuples of destination, + * prefix, next hop, metric, and additional attributes). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip_routes_to_variant (GPtrArray *routes) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + GVariantBuilder route_builder; + char **names; + int n; + + g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&route_builder, "{sv}", + "dest", + g_variant_new_string (nm_ip_route_get_dest (route))); + g_variant_builder_add (&route_builder, "{sv}", + "prefix", + g_variant_new_uint32 (nm_ip_route_get_prefix (route))); + if (nm_ip_route_get_next_hop (route)) { + g_variant_builder_add (&route_builder, "{sv}", + "next-hop", + g_variant_new_string (nm_ip_route_get_next_hop (route))); + } + if (nm_ip_route_get_metric (route) != -1) { + g_variant_builder_add (&route_builder, "{sv}", + "metric", + g_variant_new_uint32 ((guint32) nm_ip_route_get_metric (route))); + } + + names = nm_ip_route_get_attribute_names (route); + for (n = 0; names[n]; n++) { + g_variant_builder_add (&route_builder, "{sv}", + names[n], + nm_ip_route_get_attribute (route, names[n])); + } + g_strfreev (names); + + g_variant_builder_add (&builder, "a{sv}", &route_builder); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip_routes_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (which are tuples of destination, + * prefix, next hop, metric, and additional attributes) into a #GPtrArray of + * #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip_routes_from_variant (GVariant *value, + int family) +{ + GPtrArray *routes; + GVariantIter iter, attrs_iter; + GVariant *route_var; + const char *dest, *next_hop; + guint32 prefix, metric32; + gint64 metric; + const char *attr_name; + GVariant *attr_val; + NMIPRoute *route; + GError *error = NULL; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL); + + g_variant_iter_init (&iter, value); + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + + while (g_variant_iter_next (&iter, "@a{sv}", &route_var)) { + if ( !g_variant_lookup (route_var, "dest", "&s", &dest) + || !g_variant_lookup (route_var, "prefix", "u", &prefix)) { + g_warning ("Ignoring invalid address"); + g_variant_unref (route_var); + continue; + } + if (!g_variant_lookup (route_var, "next-hop", "&s", &next_hop)) + next_hop = NULL; + if (g_variant_lookup (route_var, "metric", "u", &metric32)) + metric = metric32; + else + metric = -1; + + route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &error); + if (!route) { + g_warning ("Ignoring invalid route: %s", error->message); + g_clear_error (&error); + g_variant_unref (route_var); + continue; + } + + g_variant_iter_init (&attrs_iter, route_var); + while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if ( strcmp (attr_name, "dest") != 0 + && strcmp (attr_name, "prefix") != 0 + && strcmp (attr_name, "next-hop") != 0 + && strcmp (attr_name, "metric") != 0) + nm_ip_route_set_attribute (route, attr_name, attr_val); + g_variant_unref (attr_val); + } + + g_ptr_array_add (routes, route); + } + + return routes; +} + +/** + * nm_utils_uuid_generate: + * + * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection + * object's #NMSettingConnection:id: property. Should be freed with g_free() + **/ +char * +nm_utils_uuid_generate (void) +{ + uuid_t uuid; + char *buf; + + buf = g_malloc0 (37); + uuid_generate_random (uuid); + uuid_unparse_lower (uuid, &buf[0]); + return buf; +} + +/** + * nm_utils_uuid_generate_from_string: + * @s: a string to use as the seed for the UUID + * @slen: if negative, treat @s as zero terminated C string. + * Otherwise, assume the length as given (and allow @s to be + * non-null terminated or contain '\0'). + * @uuid_type: a type identifier which UUID format to generate. + * @type_args: additional arguments, depending on the uuid_type + * + * For a given @s, this function will always return the same UUID. + * + * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection + * object's #NMSettingConnection:id: property + **/ +char * +nm_utils_uuid_generate_from_string (const char *s, gssize slen, int uuid_type, gpointer type_args) +{ + uuid_t uuid; + char *buf; + + g_return_val_if_fail (slen == 0 || s, FALSE); + + g_return_val_if_fail (uuid_type == NM_UTILS_UUID_TYPE_LEGACY || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); + g_return_val_if_fail (!type_args || uuid_type == NM_UTILS_UUID_TYPE_VARIANT3, NULL); + + switch (uuid_type) { + case NM_UTILS_UUID_TYPE_LEGACY: + crypto_md5_hash (NULL, 0, s, slen, (char *) uuid, sizeof (uuid)); + break; + case NM_UTILS_UUID_TYPE_VARIANT3: { + uuid_t ns_uuid = { 0 }; + + if (type_args) { + /* type_args can be a name space UUID. Interpret it as (char *) */ + if (uuid_parse ((char *) type_args, ns_uuid) != 0) + g_return_val_if_reached (NULL); + } + + crypto_md5_hash (s, slen, (char *) ns_uuid, sizeof (ns_uuid), (char *) uuid, sizeof (uuid)); + + uuid[6] = (uuid[6] & 0x0F) | 0x30; + uuid[8] = (uuid[8] & 0x3F) | 0x80; + break; + } + default: + g_return_val_if_reached (NULL); + } + + buf = g_malloc0 (37); + uuid_unparse_lower (uuid, &buf[0]); + + return buf; +} + +/** + * nm_utils_rsa_key_encrypt: + * @data: (array length=len): RSA private key data to be encrypted + * @len: length of @data + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was %NULL, a random + * password will be generated and returned in this argument + * @error: detailed error information on return, if an error occurred + * + * Encrypts the given RSA private key data with the given password (or generates + * a password if no password was given) and converts the data to PEM format + * suitable for writing to a file. It uses Triple DES cipher for the encryption. + * + * Returns: (transfer full): on success, PEM-formatted data suitable for writing + * to a PEM-formatted certificate/private key file. + **/ +GByteArray * +nm_utils_rsa_key_encrypt (const guint8 *data, + gsize len, + const char *in_password, + char **out_password, + GError **error) +{ + char salt[16]; + int salt_len; + char *key = NULL, *enc = NULL, *pw_buf[32]; + gsize key_len = 0, enc_len = 0; + GString *pem = NULL; + char *tmp, *tmp_password = NULL; + int left; + const char *p; + GByteArray *ret = NULL; + + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + if (out_password) + g_return_val_if_fail (*out_password == NULL, NULL); + + /* Make the password if needed */ + if (!in_password) { + if (!crypto_randomize (pw_buf, sizeof (pw_buf), error)) + return NULL; + in_password = tmp_password = nm_utils_bin2hexstr (pw_buf, sizeof (pw_buf), -1); + } + + salt_len = 8; + if (!crypto_randomize (salt, salt_len, error)) + goto out; + + key = crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, &salt[0], salt_len, in_password, &key_len, NULL); + if (!key) + g_return_val_if_reached (NULL); + + enc = crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, salt_len, key, key_len, &enc_len, error); + if (!enc) + goto out; + + pem = g_string_sized_new (enc_len * 2 + 100); + g_string_append (pem, "-----BEGIN RSA PRIVATE KEY-----\n"); + g_string_append (pem, "Proc-Type: 4,ENCRYPTED\n"); + + /* Convert the salt to a hex string */ + tmp = nm_utils_bin2hexstr (salt, salt_len, salt_len * 2); + g_string_append_printf (pem, "DEK-Info: %s,%s\n\n", CIPHER_DES_EDE3_CBC, tmp); + g_free (tmp); + + /* Convert the encrypted key to a base64 string */ + p = tmp = g_base64_encode ((const guchar *) enc, enc_len); + left = strlen (tmp); + while (left > 0) { + g_string_append_len (pem, p, (left < 64) ? left : 64); + g_string_append_c (pem, '\n'); + left -= 64; + p += 64; + } + g_free (tmp); + + g_string_append (pem, "-----END RSA PRIVATE KEY-----\n"); + + ret = g_byte_array_sized_new (pem->len); + g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len); + if (tmp_password && out_password) + *out_password = g_strdup (tmp_password); + +out: + if (key) { + memset (key, 0, key_len); + g_free (key); + } + if (enc) { + memset (enc, 0, enc_len); + g_free (enc); + } + if (pem) + g_string_free (pem, TRUE); + + if (tmp_password) { + memset (tmp_password, 0, strlen (tmp_password)); + g_free (tmp_password); + } + + return ret; +} + +static gboolean +file_has_extension (const char *filename, const char *extensions[]) +{ + const char *ext; + int i; + + ext = strrchr (filename, '.'); + if (!ext) + return FALSE; + + for (i = 0; extensions[i]; i++) { + if (!g_ascii_strcasecmp (ext, extensions[i])) + return TRUE; + } + + return FALSE; +} + +/** + * nm_utils_file_is_certificate: + * @filename: name of the file to test + * + * Tests if @filename has a valid extension for an X.509 certificate file + * (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a certificate, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_certificate (const char *filename) +{ + const char *extensions[] = { ".der", ".pem", ".crt", ".cer", NULL }; + NMCryptoFileFormat file_format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GByteArray *cert; + + g_return_val_if_fail (filename != NULL, FALSE); + + if (!file_has_extension (filename, extensions)) + return FALSE; + + cert = crypto_load_and_verify_certificate (filename, &file_format, NULL); + if (cert) + g_byte_array_unref (cert); + + return file_format = NM_CRYPTO_FILE_FORMAT_X509; +} + +/** + * nm_utils_file_is_private_key: + * @filename: name of the file to test + * @out_encrypted: (out): on return, whether the file is encrypted + * + * Tests if @filename has a valid extension for an X.509 private key file + * (".der", ".key", ".pem", or ".p12"), and contains a private key in a format + * recognized by NetworkManager. + * + * Returns: %TRUE if the file is a private key, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted) +{ + const char *extensions[] = { ".der", ".pem", ".p12", ".key", NULL }; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (out_encrypted == NULL || *out_encrypted == FALSE, FALSE); + + if (!file_has_extension (filename, extensions)) + return FALSE; + + return crypto_verify_private_key (filename, NULL, out_encrypted, NULL) != NM_CRYPTO_FILE_FORMAT_UNKNOWN; +} + +/** + * nm_utils_file_is_pkcs12: + * @filename: name of the file to test + * + * Tests if @filename is a PKCS#12 file. + * + * Returns: %TRUE if the file is PKCS#12, %FALSE if it is not + **/ +gboolean +nm_utils_file_is_pkcs12 (const char *filename) +{ + g_return_val_if_fail (filename != NULL, FALSE); + + return crypto_is_pkcs12_file (filename, NULL); +} + +/**********************************************************************************************/ + +/** + * nm_utils_file_search_in_paths: + * @progname: the helper program name, like "iptables" + * Must be a non-empty string, without path separator (/). + * @try_first: (allow-none): a custom path to try first before searching. + * It is silently ignored if it is empty or not an absolute path. + * @paths: (allow-none): a %NULL terminated list of search paths. + * Can be empty or %NULL, in which case only @try_first is checked. + * @file_test_flags: the flags passed to g_file_test() when searching + * for @progname. Set it to 0 to skip the g_file_test(). + * @predicate: (scope call): if given, pass the file name to this function + * for additional checks. This check is performed after the check for + * @file_test_flags. You cannot omit both @file_test_flags and @predicate. + * @user_data: (closure): (allow-none): user data for @predicate function. + * @error: on failure, a "not found" error using @error_domain and @error_code + * + * Searches for a @progname file in a list of search @paths. + * + * Returns: (transfer none): the full path to the helper, if found, or %NULL if not found. + * The returned string is not owned by the caller, but later + * invocations of the function might overwrite it. + */ +const char * +nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error) +{ + GString *tmp; + const char *ret; + + g_return_val_if_fail (!error || !*error, NULL); + g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL); + g_return_val_if_fail (file_test_flags || predicate, NULL); + + /* Only consider @try_first if it is a valid, absolute path. This makes + * it simpler to pass in a path from configure checks. */ + if ( try_first + && try_first[0] == '/' + && (file_test_flags == 0 || g_file_test (try_first, file_test_flags)) + && (!predicate || predicate (try_first, user_data))) + return g_intern_string (try_first); + + if (!paths || !*paths) + goto NOT_FOUND; + + tmp = g_string_sized_new (50); + for (; *paths; paths++) { + if (!*paths) + continue; + g_string_append (tmp, *paths); + if (tmp->str[tmp->len - 1] != '/') + g_string_append_c (tmp, '/'); + g_string_append (tmp, progname); + if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags)) + && (!predicate || predicate (tmp->str, user_data))) { + ret = g_intern_string (tmp->str); + g_string_free (tmp, TRUE); + return ret; + } + g_string_set_size (tmp, 0); + } + g_string_free (tmp, TRUE); + +NOT_FOUND: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname); + return NULL; +} + +/**********************************************************************************************/ + +/* Band, channel/frequency stuff for wireless */ +struct cf_pair { + guint32 chan; + guint32 freq; +}; + +static struct cf_pair a_table[] = { + /* A band */ + { 7, 5035 }, + { 8, 5040 }, + { 9, 5045 }, + { 11, 5055 }, + { 12, 5060 }, + { 16, 5080 }, + { 34, 5170 }, + { 36, 5180 }, + { 38, 5190 }, + { 40, 5200 }, + { 42, 5210 }, + { 44, 5220 }, + { 46, 5230 }, + { 48, 5240 }, + { 50, 5250 }, + { 52, 5260 }, + { 56, 5280 }, + { 58, 5290 }, + { 60, 5300 }, + { 64, 5320 }, + { 100, 5500 }, + { 104, 5520 }, + { 108, 5540 }, + { 112, 5560 }, + { 116, 5580 }, + { 120, 5600 }, + { 124, 5620 }, + { 128, 5640 }, + { 132, 5660 }, + { 136, 5680 }, + { 140, 5700 }, + { 149, 5745 }, + { 152, 5760 }, + { 153, 5765 }, + { 157, 5785 }, + { 160, 5800 }, + { 161, 5805 }, + { 165, 5825 }, + { 183, 4915 }, + { 184, 4920 }, + { 185, 4925 }, + { 187, 4935 }, + { 188, 4945 }, + { 192, 4960 }, + { 196, 4980 }, + { 0, -1 } +}; + +static struct cf_pair bg_table[] = { + /* B/G band */ + { 1, 2412 }, + { 2, 2417 }, + { 3, 2422 }, + { 4, 2427 }, + { 5, 2432 }, + { 6, 2437 }, + { 7, 2442 }, + { 8, 2447 }, + { 9, 2452 }, + { 10, 2457 }, + { 11, 2462 }, + { 12, 2467 }, + { 13, 2472 }, + { 14, 2484 }, + { 0, -1 } +}; + +/** + * nm_utils_wifi_freq_to_channel: + * @freq: frequency + * + * Utility function to translate a Wi-Fi frequency to its corresponding channel. + * + * Returns: the channel represented by the frequency or 0 + **/ +guint32 +nm_utils_wifi_freq_to_channel (guint32 freq) +{ + int i = 0; + + if (freq > 4900) { + while (a_table[i].chan && (a_table[i].freq != freq)) + i++; + return a_table[i].chan; + } else { + while (bg_table[i].chan && (bg_table[i].freq != freq)) + i++; + return bg_table[i].chan; + } + + return 0; +} + +/** + * nm_utils_wifi_channel_to_freq: + * @channel: channel + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to translate a Wi-Fi channel to its corresponding frequency. + * + * Returns: the frequency represented by the channel of the band, + * or -1 when the freq is invalid, or 0 when the band + * is invalid + **/ +guint32 +nm_utils_wifi_channel_to_freq (guint32 channel, const char *band) +{ + int i = 0; + + if (!strcmp (band, "a")) { + while (a_table[i].chan && (a_table[i].chan != channel)) + i++; + return a_table[i].freq; + } else if (!strcmp (band, "bg")) { + while (bg_table[i].chan && (bg_table[i].chan != channel)) + i++; + return bg_table[i].freq; + } + + return 0; +} + +/** + * nm_utils_wifi_find_next_channel: + * @channel: current channel + * @direction: whether going downward (0 or less) or upward (1 or more) + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to find out next/previous Wi-Fi channel for a channel. + * + * Returns: the next channel in the specified direction or 0 + **/ +guint32 +nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) +{ + size_t a_size = sizeof (a_table) / sizeof (struct cf_pair); + size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair); + struct cf_pair *pair = NULL; + + if (!strcmp (band, "a")) { + if (channel < a_table[0].chan) + return a_table[0].chan; + if (channel > a_table[a_size - 2].chan) + return a_table[a_size - 2].chan; + pair = &a_table[0]; + } else if (!strcmp (band, "bg")) { + if (channel < bg_table[0].chan) + return bg_table[0].chan; + if (channel > bg_table[bg_size - 2].chan) + return bg_table[bg_size - 2].chan; + pair = &bg_table[0]; + } else { + g_assert_not_reached (); + return 0; + } + + while (pair->chan) { + if (channel == pair->chan) + return channel; + if ((channel < (pair+1)->chan) && (channel > pair->chan)) { + if (direction > 0) + return (pair+1)->chan; + else + return pair->chan; + } + pair++; + } + return 0; +} + +/** + * nm_utils_wifi_is_channel_valid: + * @channel: channel + * @band: frequency band for wireless ("a" or "bg") + * + * Utility function to verify Wi-Fi channel validity. + * + * Returns: %TRUE or %FALSE + **/ +gboolean +nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) +{ + struct cf_pair *table = NULL; + int i = 0; + + if (!strcmp (band, "a")) + table = a_table; + else if (!strcmp (band, "bg")) + table = bg_table; + else + return FALSE; + + while (table[i].chan && (table[i].chan != channel)) + i++; + + if (table[i].chan != 0) + return TRUE; + else + return FALSE; +} + +/** + * nm_utils_wifi_strength_bars: + * @strength: the access point strength, from 0 to 100 + * + * Converts @strength into a 4-character-wide graphical representation of + * strength suitable for printing to stdout. If the current locale and terminal + * support it, this will use unicode graphics characters to represent + * "bars". Otherwise it will use 0 to 4 asterisks. + * + * Returns: the graphical representation of the access point strength + */ +const char * +nm_utils_wifi_strength_bars (guint8 strength) +{ + static const char *strength_full, *strength_high, *strength_med, *strength_low, *strength_none; + + if (G_UNLIKELY (strength_full == NULL)) { + gboolean can_show_graphics = TRUE; + char *locale_str; + + if (!g_get_charset (NULL)) { + /* Non-UTF-8 locale */ + locale_str = g_locale_from_utf8 ("\342\226\202\342\226\204\342\226\206\342\226\210", -1, NULL, NULL, NULL); + if (locale_str) + g_free (locale_str); + else + can_show_graphics = FALSE; + } + + /* The linux console font doesn't have these characters */ + if (g_strcmp0 (g_getenv ("TERM"), "linux") == 0) + can_show_graphics = FALSE; + + if (can_show_graphics) { + strength_full = /* ▂▄▆█ */ "\342\226\202\342\226\204\342\226\206\342\226\210"; + strength_high = /* ▂▄▆_ */ "\342\226\202\342\226\204\342\226\206_"; + strength_med = /* ▂▄__ */ "\342\226\202\342\226\204__"; + strength_low = /* ▂___ */ "\342\226\202___"; + strength_none = /* ____ */ "____"; + } else { + strength_full = "****"; + strength_high = "*** "; + strength_med = "** "; + strength_low = "* "; + strength_none = " "; + } + } + + if (strength > 80) + return strength_full; + else if (strength > 55) + return strength_high; + else if (strength > 30) + return strength_med; + else if (strength > 5) + return strength_low; + else + return strength_none; +} + +/** + * nm_utils_hwaddr_len: + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND + * + * Returns the length in octets of a hardware address of type @type. + * + * It is an error to call this function with any value other than + * ARPHRD_ETHER or ARPHRD_INFINIBAND. + * + * Return value: the length. + */ +gsize +nm_utils_hwaddr_len (int type) +{ + g_return_val_if_fail (type == ARPHRD_ETHER || type == ARPHRD_INFINIBAND, 0); + + if (type == ARPHRD_ETHER) + return ETH_ALEN; + else if (type == ARPHRD_INFINIBAND) + return INFINIBAND_ALEN; + + g_assert_not_reached (); +} + +#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) + +/** + * nm_utils_hwaddr_atoba: + * @asc: the ASCII representation of a hardware address + * @length: the expected length in bytes of the result + * + * Parses @asc and converts it to binary form in a #GByteArray. See + * nm_utils_hwaddr_aton() if you don't want a #GByteArray. + * + * Return value: (transfer full): a new #GByteArray, or %NULL if @asc couldn't + * be parsed + */ +GByteArray * +nm_utils_hwaddr_atoba (const char *asc, gsize length) +{ + GByteArray *ba; + + g_return_val_if_fail (asc != NULL, NULL); + g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); + + ba = g_byte_array_sized_new (length); + g_byte_array_set_size (ba, length); + if (!nm_utils_hwaddr_aton (asc, ba->data, length)) { + g_byte_array_unref (ba); + return NULL; + } + + return ba; +} + +/** + * nm_utils_hwaddr_aton: + * @asc: the ASCII representation of a hardware address + * @buffer: buffer to store the result into + * @length: the expected length in bytes of the result and + * the size of the buffer in bytes. + * + * Parses @asc and converts it to binary form in @buffer. + * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed. + * + * Return value: @buffer, or %NULL if @asc couldn't be parsed + * or would be shorter or longer than @length. + */ +guint8 * +nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length) +{ + const char *in = asc; + guint8 *out = (guint8 *)buffer; + char delimiter = '\0'; + + g_return_val_if_fail (asc != NULL, NULL); + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); + + while (length && *in) { + guint8 d1 = in[0], d2 = in[1]; + + if (!g_ascii_isxdigit (d1)) + return NULL; + + /* If there's no leading zero (ie "aa:b:cc") then fake it */ + if (d2 && g_ascii_isxdigit (d2)) { + *out++ = (HEXVAL (d1) << 4) + HEXVAL (d2); + in += 2; + } else { + /* Fake leading zero */ + *out++ = (HEXVAL ('0') << 4) + HEXVAL (d1); + in += 1; + } + + length--; + if (*in) { + if (delimiter == '\0') { + if (*in == ':' || *in == '-') + delimiter = *in; + else + return NULL; + } else { + if (*in != delimiter) + return NULL; + } + in++; + } + } + + if (length == 0 && !*in) + return buffer; + else + return NULL; +} + +/** + * nm_utils_hwaddr_ntoa: + * @addr: (type guint8) (array length=length): a binary hardware address + * @length: the length of @addr + * + * Converts @addr to textual form. + * + * Return value: (transfer full): the textual form of @addr + */ +char * +nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length) +{ + const guint8 *in = addr; + char *out, *result; + const char *LOOKUP = "0123456789ABCDEF"; + + g_return_val_if_fail (addr != NULL, g_strdup ("")); + g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, g_strdup ("")); + + result = out = g_malloc (length * 3); + while (length--) { + guint8 v = *in++; + + *out++ = LOOKUP[v >> 4]; + *out++ = LOOKUP[v & 0x0F]; + if (length) + *out++ = ':'; + } + + *out = 0; + return result; +} + +static int +hwaddr_binary_len (const char *asc) +{ + int octets = 1; + + if (!*asc) + return 0; + + for (; *asc; asc++) { + if (*asc == ':' || *asc == '-') + octets++; + } + return octets; +} + +/** + * nm_utils_hwaddr_valid: + * @asc: the ASCII representation of a hardware address + * @length: the length of address that @asc is expected to convert to + * (or -1 to accept any length up to %NM_UTILS_HWADDR_LEN_MAX) + * + * Parses @asc to see if it is a valid hardware address of the given + * length. + * + * Return value: %TRUE if @asc appears to be a valid hardware address + * of the indicated length, %FALSE if not. + */ +gboolean +nm_utils_hwaddr_valid (const char *asc, gssize length) +{ + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + + g_return_val_if_fail (asc != NULL, FALSE); + g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), FALSE); + + if (length == -1) { + length = hwaddr_binary_len (asc); + if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + } + + return nm_utils_hwaddr_aton (asc, buf, length) != NULL; +} + +/** + * nm_utils_hwaddr_canonical: + * @asc: the ASCII representation of a hardware address + * @length: the length of address that @asc is expected to convert to + * (or -1 to accept any length up to %NM_UTILS_HWADDR_LEN_MAX) + * + * Parses @asc to see if it is a valid hardware address of the given + * length, and if so, returns it in canonical form (uppercase, with + * leading 0s as needed, and with colons rather than hyphens). + * + * Return value: (transfer full): the canonicalized address if @asc appears to + * be a valid hardware address of the indicated length, %NULL if not. + */ +char * +nm_utils_hwaddr_canonical (const char *asc, gssize length) +{ + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + + g_return_val_if_fail (asc != NULL, NULL); + g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), NULL); + + if (length == -1) { + length = hwaddr_binary_len (asc); + if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX) + return NULL; + } + + if (nm_utils_hwaddr_aton (asc, buf, length) == NULL) + return NULL; + + return g_strdup (nm_utils_hwaddr_ntoa (buf, length)); +} + +/* This is used to possibly canonicalize values passed to MAC address property + * setters. Unlike nm_utils_hwaddr_canonical(), it accepts %NULL, and if you + * pass it an invalid MAC address, it just returns that string rather than + * returning %NULL (so that we can return a proper error from verify() later). + */ +char * +_nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length) +{ + char *canonical; + + if (!mac) + return NULL; + + canonical = nm_utils_hwaddr_canonical (mac, length); + if (canonical) + return canonical; + else + return g_strdup (mac); +} + +/** + * nm_utils_hwaddr_matches: + * @hwaddr1: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr1_len: size of @hwaddr1, or -1 if @hwaddr1 is ASCII + * @hwaddr2: pointer to a binary or ASCII hardware address, or %NULL + * @hwaddr2_len: size of @hwaddr2, or -1 if @hwaddr2 is ASCII + * + * Generalized hardware address comparison function. Tests if @hwaddr1 and + * @hwaddr2 "equal" (or more precisely, "equivalent"), with several advantages + * over a simple memcmp(): + * + * 1. If @hwaddr1_len or @hwaddr2_len is -1, then the corresponding address is + * assumed to be ASCII rather than binary, and will be converted to binary + * before being compared. + * + * 2. If @hwaddr1 or @hwaddr2 is %NULL, it is treated instead as though it was + * a zero-filled buffer @hwaddr1_len or @hwaddr2_len bytes long. + * + * 3. If @hwaddr1 and @hwaddr2 are InfiniBand hardware addresses (that is, if + * they are INFINIBAND_ALEN bytes long in binary form) + * then only the last 8 bytes are compared, since those are the only bytes + * that actually identify the hardware. (The other 12 bytes will change + * depending on the configuration of the InfiniBand fabric that the device + * is connected to.) + * + * If a passed-in ASCII hardware address cannot be parsed, or would parse to an + * address larger than %NM_UTILS_HWADDR_LEN_MAX, then it will silently fail to + * match. (This means that externally-provided address strings do not need to be + * sanity-checked before comparing them against known good addresses; they are + * guaranteed to not match if they are invalid.) + * + * Return value: %TRUE if @hwaddr1 and @hwaddr2 are equivalent, %FALSE if they are + * different (or either of them is invalid). + */ +gboolean +nm_utils_hwaddr_matches (gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len) +{ + guint8 buf1[NM_UTILS_HWADDR_LEN_MAX], buf2[NM_UTILS_HWADDR_LEN_MAX]; + + if (hwaddr1_len == -1) { + g_return_val_if_fail (hwaddr1 != NULL, FALSE); + + hwaddr1_len = hwaddr_binary_len (hwaddr1); + if (hwaddr1_len == 0 || hwaddr1_len > NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + if (!nm_utils_hwaddr_aton (hwaddr1, buf1, hwaddr1_len)) + return FALSE; + + hwaddr1 = buf1; + } else { + g_return_val_if_fail (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (!hwaddr1) { + memset (buf1, 0, hwaddr1_len); + hwaddr1 = buf1; + } + } + + if (hwaddr2_len == -1) { + g_return_val_if_fail (hwaddr2 != NULL, FALSE); + + if (!nm_utils_hwaddr_aton (hwaddr2, buf2, hwaddr1_len)) + return FALSE; + + hwaddr2 = buf2; + hwaddr2_len = hwaddr1_len; + } else { + g_return_val_if_fail (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + + if (!hwaddr2) { + memset (buf2, 0, hwaddr2_len); + hwaddr2 = buf2; + } + } + + if (hwaddr1_len != hwaddr2_len) + return FALSE; + + if (hwaddr1_len == INFINIBAND_ALEN) { + hwaddr1 = (guint8 *)hwaddr1 + INFINIBAND_ALEN - 8; + hwaddr2 = (guint8 *)hwaddr2 + INFINIBAND_ALEN - 8; + hwaddr1_len = hwaddr2_len = 8; + } + + return !memcmp (hwaddr1, hwaddr2, hwaddr1_len); +} + +GVariant * +_nm_utils_hwaddr_to_dbus (const GValue *prop_value) +{ + const char *str = g_value_get_string (prop_value); + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + int len; + + if (str) { + len = hwaddr_binary_len (str); + g_return_val_if_fail (len > 0 && len <= NM_UTILS_HWADDR_LEN_MAX, NULL); + if (!nm_utils_hwaddr_aton (str, buf, len)) + len = 0; + } else + len = 0; + + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1); +} + +void +_nm_utils_hwaddr_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + gsize length = 0; + const guint8 *array = g_variant_get_fixed_array (dbus_value, &length, 1); + char *str; + + str = length ? nm_utils_hwaddr_ntoa (array, length) : NULL; + g_value_take_string (prop_value, str); +} + +/** + * nm_utils_bin2hexstr: + * @src: (type guint8) (array length=len): an array of bytes + * @len: the length of the @src array + * @final_len: an index where to cut off the returned string, or -1 + * + * Converts the byte array @src into a hexadecimal string. If @final_len is + * greater than -1, the returned string is terminated at that index + * (returned_string[final_len] == '\0'), + * + * Return value: (transfer full): the textual form of @bytes + */ +/* + * Code originally by Alex Larsson and + * copyright Red Hat, Inc. under terms of the LGPL. + */ +char * +nm_utils_bin2hexstr (gconstpointer src, gsize len, int final_len) +{ + static char hex_digits[] = "0123456789abcdef"; + const guint8 *bytes = src; + 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; +} + +/** + * nm_utils_hexstr2bin: + * @hex: a string of hexadecimal characters with optional ':' separators + * + * Converts a hexadecimal string @hex into an array of bytes. The optional + * separator ':' may be used between single or pairs of hexadecimal characters, + * eg "00:11" or "0:1". Any "0x" at the beginning of @hex is ignored. @hex + * may not start or end with ':'. + * + * Return value: (transfer full): the converted bytes, or %NULL on error + */ +GBytes * +nm_utils_hexstr2bin (const char *hex) +{ + guint i = 0, x = 0; + gs_free guint8 *c = NULL; + int a, b; + gboolean found_colon = FALSE; + + g_return_val_if_fail (hex != NULL, NULL); + + if (strncasecmp (hex, "0x", 2) == 0) + hex += 2; + found_colon = !!strchr (hex, ':'); + + c = g_malloc (strlen (hex) / 2 + 1); + for (;;) { + a = g_ascii_xdigit_value (hex[i++]); + if (a < 0) + return NULL; + + if (hex[i] && hex[i] != ':') { + b = g_ascii_xdigit_value (hex[i++]); + if (b < 0) + return NULL; + c[x++] = ((guint) a << 4) | ((guint) b); + } else + c[x++] = (guint) a; + + if (!hex[i]) + break; + if (hex[i] == ':') { + if (!hex[i + 1]) { + /* trailing ':' is invalid */ + return NULL; + } + i++; + } else if (found_colon) { + /* If colons exist, they must delimit 1 or 2 hex chars */ + return NULL; + } + } + + return g_bytes_new (c, x); +} + +/** + * nm_utils_iface_valid_name: + * @name: Name of interface + * + * This function is a 1:1 copy of the kernel's interface validation + * function in net/core/dev.c. + * + * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + */ +gboolean +nm_utils_iface_valid_name (const char *name) +{ + g_return_val_if_fail (name != NULL, FALSE); + + if (*name == '\0') + return FALSE; + + if (strlen (name) >= 16) + return FALSE; + + if (!strcmp (name, ".") || !strcmp (name, "..")) + return FALSE; + + while (*name) { + if (*name == '/' || g_ascii_isspace (*name)) + return FALSE; + name++; + } + + return TRUE; +} + +/** + * nm_utils_is_uuid: + * @str: a string that might be a UUID + * + * Checks if @str is a UUID + * + * Returns: %TRUE if @str is a UUID, %FALSE if not + */ +gboolean +nm_utils_is_uuid (const char *str) +{ + const char *p = str; + int num_dashes = 0; + + while (*p) { + if (*p == '-') + num_dashes++; + else if (!g_ascii_isxdigit (*p)) + return FALSE; + p++; + } + + if ((num_dashes == 4) && (p - str == 36)) + return TRUE; + + /* Backwards compat for older configurations */ + if ((num_dashes == 0) && (p - str == 40)) + return TRUE; + + return FALSE; +} + +static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; + +/** + * nm_utils_inet4_ntop: (skip) + * @inaddr: the address that should be converted to string. + * @dst: the destination buffer, it must contain at least + * INET_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet6_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * using the internal buffer is not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. + * + * Wrapper for inet_ntop. + * + * Returns: the input buffer @dst, or a pointer to an + * internal, static buffer. This function cannot fail. + **/ +const char * +nm_utils_inet4_ntop (in_addr_t inaddr, char *dst) +{ + return inet_ntop (AF_INET, &inaddr, dst ? dst : _nm_utils_inet_ntop_buffer, + INET_ADDRSTRLEN); +} + +/** + * nm_utils_inet6_ntop: (skip) + * @in6addr: the address that should be converted to string. + * @dst: the destination buffer, it must contain at least + * INET6_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet4_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * using the internal buffer is not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. + * + * Wrapper for inet_ntop. + * + * Returns: the input buffer @dst, or a pointer to an + * internal, static buffer. %NULL is not allowed as @in6addr, + * otherwise, this function cannot fail. + **/ +const char * +nm_utils_inet6_ntop (const struct in6_addr *in6addr, char *dst) +{ + g_return_val_if_fail (in6addr, NULL); + return inet_ntop (AF_INET6, in6addr, dst ? dst : _nm_utils_inet_ntop_buffer, + INET6_ADDRSTRLEN); +} + +/** + * nm_utils_ipaddr_valid: + * @family: AF_INET or AF_INET6, or + * AF_UNSPEC to accept either + * @ip: an IP address + * + * Checks if @ip contains a valid IP address of the given family. + * + * Return value: %TRUE or %FALSE + */ +gboolean +nm_utils_ipaddr_valid (int family, const char *ip) +{ + guint8 buf[sizeof (struct in6_addr)]; + + g_return_val_if_fail (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC, FALSE); + + if (family == AF_UNSPEC) + family = strchr (ip, ':') ? AF_INET6 : AF_INET; + + return inet_pton (family, ip, buf) == 1; +} + +/** + * nm_utils_check_virtual_device_compatibility: + * @virtual_type: a virtual connection type + * @other_type: a connection type to test against @virtual_type + * + * Determines if a connection of type @virtual_type can (in the + * general case) work with connections of type @other_type. + * + * If @virtual_type is %NM_TYPE_SETTING_VLAN, then this checks if + * @other_type is a valid type for the parent of a VLAN. + * + * If @virtual_type is a "master" type (eg, %NM_TYPE_SETTING_BRIDGE), + * then this checks if @other_type is a valid type for a slave of that + * master. + * + * Note that even if this returns %TRUE it is not guaranteed that + * every connection of type @other_type is + * compatible with @virtual_type; it may depend on the exact + * configuration of the two connections, or on the capabilities of an + * underlying device driver. + * + * Returns: %TRUE or %FALSE + */ +gboolean +nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type) +{ + g_return_val_if_fail (_nm_setting_type_is_base_type (virtual_type), FALSE); + g_return_val_if_fail (_nm_setting_type_is_base_type (other_type), FALSE); + + if (virtual_type == NM_TYPE_SETTING_BOND) { + return ( other_type == NM_TYPE_SETTING_INFINIBAND + || other_type == NM_TYPE_SETTING_WIRED + || other_type == NM_TYPE_SETTING_BRIDGE + || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM + || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_BRIDGE) { + return ( other_type == NM_TYPE_SETTING_WIRED + || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM + || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_TEAM) { + return ( other_type == NM_TYPE_SETTING_WIRED + || other_type == NM_TYPE_SETTING_BRIDGE + || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM + || other_type == NM_TYPE_SETTING_VLAN); + } else if (virtual_type == NM_TYPE_SETTING_VLAN) { + return ( other_type == NM_TYPE_SETTING_WIRED + || other_type == NM_TYPE_SETTING_WIRELESS + || other_type == NM_TYPE_SETTING_BRIDGE + || other_type == NM_TYPE_SETTING_BOND + || other_type == NM_TYPE_SETTING_TEAM + || other_type == NM_TYPE_SETTING_VLAN); + } else { + g_warn_if_reached (); + return FALSE; + } +} diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h new file mode 100644 index 00000000..8c22cfd1 --- /dev/null +++ b/libnm-core/nm-utils.h @@ -0,0 +1,190 @@ +/* -*- 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. + * + * Copyright 2005 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_UTILS_H__ +#define __NM_UTILS_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +#include + +/* For ETH_ALEN and INFINIBAND_ALEN */ +#include +#include + +#include "nm-dbus-interface.h" +#include "nm-core-enum-types.h" +#include "nm-setting-wireless-security.h" + +G_BEGIN_DECLS + +/* SSID helpers */ +gboolean nm_utils_is_empty_ssid (const guint8 *ssid, gsize len); +const char *nm_utils_escape_ssid (const guint8 *ssid, gsize len); +gboolean nm_utils_same_ssid (const guint8 *ssid1, gsize len1, + const guint8 *ssid2, gsize len2, + gboolean ignore_trailing_null); +char * nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len); + +/** + * NMUtilsSecurityType: + * @NMU_SEC_INVALID: unknown or invalid security, placeholder and not used + * @NMU_SEC_NONE: unencrypted and open + * @NMU_SEC_STATIC_WEP: static WEP keys are used for encryption + * @NMU_SEC_LEAP: Cisco LEAP is used for authentication and for generating the + * dynamic WEP keys automatically + * @NMU_SEC_DYNAMIC_WEP: standard 802.1x is used for authentication and + * generating the dynamic WEP keys automatically + * @NMU_SEC_WPA_PSK: WPA1 is used with Pre-Shared Keys (PSK) + * @NMU_SEC_WPA_ENTERPRISE: WPA1 is used with 802.1x authentication + * @NMU_SEC_WPA2_PSK: WPA2/RSN is used with Pre-Shared Keys (PSK) + * @NMU_SEC_WPA2_ENTERPRISE: WPA2 is used with 802.1x authentication + * + * Describes generic security mechanisms that 802.11 access points may offer. + * Used with nm_utils_security_valid() for checking whether a given access + * point is compatible with a network device. + **/ +typedef enum { + NMU_SEC_INVALID = 0, + NMU_SEC_NONE, + NMU_SEC_STATIC_WEP, + NMU_SEC_LEAP, + NMU_SEC_DYNAMIC_WEP, + NMU_SEC_WPA_PSK, + NMU_SEC_WPA_ENTERPRISE, + NMU_SEC_WPA2_PSK, + NMU_SEC_WPA2_ENTERPRISE +} NMUtilsSecurityType; + +gboolean nm_utils_security_valid (NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps, + gboolean have_ap, + gboolean adhoc, + NM80211ApFlags ap_flags, + NM80211ApSecurityFlags ap_wpa, + NM80211ApSecurityFlags ap_rsn); + +gboolean nm_utils_ap_mode_security_valid (NMUtilsSecurityType type, + NMDeviceWifiCapabilities wifi_caps); + +gboolean nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type); +gboolean nm_utils_wpa_psk_valid (const char *psk); + +GVariant *nm_utils_ip4_dns_to_variant (char **dns); +char **nm_utils_ip4_dns_from_variant (GVariant *value); +GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses, + const char *gateway); +GPtrArray *nm_utils_ip4_addresses_from_variant (GVariant *value, + char **out_gateway); +GVariant *nm_utils_ip4_routes_to_variant (GPtrArray *routes); +GPtrArray *nm_utils_ip4_routes_from_variant (GVariant *value); + +guint32 nm_utils_ip4_netmask_to_prefix (guint32 netmask); +guint32 nm_utils_ip4_prefix_to_netmask (guint32 prefix); +guint32 nm_utils_ip4_get_default_prefix (guint32 ip); + +GVariant *nm_utils_ip6_dns_to_variant (char **dns); +char **nm_utils_ip6_dns_from_variant (GVariant *value); +GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses, + const char *gateway); +GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value, + char **out_gateway); +GVariant *nm_utils_ip6_routes_to_variant (GPtrArray *routes); +GPtrArray *nm_utils_ip6_routes_from_variant (GVariant *value); + +GVariant *nm_utils_ip_addresses_to_variant (GPtrArray *addresses); +GPtrArray *nm_utils_ip_addresses_from_variant (GVariant *value, + int family); +GVariant *nm_utils_ip_routes_to_variant (GPtrArray *routes); +GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, + int family); + +char *nm_utils_uuid_generate (void); + +gboolean nm_utils_file_is_certificate (const char *filename); +gboolean nm_utils_file_is_private_key (const char *filename, gboolean *out_encrypted); +gboolean nm_utils_file_is_pkcs12 (const char *filename); + +typedef gboolean (*NMUtilsFileSearchInPathsPredicate) (const char *filename, gpointer user_data); + +const char *nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error); + +guint32 nm_utils_wifi_freq_to_channel (guint32 freq); +guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band); +guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band); +gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band); + +const char *nm_utils_wifi_strength_bars (guint8 strength); + +/** + * NM_UTILS_HWADDR_LEN_MAX: + * + * The maximum length of hardware addresses handled by NetworkManager itself, + * nm_utils_hwaddr_len(), and nm_utils_hwaddr_aton(). + */ +#define NM_UTILS_HWADDR_LEN_MAX 20 /* INFINIBAND_ALEN */ + +gsize nm_utils_hwaddr_len (int type) G_GNUC_PURE; + +char *nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length); +GByteArray *nm_utils_hwaddr_atoba (const char *asc, gsize length); +guint8 *nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length); + +gboolean nm_utils_hwaddr_valid (const char *asc, gssize length); +char *nm_utils_hwaddr_canonical (const char *asc, gssize length); +gboolean nm_utils_hwaddr_matches (gconstpointer hwaddr1, + gssize hwaddr1_len, + gconstpointer hwaddr2, + gssize hwaddr2_len); + +char *nm_utils_bin2hexstr (gconstpointer src, gsize len, int final_len); +GBytes *nm_utils_hexstr2bin (const char *hex); + +gboolean nm_utils_iface_valid_name(const char *name); + +gboolean nm_utils_is_uuid (const char *str); + +/** + * NM_UTILS_INET_ADDRSTRLEN: + * + * Defines the minimal length for a char buffer that is suitable as @dst argument + * for both nm_utils_inet4_ntop() and nm_utils_inet6_ntop(). + **/ +#define NM_UTILS_INET_ADDRSTRLEN INET6_ADDRSTRLEN +const char *nm_utils_inet4_ntop (in_addr_t inaddr, char *dst); +const char *nm_utils_inet6_ntop (const struct in6_addr *in6addr, char *dst); + +gboolean nm_utils_ipaddr_valid (int family, const char *ip); + +gboolean nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type); + +G_END_DECLS + +#endif /* __NM_UTILS_H__ */ diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h new file mode 100644 index 00000000..39cfd63f --- /dev/null +++ b/libnm-core/nm-version.h @@ -0,0 +1,123 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_VERSION_H +#define NM_VERSION_H + +/** + * NM_MAJOR_VERSION: + * + * Evaluates to the major version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MAJOR_VERSION (1) + +/** + * NM_MINOR_VERSION: + * + * Evaluates to the minor version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MINOR_VERSION (0) + +/** + * NM_MICRO_VERSION: + * + * Evaluates to the micro version number of NetworkManager which this source + * compiled against. + */ +#define NM_MICRO_VERSION (0) + +/** + * NM_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the NetworkManager header files + * is the same as or newer than the passed-in version. + */ +#define NM_CHECK_VERSION(major,minor,micro) \ + (NM_MAJOR_VERSION > (major) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro))) + + +/* Deprecation / Availability macros */ + +#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro)) + +#define NM_VERSION_0_9_8 (NM_ENCODE_VERSION (0, 9, 8)) +#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10)) +#define NM_VERSION_1_0 (NM_ENCODE_VERSION (1, 0, 0)) + +#define NM_VERSION_CUR_STABLE NM_VERSION_0_9_10 +#define NM_VERSION_NEXT_STABLE NM_VERSION_1_0 + +#if !defined (NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0) +# undef NM_VERSION_MIN_REQUIRED +# define NM_VERSION_MIN_REQUIRED (NM_VERSION_CUR_STABLE) +#endif + +#if !defined (NM_VERSION_MAX_ALLOWED) || (NM_VERSION_MAX_ALLOWED == 0) +# undef NM_VERSION_MAX_ALLOWED +# define NM_VERSION_MAX_ALLOWED (NM_VERSION_CUR_STABLE) +#endif + +/* sanity checks */ +#if NM_VERSION_MIN_REQUIRED > NM_VERSION_NEXT_STABLE +#error "NM_VERSION_MIN_REQUIRED must be <= NM_VERSION_NEXT_STABLE" +#endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_MIN_REQUIRED +#error "NM_VERSION_MAX_ALLOWED must be >= NM_VERSION_MIN_REQUIRED" +#endif +#if NM_VERSION_MIN_REQUIRED < NM_VERSION_0_9_8 +#error "NM_VERSION_MIN_REQUIRED must be >= NM_VERSION_0_9_8" +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_0_9_10 +# define NM_DEPRECATED_IN_0_9_10 G_DEPRECATED +# define NM_DEPRECATED_IN_0_9_10_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_0_9_10 +# define NM_DEPRECATED_IN_0_9_10_FOR(f) +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_0 +# define NM_DEPRECATED_IN_1_0 G_DEPRECATED +# define NM_DEPRECATED_IN_1_0_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_1_0 +# define NM_DEPRECATED_IN_1_0_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_0_9_10 +# define NM_AVAILABLE_IN_0_9_10 G_UNAVAILABLE(0.9,10) +#else +# define NM_AVAILABLE_IN_0_9_10 +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0 +# define NM_AVAILABLE_IN_1_0 G_UNAVAILABLE(1,0) +#else +# define NM_AVAILABLE_IN_1_0 +#endif + +#endif /* NM_VERSION_H */ diff --git a/libnm-core/nm-version.h.in b/libnm-core/nm-version.h.in new file mode 100644 index 00000000..0a33ac29 --- /dev/null +++ b/libnm-core/nm-version.h.in @@ -0,0 +1,123 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_VERSION_H +#define NM_VERSION_H + +/** + * NM_MAJOR_VERSION: + * + * Evaluates to the major version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MAJOR_VERSION (@NM_MAJOR_VERSION@) + +/** + * NM_MINOR_VERSION: + * + * Evaluates to the minor version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MINOR_VERSION (@NM_MINOR_VERSION@) + +/** + * NM_MICRO_VERSION: + * + * Evaluates to the micro version number of NetworkManager which this source + * compiled against. + */ +#define NM_MICRO_VERSION (@NM_MICRO_VERSION@) + +/** + * NM_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the NetworkManager header files + * is the same as or newer than the passed-in version. + */ +#define NM_CHECK_VERSION(major,minor,micro) \ + (NM_MAJOR_VERSION > (major) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro))) + + +/* Deprecation / Availability macros */ + +#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro)) + +#define NM_VERSION_0_9_8 (NM_ENCODE_VERSION (0, 9, 8)) +#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10)) +#define NM_VERSION_1_0 (NM_ENCODE_VERSION (1, 0, 0)) + +#define NM_VERSION_CUR_STABLE NM_VERSION_0_9_10 +#define NM_VERSION_NEXT_STABLE NM_VERSION_1_0 + +#if !defined (NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0) +# undef NM_VERSION_MIN_REQUIRED +# define NM_VERSION_MIN_REQUIRED (NM_VERSION_CUR_STABLE) +#endif + +#if !defined (NM_VERSION_MAX_ALLOWED) || (NM_VERSION_MAX_ALLOWED == 0) +# undef NM_VERSION_MAX_ALLOWED +# define NM_VERSION_MAX_ALLOWED (NM_VERSION_CUR_STABLE) +#endif + +/* sanity checks */ +#if NM_VERSION_MIN_REQUIRED > NM_VERSION_NEXT_STABLE +#error "NM_VERSION_MIN_REQUIRED must be <= NM_VERSION_NEXT_STABLE" +#endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_MIN_REQUIRED +#error "NM_VERSION_MAX_ALLOWED must be >= NM_VERSION_MIN_REQUIRED" +#endif +#if NM_VERSION_MIN_REQUIRED < NM_VERSION_0_9_8 +#error "NM_VERSION_MIN_REQUIRED must be >= NM_VERSION_0_9_8" +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_0_9_10 +# define NM_DEPRECATED_IN_0_9_10 G_DEPRECATED +# define NM_DEPRECATED_IN_0_9_10_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_0_9_10 +# define NM_DEPRECATED_IN_0_9_10_FOR(f) +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_0 +# define NM_DEPRECATED_IN_1_0 G_DEPRECATED +# define NM_DEPRECATED_IN_1_0_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_1_0 +# define NM_DEPRECATED_IN_1_0_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_0_9_10 +# define NM_AVAILABLE_IN_0_9_10 G_UNAVAILABLE(0.9,10) +#else +# define NM_AVAILABLE_IN_0_9_10 +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0 +# define NM_AVAILABLE_IN_1_0 G_UNAVAILABLE(1,0) +#else +# define NM_AVAILABLE_IN_1_0 +#endif + +#endif /* NM_VERSION_H */ diff --git a/libnm-core/nm-vpn-dbus-interface.h b/libnm-core/nm-vpn-dbus-interface.h new file mode 100644 index 00000000..c4099be2 --- /dev/null +++ b/libnm-core/nm-vpn-dbus-interface.h @@ -0,0 +1,307 @@ +/* -*- 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. + * + * Copyright 2004 Red Hat, Inc. + */ + +/* D-Bus-related definitions for NetworkManager VPN plugins. + * + * Note that although this header is installed as part of libnm, it is also + * used by some external code that does not link to libnm. + */ + +#ifndef __NM_VPN_DBUS_INTERFACE_H__ +#define __NM_VPN_DBUS_INTERFACE_H__ + +/* + * dbus services details + */ +#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPN/Manager" +#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPN.Manager" + +#define NM_DBUS_PATH_VPN_CONNECTION "/org/freedesktop/NetworkManager/VPN/Connection" +#define NM_DBUS_INTERFACE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPN.Connection" + +#define NM_VPN_DBUS_PLUGIN_PATH "/org/freedesktop/NetworkManager/VPN/Plugin" +#define NM_VPN_DBUS_PLUGIN_INTERFACE "org.freedesktop.NetworkManager.VPN.Plugin" + +/* + * VPN Errors + */ +#define NM_DBUS_NO_ACTIVE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPNConnections.NoActiveVPNConnection" +#define NM_DBUS_NO_VPN_CONNECTIONS "org.freedesktop.NetworkManager.VPNConnections.NoVPNConnections" +#define NM_DBUS_INVALID_VPN_CONNECTION "org.freedesktop.NetworkManager.VPNConnections.InvalidVPNConnection" + +#define NM_DBUS_VPN_ERROR_PREFIX "org.freedesktop.NetworkManager.VPN.Error" +#define NM_DBUS_VPN_STARTING_IN_PROGRESS "StartingInProgress" +#define NM_DBUS_VPN_ALREADY_STARTED "AlreadyStarted" +#define NM_DBUS_VPN_STOPPING_IN_PROGRESS "StoppingInProgress" +#define NM_DBUS_VPN_ALREADY_STOPPED "AlreadyStopped" +#define NM_DBUS_VPN_WRONG_STATE "WrongState" +#define NM_DBUS_VPN_BAD_ARGUMENTS "BadArguments" +#define NM_DBUS_VPN_INTERACTIVE_NOT_SUPPORTED "InteractiveNotSupported" + + +/* + * VPN daemon signals + */ +#define NM_DBUS_VPN_SIGNAL_LOGIN_BANNER "LoginBanner" +#define NM_DBUS_VPN_SIGNAL_LOGIN_FAILED "LoginFailed" +#define NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED "LaunchFailed" +#define NM_DBUS_VPN_SIGNAL_CONNECT_FAILED "ConnectFailed" +#define NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD "VPNConfigBad" +#define NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD "IPConfigBad" +#define NM_DBUS_VPN_SIGNAL_STATE_CHANGE "StateChange" +#define NM_DBUS_VPN_SIGNAL_IP4_CONFIG "IP4Config" + +/** + * NMVpnServiceState: + * @NM_VPN_SERVICE_STATE_UNKNOWN: The state of the VPN plugin is unknown. + * @NM_VPN_SERVICE_STATE_INIT: The VPN plugin is initialized. + * @NM_VPN_SERVICE_STATE_SHUTDOWN: Not used. + * @NM_VPN_SERVICE_STATE_STARTING: The plugin is attempting to connect to a VPN server. + * @NM_VPN_SERVICE_STATE_STARTED: The plugin has connected to a VPN server. + * @NM_VPN_SERVICE_STATE_STOPPING: The plugin is disconnecting from the VPN server. + * @NM_VPN_SERVICE_STATE_STOPPED: The plugin has disconnected from the VPN server. + * + * VPN daemon states + * + * (Corresponds to the NM_VPN_SERVICE_STATE type in nm-vpn-connection.xml.) + */ +typedef enum { + NM_VPN_SERVICE_STATE_UNKNOWN = 0, + NM_VPN_SERVICE_STATE_INIT, + NM_VPN_SERVICE_STATE_SHUTDOWN, + NM_VPN_SERVICE_STATE_STARTING, + NM_VPN_SERVICE_STATE_STARTED, + NM_VPN_SERVICE_STATE_STOPPING, + NM_VPN_SERVICE_STATE_STOPPED +} NMVpnServiceState; + + +/** + * NMVpnConnectionState: + * @NM_VPN_CONNECTION_STATE_UNKNOWN: The state of the VPN connection is + * unknown. + * @NM_VPN_CONNECTION_STATE_PREPARE: The VPN connection is preparing to + * connect. + * @NM_VPN_CONNECTION_STATE_NEED_AUTH: The VPN connection needs authorization + * credentials. + * @NM_VPN_CONNECTION_STATE_CONNECT: The VPN connection is being established. + * @NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: The VPN connection is getting an IP + * address. + * @NM_VPN_CONNECTION_STATE_ACTIVATED: The VPN connection is active. + * @NM_VPN_CONNECTION_STATE_FAILED: The VPN connection failed. + * @NM_VPN_CONNECTION_STATE_DISCONNECTED: The VPN connection is disconnected. + * + * VPN connection states + * + * (Corresponds to the NM_VPN_CONNECTION_STATE type in nm-vpn-connection.xml.) + */ +typedef enum { + NM_VPN_CONNECTION_STATE_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_PREPARE, + NM_VPN_CONNECTION_STATE_NEED_AUTH, + NM_VPN_CONNECTION_STATE_CONNECT, + NM_VPN_CONNECTION_STATE_IP_CONFIG_GET, + NM_VPN_CONNECTION_STATE_ACTIVATED, + NM_VPN_CONNECTION_STATE_FAILED, + NM_VPN_CONNECTION_STATE_DISCONNECTED +} NMVpnConnectionState; + +/** + * NMVpnConnectionStateReason: + * @NM_VPN_CONNECTION_STATE_REASON_UNKNOWN: The reason for the VPN connection + * state change is unknown. + * @NM_VPN_CONNECTION_STATE_REASON_NONE: No reason was given for the VPN + * connection state change. + * @NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED: The VPN connection changed + * state because the user disconnected it. + * @NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: The VPN connection + * changed state because the device it was using was disconnected. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED: The service providing the + * VPN connection was stopped. + * @NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: The IP config of the VPN + * connection was invalid. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: The connection attempt to + * the VPN service timed out. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: A timeout occurred + * while starting the service providing the VPN connection. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED: Starting the service + * starting the service providing the VPN connection failed. + * @NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS: Necessary secrets for the VPN + * connection were not provided. + * @NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED: Authentication to the VPN + * server failed. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED: The connection was + * deleted from settings. + * + * VPN connection state reasons + * + * (Corresponds to the NM_VPN_CONNECTION_STATE_REASON type in nm-vpn-connection.xml.) + */ +typedef enum { + NM_VPN_CONNECTION_STATE_REASON_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_REASON_NONE, + NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED, + NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED, + NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, + NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED, + NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, + NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED, + NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED +} NMVpnConnectionStateReason; + +/** + * NMVpnPluginFailure: + * @NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED: Login failed. + * @NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED: Connect failed. + * @NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG: Invalid IP configuration returned from + * the VPN plugin. + * + * VPN plugin failure reasons + * + * (Corresponds to the NM_VPN_PLUGIN_FAILURE type in nm-vpn-plugin.xml.) + */ +typedef enum { + NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED, + NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED, + NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG +} NMVpnPluginFailure; + + +/*** Generic config ***/ + +/* string: VPN interface name (tun0, tap0, etc) */ +#define NM_VPN_PLUGIN_CONFIG_TUNDEV "tundev" + +/* string: Login message */ +#define NM_VPN_PLUGIN_CONFIG_BANNER "banner" + +/* uint32 / array of uint8: IP address of the public external VPN gateway (network byte order) */ +#define NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY "gateway" + +/* uint32: Maximum Transfer Unit that the VPN interface should use */ +#define NM_VPN_PLUGIN_CONFIG_MTU "mtu" + +/* boolean: Has IP4 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP4 "has-ip4" + +/* boolean: Has IP6 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP6 "has-ip6" + +/* boolean: If %TRUE the VPN plugin can persist/reconnect the connection over + * link changes and VPN server dropouts. + */ +#define NM_VPN_PLUGIN_CAN_PERSIST "can-persist" + + +/*** Ip4Config ***/ + +/* uint32: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY "internal-gateway" + +/* uint32: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address" + +/* uint32: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PTP "ptp" + +/* uint32: IP prefix of the VPN interface; 1 - 32 inclusive */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PREFIX "prefix" + +/* array of uint32: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DNS "dns" + +/* array of uint32: IP addresses of NBNS/WINS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NBNS "nbns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP4_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS "domains" + +/* [ip4 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip4_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ROUTES "routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT "never-default" + +/* Deprecated */ +#define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY + +/* Legacy IP4 items; these are included in the IP4 config by older plugins, + * but in the generic config by newer plugins. + */ + +#define NM_VPN_PLUGIN_IP4_CONFIG_BANNER NM_VPN_PLUGIN_CONFIG_BANNER +#define NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY +#define NM_VPN_PLUGIN_IP4_CONFIG_MTU NM_VPN_PLUGIN_CONFIG_MTU +#define NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV NM_VPN_PLUGIN_CONFIG_TUNDEV + + +/*** Ip6Config ***/ + +/* array of uint8: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY "internal-gateway" + +/* array of uint8: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS "address" + +/* array of uint8: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PTP "ptp" + +/* uint32: prefix length of the VPN interface; 1 - 128 inclusive */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PREFIX "prefix" + +/* array of array of uint8: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DNS "dns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP6_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS "domains" + +/* [ip6 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip6_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ROUTES "routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT "never-default" + +#endif /* __NM_VPN_DBUS_INTERFACE_H__ */ diff --git a/libnm-core/tests/Makefile.am b/libnm-core/tests/Makefile.am new file mode 100644 index 00000000..a21c131c --- /dev/null +++ b/libnm-core/tests/Makefile.am @@ -0,0 +1,56 @@ +if ENABLE_TESTS + +certsdir = $(srcdir)/certs + +AM_CPPFLAGS = \ + -I${top_srcdir}/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + -DTEST_CERT_DIR=\"$(certsdir)\" + +noinst_PROGRAMS = \ + test-compare \ + test-crypto \ + test-general \ + test-secrets \ + test-setting-8021x \ + test-setting-dcb \ + test-settings-defaults + +LDADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + $(GLIB_LIBS) + +TESTS = $(noinst_PROGRAMS) + +endif + +# test-cert.p12 created with: +# +# openssl pkcs12 -export \ +# -in test_key_and_cert.pem \ +# -inkey test_key_and_cert.pem \ +# -certfile test_ca_cert.pem \ +# -name "test-pkcs12" \ +# -out test-cert.p12 + +EXTRA_DIST = \ + certs/test_ca_cert.pem \ + certs/test_ca_cert.der \ + certs/test_key_and_cert.pem \ + certs/test-cert.p12 \ + certs/test2_ca_cert.pem \ + certs/test2_key_and_cert.pem \ + certs/test2-cert.p12 \ + certs/ca-no-ending-newline.pem \ + certs/test-key-only.pem \ + certs/test-key-only-decrypted.der \ + certs/test-key-only-decrypted.pem \ + certs/pkcs8-enc-key.pem \ + certs/pkcs8-noenc-key.pem \ + certs/pkcs8-decrypted.der \ + certs/test-aes-key.pem + diff --git a/libnm-core/tests/Makefile.in b/libnm-core/tests/Makefile.in new file mode 100644 index 00000000..b62df8b4 --- /dev/null +++ b/libnm-core/tests/Makefile.in @@ -0,0 +1,959 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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@ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-compare$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-crypto$(EXEEXT) test-general$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-secrets$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-8021x$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-dcb$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-settings-defaults$(EXEEXT) +subdir = libnm-core/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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) +test_compare_SOURCES = test-compare.c +test_compare_OBJECTS = test-compare.$(OBJEXT) +test_compare_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +@ENABLE_TESTS_TRUE@test_compare_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +test_crypto_SOURCES = test-crypto.c +test_crypto_OBJECTS = test-crypto.$(OBJEXT) +test_crypto_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_crypto_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_general_SOURCES = test-general.c +test_general_OBJECTS = test-general.$(OBJEXT) +test_general_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_general_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_secrets_SOURCES = test-secrets.c +test_secrets_OBJECTS = test-secrets.$(OBJEXT) +test_secrets_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_secrets_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_setting_8021x_SOURCES = test-setting-8021x.c +test_setting_8021x_OBJECTS = test-setting-8021x.$(OBJEXT) +test_setting_8021x_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_setting_8021x_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_setting_dcb_SOURCES = test-setting-dcb.c +test_setting_dcb_OBJECTS = test-setting-dcb.$(OBJEXT) +test_setting_dcb_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_setting_dcb_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +test_settings_defaults_SOURCES = test-settings-defaults.c +test_settings_defaults_OBJECTS = test-settings-defaults.$(OBJEXT) +test_settings_defaults_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_settings_defaults_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = test-compare.c test-crypto.c test-general.c test-secrets.c \ + test-setting-8021x.c test-setting-dcb.c \ + test-settings-defaults.c +DIST_SOURCES = test-compare.c test-crypto.c test-general.c \ + test-secrets.c test-setting-8021x.c test-setting-dcb.c \ + test-settings-defaults.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +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@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +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@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +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@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +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@ +PERL = @PERL@ +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_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +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_CXX = @ac_ct_CXX@ +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@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +@ENABLE_TESTS_TRUE@certsdir = $(srcdir)/certs +@ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ +@ENABLE_TESTS_TRUE@ -I${top_srcdir}/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ +@ENABLE_TESTS_TRUE@ -DTEST_CERT_DIR=\"$(certsdir)\" + +@ENABLE_TESTS_TRUE@LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-core/libnm-core.la \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) + +@ENABLE_TESTS_TRUE@TESTS = $(noinst_PROGRAMS) + +# test-cert.p12 created with: +# +# openssl pkcs12 -export \ +# -in test_key_and_cert.pem \ +# -inkey test_key_and_cert.pem \ +# -certfile test_ca_cert.pem \ +# -name "test-pkcs12" \ +# -out test-cert.p12 +EXTRA_DIST = \ + certs/test_ca_cert.pem \ + certs/test_ca_cert.der \ + certs/test_key_and_cert.pem \ + certs/test-cert.p12 \ + certs/test2_ca_cert.pem \ + certs/test2_key_and_cert.pem \ + certs/test2-cert.p12 \ + certs/ca-no-ending-newline.pem \ + certs/test-key-only.pem \ + certs/test-key-only-decrypted.der \ + certs/test-key-only-decrypted.pem \ + certs/pkcs8-enc-key.pem \ + certs/pkcs8-noenc-key.pem \ + certs/pkcs8-decrypted.der \ + certs/test-aes-key.pem + +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 libnm-core/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libnm-core/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-compare$(EXEEXT): $(test_compare_OBJECTS) $(test_compare_DEPENDENCIES) $(EXTRA_test_compare_DEPENDENCIES) + @rm -f test-compare$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_compare_OBJECTS) $(test_compare_LDADD) $(LIBS) + +test-crypto$(EXEEXT): $(test_crypto_OBJECTS) $(test_crypto_DEPENDENCIES) $(EXTRA_test_crypto_DEPENDENCIES) + @rm -f test-crypto$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_crypto_OBJECTS) $(test_crypto_LDADD) $(LIBS) + +test-general$(EXEEXT): $(test_general_OBJECTS) $(test_general_DEPENDENCIES) $(EXTRA_test_general_DEPENDENCIES) + @rm -f test-general$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_general_OBJECTS) $(test_general_LDADD) $(LIBS) + +test-secrets$(EXEEXT): $(test_secrets_OBJECTS) $(test_secrets_DEPENDENCIES) $(EXTRA_test_secrets_DEPENDENCIES) + @rm -f test-secrets$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_secrets_OBJECTS) $(test_secrets_LDADD) $(LIBS) + +test-setting-8021x$(EXEEXT): $(test_setting_8021x_OBJECTS) $(test_setting_8021x_DEPENDENCIES) $(EXTRA_test_setting_8021x_DEPENDENCIES) + @rm -f test-setting-8021x$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_setting_8021x_OBJECTS) $(test_setting_8021x_LDADD) $(LIBS) + +test-setting-dcb$(EXEEXT): $(test_setting_dcb_OBJECTS) $(test_setting_dcb_DEPENDENCIES) $(EXTRA_test_setting_dcb_DEPENDENCIES) + @rm -f test-setting-dcb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_setting_dcb_OBJECTS) $(test_setting_dcb_LDADD) $(LIBS) + +test-settings-defaults$(EXEEXT): $(test_settings_defaults_OBJECTS) $(test_settings_defaults_DEPENDENCIES) $(EXTRA_test_settings_defaults_DEPENDENCIES) + @rm -f test-settings-defaults$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_settings_defaults_OBJECTS) $(test_settings_defaults_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-compare.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-crypto.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-secrets.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-8021x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-dcb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-settings-defaults.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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 $(AM_TESTS_FD_REDIRECT); 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 \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$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-TESTS +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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 TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am 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 tags-am 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/libnm-core/tests/certs/ca-no-ending-newline.pem b/libnm-core/tests/certs/ca-no-ending-newline.pem new file mode 100644 index 00000000..664e299a --- /dev/null +++ b/libnm-core/tests/certs/ca-no-ending-newline.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- \ No newline at end of file diff --git a/libnm-core/tests/certs/pkcs8-decrypted.der b/libnm-core/tests/certs/pkcs8-decrypted.der new file mode 100644 index 00000000..2cbdeb5e Binary files /dev/null and b/libnm-core/tests/certs/pkcs8-decrypted.der differ diff --git a/libnm-core/tests/certs/pkcs8-enc-key.pem b/libnm-core/tests/certs/pkcs8-enc-key.pem new file mode 100644 index 00000000..0d08f2d2 --- /dev/null +++ b/libnm-core/tests/certs/pkcs8-enc-key.pem @@ -0,0 +1,29 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIwiGFT4Jz6RsCAggABIIEyJNMddDYofbhydUp +J3VyrYIjv3LziJ7dkTXE3+mEYRCQrGLgljWBbib2JOLVCFt8melL6Yv1RcoVR7X7 +vrRqyycu0DumI4f5+Bf4wc234JNVhSaLYsw244fFtcnK2Gyn4IaVmWmrNvrwfX/w +SKcVmO30D5C5PCKzv2bou5FmnJLKdDQV1t816cr9T8pTx7MHvBzSZXbh86334BhF +T3zNwo8j2/+Gq2NBWUn+2GTTV8/r26aIwPcFi4QH6I2ghBwFmFHqU3/PoRm6nkmg +CqJj2Dggy+8zE5qg0iId7lrio0OjCH+Qed6NGwIa2lgv/bhuJVP3FOk4gqamJWHi +WMaq9McmS+03q2iokYeSQGbx85x+I90RTFZKhFx4dkerf6oTC/YoL4F++ff0e91v +sOrQsBkgRhrRtFwa9OFCzbsknlixONdd+ITkyX490xz1wcZTDkKtMDRLIPWa2O0b +MEq75jPYThZ5pF1vc5r+rqPafN7SfI+DDmhzJYEQNRoCWA4pH9Gwv0ayKnOgoj4K +TuFhXvcyWzTnVXmcqEFyf3CRrB0Ti+Z61enupC+FCuYV5lGsx9kJaTumTk2UPD02 +9Ap3asDLozdEPSXBG3+oCM2s01/IJlxtR84C97r9rpmWTc9K6DCBScETe9KnIghW +PU7XFogueG5Gwpe+x+IlTDq+qiyUNVX1uMGDcIaCC3VsoWqZrpnGGBhsovwBaXKt +T9fT2nE27Fd6DRWso4fgos6PPx7RVveu17BTMVQeUq9L8GrV4JNrE3a9aoXdbUhc +6gMiyAqxh/HEyciYoXsR9oVNi+VM0y8q3hL5nIcgDrCZr/c9aQ8+fuQBDXRrmrQd +bR2iwNLCBnbmQmM/vM333VhJ4MSOKd3SGw/j41K+Nr3uP5KRZUwV+5yy3ef/hGxU +i9JjCmSUt2bfWRUFlNaf1hCTYaKD0xnVr1SLFU4snIgh2qKawyqVc9EE2f+FcOM5 +0RtwQ3ku6FOk3cy6/xeKpResCHbWDS6nQaIKYyLukV+gm5MJIhOMkj2z4T1eXGUr +Nu/L7Gz+ps7ct0lM8W82n5lzSEa5/l1eNGM0wtQoAwutFEZp7Nx/IBKK87jVttr6 +82UVJeRk7rO2Mpobfw2LbKwga4rsuLrx3UwVDBWdLx7dNIc1rGoAxhsc72+skFgF +Uztwy4Yv1Uiji4T6v+mObPZD/HiIDL0vF02Pz08rNlgB0DgaTKrpql2FutIuQAdf +AciffQIoh9VGERlJoWuunG/UTxg2XRl2m1vCDrgBMInax+PXCv7/5Vh21AQc3fWP +uf4k6JSy46hYni7VTVKn6C/Di9z7oIrGl/jDkDsaenAbToyX9VWr3s7EBwnhTQ/I +OQ9bkWCagHIQlwJbu4M4/VAbiR26NrcR0C3JXBlPlT0qvFFB8gKbJAQEXtwIFS2h +m2fe0k6mQASMwdbJYXZ/wfsg5PPAWsKtny1aMvi0mTPSD5uRhIfEGEuR+AT4UbEW +BkEIE0lgGly4P1SpunKDQQE6m/e7h8Nl4pi8SMSme3YoX5MJwCP/CNkLBDVenAZI +oBrdoVox86SjwnUozVG192lcEAULlk+3ZGt6T9JXLBQl9hpNtyTC6SFh84R+5RoN +AevNl1bDfO+Vci0uJw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/libnm-core/tests/certs/pkcs8-noenc-key.pem b/libnm-core/tests/certs/pkcs8-noenc-key.pem new file mode 100644 index 00000000..f73fb55a --- /dev/null +++ b/libnm-core/tests/certs/pkcs8-noenc-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC80HGgFdlFIL2F +W5rHQ99xOkMrWcZ7an9YurDebAE3M0UwqxM24+5mWbxc8FJ8yYugdMzuI5Nq77IA +DwJpv9ZjMfnKC1VDMj3bmmMdPurfx8pLdLw/jhk3wBaYk6vMvh4z66Yvmb7valGq +Pxh6CRTnekNGI9XA7me4JNBlisl0Qasn9g4pl9PiGJAruEamS4Pk6dSWbfw58bs7 +/Yo5ejyt/Mn1n0Q/r3Gv/lAS0qRvmrW6GE1rMtANMfuGRNlAln21TzNcJzykm+sp +RWptxXEI0NY7u9+RP4M3C1mJxWir7AZDbtinpOZH6vF+92yMzgEYOLK/WZVdSPdW +tROv9xtPAgMBAAECggEBAJAfp+vjYZJjuGaYEuAxjdhW+biYcWn5U7V9484TsSXa +i+DnZOZMO8iCjMaAZuZ7zYmwPlE0dK12w29KBbSEy3eySRIRboa5TgBXq3pCcXRZ +g6/vLlZw+AzXIiha6BODt3g4UwUYnWcQx79lJCDa18sNR1a9ucbn8+Har/wiYT3M +JjTbUT6wR6rKEXchB58ZugYGhOTfugSDQg4U/dwEHPIaJ/wme++JUV5B/tjeGCG3 +F43o2Oos5vjfrDSpUKIYZn+2BdhP434jkwj22wQ2sy0ruU/kQx8nogMTRfP1v4GU +9QmNXj/DB24K388ZxcDmcxBJxrGAJ0MohYFo28DqRBECgYEA6hyKEqe2UbJx/+B6 +8mYgHb+pS2j0M4jPl11q9MMLVxLnDY9xZ85IEyWHQEC0GavPSAois0oiDeGAm32c +j6TFyV3/oPTmZSyV93/agWgnH9Xtc481pbNAb0GMfyotvRRE/+6ti9+Cl7oH9Qmm +ldMk7Hn6sK9t2mUOW8idPjKqlqcCgYEAzne25BryLJoIinbRMZg9KTfxfgUE6EKc +Tk5+9CFQn0/AItQJuKbIUyggYH4psWW5hWq6hFlmMYMR48FKv9ry7pZTB0djaoYD +lN+wSuhzUYWXedkAjvPmekITmf6rbnPfwOZvsr8CGMEUekqJPnPLzsQy+Ea2y/fb +QY4SHe7gExkCgYEAr+1scOJpZvFjK7ckjT3jipd6ADpJsORxo7zG4FImFnQU/6K4 +xRpGHWVJQyaccOIkrW04cGUYPDgmrjJx0ZwwKceijvEaphMgS1JgAHklVY4sl3ea +CAAxPqoSi4lFv94Yj/9rmT4IZD6fNivfbJ20FKUBl37tXX4tkRmr2I64lOcCgYEA +x3eqzrclrmdlxvfBZOuScwbkHP6WXhk0TwbQ6eRhsnfmxP8bITSoJoaGuRJKD2Oa +l0WkSobgDwd0uhecsrvBpTS/pDGY32n3fdWZyNTHzEOHMyWtv23tBcJek5ERaBU0 +X3WBBiw4x1eKBBeMfjR6+xhbsbcHlQiw36V05UxJWMkCgYEAhtcYvrfU4K48IJTU +qp03nvd+dMY3IUTdZNOCh8bswLKyn3aq3MfWF9Vp7kDAI3cfyMpSrAQnmg4nVcn6 +Gf3wakG8bpiSRbJnGN+iLm8JsD+3Vw9KzvKOOQVmpT7xt5Kupx1hWvLHQWvfYgOG +qEtTM8/+LD7W3I7midJNt50CD8A= +-----END PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-aes-key.pem b/libnm-core/tests/certs/test-aes-key.pem new file mode 100644 index 00000000..aab8f463 --- /dev/null +++ b/libnm-core/tests/certs/test-aes-key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,800391B7DD72364B4C2562E0B6AEA000 + +E9dgNCIATOr4CN5c8o6B+8wdqq/I1BLmPmW2qT7YZepoF7E+RUb8ZLjo1VO2XsJw +Ir4EzuH7837zBD9dP5CjlY8cWfR63gZpEWRY5Jub8kzvqiL4UZ0Qr8IHOZxAkKEz +EL1Pn7e+tYt4kA372LPZHWO3vRCgmL1iSJj2/k3avPWAx7NUie4bzGI+00WNv699 +ClKzsJbWB1eiQvYgOr4aVV26oWfa896JkBoGhgZQ6ckqFpsdAos8m46iOSVZrwgq +Y2/d1CvfQod+87c8LRatwAjf+d6YAJJaeMyxjCGuAY6/JyDsorUkM2OlvbTt6WOA +gSPWO8I+Ov6THb4IuPhpIJ30Sl88tc6MlIByW49EWu2G1jPw3L8iqRzZ50Z85dyz +N9yFP91wEwi5F0Zed4iEpg3NVfklEe/VYqCldc5f9fZ84G5V98ZlAdNSqwd/UNBU +iPTflGqVpp1u+J2isOk+Agpj1MCxh2q0RNuvY9KHzOYBScirfbG4DKNbQgS/5Zw7 +3g9YL5Wbo7BczHLiXf/2adu6T8wI1LKRjkeLV9dK1Vw3ZaGy3mB9oFhCgjh9BNHw +wC78CVcUErjtOXdQagiCQn5k5EGeAB97QFROoAFjAmGvq3xCi4EHd9Sk6fcMm7Oi +1fuVR5EXUubF4Llq06lFzQp01s2F73noH49bs3qwdf0n8nrL2XhKB0XCOV/I3K5c +Y3W+YSl361QGjZ/NUcFLIIy+Uro90MmUBNk6af+wGHRJeflpVnK0ATX1PtpNHziz +jiMiIZicjgfVLxl1a5zTl6KUmGWKlZb533adQ0s6q9Qmi5Vk5L5W/GdMjcFtZbM6 +GU7EOkwihMLb3DVsNbm7vb8tUXqe/e5RmXtij8Yb+2a6/M9yaOHa0VjHzdiKHecr +eEYaKQDj7NCWLslNnRRh9GmgXcu2pqBhqRM3HAt3cEaHKKWHTcoWcz11pFwMHNtn +bU9GjGRVc3lCGhVNRiloO0zrKHmcBpDVLw2+ycXXpj/RaBW2fy0xRLKolyla+jEr +zdLzVI61O50ZMycOtPmE7DVZpkokn32hGer1eCOFnsN1lywi4cWLvU0jbQC+CJyw +T9vS8zB3WgOl8rC1AHsfQ4KYajlKleQm89deurQymnt/Qx49SiQA+TpwG9Xvx2TP +3Vc1NwZfM9ZZ1+6xit/rTuS3LhnmhEnGnV5ZyvAdmkCcV2iHjOnLnQWWQn24MHU3 +8Y9D4AdpI5V7Igwr3vH2NZMiw1W2Yc5EJuPAT8nIs5sgOYhXB/QLPJvulvOQhuNC +NPwJ6A505JrVNfHuEaoGUyA+mPeWuLwQo8y8cM6ZdFMG3RrwFNzuYTrc1Z/9GsmA +C0UfHf5dL0r7oWZ1SbpSvsmHYqc8sIypq0ohuLEbpegS/hWP8b2/XDRTjfTiJOrM +4LsUH9PMOJSxDlwS+7e3FdcGfgXfsMgB3aOjQvNpKEolOuv4A5LVFeMrrwtw4Xo1 +EuhstZwyarUTJenDUXzkakhA+8Yw/g2a7RsnANVTkeBuv2PbqFL4zdlsWvcpkz41 +ESxx1siSeU1E9beOII0zSi8vUD0IAevRHaWSlfU2po600IzX1FN97pa4DJV2ycgn +-----END RSA PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-cert.p12 b/libnm-core/tests/certs/test-cert.p12 new file mode 100644 index 00000000..ae4a6830 Binary files /dev/null and b/libnm-core/tests/certs/test-cert.p12 differ diff --git a/libnm-core/tests/certs/test-key-only-decrypted.der b/libnm-core/tests/certs/test-key-only-decrypted.der new file mode 100644 index 00000000..c8652537 Binary files /dev/null and b/libnm-core/tests/certs/test-key-only-decrypted.der differ diff --git a/libnm-core/tests/certs/test-key-only-decrypted.pem b/libnm-core/tests/certs/test-key-only-decrypted.pem new file mode 100644 index 00000000..1a25da5e --- /dev/null +++ b/libnm-core/tests/certs/test-key-only-decrypted.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAztLp+/SkzmaHzIst0sO4+r7qUwiVnidKBHgxoTbS5UL1dvck +cbjTEP23V4ZoKQIb6ZMrr8B+PVgWNBAlhX4oLUL8NH/WTwrntrlAUcjliWDNc1Fj +Z+FZNjFe0IdLXZeKQiLTQvKDYnmERVvYIJfi0TQjXuy/ikF8rYBQ85scUV3kKRzB +xnyhAHAP9nl3AyL1S6t2yiCr4U5TbIZo6dYPbpVLtbXP02zUc9vAPR0gIHKrPiW7 +P81fLXf91wuo6wxzwD90JxdWzzGaqe3BOSfHqul3SPRtVok1XHlb9i+Mn5O8ExzQ +dF8wGxVDcY7/Gt9lZWnCilqrBEqA3iApjUgcgwIDAQABAoIBAQC77HCmepf04ryp +Yhz00NoXG7mWUMqBtXlPrlaKAWKG5dxbiBwZKLK/UYlxgbLK8BuklBCx1Nnfq1Yh +YDp3nTWsSp0WpsF3eJUqNhD3Pu8xcD+9dEo6bUu+LgXUu9oC5Fq/1RzYS7qNk5RX +4Sf0FY4GQLWS3tL7MJ20mE71yg5k7qRbDydOyhTh1m1CpRYONWxSsWVLM8KGRDJp +iF0cdPfD5yoPFpgDk8gwzrnXJH2Wqzv8GvyYykRK5AW7tE50y0rTAM42WZ7YS6aZ +FNMmtYxeyzXLY3LgPP0uko5anz3OXRcqCfHfFANG0y7B9MehbrjMgI6S1BbzFl07 +V1zVQVqhAoGBAPIfrWMlh1fHlRh4iRGXK2Hvxyv2oNz9KvQ4qRaLV9ejRDzdt7Pi +/utbi5LGBuDw9016nXM3I77b6PukHzsHFnWGRnyRSbkMMt6mE17nggmNqcpFWfE8 +E7HcKMhk4gbuo5AHD3Ee1Gac2AUDnzYiE+sS6WI3O9d77cc5ych5jZ+nAoGBANqt +VZCttjY0E+hEyTP37eaE8u0jfdK8AflTJlNUHWKXglES525iu8I/Bso8KaQYsYF3 +SezGRd3KQepQhtMjFKfSpF+tbnboP57Y3XGo8xhbxqV4kRX+XGsVoW3Vg2nPKBrR ++dIY5nMwua+gkHWp9RDcemD2reiIZBVx95fK8dfFAoGAdCSH2pBs/MlrFqLzNTHr +iH4pb0hN39O9YAsx6POMfo79s6izbyHLIID4Ub6WHB7ashrIHjVr+yin+NXAeWMr +/dIcS7Kxx4c3e5/0mMi6kvSWZsWfoF0uIVo3YfEqjyK36OXKHXwpbNN9t+IF5ESy +g0e+FfPiy7nR1Ig+5+CO8+8CgYEAp/75+Ug677FaidouaMpT7gC9UAkwJLFjItQK +YYIBgTi8WOSY/2jCrhwVb1CA/RwrYjbuiARasGUt9oEe0x3kRHnC5e4rKxaJqdMZ +bLRK7a+0EHNrouXiwjG/7s1VQ/ht6wzdS9btVBlezdogoQSMzQNU0SExwa7mlMMV +X3v+B7ECgYAK+Yt4jnLH1LNWoDTU0Ug5hyXsQXV8lVBSnrkvS7GtP6ZA/4OqG7lJ +/bTYFZGoiAGzOnC+YlAqSIu45CEnpr2xBsThQiWUVxspmQD1lEWWFcd77DPUwn3C +59pLgx0AqJE3n6lBOwehiXbFKBdVzX8PfPZpuCK6qc/RiTILktwURA== +-----END RSA PRIVATE KEY----- diff --git a/libnm-core/tests/certs/test-key-only.pem b/libnm-core/tests/certs/test-key-only.pem new file mode 100644 index 00000000..5ef530e9 --- /dev/null +++ b/libnm-core/tests/certs/test-key-only.pem @@ -0,0 +1,92 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----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=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e + diff --git a/libnm-core/tests/certs/test2-cert.p12 b/libnm-core/tests/certs/test2-cert.p12 new file mode 100644 index 00000000..9d5732b0 Binary files /dev/null and b/libnm-core/tests/certs/test2-cert.p12 differ diff --git a/libnm-core/tests/certs/test2_ca_cert.pem b/libnm-core/tests/certs/test2_ca_cert.pem new file mode 100644 index 00000000..9a487ca4 --- /dev/null +++ b/libnm-core/tests/certs/test2_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCA4ygAwIBAgIJANDnVhixAO1GMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD +VQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czERMA8GA1UEBxMIV2VzdGZv +cmQxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5n +MRAwDgYDVQQDEwdlYXB0ZXN0MRgwFgYJKoZIhvcNAQkBFglpdEBpdC5jb20wHhcN +MDcxMTA5MTU0ODI1WhcNMTcxMTA2MTU0ODI1WjCBkjELMAkGA1UEBhMCVVMxFjAU +BgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQK +Ew1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMH +ZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAz9zRLSiQyQangDgEliEP8xSpnPJS7GjXzrkZS3sk +gZLuVuwoFeZRq3Hsrq/wGd/vM0KUFNmEaMc+47jnuv0UHQcQ45ZACO7s4/Aflhzj +lkmud/z06hVknIzjXmvS6q2ttCviHsXnfokl+wAxuUhsd+le0xjP9H1jXny4YBuS +jP+yGUz7PL4w1sFFghKIPrlB7m4GkFbQRqvH7FSJg86GWopPwJvNvIzhOZiO1a1D +CAAL4Ru3jxtNFxqWT87C/qUEe/2Qb7jtNyqFcKfwZyZh4u1bo0c8bjErlUZERbWz +zM3hTFypuw+i2v+0h3A8/Xb0hTjcHkUoJgfSdbsOLC5TOwIDAQABo4H6MIH3MB0G +A1UdDgQWBBR+UOaH4e8nrEuMcEXJl7UN5r/wDTCBxwYDVR0jBIG/MIG8gBR+UOaH +4e8nrEuMcEXJl7UN5r/wDaGBmKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgT +DU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQg +SGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVz +dDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tggkA0OdWGLEA7UYwDAYDVR0TBAUw +AwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAmE2jqUymfxN2Vv7bPafoK/EpZwGPxu+z +phRFsgUgWVzidc/GtOxN81LduJ+ow8MEbQIabo4JV/MdKzuPuhAHToAQdeb0LIWa +p59vTIZiVhUt0cMAbQwKcTnfmDnXw9wytvtKgeAXJq0Jd6F+uNXTiR1btlYLZqmF +oSu54cHQlXpUT9z0BnQ8eXd7m0TwfzGQkTHQI7xBa87lZDAkJaTlhv7fR5vPmJYY +0LiXii71ce+4hxdlp7hQfwQ2sb8FPY3RlVboTRD0CvGaWypWhdSZnS790dBXgZOs +NCge6NGuHzW5LtiZE9ppuv8qJysVcIFdAqt8dkx58ksOqFcARCerXw== +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test2_key_and_cert.pem b/libnm-core/tests/certs/test2_key_and_cert.pem new file mode 100644 index 00000000..a668596e --- /dev/null +++ b/libnm-core/tests/certs/test2_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,5FA2D6D6242C26D0 + +dyNdbh115sczbUEhiaGYJ6fazyvJss5thPFEmkP6aftYlvXY6vPtc++xFCCktiSd +qFVEyi6oDyV4iGPmX7pCJ0e+pSI6uFNXKFtxh5/+/wXZcOEMCvfu7w2IrvYF2LHY +qJDljcISSRxeINuYO7TETD5fLLRKj2X9vwwkwVN02b2N5jsrm6Bt//WbatqSB3ln +FHyQhVKkvdl9Hr1XNmEfgGfZSxxDoPu1DjhtZ5ja2LZj64C2CXdI0oq2wcAVvQNn +rZeeg9sinQJkz9rwsNaWqlYw4X+YD2JRSwZuvwkWRydYMwgb1XS/jCxtuFF8NXWP +RBAOAZZUy7onzohsJHVVa05wCKQ4klo+PEfI3vn7BeuHyciCc0eFqGRvz8eFDybH +ZdPbU/3vGp+mOB7gd27TptttTCQQy9uM5CIyovNSYsAIw1Z583Ea4q8eXgzkgD6D +isCqkGXMfPbNXU3myQGDnQwWRi2CqX+rXM8PJUhdewLAlmHRz/aYSuql2BRixJKx +eASzmFBYdAjrvafda5D+xTyJwXEwdq/HlqMK9cY28ZbNrzA2Kor2X23EKC1+VG8k +B67OsfUhW27j4u6aV5JdLf87OtF3mHFRR+Lzs7i7LYvJ8ACE+jiIi7PboZjK5Oiv +JqTK0BwDaeNYjkd6jiJh8It/ReMbLk65J3eldOklN0VMPYiqcQnHvSPC2DD1YAy+ +Rv/JVj6TvzvgEAj+hgH6MAAF6u3ARj6+10DlvhUubkOC5RztLKReu8B+427TuuDb +T03gFpHD6X9IqSiq/QfYFyHFojCVSrv6wDZOcHc1s71kpJ8R14YIVe+DrrZN/0D4 +M631jdNg3JARMZXcXTHrghGIdPmOtrsRyTTRZuGoVup/DW9MRzOzCTMSNCX8T+eq +13HMSNQEO9lMwy0sYeO5c7sjHY4K1ubZuVE1mvXq4JLz3YxXJIvgp8TUvqDnAsK+ +Fv63bDoTg5Tq63XvnaKc7Lawneyg5ZAMzPN3nM0/1EZcn/2ICI5c4Yepc5t63EI5 +KytuXx86Mcx234enj3uMeuM22POQ1SnKOef6dFzK/CE8J8eUEY/aDhX4eBl/s3nd +U4+aaFKYz3HTazePayt2SC6rP/KKMmS14q59bOQA1DiWxCvmA2ypRyP87fV5DstH +I53RD5xp1P38iaO8U/divD0W2dkv748s9DQqYrHPtWALT9esxNU07CgB8Zt070si +7pzjQ8FDCZ8ygDmwWGNSBz1nA90Cpd6gAFDrep7HAtDE4qgNfokycpaJZkXBei/U +tC4tWYRbqDEsEbeBHvQRJzzqWzk9e/P4fQoelM3aryKzKLG5z7KvywVifKMLECQ+ +tIpzoRp06nuTA/O+iLFdkCy3JEWszfvvOwTwtIIV6+3s8TU0k9MmzEe3rGL+QqT/ +Tf+9/dN5LK+LWyc99BfmCOrBuFtQmHyEXkfe6EuFYEwj0B2ZfnLCon6cdRujjK7H +IJslC1B/cBVqG3KCrbBzjeygKfJ5Ijo72oXZJOCFTLeJefZKGGWJCp9nG9h9Wrcf +fEN/mj3wBvTa90/PYFj9NuaBtrvMF8Rn9XDeYPq2JGL8YkNdPuO8A+2Yko8wcvST +-----END RSA PRIVATE KEY----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Massachusetts, L=Westford, O=Red Hat, Inc., OU=Engineering, CN=eaptest/emailAddress=it@it.com + Validity + Not Before: Nov 9 15:50:14 2007 GMT + Not After : Nov 6 15:50:14 2017 GMT + Subject: C=US, ST=Massachusetts, O=Red Hat, Inc., OU=Engineering, CN=client/emailAddress=it@it.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:b0:8f:4f:1c:93:d4:43:e7:87:b7:22:33:55:a8: + 35:a1:c4:01:b0:f1:ed:26:23:96:ab:65:c2:c2:54: + db:79:22:03:ad:3f:6f:22:e3:63:3f:f4:21:6d:fa: + 88:c8:8f:1a:ce:55:49:7c:98:33:6a:67:8a:8d:d9: + 34:b0:c3:42:f4:72:a4:45:43:05:72:5d:0c:d3:42: + f8:9c:66:3b:b8:f8:77:ea:f6:b6:94:d7:cc:5d:62: + 34:2a:14:48:0a:bc:65:94:f5:7a:63:98:6c:88:4c: + 25:d8:95:f1:40:3d:00:d2:fb:43:28:fa:02:fb:2c: + 80:b3:e1:33:e7:8c:ce:8a:a0:1b:3d:04:4d:bc:a1: + b6:a2:42:8b:8e:f3:5b:4a:72:34:7d:8d:ba:d8:46: + 22:35:da:5c:f8:dd:fc:6d:9e:59:22:b7:6b:e7:78: + 56:54:9f:4c:d1:e2:4a:23:a3:bc:04:ea:46:6b:70: + 8a:fb:fe:8a:73:ca:36:d5:f3:e9:17:e3:22:d5:b3: + 70:05:e7:f7:37:b7:21:b5:90:53:27:27:ea:36:9b: + 00:ff:35:b0:66:3d:dc:a9:2f:95:d2:21:18:98:4f: + 28:07:09:70:20:a8:b1:82:aa:a5:df:ae:0f:e3:36: + be:68:8c:9e:80:d3:33:d0:f5:84:17:d9:0f:eb:9d: + af:0b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 71:AB:BB:91:B7:04:DE:43:35:36:07:8A:35:CA:BE:5C:3E:EB:B1:09 + X509v3 Authority Key Identifier: + keyid:7E:50:E6:87:E1:EF:27:AC:4B:8C:70:45:C9:97:B5:0D:E6:BF:F0:0D + DirName:/C=US/ST=Massachusetts/L=Westford/O=Red Hat, Inc./OU=Engineering/CN=eaptest/emailAddress=it@it.com + serial:D0:E7:56:18:B1:00:ED:46 + + Signature Algorithm: md5WithRSAEncryption + ce:43:6d:f7:f8:4a:66:fd:8a:2c:41:a6:e0:03:0e:60:30:d4: + 41:01:ba:46:ba:81:97:64:68:83:25:9c:e1:2c:03:8b:2d:ca: + 85:cf:bc:fa:ca:22:c4:59:28:23:8f:ff:50:94:60:1c:90:dd: + 75:f4:d4:ea:8c:fa:61:61:08:35:4a:8f:aa:a7:e9:3d:76:e9: + 08:28:55:01:c4:03:42:c7:ad:58:bb:ee:94:f7:09:b3:9a:9b: + 8b:d0:25:95:18:a6:22:d5:2c:fc:b7:bb:91:0c:7c:03:7f:9b: + 85:de:b0:e4:95:a8:73:94:27:0a:11:4e:e3:67:ae:2b:cc:e7: + 51:29:10:23:57:5c:3e:e7:ea:47:e0:f0:8f:5b:a2:9f:26:cf: + 7f:b5:7c:44:b1:7b:83:67:3c:41:ae:c6:66:64:e0:d2:ef:57: + a4:5c:1b:94:11:ce:28:e5:91:51:ef:e1:98:b7:3b:9a:cc:f7: + b9:85:76:eb:a8:2b:15:4a:cc:1a:a3:42:fa:be:1c:ce:b8:eb: + ee:12:d7:2f:e4:a8:cf:eb:2a:8f:78:e8:91:88:fa:c2:98:75: + 6a:4c:92:3f:2e:0d:e1:20:39:36:c6:2c:be:67:30:c3:f3:c3: + 65:81:ac:e3:3c:19:6a:21:ee:ea:f5:22:66:74:b2:07:53:7c: + 9a:0c:24:a6 +-----BEGIN CERTIFICATE----- +MIIEtDCCA5ygAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCVVMx +FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UE +AxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMB4XDTA3MTEwOTE1 +NTAxNFoXDTE3MTEwNjE1NTAxNFowfjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1h +c3NhY2h1c2V0dHMxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0Vu +Z2luZWVyaW5nMQ8wDQYDVQQDEwZjbGllbnQxGDAWBgkqhkiG9w0BCQEWCWl0QGl0 +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCPTxyT1EPnh7ci +M1WoNaHEAbDx7SYjlqtlwsJU23kiA60/byLjYz/0IW36iMiPGs5VSXyYM2pnio3Z +NLDDQvRypEVDBXJdDNNC+JxmO7j4d+r2tpTXzF1iNCoUSAq8ZZT1emOYbIhMJdiV +8UA9ANL7Qyj6AvssgLPhM+eMzoqgGz0ETbyhtqJCi47zW0pyNH2NuthGIjXaXPjd +/G2eWSK3a+d4VlSfTNHiSiOjvATqRmtwivv+inPKNtXz6RfjItWzcAXn9ze3IbWQ +Uycn6jabAP81sGY93KkvldIhGJhPKAcJcCCosYKqpd+uD+M2vmiMnoDTM9D1hBfZ +D+udrwsCAwEAAaOCASYwggEiMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w +ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRxq7uRtwTeQzU2 +B4o1yr5cPuuxCTCBxwYDVR0jBIG/MIG8gBR+UOaH4e8nrEuMcEXJl7UN5r/wDaGB +mKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAP +BgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQL +EwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJ +aXRAaXQuY29tggkA0OdWGLEA7UYwDQYJKoZIhvcNAQEEBQADggEBAM5Dbff4Smb9 +iixBpuADDmAw1EEBuka6gZdkaIMlnOEsA4styoXPvPrKIsRZKCOP/1CUYByQ3XX0 +1OqM+mFhCDVKj6qn6T126QgoVQHEA0LHrVi77pT3CbOam4vQJZUYpiLVLPy3u5EM +fAN/m4XesOSVqHOUJwoRTuNnrivM51EpECNXXD7n6kfg8I9bop8mz3+1fESxe4Nn +PEGuxmZk4NLvV6RcG5QRzijlkVHv4Zi3O5rM97mFduuoKxVKzBqjQvq+HM646+4S +1y/kqM/rKo946JGI+sKYdWpMkj8uDeEgOTbGLL5nMMPzw2WBrOM8GWoh7ur1ImZ0 +sgdTfJoMJKY= +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test_ca_cert.der b/libnm-core/tests/certs/test_ca_cert.der new file mode 100644 index 00000000..e844f65b Binary files /dev/null and b/libnm-core/tests/certs/test_ca_cert.der differ diff --git a/libnm-core/tests/certs/test_ca_cert.pem b/libnm-core/tests/certs/test_ca_cert.pem new file mode 100644 index 00000000..faa3fc29 --- /dev/null +++ b/libnm-core/tests/certs/test_ca_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEhjCCA26gAwIBAgIJAOZMXJYmXtbQMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD +VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw +FQYDVQQKEw5NeSBDb21wYW55IEx0ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxME +dGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAyMDIwMjIx +NTJaFw0xOTAxMzEwMjIxNTJaMIGIMQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVy +a3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0 +ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3DQEJARYN +dGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZz +iHfFR6Gqdz5Gq1elSaf7J2tznfialPyMkRoqngSItrM3JWlkfBu3ZIpGSYG8+Z8H +JjaKh/zkCCH73HcjADCocm/XtgxlOlccDtBvfDqifb2dBikcmcfh0tX0o4JU9L+z +WP7sVcUkJG7C5811lA5pAsLVooJxrZnrta6XstGvFgTSxI2Y4Jowf0syM5b/AHIQ ++htsVhSyj1DWM9day3QsEMZl55SCxCLTB6ZIJLF6NmTYwdnzWWTQf4k7kcptZJU8 +Fqv60b/ATvvUf7S+ZMGLopFIIlmc1Kkn7VTseIKy4ycYuDpyimQy3Yw4flC00vhl +hTijH+5dlVOUFrRh0bsCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUUjMuImZ5guVBLo07 +suXM+r6ZM44wgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6ZM46hgY6k +gYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcT +B05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQLEwR0ZXN0 +MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA +5kxcliZe1tAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAZsWzGp9D +10NWf8ts3A9mhcEb8oDgKNpCOZF9gqr2usZygJjY9MX2n0n81T8XaWDk1wZLlcDW +hzIalCY8rpE57Dj3MEmdCmYr3BrAy6GVlc/MO7ffTHxogl9ouScSYo8ETTtNMKCg +zwkDnXjGzmb1e59DIXMVHBBbTmJXJbM8XP9A2azJkVUyE2fSdWksXMP0XklGbW2p +DksJ+8G1IWkyRhnINV5GZLLNAT5gBA6sUv/iqQKwk8r2dsweMPtLoLWZPAaZErYh +sthGy00Q0GJkmkJpQl8QIlPq5vylNcMUhvc8tmzwk+rDVUj3jTJWqFwMtnHAaNyC +FXl9ynWpe5J28w== +-----END CERTIFICATE----- diff --git a/libnm-core/tests/certs/test_key_and_cert.pem b/libnm-core/tests/certs/test_key_and_cert.pem new file mode 100644 index 00000000..c00495d0 --- /dev/null +++ b/libnm-core/tests/certs/test_key_and_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 + +KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k +r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ +PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj +5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ +amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj +yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR +PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV +xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg +T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab +HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu +Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev +0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB +m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf +rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f +FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S +uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN +vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt +1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh +ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw +l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v +tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm +aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco +0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD +u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj +DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg +-----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=test, CN=test/emailAddress=test@test.com + Validity + Not Before: Feb 2 02:22:25 2009 GMT + Not After : Jan 31 02:22:25 2019 GMT + Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: + b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: + d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: + 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: + 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: + 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: + 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: + 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: + 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: + a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: + ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: + cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: + bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: + 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: + 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: + bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: + 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: + 1c:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B + X509v3 Authority Key Identifier: + keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E + DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com + serial:E6:4C:5C:96:26:5E:D6:D0 + + Signature Algorithm: md5WithRSAEncryption + 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: + a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: + e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: + b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: + 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: + ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: + 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: + 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: + e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: + 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: + 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: + 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: + d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: + a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: + 6b:80:38:6e +-----BEGIN CERTIFICATE----- +MIIErjCCA5agAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCVVMx +EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO +TXkgQ29tcGFueSBMdGQxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxHDAa +BgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMjAyMDIyMjI1WhcNMTkw +MTMxMDIyMjI1WjCBizELMAkGA1UEBhMCVVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEX +MBUGA1UEChMOTXkgQ29tcGFueSBMdGQxFDASBgNVBAsTC3Rlc3QtY2xpZW50MRQw +EgYDVQQDEwt0ZXN0LWNsaWVudDEjMCEGCSqGSIb3DQEJARYUdGVzdC1jbGllbnRA +dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO0un79KTO +ZofMiy3Sw7j6vupTCJWeJ0oEeDGhNtLlQvV29yRxuNMQ/bdXhmgpAhvpkyuvwH49 +WBY0ECWFfigtQvw0f9ZPCue2uUBRyOWJYM1zUWNn4Vk2MV7Qh0tdl4pCItNC8oNi +eYRFW9ggl+LRNCNe7L+KQXytgFDzmxxRXeQpHMHGfKEAcA/2eXcDIvVLq3bKIKvh +TlNshmjp1g9ulUu1tc/TbNRz28A9HSAgcqs+Jbs/zV8td/3XC6jrDHPAP3QnF1bP +MZqp7cE5J8eq6XdI9G1WiTVceVv2L4yfk7wTHNB0XzAbFUNxjv8a32VlacKKWqsE +SoDeICmNSByDAgMBAAGjggEcMIIBGDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf +Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNOlc2PzH +r/dd9BPTghrNUg9Kuwswgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6Z +M46hgY6kgYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO +BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQL +EwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qu +Y29tggkA5kxcliZe1tAwDQYJKoZIhvcNAQEEBQADggEBAIjE3cVKpo4fNmKAMWsr +hTQNbKfc4Vo83XRX21m+i/J5QC29m+GrDgN1IHUv6pf51H4VdcKC9bE35Isk1O8C +OxlqVrufw6W0xDmgZJZbw6gZdOwLzzPf8xLz4qsdfd4hZM2xoG96d4TUYopQ5nZd +rzrvGocOGjjE+Q0vFOAgMkwucNJxgtXlyRMsTrTIY2UdSOjDVm2IhFdlEx5CSLQD +JXFOEp0aiGXVcSE7Dr43HPCIa0UMDmzlYMuGv79AMMTPlPgcYNQb34gCekV+0cbz +B7mxjypVL753n9FGZAW3Z8WyrIxCj2pRpA0rFqTWOaX4Je1oJRO1Gaxs6ezuA2uA +OG4= +-----END CERTIFICATE----- diff --git a/libnm-core/tests/test-compare.c b/libnm-core/tests/test-compare.c new file mode 100644 index 00000000..12db9c23 --- /dev/null +++ b/libnm-core/tests/test-compare.c @@ -0,0 +1,248 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include "nm-property-compare.h" + +#include "nm-test-utils.h" + +static void +compare_ints (void) +{ + GVariant *value1, *value2; + + value1 = g_variant_new_int32 (5); + value2 = g_variant_new_int32 (5); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_int32 (10); + g_assert (nm_property_compare (value1, value2) < 0); + + g_variant_unref (value2); + value2 = g_variant_new_int32 (-1); + g_assert (nm_property_compare (value1, value2) > 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_strings (void) +{ + GVariant *value1, *value2; + const char *str1 = "hello"; + const char *str2 = "world"; + + value1 = g_variant_new_string (str1); + value2 = g_variant_new_string (str1); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_string (str2); + g_assert (nm_property_compare (value1, value2) < 0); + + g_assert (nm_property_compare (value2, value1) > 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_strv (void) +{ + GVariant *value1, *value2; + const char * const strv1[] = { "foo", "bar", "baz", NULL }; + const char * const strv2[] = { "foo", "bar", "bar", NULL }; + const char * const strv3[] = { "foo", "bar", NULL }; + const char * const strv4[] = { "foo", "bar", "baz", "bam", NULL }; + + value1 = g_variant_new_strv (strv1, -1); + value2 = g_variant_new_strv (strv1, -1); + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv2, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv3, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new_strv (strv4, -1); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_arrays (void) +{ + GVariant *value1, *value2; + guint32 array[] = { 0, 1, 2, 3, 4 }; + + value1 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array + 1, G_N_ELEMENTS (array) - 1, + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); + + array[0] = 7; + g_variant_unref (value2); + value2 = g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, G_N_ELEMENTS (array), + sizeof (guint32)); + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_str_hash (void) +{ + GVariant *value1, *value2; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value1 = g_variant_builder_end (&builder); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + g_variant_builder_add (&builder, "{ss}", "key2", "world"); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) != 0); + g_assert (nm_property_compare (value2, value1) != 0); + + g_variant_unref (value2); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&builder, "{ss}", "key1", "hello"); + g_variant_builder_add (&builder, "{ss}", "key2", "moon"); + g_variant_builder_add (&builder, "{ss}", "key3", "!"); + value2 = g_variant_builder_end (&builder); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +static void +compare_ip6_addresses (void) +{ + GVariant *value1, *value2; + struct in6_addr addr1; + struct in6_addr addr2; + struct in6_addr addr3; + guint32 prefix1 = 64; + guint32 prefix2 = 64; + guint32 prefix3 = 0; + + inet_pton (AF_INET6, "1:2:3:4:5:6:7:8", &addr1); + inet_pton (AF_INET6, "ffff:2:3:4:5:6:7:8", &addr2); + inet_pton (AF_INET6, "::", &addr3); + + value1 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr1.s6_addr, 16, 1), + prefix1, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) == 0); + + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr2.s6_addr, 16, 1), + prefix2, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value2); + value2 = g_variant_new ("(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1), + prefix3, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + (guint8 *) addr3.s6_addr, 16, 1)); + + g_assert (nm_property_compare (value1, value2) != 0); + + g_variant_unref (value1); + g_variant_unref (value2); +} + +NMTST_DEFINE (); + +int +main (int argc, char *argv[]) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_func ("/libnm/compare/ints", compare_ints); + g_test_add_func ("/libnm/compare/strings", compare_strings); + g_test_add_func ("/libnm/compare/strv", compare_strv); + g_test_add_func ("/libnm/compare/arrays", compare_arrays); + g_test_add_func ("/libnm/compare/str_hash", compare_str_hash); + g_test_add_func ("/libnm/compare/ip6_addresses", compare_ip6_addresses); + + return g_test_run (); +} diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c new file mode 100644 index 00000000..1c8ae477 --- /dev/null +++ b/libnm-core/tests/test-crypto.c @@ -0,0 +1,501 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* + * Dan Williams + * + * 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. + * + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "crypto.h" +#include "nm-utils.h" +#include "nm-errors.h" +#include "nm-core-internal.h" + +#include "nm-test-utils.h" + +#if 0 +static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; +static const char *pem_rsa_key_end = "-----END RSA PRIVATE KEY-----"; + +static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; +static const char *pem_dsa_key_end = "-----END DSA PRIVATE KEY-----"; + +static void +dump_key_to_pem (const char *key, gsize key_len, int key_type) +{ + char *b64 = NULL; + GString *str = NULL; + const char *start_tag; + const char *end_tag; + char *p; + + switch (key_type) { + case NM_CRYPTO_KEY_TYPE_RSA: + start_tag = pem_rsa_key_begin; + end_tag = pem_rsa_key_end; + break; + case NM_CRYPTO_KEY_TYPE_DSA: + start_tag = pem_dsa_key_begin; + end_tag = pem_dsa_key_end; + break; + default: + g_warning ("Unknown key type %d", key_type); + return; + } + + b64 = g_base64_encode ((const unsigned char *) key, key_len); + if (!b64) { + g_warning ("Couldn't base64 encode the key."); + goto out; + } + + str = g_string_new (NULL); + + g_string_append (str, start_tag); + g_string_append_c (str, '\n'); + + for (p = b64; p < (b64 + strlen (b64)); p += 64) { + g_string_append_len (str, p, strnlen (p, 64)); + g_string_append_c (str, '\n'); + } + + g_string_append (str, end_tag); + g_string_append_c (str, '\n'); + + g_message ("Decrypted private key:\n\n%s", str->str); + +out: + g_free (b64); + if (str) + g_string_free (str, TRUE); +} +#endif + +static void +test_cert (gconstpointer test_data) +{ + char *path; + GByteArray *array; + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + GError *error = NULL; + + path = g_build_filename (TEST_CERT_DIR, (const char *) test_data, NULL); + + array = crypto_load_and_verify_certificate (path, &format, &error); + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_X509); + + g_byte_array_free (array, TRUE); + + g_assert (nm_utils_file_is_certificate (path)); +} + +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); + g_byte_array_append (array, (guint8 *) contents, length); + g_assert (array->len == length); + g_free (contents); + } + return array; +} + +static void +test_load_private_key (const char *path, + const char *password, + const char *decrypted_path, + int expected_error) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + gboolean is_encrypted = FALSE; + GByteArray *array, *decrypted; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, &is_encrypted)); + g_assert (is_encrypted); + + array = crypto_decrypt_openssl_private_key (path, password, &key_type, &error); + /* Even if the password is wrong, we should determine the key type */ + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + if (expected_error != -1) { + g_assert (array == NULL); + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_clear_error (&error); + return; + } + + if (password == NULL) { + g_assert (array == NULL); + g_assert_no_error (error); + return; + } + + g_assert (array != NULL); + + if (decrypted_path) { + /* Compare the crypto decrypted key against a known-good decryption */ + decrypted = file_to_byte_array (decrypted_path); + g_assert (decrypted != NULL); + g_assert (decrypted->len == array->len); + g_assert (memcmp (decrypted->data, array->data, array->len) == 0); + + g_byte_array_free (decrypted, TRUE); + } + + g_byte_array_free (array, TRUE); +} + +static void +test_load_pkcs12 (const char *path, + const char *password, + int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + format = crypto_verify_private_key (path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error (&error); + } else { + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert (is_encrypted); + } +} + +static void +test_load_pkcs12_no_password (const char *path) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + /* We should still get a valid returned crypto file format */ + format = crypto_verify_private_key (path, NULL, &is_encrypted, &error); + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_PKCS12); + g_assert (is_encrypted); +} + +static void +test_is_pkcs12 (const char *path, gboolean expect_fail) +{ + gboolean is_pkcs12; + GError *error = NULL; + + is_pkcs12 = crypto_is_pkcs12_file (path, &error); + + if (expect_fail) { + g_assert_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_INVALID_DATA); + g_assert (!is_pkcs12); + } else { + g_assert_no_error (error); + g_assert (is_pkcs12); + } +} + +static void +test_load_pkcs8 (const char *path, + const char *password, + int expected_error) +{ + NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; + gboolean is_encrypted = FALSE; + GError *error = NULL; + + g_assert (nm_utils_file_is_private_key (path, NULL)); + + format = crypto_verify_private_key (path, password, &is_encrypted, &error); + if (expected_error != -1) { + g_assert_error (error, NM_CRYPTO_ERROR, expected_error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_UNKNOWN); + g_clear_error (&error); + } else { + g_assert_no_error (error); + g_assert_cmpint (format, ==, NM_CRYPTO_FILE_FORMAT_RAW_KEY); + g_assert (is_encrypted); + } +} + +static void +test_encrypt_private_key (const char *path, + const char *password) +{ + NMCryptoKeyType key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + GByteArray *array, *encrypted, *re_decrypted; + GError *error = NULL; + + array = crypto_decrypt_openssl_private_key (path, password, &key_type, &error); + g_assert_no_error (error); + g_assert (array != NULL); + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Now re-encrypt the private key */ + encrypted = nm_utils_rsa_key_encrypt (array->data, array->len, password, NULL, &error); + g_assert_no_error (error); + g_assert (encrypted != NULL); + + /* Then re-decrypt the private key */ + key_type = NM_CRYPTO_KEY_TYPE_UNKNOWN; + re_decrypted = crypto_decrypt_openssl_private_key_data (encrypted->data, encrypted->len, + password, &key_type, &error); + g_assert_no_error (error); + g_assert (re_decrypted != NULL); + g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); + + /* Compare the original decrypted key with the re-decrypted key */ + g_assert_cmpint (array->len, ==, re_decrypted->len); + g_assert (!memcmp (array->data, re_decrypted->data, array->len)); + + g_byte_array_free (re_decrypted, TRUE); + g_byte_array_free (encrypted, TRUE); + g_byte_array_free (array, TRUE); +} + +static void +test_key (gconstpointer test_data) +{ + char **parts, *path, *password, *decrypted_path; + int len; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + len = g_strv_length (parts); + if (len != 2 && len != 3) + g_error ("wrong number of arguments (, , [])"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + decrypted_path = parts[2] ? g_build_filename (TEST_CERT_DIR, parts[2], NULL) : NULL; + + test_is_pkcs12 (path, TRUE); + test_load_private_key (path, password, decrypted_path, -1); + test_load_private_key (path, "blahblahblah", NULL, NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_private_key (path, NULL, NULL, -1); + test_encrypt_private_key (path, password); + + g_free (path); + g_free (decrypted_path); + g_strfreev (parts); +} + +static void +test_key_decrypted (gconstpointer test_data) +{ + const char *file = (const char *) test_data; + gboolean is_encrypted = FALSE; + char *path; + + path = g_build_filename (TEST_CERT_DIR, file, NULL); + + g_assert (nm_utils_file_is_private_key (path, &is_encrypted)); + g_assert (!is_encrypted); + + g_free (path); +} + +static void +test_pkcs12 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + if (g_strv_length (parts) != 2) + g_error ("wrong number of arguments (, )"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, FALSE); + test_load_pkcs12 (path, password, -1); + test_load_pkcs12 (path, "blahblahblah", NM_CRYPTO_ERROR_DECRYPTION_FAILED); + test_load_pkcs12_no_password (path); + + g_free (path); + g_strfreev (parts); +} + +static void +test_pkcs8 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + if (g_strv_length (parts) != 2) + g_error ("wrong number of arguments (, )"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, TRUE); + test_load_pkcs8 (path, password, -1); + /* Until gnutls and NSS grow support for all the ciphers that openssl + * can use with PKCS#8, we can't actually verify the password. So we + * expect a bad password to work for the time being. + */ + test_load_pkcs8 (path, "blahblahblah", -1); + + g_free (path); + g_strfreev (parts); +} + +#define SALT "sodium chloride" +#define SHORT_PASSWORD "short" +#define LONG_PASSWORD "this is a longer password than the short one" +#define SHORT_DIGEST 16 +#define LONG_DIGEST 57 + +struct { + const char *salt, *password; + gsize digest_size; + const char *result; +} md5_tests[] = { + { NULL, SHORT_PASSWORD, SHORT_DIGEST, + "4f09daa9d95bcb166a302407a0e0babe" }, + { NULL, SHORT_PASSWORD, LONG_DIGEST, + "4f09daa9d95bcb166a302407a0e0babeb7d62e5baf706830d007c253f0fe7584ad7e92dc00a599ec277293c298ae70ee3904c348e23be61c91" }, + { SALT, SHORT_PASSWORD, SHORT_DIGEST, + "774771f7292210233b5724991d1f9894" }, + { SALT, SHORT_PASSWORD, LONG_DIGEST, + "774771f7292210233b5724991d1f98941a6ffdb45e4dc7fa04b1fa6aceed379c1ade0577bc8f261d109942ed5736921c052664d72e0d5bade9" }, + { NULL, LONG_PASSWORD, SHORT_DIGEST, + "e9c03517f81ff29bb777dac21fb1699c" }, + { NULL, LONG_PASSWORD, LONG_DIGEST, + "e9c03517f81ff29bb777dac21fb1699c50968c7ccd8db4f0a59d00ffd87b05876d45f25a927d51a8400c35af60fbd64584349a8b7435d62fd9" }, + { SALT, LONG_PASSWORD, SHORT_DIGEST, + "4e5c076e2f85f5e03994acbf3a9e10d6" }, + { SALT, LONG_PASSWORD, LONG_DIGEST, + "4e5c076e2f85f5e03994acbf3a9e10d61a6969c9fdf47ae8b1f7e2725b3767b05cc974bfcb5344b630c91761e015e09d7794b5065662533bc9" }, + { NULL, "", SHORT_DIGEST, + "d41d8cd98f00b204e9800998ecf8427e" }, + { SALT, "", SHORT_DIGEST, + "7df1e0494c977195005d82a1809685e4" }, +}; + +static void +test_md5 (void) +{ + char digest[LONG_DIGEST], *hex; + int i; + + for (i = 0; i < G_N_ELEMENTS (md5_tests); i++) { + memset (digest, 0, sizeof (digest)); + crypto_md5_hash (md5_tests[i].salt, + /* crypto_md5_hash() used to clamp salt_len to 8. It + * doesn't any more, so we need to do it here now to + * get output that matches md5_tests[i].result. + */ + md5_tests[i].salt ? 8 : 0, + md5_tests[i].password, + strlen (md5_tests[i].password), + digest, md5_tests[i].digest_size); + + hex = nm_utils_bin2hexstr (digest, md5_tests[i].digest_size, -1); + g_assert_cmpstr (hex, ==, md5_tests[i].result); + g_free (hex); + } +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + GError *error = NULL; + int ret; + + nmtst_init (&argc, &argv, TRUE); + + if (!crypto_init (&error)) + FAIL ("crypto-init", "failed to initialize crypto: %s", error->message); + + g_test_add_data_func ("/libnm/crypto/cert/pem", + "test_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-2", + "test2_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/der", + "test_ca_cert.der", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-no-ending-newline", + "ca-no-ending-newline.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined", + "test_key_and_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined-2", + "test2_key_and_cert.pem", + test_cert); + + g_test_add_data_func ("/libnm/crypto/key/padding-6", + "test_key_and_cert.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/key-only", + "test-key-only.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/padding-8", + "test2_key_and_cert.pem, 12345testing", + test_key); + g_test_add_data_func ("/libnm/crypto/key/aes", + "test-aes-key.pem, test-aes-password", + test_key); + g_test_add_data_func ("/libnm/crypto/key/decrypted", + "test-key-only-decrypted.pem", + test_key_decrypted); + + g_test_add_data_func ("/libnm/crypto/PKCS#12/1", + "test-cert.p12, test", + test_pkcs12); + g_test_add_data_func ("/libnm/crypto/PKCS#12/2", + "test2-cert.p12, 12345testing", + test_pkcs12); + + g_test_add_data_func ("/libnm/crypto/PKCS#8", + "pkcs8-enc-key.pem, 1234567890", + test_pkcs8); + + g_test_add_func ("/libnm/crypto/md5", test_md5); + + ret = g_test_run (); + + return ret; +} + diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c new file mode 100644 index 00000000..d309c800 --- /dev/null +++ b/libnm-core/tests/test-general.c @@ -0,0 +1,3961 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include + +#include "nm-setting-private.h" +#include "nm-utils.h" +#include "nm-core-internal.h" + +#include "nm-setting-8021x.h" +#include "nm-setting-adsl.h" +#include "nm-setting-bluetooth.h" +#include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" +#include "nm-setting-cdma.h" +#include "nm-setting-connection.h" +#include "nm-setting-generic.h" +#include "nm-setting-gsm.h" +#include "nm-setting-infiniband.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-team.h" +#include "nm-setting-team-port.h" +#include "nm-setting-vlan.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wimax.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-simple-connection.h" + +#include "nm-test-utils.h" + +static void +vpn_check_func (const char *key, const char *value, gpointer user_data) +{ + const char *test = user_data; + + if (!strcmp (key, "foobar1")) { + ASSERT (strcmp (value, "blahblah1") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar2")) { + ASSERT (strcmp (value, "blahblah2") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar3")) { + ASSERT (strcmp (value, "blahblah3") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + if (!strcmp (key, "foobar4")) { + ASSERT (strcmp (value, "blahblah4") == 0, + test, "unexpected vpn item '%s' / '%s'", key, value); + return; + } + + ASSERT (FALSE, test, "unexpected vpn item '%s'", key); +} + +static void +vpn_check_empty_func (const char *key, const char *value, gpointer user_data) +{ + const char *test = user_data; + + /* We don't expect any values */ + ASSERT (FALSE, test, "unexpected vpn item '%s'", key); +} + +static void +test_setting_vpn_items (void) +{ + NMSettingVpn *s_vpn; + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-items", + "error creating vpn setting"); + + nm_setting_vpn_add_data_item (s_vpn, "foobar1", "blahblah1"); + nm_setting_vpn_add_data_item (s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_data_item (s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_data_item (s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_func, "vpn-data"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar1"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar2"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar3"); + nm_setting_vpn_remove_data_item (s_vpn, "foobar4"); + + nm_setting_vpn_add_secret (s_vpn, "foobar1", "blahblah1"); + nm_setting_vpn_add_secret (s_vpn, "foobar2", "blahblah2"); + nm_setting_vpn_add_secret (s_vpn, "foobar3", "blahblah3"); + nm_setting_vpn_add_secret (s_vpn, "foobar4", "blahblah4"); + + /* Ensure that added values are all present */ + nm_setting_vpn_foreach_secret (s_vpn, vpn_check_func, "vpn-secrets"); + nm_setting_vpn_remove_secret (s_vpn, "foobar1"); + nm_setting_vpn_remove_secret (s_vpn, "foobar2"); + nm_setting_vpn_remove_secret (s_vpn, "foobar3"); + nm_setting_vpn_remove_secret (s_vpn, "foobar4"); + + /* Try to add some blank values and make sure they are rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, NULL, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*item != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (item) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "foobar1", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1"); + g_test_assert_expected_messages (); + + nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, "vpn-data-empty"); + + /* Try to add some blank secrets and make sure they are rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_secret (s_vpn, NULL, NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*secret != NULL*"); + nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (secret) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "foobar1", ""); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*key != NULL*"); + nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1"); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strlen (key) > 0*"); + nm_setting_vpn_add_secret (s_vpn, "", "blahblah1"); + g_test_assert_expected_messages (); + + nm_setting_vpn_foreach_secret (s_vpn, vpn_check_empty_func, "vpn-secrets-empty"); + + g_object_unref (s_vpn); +} + +static void +test_setting_vpn_update_secrets (void) +{ + NMConnection *connection; + NMSettingVpn *s_vpn; + GVariantBuilder settings_builder, vpn_builder, secrets_builder; + GVariant *settings; + gboolean success; + GError *error = NULL; + const char *tmp; + const char *key1 = "foobar"; + const char *key2 = "blahblah"; + const char *val1 = "value1"; + const char *val2 = "value2"; + + connection = nm_simple_connection_new (); + ASSERT (connection != NULL, + "vpn-update-secrets", + "error creating connection"); + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-update-secrets", + "error creating vpn setting"); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + g_variant_builder_init (&settings_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&vpn_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_init (&secrets_builder, G_VARIANT_TYPE ("a{ss}")); + + g_variant_builder_add (&secrets_builder, "{ss}", key1, val1); + g_variant_builder_add (&secrets_builder, "{ss}", key2, val2); + + g_variant_builder_add (&vpn_builder, "{sv}", + NM_SETTING_VPN_SECRETS, + g_variant_builder_end (&secrets_builder)); + g_variant_builder_add (&settings_builder, "{sa{sv}}", + NM_SETTING_VPN_SETTING_NAME, + &vpn_builder); + settings = g_variant_builder_end (&settings_builder); + + success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error); + ASSERT (success == TRUE, + "vpn-update-secrets", "failed to update VPN secrets: %s", error->message); + + /* Read the secrets back out */ + tmp = nm_setting_vpn_get_secret (s_vpn, key1); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #1"); + ASSERT (strcmp (tmp, val1) == 0, + "vpn-update-secrets", "unexpected key #1 value"); + + tmp = nm_setting_vpn_get_secret (s_vpn, key2); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #2"); + ASSERT (strcmp (tmp, val2) == 0, + "vpn-update-secrets", "unexpected key #2 value"); + + g_variant_unref (settings); + g_object_unref (connection); +} + +#define TO_DEL_NUM 50 +typedef struct { + NMSettingVpn *s_vpn; + char *to_del[TO_DEL_NUM]; + guint called; +} IterInfo; + +static void +del_iter_func (const char *key, const char *value, gpointer user_data) +{ + IterInfo *info = user_data; + int i; + + /* Record how many times this function gets called; it should get called + * exactly as many times as there are keys in the hash table, regardless + * of what keys we delete from the table. + */ + info->called++; + + /* During the iteration, remove a bunch of stuff from the table */ + if (info->called == 1) { + for (i = 0; i < TO_DEL_NUM; i++) + nm_setting_vpn_remove_data_item (info->s_vpn, info->to_del[i]); + } +} + +static void +test_setting_vpn_modify_during_foreach (void) +{ + NMSettingVpn *s_vpn; + IterInfo info; + char *key, *val; + int i, u = 0; + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + g_assert (s_vpn); + + for (i = 0; i < TO_DEL_NUM * 2; i++) { + key = g_strdup_printf ("adsfasdfadf%d", i); + val = g_strdup_printf ("42263236236awt%d", i); + nm_setting_vpn_add_data_item (s_vpn, key, val); + + /* Cache some keys to delete */ + if (i % 2) + info.to_del[u++] = g_strdup (key); + + g_free (key); + g_free (val); + } + + /* Iterate over current table keys */ + info.s_vpn = s_vpn; + info.called = 0; + nm_setting_vpn_foreach_data_item (s_vpn, del_iter_func, &info); + + /* Make sure all the things we removed during iteration are really gone */ + for (i = 0; i < TO_DEL_NUM; i++) { + g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, info.to_del[i]), ==, NULL); + g_free (info.to_del[i]); + } + + /* And make sure the foreach callback was called the same number of times + * as there were keys in the table at the beginning of the foreach. + */ + g_assert_cmpint (info.called, ==, TO_DEL_NUM * 2); + + g_object_unref (s_vpn); +} + +static void +test_setting_ip4_config_labels (void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GVariant *label; + GPtrArray *addrs; + char **labels; + NMConnection *conn; + GVariant *dict, *dict2, *setting_dict, *value; + GError *error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new (AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error (error); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* The 'address-labels' property should be omitted from the serialization if + * there are no non-NULL labels. + */ + conn = nmtst_create_minimal_connection ("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, nm_setting_duplicate (NM_SETTING (s_ip4))); + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (conn); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "address-labels", NULL); + g_assert (value == NULL); + + g_variant_unref (setting_dict); + g_variant_unref (dict); + + /* Now back to constructing the original s_ip4... */ + + /* addr 2 */ + addr = nm_ip_address_new (AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "label", g_variant_new_string ("eth0:1")); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + /* addr 3 */ + addr = nm_ip_address_new (AF_INET, "3.4.5.6", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "label", NULL); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 2); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* Remove addr 1 and re-verify remaining addresses */ + nm_setting_ip_config_remove_address (s_ip4, 0); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* If we serialize as the daemon, the labels should appear in the D-Bus + * serialization under both 'address-labels' and 'address-data'. + */ + conn = nmtst_create_minimal_connection ("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "address-labels", G_VARIANT_TYPE_STRING_ARRAY); + g_assert (value != NULL); + g_variant_get (value, "^as", &labels); + g_assert_cmpint (g_strv_length (labels), ==, 2); + g_assert_cmpstr (labels[0], ==, "eth0:1"); + g_assert_cmpstr (labels[1], ==, ""); + g_variant_unref (value); + g_strfreev (labels); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_variant_unref (value); + g_assert (addrs != NULL); + g_assert_cmpint (addrs->len, ==, 2); + addr = addrs->pdata[0]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + addr = addrs->pdata[1]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + g_ptr_array_unref (addrs); + + g_variant_unref (setting_dict); + + /* We should be able to deserialize the labels from either 'address-labels' + * or 'address-data'. + */ + dict2 = g_variant_ref (dict); + + NMTST_VARIANT_EDITOR (dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); + ); + conn = nm_simple_connection_new_from_dbus (dict, &error); + g_assert_no_error (error); + g_variant_unref (dict); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + g_object_unref (conn); + + NMTST_VARIANT_EDITOR (dict2, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-labels"); + ); + conn = nm_simple_connection_new_from_dbus (dict2, &error); + g_assert_no_error (error); + g_variant_unref (dict2); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + /* Test explicit property assignment */ + g_object_get (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, + NULL); + + nm_setting_ip_config_clear_addresses (s_ip4); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 0); + + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_ADDRESSES, addrs, + NULL); + g_ptr_array_unref (addrs); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 2); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.3.4.5"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.4.5.6"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + + g_object_unref (conn); +} + +static void +test_setting_ip4_config_address_data (void) +{ + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GPtrArray *addrs; + NMConnection *conn; + GVariant *dict, *setting_dict, *value; + GError *error = NULL; + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + /* addr 1 */ + addr = nm_ip_address_new (AF_INET, "1.2.3.4", 24, &error); + g_assert_no_error (error); + nm_ip_address_set_attribute (addr, "one", g_variant_new_string ("foo")); + nm_ip_address_set_attribute (addr, "two", g_variant_new_int32 (42)); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + /* addr 2 */ + addr = nm_ip_address_new (AF_INET, "2.3.4.5", 24, &error); + g_assert_no_error (error); + + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + nmtst_assert_setting_verifies (NM_SETTING (s_ip4)); + + /* The client-side D-Bus serialization should include the attributes in + * "address-data", and should not have an "addresses" property. + */ + conn = nmtst_create_minimal_connection ("address-data test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "addresses", NULL); + g_assert (value == NULL); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_variant_unref (value); + g_assert (addrs != NULL); + g_assert_cmpint (addrs->len, ==, 2); + + addr = addrs->pdata[0]; + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value != NULL); + g_assert_cmpint (g_variant_get_int32 (value), ==, 42); + + g_ptr_array_unref (addrs); + g_variant_unref (setting_dict); + g_variant_unref (dict); + + /* The daemon-side serialization should include both 'addresses' and 'address-data' */ + _nm_utils_is_manager_process = TRUE; + dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + + setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + + value = g_variant_lookup_value (setting_dict, "addresses", G_VARIANT_TYPE ("aau")); + g_assert (value != NULL); + g_variant_unref (value); + + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + g_assert (value != NULL); + g_variant_unref (value); + + g_variant_unref (setting_dict); + g_object_unref (conn); + + /* When we reserialize that dictionary as a client, 'address-data' will be preferred. */ + conn = nm_simple_connection_new_from_dbus (dict, &error); + g_assert_no_error (error); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "foo"); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value != NULL); + g_assert_cmpint (g_variant_get_int32 (value), ==, 42); + + /* But on the server side, 'addresses' will have precedence. */ + _nm_utils_is_manager_process = TRUE; + conn = nm_simple_connection_new_from_dbus (dict, &error); + _nm_utils_is_manager_process = FALSE; + g_assert_no_error (error); + g_variant_unref (dict); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.2.3.4"); + value = nm_ip_address_get_attribute (addr, "one"); + g_assert (value == NULL); + value = nm_ip_address_get_attribute (addr, "two"); + g_assert (value == NULL); + + g_object_unref (conn); +} + +static void +test_setting_gsm_apn_spaces (void) +{ + NMSettingGsm *s_gsm; + const char *tmp; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + ASSERT (s_gsm != NULL, + "gsm-apn-spaces", + "error creating GSM setting"); + + /* Trailing space */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar ", NULL); + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "gsm-apn-spaces", "empty APN"); + ASSERT (strcmp (tmp, "foobar") == 0, + "gsm-apn-spaces", "unexpected APN"); + + /* Leading space */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, " foobar", NULL); + tmp = nm_setting_gsm_get_apn (s_gsm); + ASSERT (tmp != NULL, + "gsm-apn-spaces", "empty APN"); + ASSERT (strcmp (tmp, "foobar") == 0, + "gsm-apn-spaces", "unexpected APN"); +} + +static void +test_setting_gsm_apn_bad_chars (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + ASSERT (s_gsm != NULL, + "gsm-apn-bad-chars", + "error creating GSM setting"); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); + + /* Make sure a valid APN works */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar123.-baz", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == TRUE, + "gsm-apn-bad-chars", "unexpectedly invalid GSM setting"); + + /* Random invalid chars */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "@#%$@#%@#%", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* Spaces */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar baz", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* 0 characters long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); + + /* 65-character long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", NULL); + ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE, + "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); +} + +static void +test_setting_gsm_apn_underscore (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + g_assert (s_gsm); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL); + + /* 65-character long */ + g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar_baz", NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); +} + +static void +test_setting_gsm_without_number (void) +{ + NMSettingGsm *s_gsm; + + s_gsm = (NMSettingGsm *) nm_setting_gsm_new (); + g_assert (s_gsm); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, NULL, NULL); + nmtst_assert_setting_verifies (NM_SETTING (s_gsm)); + + g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "", NULL); + nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static NMSettingWirelessSecurity * +make_test_wsec_setting (const char *detail) +{ + NMSettingWirelessSecurity *s_wsec; + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, detail, "error creating setting"); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "foobarbaz", + NM_SETTING_WIRELESS_SECURITY_PSK, "random psk", + NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "aaaaaaaaaa", + NULL); + + return s_wsec; +} + +#define ASSERT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value != NULL, test_name, msg); \ + g_variant_unref (value); \ + } + +#define ASSERT_NOT_CONTAINS(vardict, key, test_name, msg) \ + { \ + GVariant *value; \ + value = g_variant_lookup_value (vardict, key, NULL); \ + ASSERT (value == NULL, test_name, msg); \ + } + +static void +test_setting_to_dbus_all (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-all"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + + /* Make sure all keys are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_no_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-no-secrets"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_NO_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_only_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-to-dbus-only-secrets"); + + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + + /* Make sure non-secret keys are not there */ + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT_NOT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, + "setting-to-dbus-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are there */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_PSK, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "setting-to-dbus-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_variant_unref (dict); + g_object_unref (s_wsec); +} + +static void +test_setting_to_dbus_transform (void) +{ + NMSetting *s_wired; + GVariant *dict, *val; + const char *test_mac_address = "11:22:33:44:55:66"; + const guint8 *dbus_mac_address; + guint8 cmp_mac_address[ETH_ALEN]; + gsize len; + + s_wired = nm_setting_wired_new (); + g_object_set (s_wired, + NM_SETTING_WIRED_MAC_ADDRESS, test_mac_address, + NULL); + + g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); + + dict = _nm_setting_to_dbus (s_wired, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRED_MAC_ADDRESS, G_VARIANT_TYPE_BYTESTRING); + g_assert (val != NULL); + + dbus_mac_address = g_variant_get_fixed_array (val, &len, 1); + g_assert_cmpint (len, ==, ETH_ALEN); + + nm_utils_hwaddr_aton (test_mac_address, cmp_mac_address, ETH_ALEN); + g_assert (memcmp (dbus_mac_address, cmp_mac_address, ETH_ALEN) == 0); + + g_variant_unref (val); + g_variant_unref (dict); + g_object_unref (s_wired); +} + +static void +test_setting_to_dbus_enum (void) +{ + NMSetting *s_ip6, *s_wsec, *s_serial; + GVariant *dict, *val; + + /* enum */ + s_ip6 = nm_setting_ip6_config_new (); + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NULL); + + dict = _nm_setting_to_dbus (s_ip6, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_IP6_CONFIG_IP6_PRIVACY, G_VARIANT_TYPE_INT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_int32 (val), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_ip6); + + /* flags (and a transformed enum) */ + s_wsec = nm_setting_wireless_security_new (); + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_KEY, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED), + NULL); + + dict = _nm_setting_to_dbus (s_wsec, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, G_VARIANT_TYPE_UINT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_uint32 (val), ==, NM_WEP_KEY_TYPE_KEY); + g_variant_unref (val); + + val = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, G_VARIANT_TYPE_UINT32); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_uint32 (val), ==, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_wsec); + + /* another transformed enum */ + s_serial = nm_setting_serial_new (); + g_object_set (s_serial, + NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_ODD, + NULL); + + dict = _nm_setting_to_dbus (s_serial, NULL, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + val = g_variant_lookup_value (dict, NM_SETTING_SERIAL_PARITY, G_VARIANT_TYPE_BYTE); + g_assert (val != NULL); + g_assert_cmpint (g_variant_get_byte (val), ==, 'o'); + g_variant_unref (val); + + g_variant_unref (dict); + g_object_unref (s_serial); +} + +static void +test_connection_to_dbus_setting_name (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + connection = nm_simple_connection_new (); + s_wsec = make_test_wsec_setting ("connection-to-dbus-setting-name"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Make sure the keys of the first level dict are setting names, not + * the GType name of the setting objects. + */ + ASSERT_CONTAINS (dict, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + "connection-to-dbus-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_variant_unref (dict); + g_object_unref (connection); +} + +static void +test_connection_to_dbus_deprecated_props (void) +{ + NMConnection *connection; + NMSetting *s_wireless; + GBytes *ssid; + NMSettingWirelessSecurity *s_wsec; + GVariant *dict, *wireless_dict, *sec_val; + + connection = nmtst_create_minimal_connection ("test-connection-to-dbus-deprecated-props", + NULL, + NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + + s_wireless = nm_setting_wireless_new (); + ssid = g_bytes_new ("1234567", 7); + g_object_set (s_wireless, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, s_wireless); + + /* Serialization should not have an 802-11-wireless.security property */ + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); + + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); + g_assert (sec_val == NULL); + + g_variant_unref (wireless_dict); + g_variant_unref (dict); + + /* Now add an NMSettingWirelessSecurity and try again */ + s_wsec = make_test_wsec_setting ("test-connection-to-dbus-deprecated-props"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (dict != NULL); + + wireless_dict = g_variant_lookup_value (dict, NM_SETTING_WIRELESS_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (wireless_dict != NULL); + + sec_val = g_variant_lookup_value (wireless_dict, "security", NULL); + g_assert (g_variant_is_of_type (sec_val, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (sec_val, NULL), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_variant_unref (sec_val); + g_variant_unref (wireless_dict); + g_variant_unref (dict); + g_object_unref (connection); +} + +static void +test_setting_new_from_dbus (void) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *dict; + + s_wsec = make_test_wsec_setting ("setting-new-from-dbus"); + dict = _nm_setting_to_dbus (NM_SETTING (s_wsec), NULL, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (s_wsec); + + s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, NULL); + g_variant_unref (dict); + + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); + g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, "foobarbaz"); + g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "random psk"); + g_object_unref (s_wsec); +} + +static void +test_setting_new_from_dbus_transform (void) +{ + NMSetting *s_wired; + GVariant *dict; + GVariantBuilder builder; + const char *test_mac_address = "11:22:33:44:55:66"; + guint8 dbus_mac_address[ETH_ALEN]; + GError *error = NULL; + + nm_utils_hwaddr_aton (test_mac_address, dbus_mac_address, ETH_ALEN); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRED_MAC_ADDRESS, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + dbus_mac_address, ETH_ALEN, 1)); + dict = g_variant_builder_end (&builder); + + s_wired = _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRED, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_setting_wired_get_mac_address (NM_SETTING_WIRED (s_wired)), ==, test_mac_address); + + g_variant_unref (dict); + g_object_unref (s_wired); +} + +static void +test_setting_new_from_dbus_enum (void) +{ + NMSettingIP6Config *s_ip6; + NMSettingWirelessSecurity *s_wsec; + NMSettingSerial *s_serial; + GVariant *dict; + GVariantBuilder builder; + GError *error = NULL; + + /* enum */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, + g_variant_new_int32 (NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); + dict = g_variant_builder_end (&builder); + + s_ip6 = (NMSettingIP6Config *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_IP6_CONFIG, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (s_ip6), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + + g_variant_unref (dict); + g_object_unref (s_ip6); + + /* flags (and a transformed enum) */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32 (NM_WEP_KEY_TYPE_KEY)); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + g_variant_new_uint32 (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + dict = g_variant_builder_end (&builder); + + s_wsec = (NMSettingWirelessSecurity *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_WIRELESS_SECURITY, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_wireless_security_get_wep_key_type (s_wsec), ==, NM_WEP_KEY_TYPE_KEY); + g_assert_cmpint (nm_setting_wireless_security_get_wep_key_flags (s_wsec), ==, (NM_SETTING_SECRET_FLAG_AGENT_OWNED | + NM_SETTING_SECRET_FLAG_NOT_SAVED)); + + g_variant_unref (dict); + g_object_unref (s_wsec); + + /* another transformed enum */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_SERIAL_PARITY, + g_variant_new_byte ('E')); + dict = g_variant_builder_end (&builder); + + s_serial = (NMSettingSerial *) _nm_setting_new_from_dbus (NM_TYPE_SETTING_SERIAL, dict, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (nm_setting_serial_get_parity (s_serial), ==, NM_SETTING_SERIAL_PARITY_EVEN); + + g_variant_unref (dict); + g_object_unref (s_serial); +} + +static NMConnection * +new_test_connection (void) +{ + NMConnection *connection; + NMSetting *setting; + char *uuid; + guint64 timestamp = time (NULL); + + connection = nm_simple_connection_new (); + + setting = nm_setting_connection_new (); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_ID, "foobar", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_TIMESTAMP, timestamp, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_wired_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_WIRED_MTU, 1592, + NULL); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "eyeofthetiger", + NULL); + nm_connection_add_setting (connection, setting); + + return connection; +} + +static GVariant * +new_connection_dict (char **out_uuid, + const char **out_expected_id, + const char **out_expected_ip6_method) +{ + GVariantBuilder conn_builder, setting_builder; + + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + + *out_uuid = nm_utils_uuid_generate (); + *out_expected_id = "My happy connection"; + *out_expected_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + + /* Connection setting */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_NAME, + g_variant_new_string (NM_SETTING_CONNECTION_SETTING_NAME)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_ID, + g_variant_new_string (*out_expected_id)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_UUID, + g_variant_new_string (*out_uuid)); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_CONNECTION_TYPE, + g_variant_new_string (NM_SETTING_WIRED_SETTING_NAME)); + + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_CONNECTION_SETTING_NAME, + &setting_builder); + + /* Wired setting */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_WIRED_SETTING_NAME, + &setting_builder); + + /* IP6 */ + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_IP_CONFIG_METHOD, + g_variant_new_string (*out_expected_ip6_method)); + g_variant_builder_add (&conn_builder, "{sa{sv}}", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + &setting_builder); + + return g_variant_builder_end (&conn_builder); +} + +static void +test_connection_replace_settings (void) +{ + NMConnection *connection; + GVariant *new_settings; + GError *error = NULL; + gboolean success; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip6; + char *uuid = NULL; + const char *expected_id = NULL, *expected_method = NULL; + + connection = new_test_connection (); + + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); + g_assert (new_settings); + + /* Replace settings and test */ + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_no_error (error); + g_assert (success); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (nm_connection_get_setting_wired (connection)); + g_assert (!nm_connection_get_setting_ip4_config (connection)); + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, expected_method); + + g_free (uuid); + g_variant_unref (new_settings); + g_object_unref (connection); +} + +static void +test_connection_replace_settings_from_connection (void) +{ + NMConnection *connection, *replacement; + NMSettingConnection *s_con; + NMSetting *setting; + GBytes *ssid; + char *uuid = NULL; + const char *expected_id = "Awesome connection"; + + connection = new_test_connection (); + g_assert (connection); + + replacement = nm_simple_connection_new (); + g_assert (replacement); + + /* New connection setting */ + setting = nm_setting_connection_new (); + g_assert (setting); + + uuid = nm_utils_uuid_generate (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, expected_id, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + nm_connection_add_setting (replacement, setting); + + /* New wifi setting */ + setting = nm_setting_wireless_new (); + g_assert (setting); + + ssid = g_bytes_new ("1234567", 7); + g_object_set (setting, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (replacement, setting); + + /* Replace settings and test */ + nm_connection_replace_settings_from_connection (connection, replacement); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (!nm_connection_get_setting_wired (connection)); + g_assert (!nm_connection_get_setting_ip6_config (connection)); + g_assert (nm_connection_get_setting_wireless (connection)); + + g_free (uuid); + g_object_unref (replacement); + g_object_unref (connection); +} + +static void +test_connection_replace_settings_bad (void) +{ + NMConnection *connection, *new_connection; + GVariant *new_settings; + GVariantBuilder builder, setting_builder; + GError *error = NULL; + gboolean success; + NMSettingConnection *s_con; + + new_connection = new_test_connection (); + g_assert (nm_connection_verify (new_connection, NULL)); + s_con = nm_connection_get_setting_connection (new_connection); + g_object_set (s_con, + NM_SETTING_CONNECTION_UUID, NULL, + NM_SETTING_CONNECTION_ID, "bad-connection", + NULL); + g_assert (!nm_connection_verify (new_connection, NULL)); + + /* nm_connection_replace_settings_from_connection() should succeed */ + connection = new_test_connection (); + nm_connection_replace_settings_from_connection (connection, new_connection); + g_assert_cmpstr (nm_connection_get_id (connection), ==, "bad-connection"); + g_assert (!nm_connection_verify (connection, NULL)); + g_object_unref (connection); + + /* nm_connection_replace_settings() should succeed */ + new_settings = nm_connection_to_dbus (new_connection, NM_CONNECTION_SERIALIZE_ALL); + g_assert (new_settings != NULL); + + connection = new_test_connection (); + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert_cmpstr (nm_connection_get_id (connection), ==, "bad-connection"); + g_assert (!nm_connection_verify (connection, NULL)); + g_object_unref (connection); + g_variant_unref (new_settings); + + /* But given an invalid dict, it should fail */ + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&builder, "{sa{sv}}", + "ip-over-avian-carrier", + &setting_builder); + new_settings = g_variant_builder_end (&builder); + + connection = new_test_connection (); + success = nm_connection_replace_settings (connection, new_settings, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); + g_assert (!success); + + g_assert (nm_connection_verify (connection, NULL)); + g_object_unref (connection); + + g_variant_unref (new_settings); + g_object_unref (new_connection); +} + +static void +test_connection_new_from_dbus (void) +{ + NMConnection *connection; + GVariant *new_settings; + GError *error = NULL; + NMSettingConnection *s_con; + NMSettingIPConfig *s_ip6; + char *uuid = NULL; + const char *expected_id = NULL, *expected_method = NULL; + + new_settings = new_connection_dict (&uuid, &expected_id, &expected_method); + g_assert (new_settings); + + /* Replace settings and test */ + connection = nm_simple_connection_new_from_dbus (new_settings, &error); + g_assert_no_error (error); + g_assert (connection); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); + g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid); + + g_assert (nm_connection_get_setting_wired (connection)); + g_assert (nm_connection_get_setting_ip4_config (connection)); + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, expected_method); + + g_free (uuid); + g_variant_unref (new_settings); + g_object_unref (connection); +} + +static void +check_permission (NMSettingConnection *s_con, + guint32 idx, + const char *expected_uname, + const char *tag) +{ + gboolean success; + const char *ptype = NULL, *pitem = NULL, *detail = NULL; + + success = nm_setting_connection_get_permission (s_con, 0, &ptype, &pitem, &detail); + ASSERT (success == TRUE, tag, "unexpected failure getting added permission"); + + /* Permission type */ + ASSERT (ptype != NULL, tag, "unexpected failure getting permission type"); + ASSERT (strcmp (ptype, "user") == 0, tag, "retrieved unexpected permission type"); + + /* Permission item */ + ASSERT (pitem != NULL, tag, "unexpected failure getting permission item"); + ASSERT (strcmp (pitem, expected_uname) == 0, tag, "retrieved unexpected permission item"); + + ASSERT (detail == NULL, tag, "unexpected success getting permission detail"); +} + +#define TEST_UNAME "asdfasfasdf" + +static void +test_setting_connection_permissions_helpers (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + char **perms; + const char *expected_perm = "user:" TEST_UNAME ":"; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strcmp (ptype, \"user\") == 0*"); + success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*ptype*"); + success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*uname*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*uname[0] != '\\0'*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strchr (uname, ':')*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #3"); + + /* Ensure a non-UTF-8 [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*g_utf8_validate (uname, -1, NULL)*"); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*p != NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", buf, NULL); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #4"); + + /* Ensure a non-NULL [detail] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*detail == NULL*"); + success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf"); + g_test_assert_expected_messages (); + ASSERT (success == FALSE, + "setting-connection-permissions-helpers", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (success == TRUE, + "setting-connection-permissions-helpers", "unexpected failure adding valid user permisson"); + + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions"); + + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-helpers"); + + /* Check the actual GObject property just to be paranoid */ + g_object_get (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, &perms, NULL); + ASSERT (perms != NULL, + "setting-connection-permissions-helpers", "unexpected failure getting permissions"); + ASSERT (g_strv_length (perms) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions"); + ASSERT (strcmp (perms[0], expected_perm) == 0, + "setting-connection-permissions-helpers", "unexpected permission property data"); + g_strfreev (perms); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-helpers", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + +static void +add_permission_property (NMSettingConnection *s_con, + const char *ptype, + const char *pitem, + int pitem_len, + const char *detail) +{ + GString *str; + char *perms[2]; + + str = g_string_sized_new (50); + if (ptype) + g_string_append (str, ptype); + g_string_append_c (str, ':'); + + if (pitem) { + if (pitem_len >= 0) + g_string_append_len (str, pitem, pitem_len); + else + g_string_append (str, pitem); + } + + g_string_append_c (str, ':'); + + if (detail) + g_string_append (str, detail); + + perms[0] = str->str; + perms[1] = NULL; + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, perms, NULL); + + g_string_free (str, TRUE); +} + +static void +test_setting_connection_permissions_property (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0*"); + add_permission_property (s_con, "foobar", "blah", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0*"); + add_permission_property (s_con, NULL, "blah", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*last_colon > str*"); + add_permission_property (s_con, "user", NULL, -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*last_colon > str*"); + add_permission_property (s_con, "user", "", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' in the middle is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*str[i] != ':'*"); + add_permission_property (s_con, "user", "ad:asdf", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #3"); + + /* Ensure an [item] with ':' at the end is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*str[i] != ':'*"); + add_permission_property (s_con, "user", "adasdfaf:", -1, NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #4"); + + /* Ensure a non-UTF-8 [item] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*g_utf8_validate (str, -1, NULL)*"); + add_permission_property (s_con, "user", buf, (int) sizeof (buf), NULL); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #5"); + + /* Ensure a non-NULL [detail] is rejected */ + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*(last_colon + 1) == '\\0'*"); + add_permission_property (s_con, "user", "dafasdf", -1, "asdf"); + g_test_assert_expected_messages (); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-permissions-property", "unexpected failure adding valid user permisson"); + + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-property"); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + +static void +test_connection_compare_same (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + g_assert (nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_key_only_in_a (void) +{ + NMConnection *a, *b; + NMSettingConnection *s_con; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_setting_only_in_a (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + nm_connection_remove_setting (b, NM_TYPE_SETTING_IP4_CONFIG); + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_key_only_in_b (void) +{ + NMConnection *a, *b; + NMSettingConnection *s_con; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 0, NULL); + + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_compare_setting_only_in_b (void) +{ + NMConnection *a, *b; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + nm_connection_remove_setting (a, NM_TYPE_SETTING_IP4_CONFIG); + g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT)); + g_object_unref (a); + g_object_unref (b); +} + +typedef struct { + const char *key_name; + guint32 result; +} DiffKey; + +typedef struct { + const char *name; + DiffKey keys[30]; +} DiffSetting; + +#define ARRAY_LEN(a) (sizeof (a) / sizeof (a[0])) + +static void +ensure_diffs (GHashTable *diffs, const DiffSetting *check, gsize n_check) +{ + guint i; + + g_assert (g_hash_table_size (diffs) == n_check); + + /* Loop through the settings */ + for (i = 0; i < n_check; i++) { + GHashTable *setting_hash; + guint z = 0; + + setting_hash = g_hash_table_lookup (diffs, check[i].name); + g_assert (setting_hash); + + /* Get the number of keys to check */ + while (check[i].keys[z].key_name) + z++; + g_assert (g_hash_table_size (setting_hash) == z); + + /* Now compare the actual keys */ + for (z = 0; check[i].keys[z].key_name; z++) { + NMSettingDiffResult result; + + result = GPOINTER_TO_UINT (g_hash_table_lookup (setting_hash, check[i].keys[z].key_name)); + g_assert (result == check[i].keys[z].result); + } + } +} + +static void +test_connection_diff_a_only (void) +{ + NMConnection *connection; + GHashTable *out_diffs = NULL; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, { + { NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_READ_ONLY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } + } }, + { NM_SETTING_WIRED_SETTING_NAME, { + { NM_SETTING_WIRED_PORT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_SPEED, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_DUPLEX, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_AUTO_NEGOTIATE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_MTU, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_SUBCHANNELS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_NETTYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_WIRED_S390_OPTIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, { + { NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_GATEWAY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_NEVER_DEFAULT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP_CONFIG_MAY_FAIL, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + connection = new_test_connection (); + + same = nm_connection_diff (connection, NULL, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (connection); +} + +static void +test_connection_diff_same (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + gboolean same; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_different (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + NMSettingIPConfig *s_ip4; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_IP4_CONFIG_SETTING_NAME, { + { NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + s_ip4 = nm_connection_get_setting_ip4_config (a); + g_assert (s_ip4); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NULL); + + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_no_secrets (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + NMSetting *s_pppoe; + gboolean same; + const DiffSetting settings[] = { + { NM_SETTING_PPPOE_SETTING_NAME, { + { NM_SETTING_PPPOE_PASSWORD, NM_SETTING_DIFF_RESULT_IN_B }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + s_pppoe = nm_setting_pppoe_new (); + g_object_set (G_OBJECT (s_pppoe), + NM_SETTING_PPPOE_USERNAME, "thomas", + NULL); + nm_connection_add_setting (a, s_pppoe); + + b = nm_simple_connection_new_clone (a); + + /* Add a secret to B */ + s_pppoe = NM_SETTING (nm_connection_get_setting_pppoe (b)); + g_assert (s_pppoe); + g_object_set (G_OBJECT (s_pppoe), + NM_SETTING_PPPOE_PASSWORD, "secretpassword", + NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + + /* Now make sure the diff returns results if secrets are not ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +test_connection_diff_inferrable (void) +{ + NMConnection *a, *b; + GHashTable *out_diffs = NULL; + gboolean same; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + char *uuid; + const DiffSetting settings[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, { + { NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }, + } }, + }; + + a = new_test_connection (); + b = nm_simple_connection_new_clone (a); + + /* Change the UUID, wired MTU, and set ignore-auto-dns */ + s_con = nm_connection_get_setting_connection (a); + g_assert (s_con); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, "really neat connection", + NULL); + g_free (uuid); + + s_wired = nm_connection_get_setting_wired (a); + g_assert (s_wired); + g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MTU, 300, NULL); + + s_ip4 = nm_connection_get_setting_ip4_config (a); + g_assert (s_ip4); + g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert (same == TRUE); + g_assert (out_diffs == NULL); + + /* And change a INFERRABLE property to ensure that it shows up in the diff results */ + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, "usb0", NULL); + + /* Make sure the diff returns no results as secrets are ignored */ + same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_INFERRABLE, &out_diffs); + g_assert (same == FALSE); + g_assert (out_diffs != NULL); + g_assert (g_hash_table_size (out_diffs) > 0); + + ensure_diffs (out_diffs, settings, ARRAY_LEN (settings)); + + g_hash_table_destroy (out_diffs); + g_object_unref (a); + g_object_unref (b); +} + +static void +add_generic_settings (NMConnection *connection, const char *ctype) +{ + NMSetting *setting; + char *uuid; + + uuid = nm_utils_uuid_generate (); + + setting = nm_setting_connection_new (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, "asdfasdfadf", + NM_SETTING_CONNECTION_TYPE, ctype, + NM_SETTING_CONNECTION_UUID, uuid, + NULL); + nm_connection_add_setting (connection, setting); + + g_free (uuid); + + setting = nm_setting_ip4_config_new (); + g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, setting); + + setting = nm_setting_ip6_config_new (); + g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, setting); +} + +static void +test_connection_good_base_types (void) +{ + NMConnection *connection; + NMSetting *setting; + gboolean success; + GError *error = NULL; + GBytes *ssid; + const char *bdaddr = "11:22:33:44:55:66"; + + /* Try a basic wired connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIRED_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Try a wired PPPoE connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_PPPOE_SETTING_NAME); + setting = nm_setting_pppoe_new (); + g_object_set (setting, NM_SETTING_PPPOE_USERNAME, "bob smith", NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Wifi connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIRELESS_SETTING_NAME); + + setting = nm_setting_wireless_new (); + ssid = g_bytes_new ("1234567", 7); + g_object_set (setting, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* Bluetooth connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_BLUETOOTH_SETTING_NAME); + + setting = nm_setting_bluetooth_new (); + g_object_set (setting, + NM_SETTING_BLUETOOTH_BDADDR, bdaddr, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* WiMAX connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_WIMAX_SETTING_NAME); + setting = nm_setting_wimax_new (); + g_object_set (setting, NM_SETTING_WIMAX_NETWORK_NAME, "CLEAR", NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); + + /* GSM connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_GSM_SETTING_NAME); + + setting = nm_setting_gsm_new (); + g_object_set (setting, + NM_SETTING_GSM_NUMBER, "*99#", + NM_SETTING_GSM_APN, "metered.billing.sucks", + NULL); + nm_connection_add_setting (connection, setting); + + /* CDMA connection */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_CDMA_SETTING_NAME); + + setting = nm_setting_cdma_new (); + g_object_set (setting, + NM_SETTING_CDMA_NUMBER, "#777", + NM_SETTING_CDMA_USERNAME, "foobar@vzw.com", + NULL); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + g_object_unref (connection); +} + +static void +test_connection_bad_base_types (void) +{ + NMConnection *connection; + NMSetting *setting; + gboolean success; + GError *error = NULL; + + /* Test various non-base connection types to make sure they are rejected; + * using a fake 'wired' connection so the rest of it verifies + */ + + /* Connection setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_CONNECTION_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* PPP setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_PPP_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + setting = nm_setting_ppp_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* Serial setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_SERIAL_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + setting = nm_setting_serial_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP4 setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_IP4_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); + + /* IP6 setting */ + connection = nm_simple_connection_new (); + add_generic_settings (connection, NM_SETTING_IP6_CONFIG_SETTING_NAME); + setting = nm_setting_wired_new (); + nm_connection_add_setting (connection, setting); + + success = nm_connection_verify (connection, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (g_str_has_prefix (error->message, "connection.type: ")); + g_assert (success == FALSE); + g_object_unref (connection); + g_clear_error (&error); +} + +static void +test_setting_compare_id (void) +{ + NMSetting *old, *new; + gboolean success; + + old = nm_setting_connection_new (); + g_object_set (old, + NM_SETTING_CONNECTION_ID, "really awesome cool connection", + NM_SETTING_CONNECTION_UUID, "fbbd59d5-acab-4e30-8f86-258d272617e7", + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NULL); + + new = nm_setting_duplicate (old); + g_object_set (new, NM_SETTING_CONNECTION_ID, "some different connection id", NULL); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_ID); + g_assert (success); +} + +static void +test_setting_compare_timestamp (void) +{ + NMSetting *old, *new; + gboolean success; + + old = nm_setting_connection_new (); + g_object_set (old, + NM_SETTING_CONNECTION_ID, "ignore timestamp connection", + NM_SETTING_CONNECTION_UUID, "b047a198-0e0a-4f0e-a653-eea09bb35e40", + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 1234567890, + NULL); + + new = nm_setting_duplicate (old); + g_object_set (new, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) 1416316539, NULL); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP); + g_assert (success); +} + +typedef struct { + NMSettingSecretFlags secret_flags; + NMSettingCompareFlags comp_flags; + gboolean remove_secret; +} TestDataCompareSecrets; + +static TestDataCompareSecrets * +test_data_compare_secrets_new (NMSettingSecretFlags secret_flags, + NMSettingCompareFlags comp_flags, + gboolean remove_secret) +{ + TestDataCompareSecrets *data = g_new0 (TestDataCompareSecrets, 1); + + data->secret_flags = secret_flags; + data->comp_flags = comp_flags; + data->remove_secret = remove_secret; + return data; +} + +static void +test_setting_compare_secrets (gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + NMSetting *old, *new; + gboolean success; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_wireless_security_new (); + g_object_set (old, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, "really cool psk", + NULL); + nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, data->secret_flags, NULL); + + /* Clear the PSK from the duplicated setting */ + new = nm_setting_duplicate (old); + if (data->remove_secret) { + g_object_set (new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL); + + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + } + + success = nm_setting_compare (old, new, data->comp_flags); + g_assert (success); +} + +static void +test_setting_compare_vpn_secrets (gconstpointer test_data) +{ + const TestDataCompareSecrets *data = test_data; + NMSetting *old, *new; + gboolean success; + + /* Make sure that a connection with transient/unsaved secrets compares + * successfully to the same connection without those secrets. + */ + + old = nm_setting_vpn_new (); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "foobarbaz", "really secret password"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "asdfasdfasdf", "really adfasdfasdfasdf"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "0123456778", "abcdefghijklmnpqrstuvqxyz"); + nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "borkbork", "yet another really secret password"); + nm_setting_set_secret_flags (old, "borkbork", data->secret_flags, NULL); + + /* Clear "borkbork" from the duplicated setting */ + new = nm_setting_duplicate (old); + if (data->remove_secret) { + nm_setting_vpn_remove_secret (NM_SETTING_VPN (new), "borkbork"); + + /* First make sure they are different */ + success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success == FALSE); + } + + success = nm_setting_compare (old, new, data->comp_flags); + g_assert (success); +} + +static void +test_hwaddr_aton_ether_normal (void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + + g_assert (nm_utils_hwaddr_aton ("00:11:22:33:44:55", buf, ETH_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_ib_normal (void) +{ + guint8 buf[100]; + const char *source = "00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90"; + guint8 expected[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, + 0x90 }; + + g_assert (nm_utils_hwaddr_aton (source, buf, INFINIBAND_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_no_leading_zeros (void) +{ + guint8 buf[100]; + guint8 expected[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 }; + + g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:44:5", buf, ETH_ALEN) != NULL); + g_assert (memcmp (buf, expected, sizeof (expected)) == 0); +} + +static void +test_hwaddr_aton_malformed (void) +{ + guint8 buf[100]; + + g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:a@%%", buf, ETH_ALEN) == NULL); +} + +static void +test_hwaddr_equal (void) +{ + const char *string = "00:1a:2b:03:44:05"; + const char *upper_string = "00:1A:2B:03:44:05"; + const char *bad_string = "0:1a:2b:3:44:5"; + const guint8 binary[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 }; + const char *other_string = "1a:2b:03:44:05:00"; + const guint8 other_binary[ETH_ALEN] = { 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x00 }; + const char *long_string = "00:1a:2b:03:44:05:06:07"; + const guint8 long_binary[8] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05, 0x06, 0x07 }; + const char *null_string = "00:00:00:00:00:00"; + const guint8 null_binary[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + g_assert (nm_utils_hwaddr_matches (string, -1, string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (string, -1, null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (string, -1, NULL, ETH_ALEN)); + + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), upper_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), bad_string, -1)); + g_assert (nm_utils_hwaddr_matches (binary, sizeof (binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), long_binary, sizeof (long_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_string, -1)); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), null_binary, sizeof (null_binary))); + g_assert (!nm_utils_hwaddr_matches (binary, sizeof (binary), NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_string, -1, string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_string, -1, long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_string, -1, null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_string, -1, NULL, ETH_ALEN)); + + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), upper_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), bad_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), binary, sizeof (binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), other_binary, sizeof (other_binary))); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_string, -1)); + g_assert (!nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), long_binary, sizeof (long_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_string, -1)); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), null_binary, sizeof (null_binary))); + g_assert (nm_utils_hwaddr_matches (null_binary, sizeof (null_binary), NULL, ETH_ALEN)); +} + +static void +test_hwaddr_canonical (void) +{ + const char *string = "00:1A:2B:03:44:05"; + const char *lower_string = "00:1a:2b:03:44:05"; + const char *short_string = "0:1a:2b:3:44:5"; + const char *hyphen_string = "00-1a-2b-03-44-05"; + const char *invalid_string = "00:1A:2B"; + char *canonical; + + canonical = nm_utils_hwaddr_canonical (string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (lower_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (short_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (hyphen_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, string); + g_free (canonical); + + canonical = nm_utils_hwaddr_canonical (invalid_string, ETH_ALEN); + g_assert_cmpstr (canonical, ==, NULL); + + canonical = nm_utils_hwaddr_canonical (invalid_string, -1); + g_assert_cmpstr (canonical, ==, invalid_string); + g_free (canonical); +} + +static void +test_connection_changed_cb (NMConnection *connection, gboolean *data) +{ + *data = TRUE; +} + +static void +test_ip4_prefix_to_netmask (void) +{ + int i; + + for (i = 0; i<=32; i++) { + guint32 netmask = nm_utils_ip4_prefix_to_netmask (i); + int plen = nm_utils_ip4_netmask_to_prefix (netmask); + + g_assert_cmpint (i, ==, plen); + { + guint32 msk = 0x80000000; + guint32 netmask2 = 0; + guint32 prefix = i; + while (prefix > 0) { + netmask2 |= msk; + msk >>= 1; + prefix--; + } + g_assert_cmpint (netmask, ==, (guint32) htonl (netmask2)); + } + } +} + +static void +test_ip4_netmask_to_prefix (void) +{ + int i, j; + + GRand *rand = g_rand_new (); + + g_rand_set_seed (rand, 1); + + for (i = 2; i<=32; i++) { + guint32 netmask = nm_utils_ip4_prefix_to_netmask (i); + guint32 netmask_lowest_bit = netmask & ~nm_utils_ip4_prefix_to_netmask (i-1); + + g_assert_cmpint (i, ==, nm_utils_ip4_netmask_to_prefix (netmask)); + + for (j = 0; j < 2*i; j++) { + guint32 r = g_rand_int (rand); + guint32 netmask_holey; + guint32 prefix_holey; + + netmask_holey = (netmask & r) | netmask_lowest_bit; + + if (netmask_holey == netmask) + continue; + + /* create an invalid netmask with holes and check that the function + * returns the longest prefix. */ + prefix_holey = nm_utils_ip4_netmask_to_prefix (netmask_holey); + + g_assert_cmpint (i, ==, prefix_holey); + } + } + + g_rand_free (rand); +} + +#define ASSERT_CHANGED(statement) \ +{ \ + changed = FALSE; \ + statement; \ + g_assert (changed); \ +} + +#define ASSERT_UNCHANGED(statement) \ +{ \ + changed = FALSE; \ + statement; \ + g_assert (!changed); \ +} + +static void +test_connection_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + + connection = new_test_connection (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + /* Add new setting */ + ASSERT_CHANGED (nm_connection_add_setting (connection, nm_setting_vlan_new ())); + + /* Remove existing setting */ + ASSERT_CHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN)); + + /* Remove non-existing setting */ + ASSERT_UNCHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN)); + + g_object_unref (connection); +} + +static void +test_setting_connection_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingConnection *s_con; + char *uuid; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + ASSERT_CHANGED (g_object_set (s_con, NM_SETTING_CONNECTION_ID, "adfadfasdfaf", NULL)); + + ASSERT_CHANGED (nm_setting_connection_add_permission (s_con, "user", "billsmith", NULL)); + ASSERT_CHANGED (nm_setting_connection_remove_permission (s_con, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*iter != NULL*"); + ASSERT_UNCHANGED (nm_setting_connection_remove_permission (s_con, 1)); + g_test_assert_expected_messages (); + + uuid = nm_utils_uuid_generate (); + ASSERT_CHANGED (nm_setting_connection_add_secondary (s_con, uuid)); + ASSERT_CHANGED (nm_setting_connection_remove_secondary (s_con, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_connection_remove_secondary (s_con, 1)); + g_test_assert_expected_messages (); + + g_object_unref (connection); +} + +static void +test_setting_bond_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingBond *s_bond; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_bond = (NMSettingBond *) nm_setting_bond_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bond)); + + ASSERT_CHANGED (nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "10")); + ASSERT_CHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY)); + ASSERT_UNCHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY)); + + g_object_unref (connection); +} + +static void +test_setting_ip4_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + NMIPRoute *route; + GError *error = NULL; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip4, "11.22.0.0")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns (s_ip4, "33.44.0.0"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns (s_ip4)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip4, 1)); + g_test_assert_expected_messages (); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip4)); + + addr = nm_ip_address_new (AF_INET, "22.33.0.0", 24, &error); + g_assert_no_error (error); + ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip4, addr)); + ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_address (s_ip4, addr); + ASSERT_CHANGED (nm_setting_ip_config_clear_addresses (s_ip4)); + + route = nm_ip_route_new (AF_INET, "22.33.0.0", 24, NULL, 0, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip4, route)); + ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip4, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip4, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_route (s_ip4, route); + ASSERT_CHANGED (nm_setting_ip_config_clear_routes (s_ip4)); + + nm_ip_address_unref (addr); + nm_ip_route_unref (route); + g_object_unref (connection); +} + +static void +test_setting_ip6_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingIPConfig *s_ip6; + NMIPAddress *addr; + NMIPRoute *route; + GError *error = NULL; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns (s_ip6, "1:2:3::4:5:6"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns (s_ip6)); + + ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com")); + ASSERT_CHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->dns_search->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_dns_search (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com"); + ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip6)); + + addr = nm_ip_address_new (AF_INET6, "1:2:3::4:5:6", 64, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip6, addr)); + ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->addresses->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_address (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_address (s_ip6, addr); + ASSERT_CHANGED (nm_setting_ip_config_clear_addresses (s_ip6)); + + route = nm_ip_route_new (AF_INET6, "1:2:3::4:5:6", 128, NULL, 0, &error); + g_assert_no_error (error); + + ASSERT_CHANGED (nm_setting_ip_config_add_route (s_ip6, route)); + ASSERT_CHANGED (nm_setting_ip_config_remove_route (s_ip6, 0)); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*i < priv->routes->len*"); + ASSERT_UNCHANGED (nm_setting_ip_config_remove_route (s_ip6, 1)); + g_test_assert_expected_messages (); + + nm_setting_ip_config_add_route (s_ip6, route); + ASSERT_CHANGED (nm_setting_ip_config_clear_routes (s_ip6)); + + nm_ip_address_unref (addr); + nm_ip_route_unref (route); + g_object_unref (connection); +} + +static void +test_setting_vlan_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingVlan *s_vlan; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); + nm_connection_add_setting (connection, NM_SETTING (s_vlan)); + + ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, 3)); + ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < g_slist_length (list)*"); + ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1)); + g_test_assert_expected_messages (); + ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_INGRESS_MAP, "1:3")); + ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_INGRESS_MAP)); + + ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, 3)); + ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*idx < g_slist_length (list)*"); + ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1)); + g_test_assert_expected_messages (); + ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_EGRESS_MAP, "1:3")); + ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_EGRESS_MAP)); + + g_object_unref (connection); +} + +static void +test_setting_vpn_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingVpn *s_vpn; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + ASSERT_CHANGED (nm_setting_vpn_add_data_item (s_vpn, "foobar", "baz")); + ASSERT_CHANGED (nm_setting_vpn_remove_data_item (s_vpn, "foobar")); + ASSERT_UNCHANGED (nm_setting_vpn_remove_data_item (s_vpn, "not added")); + + ASSERT_CHANGED (nm_setting_vpn_add_secret (s_vpn, "foobar", "baz")); + ASSERT_CHANGED (nm_setting_vpn_remove_secret (s_vpn, "foobar")); + ASSERT_UNCHANGED (nm_setting_vpn_remove_secret (s_vpn, "not added")); + + g_object_unref (connection); +} + +static void +test_setting_wired_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWired *s_wired; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + ASSERT_CHANGED (nm_setting_wired_add_s390_option (s_wired, "portno", "1")); + ASSERT_CHANGED (nm_setting_wired_remove_s390_option (s_wired, "portno")); + ASSERT_UNCHANGED (nm_setting_wired_remove_s390_option (s_wired, "layer2")); + + g_object_unref (connection); +} + +static void +test_setting_wireless_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWireless *s_wifi; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ASSERT_CHANGED (nm_setting_wireless_add_seen_bssid (s_wifi, "00:11:22:33:44:55")); + + g_object_unref (connection); +} + +static void +test_setting_wireless_security_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSettingWirelessSecurity *s_wsec; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + /* Protos */ + ASSERT_CHANGED (nm_setting_wireless_security_add_proto (s_wsec, "wpa")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_proto (s_wsec, "wep"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_protos (s_wsec)); + + /* Pairwise ciphers */ + ASSERT_CHANGED (nm_setting_wireless_security_add_pairwise (s_wsec, "tkip")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_pairwise (s_wsec)); + + /* Group ciphers */ + ASSERT_CHANGED (nm_setting_wireless_security_add_group (s_wsec, "ccmp")); + ASSERT_CHANGED (nm_setting_wireless_security_remove_group (s_wsec, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_wireless_security_remove_group (s_wsec, 1)); + g_test_assert_expected_messages (); + + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + ASSERT_CHANGED (nm_setting_wireless_security_clear_groups (s_wsec)); + + /* WEP key secret flags */ + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key0", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key1", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key2", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key3", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL))); + + g_object_unref (connection); +} + +static void +test_setting_802_1x_changed_signal (void) +{ + NMConnection *connection; + gboolean changed = FALSE; + NMSetting8021x *s_8021x; + + connection = nm_simple_connection_new (); + g_signal_connect (connection, + NM_CONNECTION_CHANGED, + (GCallback) test_connection_changed_cb, + &changed); + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + /* EAP methods */ + ASSERT_CHANGED (nm_setting_802_1x_add_eap_method (s_8021x, "tls")); + ASSERT_CHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + ASSERT_CHANGED (nm_setting_802_1x_clear_eap_methods (s_8021x)); + + /* alternate subject matches */ + ASSERT_CHANGED (nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED (nm_setting_802_1x_clear_altsubject_matches (s_8021x)); + + /* phase2 alternate subject matches */ + ASSERT_CHANGED (nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com")); + ASSERT_CHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 0)); + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); + ASSERT_UNCHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 1)); + g_test_assert_expected_messages (); + + nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com"); + ASSERT_CHANGED (nm_setting_802_1x_clear_phase2_altsubject_matches (s_8021x)); + + g_object_unref (connection); +} + +static void +test_setting_old_uuid (void) +{ + NMSetting *setting; + + /* NetworkManager-0.9.4.0 generated 40-character UUIDs with no dashes, + * like this one. Test that we maintain compatibility. */ + const char *uuid = "f43bec2cdd60e5da381ebb1eb1fa39f3cc52660c"; + + setting = nm_setting_connection_new (); + g_object_set (G_OBJECT (setting), + NM_SETTING_CONNECTION_ID, "uuidtest", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + + nmtst_assert_setting_verifies (NM_SETTING (setting)); +} + +/******************************************************************************/ + +static void +test_connection_normalize_uuid (void) +{ + gs_unref_object NMConnection *con = NULL; + + con = nmtst_create_minimal_connection ("test1", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nmtst_assert_connection_verifies_and_normalizable (con); + + g_object_set (nm_connection_get_setting_connection (con), + NM_SETTING_CONNECTION_UUID, NULL, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); +} + +/******************************************************************************/ + +/* + * Test normalization of interface-name + */ +static void +test_connection_normalize_virtual_iface_name (void) +{ + NMConnection *con = NULL; + NMSettingConnection *s_con; + NMSettingVlan *s_vlan; + GVariant *connection_dict, *setting_dict, *var; + GError *error = NULL; + const char *IFACE_NAME = "iface"; + const char *IFACE_VIRT = "iface-X"; + + con = nmtst_create_minimal_connection ("test1", + "22001632-bbb4-4616-b277-363dce3dfb5b", + NM_SETTING_VLAN_SETTING_NAME, + &s_con); + + nm_connection_add_setting (con, + g_object_new (NM_TYPE_SETTING_IP4_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + nm_connection_add_setting (con, + g_object_new (NM_TYPE_SETTING_IP6_CONFIG, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL)); + + s_vlan = nm_connection_get_setting_vlan (con); + + g_object_set (G_OBJECT (s_vlan), + NM_SETTING_VLAN_PARENT, "eth0", + NULL); + + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, NULL); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + + connection_dict = nm_connection_to_dbus (con, NM_CONNECTION_SERIALIZE_ALL); + g_object_unref (con); + + /* Serialized form should include vlan.interface-name as well. */ + setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (setting_dict != NULL); + var = g_variant_lookup_value (setting_dict, "interface-name", NULL); + g_assert (var != NULL); + g_assert (g_variant_is_of_type (var, G_VARIANT_TYPE_STRING)); + g_assert_cmpstr (g_variant_get_string (var, NULL), ==, IFACE_NAME); + + g_variant_unref (setting_dict); + g_variant_unref (var); + + /* If vlan.interface-name is invalid, deserialization will fail. */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + ":::this-is-not-a-valid-interface-name:::"); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_clear_error (&error); + + /* If vlan.interface-name is valid, but doesn't match, it will be ignored. */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME, + "interface-name", + "s", + IFACE_VIRT); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + s_con = nm_connection_get_setting_connection (con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, IFACE_NAME); + g_object_unref (con); + + /* But removing connection.interface-name should result in vlan.connection-name + * being "promoted". + */ + NMTST_VARIANT_EDITOR (connection_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME); + ); + + con = nm_simple_connection_new_from_dbus (connection_dict, &error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_VIRT); + s_con = nm_connection_get_setting_connection (con); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, IFACE_VIRT); + g_object_unref (con); + + g_variant_unref (connection_dict); +} + +static void +_test_connection_normalize_type_normalizable_setting (const char *type, + void (*prepare_normalizable_fcn) (NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting *s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + if (prepare_normalizable_fcn) + prepare_normalizable_fcn (con); + + g_assert (!nm_connection_get_setting_by_name (con, type)); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); + + s_base = nm_connection_get_setting_by_name (con, type); + g_assert (s_base); + g_assert (G_OBJECT_TYPE (s_base) == base_type); +} + +static void +_test_connection_normalize_type_unnormalizable_setting (const char *type) +{ + NMSettingConnection *s_con; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); +} + +static void +_test_connection_normalize_type_normalizable_type (const char *type, + NMSetting *(*add_setting_fcn) (NMConnection *con)) +{ + NMSettingConnection *s_con; + NMSetting *s_base; + GType base_type; + gs_unref_object NMConnection *con = NULL; + gs_free char *id = g_strdup_printf ("%s[%s]", G_STRFUNC, type); + + base_type = nm_setting_lookup_type (type); + g_assert (base_type != G_TYPE_INVALID); + g_assert (_nm_setting_type_is_base_type (base_type)); + + con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + if (add_setting_fcn) + s_base = add_setting_fcn (con); + else { + s_base = NM_SETTING (g_object_new (base_type, NULL)); + nm_connection_add_setting (con, s_base); + } + + g_assert (!nm_connection_get_connection_type (con)); + g_assert (nm_connection_get_setting_by_name (con, type) == s_base); + + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + + g_assert_cmpstr (nm_connection_get_connection_type (con), ==, type); + g_assert (nm_connection_get_setting_by_name (con, type) == s_base); +} + +static NMSetting * +_add_setting_fcn_adsl (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_ADSL, + NM_SETTING_ADSL_USERNAME, "test-user", + NM_SETTING_ADSL_PROTOCOL, NM_SETTING_ADSL_PROTOCOL_PPPOA, + NM_SETTING_ADSL_ENCAPSULATION, NM_SETTING_ADSL_ENCAPSULATION_VCMUX, + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bluetooth (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_BLUETOOTH, + NM_SETTING_BLUETOOTH_BDADDR, "11:22:33:44:55:66", + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_bond (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_BOND, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bond", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_bridge (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_BRIDGE, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-bridge", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_cdma (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_CDMA, + NM_SETTING_CDMA_NUMBER, "test-number", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_infiniband (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_INFINIBAND, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_olpc_mesh (NMConnection *con) +{ + NMSetting *setting; + const char *ssid_data = "ssid-test"; + GBytes *ssid; + + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + setting = g_object_new (NM_TYPE_SETTING_OLPC_MESH, + NM_SETTING_OLPC_MESH_SSID, ssid, + NM_SETTING_OLPC_MESH_CHANNEL, 1, + NULL); + g_bytes_unref (ssid); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_team (NMConnection *con) +{ + NMSetting *setting; + NMSettingConnection *s_con; + + setting = g_object_new (NM_TYPE_SETTING_TEAM, NULL); + + nm_connection_add_setting (con, setting); + + s_con = nm_connection_get_setting_connection (con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "test-team", + NULL); + + return setting; +} + +static NMSetting * +_add_setting_fcn_vlan (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_VLAN, + NM_SETTING_VLAN_PARENT, "test-parent", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_vpn (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_VPN, + NM_SETTING_VPN_SERVICE_TYPE, "test-vpn-service-type", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wimax (NMConnection *con) +{ + NMSetting *setting; + + setting = g_object_new (NM_TYPE_SETTING_WIMAX, + NM_SETTING_WIMAX_NETWORK_NAME, "test-network", + NULL); + + nm_connection_add_setting (con, setting); + return setting; +} + +static NMSetting * +_add_setting_fcn_wireless (NMConnection *con) +{ + NMSetting *setting; + const char *ssid_data = "ssid-test"; + GBytes *ssid; + + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); + setting = g_object_new (NM_TYPE_SETTING_WIRELESS, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + + nm_connection_add_setting (con, setting); + return setting; +} + +static void +_prepare_normalizable_fcn_vlan (NMConnection *con) +{ + nm_connection_add_setting (con, g_object_new (NM_TYPE_SETTING_WIRED, + NM_SETTING_WIRED_MAC_ADDRESS, "11:22:33:44:55:66", + NULL)); +} + +static void +test_connection_normalize_type (void) +{ + guint i; + struct { + const char *type; + gboolean normalizable; + NMSetting *(*add_setting_fcn) (NMConnection *con); + void (*prepare_normalizable_fcn) (NMConnection *con); + } types[] = { + { NM_SETTING_GENERIC_SETTING_NAME, TRUE }, + { NM_SETTING_GSM_SETTING_NAME, TRUE }, + { NM_SETTING_WIRED_SETTING_NAME, TRUE }, + { NM_SETTING_VLAN_SETTING_NAME, TRUE, _add_setting_fcn_vlan, _prepare_normalizable_fcn_vlan }, + + { NM_SETTING_ADSL_SETTING_NAME, FALSE, _add_setting_fcn_adsl }, + { NM_SETTING_BLUETOOTH_SETTING_NAME, FALSE, _add_setting_fcn_bluetooth }, + { NM_SETTING_BOND_SETTING_NAME, FALSE, _add_setting_fcn_bond }, + { NM_SETTING_BRIDGE_SETTING_NAME, FALSE, _add_setting_fcn_bridge }, + { NM_SETTING_CDMA_SETTING_NAME, FALSE, _add_setting_fcn_cdma }, + { NM_SETTING_INFINIBAND_SETTING_NAME, FALSE, _add_setting_fcn_infiniband }, + { NM_SETTING_OLPC_MESH_SETTING_NAME, FALSE, _add_setting_fcn_olpc_mesh }, + { NM_SETTING_TEAM_SETTING_NAME, FALSE, _add_setting_fcn_team }, + { NM_SETTING_VLAN_SETTING_NAME, FALSE, _add_setting_fcn_vlan }, + { NM_SETTING_VPN_SETTING_NAME, FALSE, _add_setting_fcn_vpn }, + { NM_SETTING_WIMAX_SETTING_NAME, FALSE, _add_setting_fcn_wimax }, + { NM_SETTING_WIRELESS_SETTING_NAME, FALSE, _add_setting_fcn_wireless }, + { 0 }, + }; + + for (i = 0; types[i].type; i++) { + const char *type = types[i].type; + + if (types[i].normalizable) + _test_connection_normalize_type_normalizable_setting (type, types[i].prepare_normalizable_fcn); + else + _test_connection_normalize_type_unnormalizable_setting (type); + _test_connection_normalize_type_normalizable_type (type, types[i].add_setting_fcn); + } +} + +static void +test_connection_normalize_slave_type_1 (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection *s_con; + + con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_1", + "cc4cd5df-45dc-483e-b291-6b76c2338ecb", + NM_SETTING_WIRED_SETTING_NAME, &s_con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set (s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", + NULL); + + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING); + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_slave_type_2 (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingConnection *s_con; + + con = nmtst_create_minimal_connection ("test_connection_normalize_slave_type_2", + "40bea008-ca72-439a-946b-e65f827656f9", + NM_SETTING_WIRED_SETTING_NAME, &s_con); + + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, "master0", + NM_SETTING_CONNECTION_SLAVE_TYPE, "invalid-type", + NULL); + + nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (!nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + + g_object_set (s_con, + NM_SETTING_CONNECTION_SLAVE_TYPE, NULL, + NULL); + nm_connection_add_setting (con, nm_setting_bridge_port_new ()); + + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); + g_assert (nm_connection_get_setting_by_name (con, NM_SETTING_BRIDGE_PORT_SETTING_NAME)); + g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_BRIDGE_SETTING_NAME); +} + +static void +test_connection_normalize_infiniband_mtu (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingInfiniband *s_infini; + + con = nmtst_create_minimal_connection ("test_connection_normalize_infiniband_mtu", NULL, + NM_SETTING_INFINIBAND_SETTING_NAME, NULL); + + s_infini = nm_connection_get_setting_infiniband (con); + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NULL); + nmtst_assert_connection_verifies_and_normalizable (con); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NM_SETTING_INFINIBAND_MTU, (guint) 2044, + NULL); + nmtst_assert_connection_verifies_without_normalization (con); + g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", + NM_SETTING_INFINIBAND_MTU, (guint) 2045, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert_cmpint (2044, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NM_SETTING_INFINIBAND_MTU, (guint) 65520, + NULL); + nmtst_assert_connection_verifies_without_normalization (con); + g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); + + g_object_set (s_infini, + NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", + NM_SETTING_INFINIBAND_MTU, (guint) 65521, + NULL); + nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini)); +} + +static void +test_setting_ip4_gateway (void) +{ + NMConnection *conn; + NMSettingIPConfig *s_ip4; + NMIPAddress *addr; + GVariant *conn_dict, *ip4_dict, *value; + GVariantIter iter; + GVariant *addr_var; + guint32 addr_vals_0[] = { htonl (0xc0a8010a), 0x00000018, htonl (0x00000000) }; + guint32 addr_vals_1[] = { htonl (0xc0a8010b), 0x00000018, htonl (0xc0a80101) }; + GVariantBuilder addrs_builder; + GError *error = NULL; + + g_assert_cmpstr (nm_utils_inet4_ntop (addr_vals_0[0], NULL), ==, "192.168.1.10"); + + /* When serializing on the daemon side, ipv4.gateway is copied to the first + * entry of ipv4.addresses + */ + conn = nmtst_create_minimal_connection ("test_setting_ip4_gateway", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "192.168.1.1", + NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip4)); + + addr = nm_ip_address_new (AF_INET, "192.168.1.10", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + ip4_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (ip4_dict != NULL); + + value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "192.168.1.1"); + g_variant_unref (value); + + value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("aau")); + g_assert (value != NULL); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "@au", &addr_var)) { + const guint32 *addr_array; + gsize length; + + addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32)); + g_assert_cmpint (length, ==, 3); + g_assert_cmpstr (nm_utils_inet4_ntop (addr_array[2], NULL), ==, "192.168.1.1"); + g_variant_unref (addr_var); + } + g_variant_unref (value); + + g_variant_unref (ip4_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv4.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + + g_object_unref (conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("aau")); + g_variant_builder_add (&addrs_builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + addr_vals_0, 3, 4)); + g_variant_builder_add (&addrs_builder, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + addr_vals_1, 3, 4)); + + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "addresses", "aau", &addrs_builder); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + g_variant_unref (conn_dict); + + s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); + + g_object_unref (conn); +} + +static void +test_setting_ip6_gateway (void) +{ + NMConnection *conn; + NMSettingIPConfig *s_ip6; + NMIPAddress *addr; + GVariant *conn_dict, *ip6_dict, *value; + GVariantIter iter; + GVariant *gateway_var; + GVariantBuilder addrs_builder; + guint8 addr_bytes_0[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a }; + guint8 addr_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b }; + guint8 gateway_bytes_1[] = { 0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; + GError *error = NULL; + + /* When serializing on the daemon side, ipv6.gateway is copied to the first + * entry of ipv6.addresses + */ + conn = nmtst_create_minimal_connection ("test_setting_ip6_gateway", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "abcd::1", + NULL); + nm_connection_add_setting (conn, NM_SETTING (s_ip6)); + + addr = nm_ip_address_new (AF_INET6, "abcd::10", 64, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr); + nm_ip_address_unref (addr); + + _nm_utils_is_manager_process = TRUE; + conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); + _nm_utils_is_manager_process = FALSE; + g_object_unref (conn); + + ip6_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + g_assert (ip6_dict != NULL); + + value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING); + g_assert (value != NULL); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "abcd::1"); + + value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("a(ayuay)")); + g_assert (value != NULL); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "(@ayu@ay)", NULL, NULL, &gateway_var)) { + const guint8 *gateway_bytes; + gsize length; + + gateway_bytes = g_variant_get_fixed_array (gateway_var, &length, 1); + g_assert_cmpint (length, ==, 16); + g_assert_cmpstr (nm_utils_inet6_ntop ((struct in6_addr *) gateway_bytes, NULL), ==, "abcd::1"); + g_variant_unref (gateway_var); + } + g_variant_unref (value); + + g_variant_unref (ip6_dict); + + /* When deserializing an old-style connection, the first non-0 gateway in + * ipv6.addresses is copied to :gateway. + */ + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + "address-data"); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1"); + + g_object_unref (conn); + + /* Try again with the gateway in the second address. */ + g_variant_builder_init (&addrs_builder, G_VARIANT_TYPE ("a(ayuay)")); + g_variant_builder_add (&addrs_builder, "(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + addr_bytes_0, 16, 1), + 64, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &in6addr_any, 16, 1)); + g_variant_builder_add (&addrs_builder, "(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + addr_bytes_1, 16, 1), + 64, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + gateway_bytes_1, 16, 1)); + + NMTST_VARIANT_EDITOR (conn_dict, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + "addresses", "a(ayuay)", &addrs_builder); + ); + + conn = nm_simple_connection_new_from_dbus (conn_dict, &error); + g_assert_no_error (error); + g_variant_unref (conn_dict); + + s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1"); + + g_object_unref (conn); +} + +typedef struct { + const char *str; + const guint8 expected[20]; + const guint expected_len; +} HexItem; + +static void +test_hexstr2bin (void) +{ + static const HexItem items[] = { + { "aaBBCCddDD10496a", { 0xaa, 0xbb, 0xcc, 0xdd, 0xdd, 0x10, 0x49, 0x6a }, 8 }, + { "aa:bb:cc:dd:10:49:6a", { 0xaa, 0xbb, 0xcc, 0xdd, 0x10, 0x49, 0x6a }, 7 }, + { "0xccddeeff", { 0xcc, 0xdd, 0xee, 0xff }, 4 }, + { "1:2:66:77:80", { 0x01, 0x02, 0x66, 0x77, 0x80 }, 5 }, + { "e", { 0x0e }, 1 }, + { "aabb1199:" }, + { ":aabb1199" }, + { "aabb$$dd" }, + { "aab:ccc:ddd" }, + { "aab::ccc:ddd" }, + }; + GBytes *b; + guint i; + + for (i = 0; i < G_N_ELEMENTS (items); i++) { + b = nm_utils_hexstr2bin (items[i].str); + if (items[i].expected_len) { + g_assert (b); + g_assert_cmpint (g_bytes_get_size (b), ==, items[i].expected_len); + g_assert (memcmp (g_bytes_get_data (b, NULL), items[i].expected, g_bytes_get_size (b)) == 0); + } else + g_assert (b == NULL); + } +} + +/******************************************************************************/ + +#define UUID_NIL "00000000-0000-0000-0000-000000000000" +#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + +static void +_test_uuid (int uuid_type, const char *expected_uuid, const char *str, gssize slen, gpointer type_args) +{ + gs_free char *uuid_test = NULL; + + uuid_test = nm_utils_uuid_generate_from_string (str, slen, uuid_type, type_args); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed: type=%d; text=%s, len=%lld, uuid=%s, expected=%s", uuid_type, + str, (long long) slen, uuid_test, expected_uuid); + } + + if (slen < 0) { + /* also test that passing slen==-1 yields the same result as passing strlen(str). */ + _test_uuid (uuid_type, expected_uuid, str, strlen (str), type_args); + } else if (str && slen == 0) { + /* also test if we accept NULL for slen==0 */ + _test_uuid (uuid_type, expected_uuid, NULL, 0, type_args); + } + + if (uuid_type == NM_UTILS_UUID_TYPE_VARIANT3 && !type_args) { + /* For NM_UTILS_UUID_TYPE_VARIANT3, a missing @type_args is equal to UUID_NIL */ + _test_uuid (uuid_type, expected_uuid, str, slen, UUID_NIL); + } +} + +static void +test_nm_utils_uuid_generate_from_string (void) +{ + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "d41d8cd9-8f00-b204-e980-0998ecf8427e", "", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "0cc175b9-c0f1-b6a8-31c3-99e269772661", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "098f6bcd-4621-d373-cade-4e832627b4f6", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "70350f60-27bc-e371-3f6b-76473084309b", "a\0b", 3, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_LEGACY, "59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1", -1, NULL); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4ae71336-e44b-39bf-b9d2-752e234818a5", "", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "0531103a-d8fc-3dd4-b972-d98e4750994e", "a", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "96e17d7a-ac89-38cf-95e1-bf5098da34e1", "test", -1, NULL); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "8156568e-4ae6-3f34-a93e-18e2c6cbbf78", "a\0b", 3, NULL); + + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "c87ee674-4ddc-3efe-a74e-dfe25da5d7b3", "", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "4c104dd0-4821-30d5-9ce3-0e7a1f8b7c0d", "a", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "45a113ac-c7f2-30b0-90a5-a399ab912716", "test", -1, UUID_NS_DNS); + _test_uuid (NM_UTILS_UUID_TYPE_VARIANT3, "002a0ada-f547-375a-bab5-896a11d1927e", "a\0b", 3, UUID_NS_DNS); +} + +/******************************************************************************/ + +NMTST_DEFINE (); + +int main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + /* The tests */ + g_test_add_func ("/core/general/test_setting_vpn_items", test_setting_vpn_items); + g_test_add_func ("/core/general/test_setting_vpn_update_secrets", test_setting_vpn_update_secrets); + g_test_add_func ("/core/general/test_setting_vpn_modify_during_foreach", test_setting_vpn_modify_during_foreach); + g_test_add_func ("/core/general/test_setting_ip4_config_labels", test_setting_ip4_config_labels); + g_test_add_func ("/core/general/test_setting_ip4_config_address_data", test_setting_ip4_config_address_data); + g_test_add_func ("/core/general/test_setting_gsm_apn_spaces", test_setting_gsm_apn_spaces); + g_test_add_func ("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars); + g_test_add_func ("/core/general/test_setting_gsm_apn_underscore", test_setting_gsm_apn_underscore); + g_test_add_func ("/core/general/test_setting_gsm_without_number", test_setting_gsm_without_number); + g_test_add_func ("/core/general/test_setting_to_dbus_all", test_setting_to_dbus_all); + g_test_add_func ("/core/general/test_setting_to_dbus_no_secrets", test_setting_to_dbus_no_secrets); + g_test_add_func ("/core/general/test_setting_to_dbus_only_secrets", test_setting_to_dbus_only_secrets); + g_test_add_func ("/core/general/test_setting_to_dbus_transform", test_setting_to_dbus_transform); + g_test_add_func ("/core/general/test_setting_to_dbus_enum", test_setting_to_dbus_enum); + g_test_add_func ("/core/general/test_setting_compare_id", test_setting_compare_id); + g_test_add_func ("/core/general/test_setting_compare_timestamp", test_setting_compare_timestamp); +#define ADD_FUNC(func, secret_flags, comp_flags, remove_secret) \ + g_test_add_data_func_full ("/core/general/" G_STRINGIFY (func), \ + test_data_compare_secrets_new (secret_flags, comp_flags, remove_secret), \ + func, g_free) + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE); + ADD_FUNC (test_setting_compare_vpn_secrets, NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE); + g_test_add_func ("/core/general/test_setting_old_uuid", test_setting_old_uuid); + + g_test_add_func ("/core/general/test_connection_to_dbus_setting_name", test_connection_to_dbus_setting_name); + g_test_add_func ("/core/general/test_connection_to_dbus_deprecated_props", test_connection_to_dbus_deprecated_props); + g_test_add_func ("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus); + g_test_add_func ("/core/general/test_setting_new_from_dbus_transform", test_setting_new_from_dbus_transform); + g_test_add_func ("/core/general/test_setting_new_from_dbus_enum", test_setting_new_from_dbus_enum); + g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings); + g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection); + g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad); + g_test_add_func ("/core/general/test_connection_new_from_dbus", test_connection_new_from_dbus); + g_test_add_func ("/core/general/test_connection_normalize_virtual_iface_name", test_connection_normalize_virtual_iface_name); + g_test_add_func ("/core/general/test_connection_normalize_uuid", test_connection_normalize_uuid); + g_test_add_func ("/core/general/test_connection_normalize_type", test_connection_normalize_type); + g_test_add_func ("/core/general/test_connection_normalize_slave_type_1", test_connection_normalize_slave_type_1); + g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2); + g_test_add_func ("/core/general/test_connection_normalize_infiniband_mtu", test_connection_normalize_infiniband_mtu); + + g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers); + g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property); + + g_test_add_func ("/core/general/test_connection_compare_same", test_connection_compare_same); + g_test_add_func ("/core/general/test_connection_compare_key_only_in_a", test_connection_compare_key_only_in_a); + g_test_add_func ("/core/general/test_connection_compare_setting_only_in_a", test_connection_compare_setting_only_in_a); + g_test_add_func ("/core/general/test_connection_compare_key_only_in_b", test_connection_compare_key_only_in_b); + g_test_add_func ("/core/general/test_connection_compare_setting_only_in_b", test_connection_compare_setting_only_in_b); + + g_test_add_func ("/core/general/test_connection_diff_a_only", test_connection_diff_a_only); + g_test_add_func ("/core/general/test_connection_diff_same", test_connection_diff_same); + g_test_add_func ("/core/general/test_connection_diff_different", test_connection_diff_different); + g_test_add_func ("/core/general/test_connection_diff_no_secrets", test_connection_diff_no_secrets); + g_test_add_func ("/core/general/test_connection_diff_inferrable", test_connection_diff_inferrable); + g_test_add_func ("/core/general/test_connection_good_base_types", test_connection_good_base_types); + g_test_add_func ("/core/general/test_connection_bad_base_types", test_connection_bad_base_types); + + g_test_add_func ("/core/general/test_hwaddr_aton_ether_normal", test_hwaddr_aton_ether_normal); + g_test_add_func ("/core/general/test_hwaddr_aton_ib_normal", test_hwaddr_aton_ib_normal); + g_test_add_func ("/core/general/test_hwaddr_aton_no_leading_zeros", test_hwaddr_aton_no_leading_zeros); + g_test_add_func ("/core/general/test_hwaddr_aton_malformed", test_hwaddr_aton_malformed); + g_test_add_func ("/core/general/test_hwaddr_equal", test_hwaddr_equal); + g_test_add_func ("/core/general/test_hwaddr_canonical", test_hwaddr_canonical); + + g_test_add_func ("/core/general/test_ip4_prefix_to_netmask", test_ip4_prefix_to_netmask); + g_test_add_func ("/core/general/test_ip4_netmask_to_prefix", test_ip4_netmask_to_prefix); + + g_test_add_func ("/core/general/test_connection_changed_signal", test_connection_changed_signal); + g_test_add_func ("/core/general/test_setting_connection_changed_signal", test_setting_connection_changed_signal); + g_test_add_func ("/core/general/test_setting_bond_changed_signal", test_setting_bond_changed_signal); + g_test_add_func ("/core/general/test_setting_ip4_changed_signal", test_setting_ip4_changed_signal); + g_test_add_func ("/core/general/test_setting_ip6_changed_signal", test_setting_ip6_changed_signal); + g_test_add_func ("/core/general/test_setting_vlan_changed_signal", test_setting_vlan_changed_signal); + g_test_add_func ("/core/general/test_setting_vpn_changed_signal", test_setting_vpn_changed_signal); + g_test_add_func ("/core/general/test_setting_wired_changed_signal", test_setting_wired_changed_signal); + g_test_add_func ("/core/general/test_setting_wireless_changed_signal", test_setting_wireless_changed_signal); + g_test_add_func ("/core/general/test_setting_wireless_security_changed_signal", test_setting_wireless_security_changed_signal); + g_test_add_func ("/core/general/test_setting_802_1x_changed_signal", test_setting_802_1x_changed_signal); + g_test_add_func ("/core/general/test_setting_ip4_gateway", test_setting_ip4_gateway); + g_test_add_func ("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway); + + g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin); + g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-secrets.c b/libnm-core/tests/test-secrets.c new file mode 100644 index 00000000..1254dfff --- /dev/null +++ b/libnm-core/tests/test-secrets.c @@ -0,0 +1,766 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include "nm-setting-8021x.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-ppp.h" +#include "nm-setting-pppoe.h" +#include "nm-setting-vpn.h" +#include "nm-setting-wired.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-wireless.h" +#include "nm-simple-connection.h" +#include "nm-utils.h" + +#include "nm-test-utils.h" + +#define TEST_NEED_SECRETS_EAP_TLS_CA_CERT TEST_CERT_DIR "/test_ca_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT TEST_CERT_DIR "/test_key_and_cert.pem" +#define TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY TEST_CERT_DIR "/test_key_and_cert.pem" + +static gboolean +find_hints_item (GPtrArray *hints, const char *item) +{ + int i; + + for (i = 0; i < hints->len; i++) { + if (!strcmp (item, (const char *) g_ptr_array_index (hints, i))) + return TRUE; + } + return FALSE; +} + +static NMConnection * +make_tls_connection (const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *uuid; + gboolean success; + GError *error = NULL; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets", + 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 (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + 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_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set CA certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message); + + success = nm_setting_802_1x_set_client_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set client certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message); + + success = nm_setting_802_1x_set_private_key (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set private key '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + return connection; +} + +static void +test_need_tls_secrets_path (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); + ASSERT (connection != NULL, + "need-tls-secrets-path-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-secrets-path-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-secrets-path-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-secrets-path-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-secrets-path-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-secrets-path-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), + "need-tls-secrets-path-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static void +test_need_tls_secrets_blob (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); + ASSERT (connection != NULL, + "need-tls-secrets-blob-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-secrets-blob-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-secrets-blob-key", + "hints should be NULL since no secrets were required"); + + /* Clear secrets and ensure password is again required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-secrets-blob-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-secrets-blob-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-secrets-blob-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), + "need-tls-secrets-blob-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static NMConnection * +make_tls_phase2_connection (const char *detail, NMSetting8021xCKScheme scheme) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + char *uuid; + gboolean success; + GError *error = NULL; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets", + 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 (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "blahblah", NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); + + success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 CA certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message); + + success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 client certificate '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, + "test", + scheme, + NULL, + &error); + ASSERT (success == TRUE, + detail, "failed to set phase2 private key '%s': %s", + TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + + ASSERT (nm_connection_verify (connection, &error) == TRUE, + detail, "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + return connection; +} + +static void +test_need_tls_phase2_secrets_path (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key", + NM_SETTING_802_1X_CK_SCHEME_PATH); + ASSERT (connection != NULL, + "need-tls-phase2-secrets-path-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-phase2-secrets-path-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-phase2-secrets-path-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-phase2-secrets-path-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-phase2-secrets-path-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-phase2-secrets-path-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), + "need-tls-phase2-secrets-path-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static void +test_need_tls_phase2_secrets_blob (void) +{ + NMConnection *connection; + const char *setting_name; + GPtrArray *hints = NULL; + + connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key", + NM_SETTING_802_1X_CK_SCHEME_BLOB); + ASSERT (connection != NULL, + "need-tls-phase2-secrets-blob-key", + "error creating test connection"); + + /* Ensure we don't need any secrets since we just set up the connection */ + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name == NULL, + "need-tls-phase2-secrets-blob-key", + "secrets are unexpectedly required"); + ASSERT (hints == NULL, + "need-tls-phase2-secrets-blob-key", + "hints should be NULL since no secrets were required"); + + /* Connection is good; clear secrets and ensure private key password is then required */ + nm_connection_clear_secrets (connection); + + hints = NULL; + setting_name = nm_connection_need_secrets (connection, &hints); + ASSERT (setting_name != NULL, + "need-tls-phase2-secrets-blob-key-password", + "unexpected secrets success"); + ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, + "need-tls-phase2-secrets-blob-key-password", + "unexpected setting secrets required"); + + ASSERT (hints != NULL, + "need-tls-phase2-secrets-blob-key-password", + "expected returned secrets hints"); + ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), + "need-tls-phase2-secrets-blob-key-password", + "expected to require private key password, but it wasn't"); + + g_object_unref (connection); +} + +static NMConnection * +wifi_connection_new (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; + char *uuid; + GBytes *ssid; + + connection = nm_simple_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Wireless", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + /* Wireless setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + /* Wifi security */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NULL); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + return connection; +} + +static GVariant * +build_wep_secrets (const char *wepkey) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + g_variant_new_string (wepkey)); + g_variant_builder_add (&builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, + g_variant_new_uint32 (NM_WEP_KEY_TYPE_KEY)); + + return g_variant_builder_end (&builder); +} + +static void +test_update_secrets_wifi_single_setting (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; + + /* Test update with a hashed setting of 802-11-wireless secrets */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (secrets); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + g_assert_cmpstr (tmp, ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_wifi_full_hash (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariantBuilder builder; + GVariant *all; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + const char *tmp; + + /* Test update with a hashed connection containing only 802-11-wireless + * setting and secrets. + */ + + connection = wifi_connection_new (); + + g_variant_builder_init (&builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&builder, "{s@a{sv}}", + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + build_wep_secrets (wepkey)); + all = g_variant_builder_end (&builder); + + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + all, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (all); + + /* Make sure the secret is now in the connection */ + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + g_assert_cmpstr (tmp, ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_wifi_bad_setting_name (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test that passing an invalid setting name to + * nm_connection_update_secrets() fails with the correct error. + */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + + success = nm_connection_update_secrets (connection, + "asdfasdfasdfasf", + secrets, + &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert (success == FALSE); + + g_variant_unref (secrets); + + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test calling nm_connection_update_secrets() with an entire hashed + * connection including non-secrets. + */ + + connection = wifi_connection_new (); + + /* Build up the secrets dictionary */ + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + NMTST_VARIANT_EDITOR (secrets, + NMTST_VARIANT_ADD_PROPERTY (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, + "s", + wepkey); + ); + + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_assert_no_error (error); + g_assert (success == TRUE); + + g_variant_unref (secrets); + + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey); + + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_empty_hash (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + + /* Test that updating secrets with an empty connection hash returns success */ + + connection = wifi_connection_new (); + secrets = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_assert_no_error (error); + g_assert (success == TRUE); + g_variant_unref (secrets); + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_bad_setting (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets, *copy, *setting_hash; + const char *setting_name; + GVariantBuilder conn_builder; + GVariantIter conn_iter; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Test that sending a hashed connection containing an invalid setting + * name fails with the right error. + */ + + connection = wifi_connection_new (); + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec != NULL); + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, wepkey, + NULL); + + /* Build up the secrets hash */ + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + + /* Copy the dict, renaming the wireless-security setting in the process + * (so we ensure libnm is returning the right error when it finds an entry + * in the connection hash that doesn't match any setting in the connection). + */ + g_variant_builder_init (&conn_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_iter_init (&conn_iter, secrets); + while (g_variant_iter_next (&conn_iter, "{&s@a{sv}}", &setting_name, &setting_hash)) { + if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0) + setting_name = "asdfasdfasdfasdf"; + + g_variant_builder_add (&conn_builder, "{s@a{sv}}", setting_name, setting_hash); + g_variant_unref (setting_hash); + } + copy = g_variant_builder_end (&conn_builder); + g_variant_unref (secrets); + + success = nm_connection_update_secrets (connection, NULL, copy, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND); + g_assert (success == FALSE); + + g_variant_unref (copy); + g_object_unref (connection); +} + +static void +test_update_secrets_whole_connection_empty_base_setting (void) +{ + NMConnection *connection; + GVariant *secrets, *setting; + GError *error = NULL; + gboolean success; + + /* Test that a hashed connection which does not have any hashed secrets + * for the requested setting returns success. + */ + + connection = wifi_connection_new (); + secrets = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + g_assert_cmpint (g_variant_n_children (secrets), ==, 3); + + setting = g_variant_lookup_value (secrets, NM_SETTING_WIRELESS_SETTING_NAME, NULL); + g_assert (setting != NULL); + g_variant_unref (setting); + + success = nm_connection_update_secrets (connection, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + secrets, + &error); + g_assert_no_error (error); + g_assert (success); + + g_variant_unref (secrets); + g_object_unref (connection); +} + +static void +test_update_secrets_null_setting_name_with_setting_hash (void) +{ + NMConnection *connection; + GVariant *secrets; + GError *error = NULL; + gboolean success; + const char *wepkey = "11111111111111111111111111"; + + /* Ensure that a NULL setting name and only a hashed setting fails */ + + connection = wifi_connection_new (); + + secrets = build_wep_secrets (wepkey); + + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, + "*nm_connection_update_secrets*setting_name != NULL || full_connection*"); + success = nm_connection_update_secrets (connection, NULL, secrets, &error); + g_test_assert_expected_messages (); + g_assert_no_error (error); + g_assert (!success); + + g_variant_unref (secrets); + g_object_unref (connection); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + char *base; + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + nmtst_init (&argc, &argv, TRUE); + + /* The tests */ + test_need_tls_secrets_path (); + test_need_tls_secrets_blob (); + test_need_tls_phase2_secrets_path (); + test_need_tls_phase2_secrets_blob (); + + test_update_secrets_wifi_single_setting (); + test_update_secrets_wifi_full_hash (); + test_update_secrets_wifi_bad_setting_name (); + + test_update_secrets_whole_connection (); + test_update_secrets_whole_connection_empty_hash (); + test_update_secrets_whole_connection_bad_setting (); + test_update_secrets_whole_connection_empty_base_setting (); + test_update_secrets_null_setting_name_with_setting_hash (); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/libnm-core/tests/test-setting-8021x.c b/libnm-core/tests/test-setting-8021x.c new file mode 100644 index 00000000..637ab81c --- /dev/null +++ b/libnm-core/tests/test-setting-8021x.c @@ -0,0 +1,458 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include + +#include "nm-setting-connection.h" +#include "nm-setting-8021x.h" + +#include "nm-test-utils.h" + +static void +compare_blob_data (const char *test, + const char *key_path, + GBytes *key) +{ + char *contents = NULL; + gsize len = 0; + GError *error = NULL; + gboolean success; + + success = g_file_get_contents (key_path, &contents, &len, &error); + ASSERT (success == TRUE, + test, "failed to read blob key file: %s", error->message); + + ASSERT (len > 0, test, "blob key file invalid (size 0)"); + + ASSERT (len == g_bytes_get_size (key), + test, "blob key file (%d) and setting key data (%d) lengths don't match", + len, g_bytes_get_size (key)); + + ASSERT (memcmp (contents, g_bytes_get_data (key, NULL), len) == 0, + test, "blob key file and blob key data don't match"); + + g_free (contents); +} + +#define SCHEME_PATH "file://" + +static void +check_scheme_path (GBytes *value, const char *path) +{ + const guint8 *p = g_bytes_get_data (value, NULL); + + g_assert (memcmp (p, SCHEME_PATH, strlen (SCHEME_PATH)) == 0); + p += strlen (SCHEME_PATH); + g_assert (memcmp (p, path, strlen (path)) == 0); + p += strlen (path); + g_assert (*p == '\0'); +} + +static void +test_private_key_import (const char *path, + const char *password, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError *error = NULL; + GBytes *tmp_key = NULL, *client_cert = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "private-key-import", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "private-key-import", "unexpected private key format (got %d)", format); + tmp_fmt = nm_setting_802_1x_get_private_key_format (s_8021x); + ASSERT (tmp_fmt == format, + "private-key-import", "unexpected re-read private key format (expected %d, got %d)", + format, tmp_fmt); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "private-key-import", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "private-key-import", "failed to compare private key password"); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_private_key_blob (s_8021x); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key blob"); + compare_blob_data ("private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + check_scheme_path (tmp_key, path); + g_bytes_unref (tmp_key); + } else + g_assert_not_reached (); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + + g_object_get (s_8021x, NM_SETTING_802_1X_CLIENT_CERT, &client_cert, NULL); + ASSERT (client_cert != NULL, "private-key-import", "missing client certificate value"); + + /* make sure they are the same */ + ASSERT (g_bytes_equal (tmp_key, client_cert), + "private-key-import", "unexpected different private key and client cert data"); + + g_bytes_unref (tmp_key); + g_bytes_unref (client_cert); + } + + g_object_unref (s_8021x); +} + +static void +test_phase2_private_key_import (const char *path, + const char *password, + NMSetting8021xCKScheme scheme) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat tmp_fmt; + GError *error = NULL; + GBytes *tmp_key = NULL, *client_cert = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "phase2-private-key-import", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + scheme, + &format, + &error); + ASSERT (success == TRUE, + "phase2-private-key-import", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "phase2-private-key-import", "unexpected private key format"); + tmp_fmt = nm_setting_802_1x_get_phase2_private_key_format (s_8021x); + ASSERT (tmp_fmt == format, + "phase2-private-key-import", "unexpected re-read private key format (expected %d, got %d)", + format, tmp_fmt); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "phase2-private-key-import", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "phase2-private-key-import", "failed to compare private key password"); + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { + tmp_key = nm_setting_802_1x_get_phase2_private_key_blob (s_8021x); + ASSERT (tmp_key != NULL, "phase2-private-key-import", "missing private key blob"); + compare_blob_data ("phase2-private-key-import", path, tmp_key); + } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "phase2-private-key-import", "missing private key value"); + check_scheme_path (tmp_key, path); + } else + g_assert_not_reached (); + + /* If it's PKCS#12 ensure the client cert is the same value */ + if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &tmp_key, NULL); + ASSERT (tmp_key != NULL, "private-key-import", "missing private key value"); + + g_object_get (s_8021x, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, &client_cert, NULL); + ASSERT (client_cert != NULL, "private-key-import", "missing client certificate value"); + + /* make sure they are the same */ + ASSERT (g_bytes_equal (tmp_key, client_cert), + "private-key-import", "unexpected different private key and client cert data"); + + g_bytes_unref (tmp_key); + g_bytes_unref (client_cert); + } + + g_object_unref (s_8021x); +} + +static void +test_wrong_password_keeps_data (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "wrong-password-keeps-data", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "wrong-password-keeps-data", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-password-keeps-data", "unexpected private key format (got %d)", format); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_private_key (s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == FALSE, + "wrong-password-keeps-data", "unexpected success reading private key"); + ASSERT (error != NULL, + "wrong-password-keeps-data", "unexpected missing error"); + ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-password-keeps-data", "unexpected success reading private key format"); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "wrong-password-keeps-data", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "wrong-password-keeps-data", "failed to compare private key password"); + + g_object_unref (s_8021x); +} + +static void +test_clear_private_key (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "clear-private-key", "setting was NULL"); + + success = nm_setting_802_1x_set_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "clear-private-key", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "clear-private-key", "unexpected private key format (got %d)", format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_private_key_password (s_8021x); + ASSERT (pw != NULL, + "clear-private-key", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "clear-private-key", "failed to compare private key password"); + + /* Now clear it */ + success = nm_setting_802_1x_set_private_key (s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + ASSERT (success == TRUE, + "clear-private-key", "unexpected failure clearing private key"); + ASSERT (error == NULL, + "clear-private-key", "unexpected error clearing private key"); + + /* Ensure the password is also now clear */ + ASSERT (nm_setting_802_1x_get_private_key_password (s_8021x) == NULL, + "clear-private-key", "unexpected private key password"); + + g_object_unref (s_8021x); +} + +static void +test_wrong_phase2_password_keeps_data (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "wrong-phase2-password-keeps-data", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "wrong-phase2-password-keeps-data", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-phase2-password-keeps-data", "unexpected private key format (got %d)", format); + + /* Now try to set it to something that's not a certificate */ + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + "Makefile.am", + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == FALSE, + "wrong-phase2-password-keeps-data", "unexpected success reading private key"); + ASSERT (error != NULL, + "wrong-phase2-password-keeps-data", "unexpected missing error"); + ASSERT (format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "wrong-phase2-password-keeps-data", "unexpected success reading private key format"); + + /* Make sure the password hasn't changed */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "wrong-phase2-password-keeps-data", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "wrong-phase2-password-keeps-data", "failed to compare private key password"); + + g_object_unref (s_8021x); +} + +static void +test_clear_phase2_private_key (const char *path, const char *password) +{ + NMSetting8021x *s_8021x; + gboolean success; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GError *error = NULL; + const char *pw; + + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + ASSERT (s_8021x != NULL, "clear-phase2-private-key", "setting was NULL"); + + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + path, + password, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + &format, + &error); + ASSERT (success == TRUE, + "clear-phase2-private-key", "error reading private key: %s", error->message); + ASSERT (format != NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, + "clear-phase2-private-key", "unexpected private key format (got %d)", format); + + /* Make sure the password is what we expect */ + pw = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + ASSERT (pw != NULL, + "clear-phase2-private-key", "failed to get previous private key password"); + ASSERT (strcmp (pw, password) == 0, + "clear-phase2-private-key", "failed to compare private key password"); + + /* Now clear it */ + success = nm_setting_802_1x_set_phase2_private_key (s_8021x, + NULL, + NULL, + NM_SETTING_802_1X_CK_SCHEME_BLOB, + NULL, + &error); + ASSERT (success == TRUE, + "clear-phase2-private-key", "unexpected failure clearing private key"); + ASSERT (error == NULL, + "clear-phase2-private-key", "unexpected error clearing private key"); + + /* Ensure the password is also now clear */ + ASSERT (nm_setting_802_1x_get_phase2_private_key_password (s_8021x) == NULL, + "clear-phase2-private-key", "unexpected private key password"); + + g_object_unref (s_8021x); +} + +static void +do_8021x_test (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + g_assert_cmpint (g_strv_length (parts), ==, 2); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + /* Test phase1 and phase2 path scheme */ + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + + /* Test phase1 and phase2 blob scheme */ + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + + /* Test that using a wrong password does not change existing data */ + test_wrong_password_keeps_data (path, password); + test_wrong_phase2_password_keeps_data (path, password); + + /* Test clearing the private key */ + test_clear_private_key (path, password); + test_clear_phase2_private_key (path, password); + + g_free (path); + g_strfreev (parts); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_data_func ("/libnm/setting-8021x/key-and-cert", + "test_key_and_cert.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/key-only", + "test-key-only.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/pkcs8-enc-key", + "pkcs8-enc-key.pem, 1234567890", + do_8021x_test); + g_test_add_data_func ("/libnm/setting-8021x/pkcs12", + "test-cert.p12, test", + do_8021x_test); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-setting-dcb.c b/libnm-core/tests/test-setting-dcb.c new file mode 100644 index 00000000..8adab8ce --- /dev/null +++ b/libnm-core/tests/test-setting-dcb.c @@ -0,0 +1,326 @@ +/* -*- 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 2013 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include "nm-setting-dcb.h" +#include "nm-connection.h" +#include "nm-errors.h" + +#define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \ + NM_SETTING_DCB_FLAG_ADVERTISE | \ + NM_SETTING_DCB_FLAG_WILLING) + +static void +test_dcb_flags_valid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, 0); + g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, 0); + + g_object_set (G_OBJECT (s_dcb), + NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_ISCSI_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_APP_FIP_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_FLAGS_ALL, + NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_FLAGS_ALL, + NULL); + /* Priority Group Bandwidth must total 100% */ + for (i = 0; i < 7; i++) + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 12); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); + + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, DCB_FLAGS_ALL); + g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, DCB_FLAGS_ALL); +} + +#define TEST_FLAG(p, f, v) \ +{ \ + /* GObject property min/max should ensure the property does not get set to \ + * the invalid value, so we ensure the value we just tried to set is 0 and \ + * that verify is successful since the property never got set. \ + */ \ + g_object_set (G_OBJECT (s_dcb), p, v, NULL); \ + g_assert_cmpint (f (s_dcb), ==, 0); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ +} + +static void +test_dcb_flags_invalid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_FCOE_FLAGS, nm_setting_dcb_get_app_fcoe_flags, 0x332523); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_ISCSI_FLAGS, nm_setting_dcb_get_app_iscsi_flags, 0xFF); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_APP_FIP_FLAGS, nm_setting_dcb_get_app_fip_flags, 0x1111); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, nm_setting_dcb_get_priority_flow_control_flags, G_MAXUINT32); + g_test_assert_expected_messages (); + + g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING, "*invalid or out of range*"); + TEST_FLAG (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, nm_setting_dcb_get_priority_group_flags, + (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + 1); + g_test_assert_expected_messages (); +} + +#define TEST_APP_PRIORITY(lcprop, ucprop, v) \ +{ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \ + \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, v, NULL); \ + g_assert_cmpint (nm_setting_dcb_get_app_##lcprop##_priority (s_dcb), ==, v); \ + \ + /* Assert that the setting is invalid while the app is disabled unless v is default */ \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + if (v >= 0) { \ + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert (success == FALSE); \ + } else { \ + g_assert_no_error (error); \ + g_assert (success); \ + } \ + g_clear_error (&error); \ + \ + /* Set the enable flag and re-verify, this time it should be valid */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ + \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, 0, NULL); \ +} + +static void +test_dcb_app_priorities (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + /* Defaults */ + g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, -1); + g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, -1); + g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, -1); + + TEST_APP_PRIORITY (fcoe, FCOE, 6); + TEST_APP_PRIORITY (iscsi, ISCSI, 5); + TEST_APP_PRIORITY (fip, FIP, 4); + + TEST_APP_PRIORITY (fcoe, FCOE, -1); + TEST_APP_PRIORITY (iscsi, ISCSI, -1); + TEST_APP_PRIORITY (fip, FIP, -1); +} + +#define TEST_PRIORITY_VALID(fn, id, val, flagsprop, verify) \ +{ \ + /* Assert that setting the value gets the same value back out */ \ + nm_setting_dcb_set_priority_##fn (s_dcb, id, val); \ + g_assert_cmpint (nm_setting_dcb_get_priority_##fn (s_dcb, id), ==, val); \ + \ + if (verify) { \ + if (val != 0) { \ + /* Assert that verify fails because the flags do not include 'enabled' \ + * and a value has been set. \ + */ \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); \ + g_assert (success == FALSE); \ + g_clear_error (&error); \ + } \ + \ + /* Assert that adding the 'enabled' flag verifies the setting */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \ + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \ + g_assert_no_error (error); \ + g_assert (success); \ + } \ + \ + /* Reset everything */ \ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \ + nm_setting_dcb_set_priority_##fn (s_dcb, id, 0); \ +} + +/* If Priority Groups are enabled, PG bandwidth must equal 100% */ +#define SET_VALID_PRIORITY_GROUP_BANDWIDTH \ +{ \ + guint x; \ + for (x = 0; x < 7; x++) \ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, x, 12); \ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); \ +} + +static void +test_dcb_priorities_valid (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + guint i; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID (flow_control, i, TRUE, FLOW_CONTROL, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (group_id, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (group_id, i, 7 - i, GROUP, TRUE); + } + + /* Clear PG bandwidth from earlier tests */ + for (i = 0; i < 8; i++) + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 0); + + /* Priority Group Bandwidth must add up to 100% if enabled, which requires + * some dancing for verifying individual values here. + */ + for (i = 0; i < 8; i++) { + guint other = 7 - (i % 8); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - i); + TEST_PRIORITY_VALID (group_bandwidth, i, i, GROUP, TRUE); + + /* Set another priority group to the remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - (7 - i)); + TEST_PRIORITY_VALID (group_bandwidth, i, 7 - i, GROUP, TRUE); + + /* Clear remaining bandwidth */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 0); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (bandwidth, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (bandwidth, i, 7 - i, GROUP, TRUE); + } + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) + TEST_PRIORITY_VALID (strict_bandwidth, i, TRUE, GROUP, TRUE); + + SET_VALID_PRIORITY_GROUP_BANDWIDTH + for (i = 0; i < 8; i++) { + TEST_PRIORITY_VALID (traffic_class, i, i, GROUP, TRUE); + TEST_PRIORITY_VALID (traffic_class, i, 7 - i, GROUP, TRUE); + } +} + +static void +test_dcb_bandwidth_sums (void) +{ + NMSettingDcb *s_dcb; + GError *error = NULL; + gboolean success; + + s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); + g_assert (s_dcb); + + /* Assert that setting the value gets the same value back out */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 0, 9); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 1, 10); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 2, 11); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 3, 12); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 13); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 5, 14); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 6, 15); + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); + + /* Assert verify success when sums total 100% */ + g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Assert verify fails when sums do not total 100% */ + nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 20); + success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + g_assert (success == FALSE); + g_clear_error (&error); +} + +#define TPATH "/libnm/settings/dcb/" + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + +#if !GLIB_CHECK_VERSION(2,34,0) + g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); +#endif + + g_test_add_func (TPATH "flags-valid", test_dcb_flags_valid); + g_test_add_func (TPATH "flags-invalid", test_dcb_flags_invalid); + g_test_add_func (TPATH "app-priorities", test_dcb_app_priorities); + g_test_add_func (TPATH "priorities", test_dcb_priorities_valid); + g_test_add_func (TPATH "bandwidth-sums", test_dcb_bandwidth_sums); + + return g_test_run (); +} + diff --git a/libnm-core/tests/test-settings-defaults.c b/libnm-core/tests/test-settings-defaults.c new file mode 100644 index 00000000..0e786187 --- /dev/null +++ b/libnm-core/tests/test-settings-defaults.c @@ -0,0 +1,133 @@ +/* -*- 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 2008 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include + +#include "nm-setting-8021x.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-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-test-utils.h" + +static void +test_defaults (GType type, const char *name) +{ + GParamSpec **property_specs; + guint n_property_specs; + GObject *setting; + int i; + + setting = g_object_new (type, NULL); + + property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); + ASSERT (property_specs != NULL, + name, "couldn't find property specs for object of type '%s'", + g_type_name (G_OBJECT_TYPE (setting))); + + for (i = 0; i < n_property_specs; i++) { + GParamSpec *prop_spec = property_specs[i]; + GValue value = G_VALUE_INIT; + GValue defvalue = G_VALUE_INIT; + char *actual, *expected; + gboolean ok = FALSE; + + /* Ignore non-fundamental types since they won't really have + * defaults. + */ + if (!G_TYPE_IS_FUNDAMENTAL (prop_spec->value_type)) + continue; + + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, &value); + + g_value_init (&defvalue, prop_spec->value_type); + g_param_value_set_default (prop_spec, &defvalue); + + actual = g_strdup_value_contents (&value); + expected = g_strdup_value_contents (&defvalue); + + if (!strcmp (prop_spec->name, NM_SETTING_NAME)) { + /* 'name' is always the setting name, not the default value */ + ok = !strcmp (nm_setting_get_name (NM_SETTING (setting)), name); + g_free (expected); + expected = g_strdup (name); + } else + ok = g_param_value_defaults (prop_spec, &value); + + ASSERT (ok, + name, "property '%s' value '%s' not the expected default value '%s'", + prop_spec->name, actual, expected); + + g_free (actual); + g_free (expected); + g_value_unset (&value); + g_value_unset (&defvalue); + } + + g_free (property_specs); + g_object_unref (setting); +} + +int +main (int argc, char **argv) +{ + char *base; + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + /* The tests */ + test_defaults (NM_TYPE_SETTING_CONNECTION, NM_SETTING_CONNECTION_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_802_1X, NM_SETTING_802_1X_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_CDMA, NM_SETTING_CDMA_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_GSM, NM_SETTING_GSM_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_IP6_CONFIG, NM_SETTING_IP6_CONFIG_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_PPP, NM_SETTING_PPP_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_PPPOE, NM_SETTING_PPPOE_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_SERIAL, NM_SETTING_SERIAL_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_VPN, NM_SETTING_VPN_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRED, NM_SETTING_WIRED_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRELESS, NM_SETTING_WIRELESS_SETTING_NAME); + test_defaults (NM_TYPE_SETTING_WIRELESS_SECURITY, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + base = g_path_get_basename (argv[0]); + fprintf (stdout, "%s: SUCCESS\n", base); + g_free (base); + return 0; +} + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 623bf45d..20a24811 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -4,7 +4,6 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -DG_LOG_DOMAIN=\""libnm-glib"\" \ @@ -18,8 +17,7 @@ BUILT_SOURCES = \ noinst_LTLIBRARIES = \ - libdeprecated-nm-glib.la \ - libnm-glib-test.la + libdeprecated-nm-glib.la ##################################################### # Deprecated original libnm_glib bits @@ -153,7 +151,7 @@ libnm_glib_la_LIBADD = \ SYMBOL_VIS_FILE=$(srcdir)/libnm-glib.ver libnm_glib_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "12:0:8" + -version-info "13:0:9" noinst_PROGRAMS = libnm-glib-test @@ -176,27 +174,6 @@ libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ BUILT_SOURCES += $(GLIB_GENERATED) -##################################################### -# Test libnm-glib stuff -##################################################### - -libnm_glib_test_la_CFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(GUDEV_CFLAGS) \ - -DLIBNM_GLIB_TEST \ - -DNMRUNDIR=\"$(nmrundir)\" - -libnm_glib_test_la_SOURCES = \ - $(libnminclude_HEADERS) \ - $(libnm_glib_la_SOURCES) - -libnm_glib_test_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) \ - $(GUDEV_LIBS) - ##################################################### nm-vpn-plugin-glue.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml diff --git a/libnm-glib/Makefile.in b/libnm-glib/Makefile.in index 4b169f40..a6c5d03a 100644 --- a/libnm-glib/Makefile.in +++ b/libnm-glib/Makefile.in @@ -152,48 +152,6 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libnm_glib_test_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_1 = -am__objects_2 = libnm_glib_test_la-nm-object.lo \ - libnm_glib_test_la-nm-dbus-helpers.lo \ - libnm_glib_test_la-nm-client.lo \ - libnm_glib_test_la-nm-device.lo \ - libnm_glib_test_la-nm-device-ethernet.lo \ - libnm_glib_test_la-nm-device-infiniband.lo \ - libnm_glib_test_la-nm-device-adsl.lo \ - libnm_glib_test_la-nm-device-wifi.lo \ - libnm_glib_test_la-nm-device-bt.lo \ - libnm_glib_test_la-nm-device-olpc-mesh.lo \ - libnm_glib_test_la-nm-device-bond.lo \ - libnm_glib_test_la-nm-device-team.lo \ - libnm_glib_test_la-nm-device-bridge.lo \ - libnm_glib_test_la-nm-device-vlan.lo \ - libnm_glib_test_la-nm-device-generic.lo \ - libnm_glib_test_la-nm-access-point.lo \ - libnm_glib_test_la-nm-ip4-config.lo \ - libnm_glib_test_la-nm-device-modem.lo \ - libnm_glib_test_la-nm-vpn-connection.lo \ - libnm_glib_test_la-nm-types.lo \ - libnm_glib_test_la-nm-object-cache.lo \ - libnm_glib_test_la-nm-active-connection.lo \ - libnm_glib_test_la-nm-dhcp4-config.lo \ - libnm_glib_test_la-nm-ip6-config.lo \ - libnm_glib_test_la-nm-dhcp6-config.lo \ - libnm_glib_test_la-nm-remote-connection.lo \ - libnm_glib_test_la-nm-remote-settings.lo \ - libnm_glib_test_la-nm-secret-agent.lo \ - libnm_glib_test_la-nm-device-wimax.lo \ - libnm_glib_test_la-nm-wimax-nsp.lo \ - libnm_glib_test_la-nm-glib-enum-types.lo -am__objects_3 = $(am__objects_2) $(am__objects_1) -am_libnm_glib_test_la_OBJECTS = $(am__objects_1) $(am__objects_3) -libnm_glib_test_la_OBJECTS = $(am_libnm_glib_test_la_OBJECTS) -libnm_glib_test_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libnm_glib_test_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ libnm_glib_vpn_la_DEPENDENCIES = \ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -209,7 +167,7 @@ libnm_glib_vpn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ libnm_glib_la_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \ $(builddir)/libdeprecated-nm-glib.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_4 = libnm_glib_la-nm-object.lo \ +am__objects_1 = libnm_glib_la-nm-object.lo \ libnm_glib_la-nm-dbus-helpers.lo libnm_glib_la-nm-client.lo \ libnm_glib_la-nm-device.lo libnm_glib_la-nm-device-ethernet.lo \ libnm_glib_la-nm-device-infiniband.lo \ @@ -235,7 +193,8 @@ am__objects_4 = libnm_glib_la-nm-object.lo \ libnm_glib_la-nm-secret-agent.lo \ libnm_glib_la-nm-device-wimax.lo libnm_glib_la-nm-wimax-nsp.lo \ libnm_glib_la-nm-glib-enum-types.lo -am_libnm_glib_la_OBJECTS = $(am__objects_4) $(am__objects_1) +am__objects_2 = +am_libnm_glib_la_OBJECTS = $(am__objects_1) $(am__objects_2) libnm_glib_la_OBJECTS = $(am_libnm_glib_la_OBJECTS) libnm_glib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libnm_glib_la_CFLAGS) \ @@ -286,11 +245,11 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdeprecated_nm_glib_la_SOURCES) \ - $(libnm_glib_test_la_SOURCES) $(libnm_glib_vpn_la_SOURCES) \ - $(libnm_glib_la_SOURCES) $(libnm_glib_test_SOURCES) + $(libnm_glib_vpn_la_SOURCES) $(libnm_glib_la_SOURCES) \ + $(libnm_glib_test_SOURCES) DIST_SOURCES = $(libdeprecated_nm_glib_la_SOURCES) \ - $(libnm_glib_test_la_SOURCES) $(libnm_glib_vpn_la_SOURCES) \ - $(libnm_glib_la_SOURCES) $(libnm_glib_test_SOURCES) + $(libnm_glib_vpn_la_SOURCES) $(libnm_glib_la_SOURCES) \ + $(libnm_glib_test_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -370,6 +329,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -493,6 +454,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -512,6 +474,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -538,7 +501,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -620,7 +583,6 @@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -DG_LOG_DOMAIN=\""libnm-glib"\" \ @@ -631,8 +593,7 @@ AM_CPPFLAGS = \ BUILT_SOURCES = nm-vpn-plugin-glue.h nm-secret-agent-glue.h \ $(GLIB_GENERATED) noinst_LTLIBRARIES = \ - libdeprecated-nm-glib.la \ - libnm-glib-test.la + libdeprecated-nm-glib.la ##################################################### @@ -762,7 +723,7 @@ libnm_glib_la_LIBADD = \ SYMBOL_VIS_FILE = $(srcdir)/libnm-glib.ver libnm_glib_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "12:0:8" + -version-info "13:0:9" libnm_glib_test_SOURCES = libnm-glib-test.c libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) @@ -779,27 +740,6 @@ libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ -version-info "3:0:2" - -##################################################### -# Test libnm-glib stuff -##################################################### -libnm_glib_test_la_CFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(GUDEV_CFLAGS) \ - -DLIBNM_GLIB_TEST \ - -DNMRUNDIR=\"$(nmrundir)\" - -libnm_glib_test_la_SOURCES = \ - $(libnminclude_HEADERS) \ - $(libnm_glib_la_SOURCES) - -libnm_glib_test_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) \ - $(GUDEV_LIBS) - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc DISTCLEANFILES = libnm-glib.pc libnm-glib.pc @@ -908,9 +848,6 @@ clean-noinstLTLIBRARIES: libdeprecated-nm-glib.la: $(libdeprecated_nm_glib_la_OBJECTS) $(libdeprecated_nm_glib_la_DEPENDENCIES) $(EXTRA_libdeprecated_nm_glib_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdeprecated_nm_glib_la_OBJECTS) $(libdeprecated_nm_glib_la_LIBADD) $(LIBS) -libnm-glib-test.la: $(libnm_glib_test_la_OBJECTS) $(libnm_glib_test_la_DEPENDENCIES) $(EXTRA_libnm_glib_test_la_DEPENDENCIES) - $(AM_V_CCLD)$(libnm_glib_test_la_LINK) $(libnm_glib_test_la_OBJECTS) $(libnm_glib_test_la_LIBADD) $(LIBS) - libnm-glib-vpn.la: $(libnm_glib_vpn_la_OBJECTS) $(libnm_glib_vpn_la_DEPENDENCIES) $(EXTRA_libnm_glib_vpn_la_DEPENDENCIES) $(AM_V_CCLD)$(libnm_glib_vpn_la_LINK) -rpath $(libdir) $(libnm_glib_vpn_la_OBJECTS) $(libnm_glib_vpn_la_LIBADD) $(LIBS) @@ -969,37 +906,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-vpn-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_la-nm-wimax-nsp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test-libnm-glib-test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-access-point.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-active-connection.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-adsl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bond.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-bt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-ethernet.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-generic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-infiniband.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-modem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-olpc-mesh.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-team.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-vlan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-wifi.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device-wimax.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-device.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dhcp4-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-dhcp6-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-glib-enum-types.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-ip4-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-ip6-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-object-cache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-object.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-remote-connection.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-remote-settings.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-secret-agent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-types.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-vpn-connection.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_test_la-nm-wimax-nsp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_vpn_la-nm-vpn-enum-types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin-ui-interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin-utils.Plo@am__quote@ @@ -1033,223 +939,6 @@ libdeprecated_nm_glib_la-libnm_glib.lo: libnm_glib.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdeprecated_nm_glib_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdeprecated_nm_glib_la-libnm_glib.lo `test -f 'libnm_glib.c' || echo '$(srcdir)/'`libnm_glib.c -libnm_glib_test_la-nm-object.lo: nm-object.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-object.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-object.Tpo -c -o libnm_glib_test_la-nm-object.lo `test -f 'nm-object.c' || echo '$(srcdir)/'`nm-object.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-object.Tpo $(DEPDIR)/libnm_glib_test_la-nm-object.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-object.c' object='libnm_glib_test_la-nm-object.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-object.lo `test -f 'nm-object.c' || echo '$(srcdir)/'`nm-object.c - -libnm_glib_test_la-nm-dbus-helpers.lo: nm-dbus-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-dbus-helpers.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Tpo -c -o libnm_glib_test_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Tpo $(DEPDIR)/libnm_glib_test_la-nm-dbus-helpers.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dbus-helpers.c' object='libnm_glib_test_la-nm-dbus-helpers.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-dbus-helpers.lo `test -f 'nm-dbus-helpers.c' || echo '$(srcdir)/'`nm-dbus-helpers.c - -libnm_glib_test_la-nm-client.lo: nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-client.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-client.Tpo -c -o libnm_glib_test_la-nm-client.lo `test -f 'nm-client.c' || echo '$(srcdir)/'`nm-client.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-client.Tpo $(DEPDIR)/libnm_glib_test_la-nm-client.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-client.c' object='libnm_glib_test_la-nm-client.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-client.lo `test -f 'nm-client.c' || echo '$(srcdir)/'`nm-client.c - -libnm_glib_test_la-nm-device.lo: nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device.Tpo -c -o libnm_glib_test_la-nm-device.lo `test -f 'nm-device.c' || echo '$(srcdir)/'`nm-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device.c' object='libnm_glib_test_la-nm-device.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device.lo `test -f 'nm-device.c' || echo '$(srcdir)/'`nm-device.c - -libnm_glib_test_la-nm-device-ethernet.lo: nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-ethernet.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-ethernet.Tpo -c -o libnm_glib_test_la-nm-device-ethernet.lo `test -f 'nm-device-ethernet.c' || echo '$(srcdir)/'`nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-ethernet.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-ethernet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-ethernet.c' object='libnm_glib_test_la-nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-ethernet.lo `test -f 'nm-device-ethernet.c' || echo '$(srcdir)/'`nm-device-ethernet.c - -libnm_glib_test_la-nm-device-infiniband.lo: nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-infiniband.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-infiniband.Tpo -c -o libnm_glib_test_la-nm-device-infiniband.lo `test -f 'nm-device-infiniband.c' || echo '$(srcdir)/'`nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-infiniband.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-infiniband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-infiniband.c' object='libnm_glib_test_la-nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-infiniband.lo `test -f 'nm-device-infiniband.c' || echo '$(srcdir)/'`nm-device-infiniband.c - -libnm_glib_test_la-nm-device-adsl.lo: nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-adsl.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-adsl.Tpo -c -o libnm_glib_test_la-nm-device-adsl.lo `test -f 'nm-device-adsl.c' || echo '$(srcdir)/'`nm-device-adsl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-adsl.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-adsl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-adsl.c' object='libnm_glib_test_la-nm-device-adsl.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-adsl.lo `test -f 'nm-device-adsl.c' || echo '$(srcdir)/'`nm-device-adsl.c - -libnm_glib_test_la-nm-device-wifi.lo: nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-wifi.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-wifi.Tpo -c -o libnm_glib_test_la-nm-device-wifi.lo `test -f 'nm-device-wifi.c' || echo '$(srcdir)/'`nm-device-wifi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-wifi.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-wifi.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-wifi.c' object='libnm_glib_test_la-nm-device-wifi.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-wifi.lo `test -f 'nm-device-wifi.c' || echo '$(srcdir)/'`nm-device-wifi.c - -libnm_glib_test_la-nm-device-bt.lo: nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-bt.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-bt.Tpo -c -o libnm_glib_test_la-nm-device-bt.lo `test -f 'nm-device-bt.c' || echo '$(srcdir)/'`nm-device-bt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-bt.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-bt.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-bt.c' object='libnm_glib_test_la-nm-device-bt.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-bt.lo `test -f 'nm-device-bt.c' || echo '$(srcdir)/'`nm-device-bt.c - -libnm_glib_test_la-nm-device-olpc-mesh.lo: nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-olpc-mesh.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-olpc-mesh.Tpo -c -o libnm_glib_test_la-nm-device-olpc-mesh.lo `test -f 'nm-device-olpc-mesh.c' || echo '$(srcdir)/'`nm-device-olpc-mesh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-olpc-mesh.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-olpc-mesh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-olpc-mesh.c' object='libnm_glib_test_la-nm-device-olpc-mesh.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-olpc-mesh.lo `test -f 'nm-device-olpc-mesh.c' || echo '$(srcdir)/'`nm-device-olpc-mesh.c - -libnm_glib_test_la-nm-device-bond.lo: nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-bond.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-bond.Tpo -c -o libnm_glib_test_la-nm-device-bond.lo `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-bond.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-bond.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-bond.c' object='libnm_glib_test_la-nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-bond.lo `test -f 'nm-device-bond.c' || echo '$(srcdir)/'`nm-device-bond.c - -libnm_glib_test_la-nm-device-team.lo: nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-team.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-team.Tpo -c -o libnm_glib_test_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-team.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-team.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-team.c' object='libnm_glib_test_la-nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-team.lo `test -f 'nm-device-team.c' || echo '$(srcdir)/'`nm-device-team.c - -libnm_glib_test_la-nm-device-bridge.lo: nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-bridge.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Tpo -c -o libnm_glib_test_la-nm-device-bridge.lo `test -f 'nm-device-bridge.c' || echo '$(srcdir)/'`nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-bridge.c' object='libnm_glib_test_la-nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-bridge.lo `test -f 'nm-device-bridge.c' || echo '$(srcdir)/'`nm-device-bridge.c - -libnm_glib_test_la-nm-device-vlan.lo: nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-vlan.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-vlan.Tpo -c -o libnm_glib_test_la-nm-device-vlan.lo `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-vlan.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-vlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-vlan.c' object='libnm_glib_test_la-nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-vlan.lo `test -f 'nm-device-vlan.c' || echo '$(srcdir)/'`nm-device-vlan.c - -libnm_glib_test_la-nm-device-generic.lo: nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-generic.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Tpo -c -o libnm_glib_test_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-generic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-generic.c' object='libnm_glib_test_la-nm-device-generic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-generic.lo `test -f 'nm-device-generic.c' || echo '$(srcdir)/'`nm-device-generic.c - -libnm_glib_test_la-nm-access-point.lo: nm-access-point.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-access-point.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-access-point.Tpo -c -o libnm_glib_test_la-nm-access-point.lo `test -f 'nm-access-point.c' || echo '$(srcdir)/'`nm-access-point.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-access-point.Tpo $(DEPDIR)/libnm_glib_test_la-nm-access-point.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-access-point.c' object='libnm_glib_test_la-nm-access-point.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-access-point.lo `test -f 'nm-access-point.c' || echo '$(srcdir)/'`nm-access-point.c - -libnm_glib_test_la-nm-ip4-config.lo: nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-ip4-config.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-ip4-config.Tpo -c -o libnm_glib_test_la-nm-ip4-config.lo `test -f 'nm-ip4-config.c' || echo '$(srcdir)/'`nm-ip4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-ip4-config.Tpo $(DEPDIR)/libnm_glib_test_la-nm-ip4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-ip4-config.c' object='libnm_glib_test_la-nm-ip4-config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-ip4-config.lo `test -f 'nm-ip4-config.c' || echo '$(srcdir)/'`nm-ip4-config.c - -libnm_glib_test_la-nm-device-modem.lo: nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-modem.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-modem.Tpo -c -o libnm_glib_test_la-nm-device-modem.lo `test -f 'nm-device-modem.c' || echo '$(srcdir)/'`nm-device-modem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-device-modem.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-modem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-modem.c' object='libnm_glib_test_la-nm-device-modem.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-modem.lo `test -f 'nm-device-modem.c' || echo '$(srcdir)/'`nm-device-modem.c - -libnm_glib_test_la-nm-vpn-connection.lo: nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-vpn-connection.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-vpn-connection.Tpo -c -o libnm_glib_test_la-nm-vpn-connection.lo `test -f 'nm-vpn-connection.c' || echo '$(srcdir)/'`nm-vpn-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-vpn-connection.Tpo $(DEPDIR)/libnm_glib_test_la-nm-vpn-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-vpn-connection.c' object='libnm_glib_test_la-nm-vpn-connection.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-vpn-connection.lo `test -f 'nm-vpn-connection.c' || echo '$(srcdir)/'`nm-vpn-connection.c - -libnm_glib_test_la-nm-types.lo: nm-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-types.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-types.Tpo -c -o libnm_glib_test_la-nm-types.lo `test -f 'nm-types.c' || echo '$(srcdir)/'`nm-types.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-types.Tpo $(DEPDIR)/libnm_glib_test_la-nm-types.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-types.c' object='libnm_glib_test_la-nm-types.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-types.lo `test -f 'nm-types.c' || echo '$(srcdir)/'`nm-types.c - -libnm_glib_test_la-nm-object-cache.lo: nm-object-cache.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-object-cache.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-object-cache.Tpo -c -o libnm_glib_test_la-nm-object-cache.lo `test -f 'nm-object-cache.c' || echo '$(srcdir)/'`nm-object-cache.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-object-cache.Tpo $(DEPDIR)/libnm_glib_test_la-nm-object-cache.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-object-cache.c' object='libnm_glib_test_la-nm-object-cache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-object-cache.lo `test -f 'nm-object-cache.c' || echo '$(srcdir)/'`nm-object-cache.c - -libnm_glib_test_la-nm-active-connection.lo: nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-active-connection.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-active-connection.Tpo -c -o libnm_glib_test_la-nm-active-connection.lo `test -f 'nm-active-connection.c' || echo '$(srcdir)/'`nm-active-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-active-connection.Tpo $(DEPDIR)/libnm_glib_test_la-nm-active-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-active-connection.c' object='libnm_glib_test_la-nm-active-connection.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-active-connection.lo `test -f 'nm-active-connection.c' || echo '$(srcdir)/'`nm-active-connection.c - -libnm_glib_test_la-nm-dhcp4-config.lo: nm-dhcp4-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-dhcp4-config.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-dhcp4-config.Tpo -c -o libnm_glib_test_la-nm-dhcp4-config.lo `test -f 'nm-dhcp4-config.c' || echo '$(srcdir)/'`nm-dhcp4-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-dhcp4-config.Tpo $(DEPDIR)/libnm_glib_test_la-nm-dhcp4-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp4-config.c' object='libnm_glib_test_la-nm-dhcp4-config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-dhcp4-config.lo `test -f 'nm-dhcp4-config.c' || echo '$(srcdir)/'`nm-dhcp4-config.c - -libnm_glib_test_la-nm-ip6-config.lo: nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-ip6-config.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-ip6-config.Tpo -c -o libnm_glib_test_la-nm-ip6-config.lo `test -f 'nm-ip6-config.c' || echo '$(srcdir)/'`nm-ip6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-ip6-config.Tpo $(DEPDIR)/libnm_glib_test_la-nm-ip6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-ip6-config.c' object='libnm_glib_test_la-nm-ip6-config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-ip6-config.lo `test -f 'nm-ip6-config.c' || echo '$(srcdir)/'`nm-ip6-config.c - -libnm_glib_test_la-nm-dhcp6-config.lo: nm-dhcp6-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-dhcp6-config.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-dhcp6-config.Tpo -c -o libnm_glib_test_la-nm-dhcp6-config.lo `test -f 'nm-dhcp6-config.c' || echo '$(srcdir)/'`nm-dhcp6-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-dhcp6-config.Tpo $(DEPDIR)/libnm_glib_test_la-nm-dhcp6-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-dhcp6-config.c' object='libnm_glib_test_la-nm-dhcp6-config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-dhcp6-config.lo `test -f 'nm-dhcp6-config.c' || echo '$(srcdir)/'`nm-dhcp6-config.c - -libnm_glib_test_la-nm-remote-connection.lo: nm-remote-connection.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-remote-connection.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-remote-connection.Tpo -c -o libnm_glib_test_la-nm-remote-connection.lo `test -f 'nm-remote-connection.c' || echo '$(srcdir)/'`nm-remote-connection.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-remote-connection.Tpo $(DEPDIR)/libnm_glib_test_la-nm-remote-connection.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-remote-connection.c' object='libnm_glib_test_la-nm-remote-connection.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-remote-connection.lo `test -f 'nm-remote-connection.c' || echo '$(srcdir)/'`nm-remote-connection.c - -libnm_glib_test_la-nm-remote-settings.lo: nm-remote-settings.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-remote-settings.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-remote-settings.Tpo -c -o libnm_glib_test_la-nm-remote-settings.lo `test -f 'nm-remote-settings.c' || echo '$(srcdir)/'`nm-remote-settings.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-remote-settings.Tpo $(DEPDIR)/libnm_glib_test_la-nm-remote-settings.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-remote-settings.c' object='libnm_glib_test_la-nm-remote-settings.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-remote-settings.lo `test -f 'nm-remote-settings.c' || echo '$(srcdir)/'`nm-remote-settings.c - -libnm_glib_test_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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-secret-agent.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-secret-agent.Tpo -c -o libnm_glib_test_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)/libnm_glib_test_la-nm-secret-agent.Tpo $(DEPDIR)/libnm_glib_test_la-nm-secret-agent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-secret-agent.c' object='libnm_glib_test_la-nm-secret-agent.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-secret-agent.lo `test -f 'nm-secret-agent.c' || echo '$(srcdir)/'`nm-secret-agent.c - -libnm_glib_test_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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-device-wimax.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-device-wimax.Tpo -c -o libnm_glib_test_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)/libnm_glib_test_la-nm-device-wimax.Tpo $(DEPDIR)/libnm_glib_test_la-nm-device-wimax.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-device-wimax.c' object='libnm_glib_test_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c - -libnm_glib_test_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) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-wimax-nsp.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-wimax-nsp.Tpo -c -o libnm_glib_test_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)/libnm_glib_test_la-nm-wimax-nsp.Tpo $(DEPDIR)/libnm_glib_test_la-nm-wimax-nsp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-wimax-nsp.c' object='libnm_glib_test_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c - -libnm_glib_test_la-nm-glib-enum-types.lo: nm-glib-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -MT libnm_glib_test_la-nm-glib-enum-types.lo -MD -MP -MF $(DEPDIR)/libnm_glib_test_la-nm-glib-enum-types.Tpo -c -o libnm_glib_test_la-nm-glib-enum-types.lo `test -f 'nm-glib-enum-types.c' || echo '$(srcdir)/'`nm-glib-enum-types.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_test_la-nm-glib-enum-types.Tpo $(DEPDIR)/libnm_glib_test_la-nm-glib-enum-types.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nm-glib-enum-types.c' object='libnm_glib_test_la-nm-glib-enum-types.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_test_la_CFLAGS) $(CFLAGS) -c -o libnm_glib_test_la-nm-glib-enum-types.lo `test -f 'nm-glib-enum-types.c' || echo '$(srcdir)/'`nm-glib-enum-types.c - libnm_glib_vpn_la-nm-vpn-plugin.lo: nm-vpn-plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnm_glib_vpn_la_CFLAGS) $(CFLAGS) -MT libnm_glib_vpn_la-nm-vpn-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Tpo -c -o libnm_glib_vpn_la-nm-vpn-plugin.lo `test -f 'nm-vpn-plugin.c' || echo '$(srcdir)/'`nm-vpn-plugin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Tpo $(DEPDIR)/libnm_glib_vpn_la-nm-vpn-plugin.Plo diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index e38457f0..7dc6823e 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -20,6 +20,8 @@ * Copyright (C) 2007 - 2008 Red Hat, Inc. */ +#include "config.h" + #include #include #include diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 982288e5..9219c4a2 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -104,6 +104,7 @@ global: nm_device_bt_new; nm_device_connection_compatible; nm_device_connection_valid; + nm_device_delete; nm_device_disambiguate_names; nm_device_disconnect; nm_device_error_get_type; @@ -156,6 +157,7 @@ global: nm_device_infiniband_get_hw_address; nm_device_infiniband_get_type; nm_device_infiniband_new; + nm_device_is_software; nm_device_modem_error_get_type; nm_device_modem_error_quark; nm_device_modem_get_current_capabilities; @@ -181,6 +183,7 @@ global: nm_device_vlan_error_quark; nm_device_vlan_get_carrier; nm_device_vlan_get_hw_address; + nm_device_vlan_get_parent; nm_device_vlan_get_type; nm_device_vlan_get_vlan_id; nm_device_vlan_new; diff --git a/libnm-glib/libnm_glib.c b/libnm-glib/libnm_glib.c index a2a6d26e..fed80160 100644 --- a/libnm-glib/libnm_glib.c +++ b/libnm-glib/libnm_glib.c @@ -21,6 +21,8 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c index ca3f1bf2..abf61cc9 100644 --- a/libnm-glib/nm-access-point.c +++ b/libnm-glib/nm-access-point.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -88,9 +87,9 @@ nm_access_point_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); return (GObject *) g_object_new (NM_TYPE_ACCESS_POINT, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } /** @@ -377,7 +376,7 @@ nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection) /** * nm_access_point_filter_connections: * @ap: an #NMAccessPoint to filter connections for - * @connections: (element-type NetworkManager.Connection): a list of + * @connections: (element-type NMConnection): a list of * #NMConnection objects to filter * * Filters a given list of connections for a given #NMAccessPoint object and @@ -390,7 +389,7 @@ nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection) * for a given #NMDevice using nm_device_filter_connections() and finally * filter that list with this function. * - * Returns: (transfer container) (element-type NetworkManager.Connection): a + * Returns: (transfer container) (element-type NMConnection): a * list of #NMConnection objects that could be activated with the given @ap. * The elements of the list are owned by their creator and should not be freed * by the caller, but the returned list itself is owned by the caller and should @@ -556,13 +555,12 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_FLAGS, - g_param_spec_uint (NM_ACCESS_POINT_FLAGS, - "Flags", - "Flags", + g_param_spec_uint (NM_ACCESS_POINT_FLAGS, "", "", NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_FLAGS_NONE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:wpa-flags: @@ -571,11 +569,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_WPA_FLAGS, - g_param_spec_uint (NM_ACCESS_POINT_WPA_FLAGS, - "WPA Flags", - "WPA Flags", + g_param_spec_uint (NM_ACCESS_POINT_WPA_FLAGS, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:rsn-flags: @@ -584,11 +581,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_RSN_FLAGS, - g_param_spec_uint (NM_ACCESS_POINT_RSN_FLAGS, - "RSN Flags", - "RSN Flags", + g_param_spec_uint (NM_ACCESS_POINT_RSN_FLAGS, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:ssid: @@ -597,11 +593,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_SSID, - g_param_spec_boxed (NM_ACCESS_POINT_SSID, - "SSID", - "SSID", - NM_TYPE_SSID, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_ACCESS_POINT_SSID, "", "", + NM_TYPE_SSID, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:frequency: @@ -610,11 +605,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_FREQUENCY, - g_param_spec_uint (NM_ACCESS_POINT_FREQUENCY, - "Frequency", - "Frequency", - 0, 10000, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_ACCESS_POINT_FREQUENCY, "", "", + 0, 10000, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:bssid: @@ -623,11 +617,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_BSSID, - g_param_spec_string (NM_ACCESS_POINT_BSSID, - "BSSID", - "BSSID", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACCESS_POINT_BSSID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:hw-address: @@ -636,11 +629,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:mode: @@ -651,11 +643,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_ACCESS_POINT_MODE, - "Mode", - "Mode", - NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, - G_PARAM_READABLE)); + g_param_spec_uint (NM_ACCESS_POINT_MODE, "", "", + NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:max-bitrate: @@ -664,11 +655,10 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_MAX_BITRATE, - g_param_spec_uint (NM_ACCESS_POINT_MAX_BITRATE, - "Max Bitrate", - "Max Bitrate", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_ACCESS_POINT_MAX_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMAccessPoint:strength: @@ -677,9 +667,8 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) **/ g_object_class_install_property (object_class, PROP_STRENGTH, - g_param_spec_uchar (NM_ACCESS_POINT_STRENGTH, - "Strength", - "Strength", - 0, G_MAXUINT8, 0, - G_PARAM_READABLE)); + g_param_spec_uchar (NM_ACCESS_POINT_STRENGTH, "", "", + 0, G_MAXUINT8, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-access-point.h b/libnm-glib/nm-access-point.h index 4862e6b7..d3150f8e 100644 --- a/libnm-glib/nm-access-point.h +++ b/libnm-glib/nm-access-point.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ #ifndef NM_ACCESS_POINT_H diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c index bca21b4d..7067a110 100644 --- a/libnm-glib/nm-active-connection.c +++ b/libnm-glib/nm-active-connection.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2014 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ +#include "config.h" + #include #include "NetworkManager.h" @@ -106,9 +106,9 @@ nm_active_connection_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); return g_object_new (NM_TYPE_ACTIVE_CONNECTION, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } static GType @@ -308,7 +308,7 @@ nm_active_connection_get_specific_object (NMActiveConnection *connection) * * Gets the #NMDevices used for the active connections. * - * Returns: (element-type NMClient.Device): the #GPtrArray containing #NMDevices. + * Returns: (element-type NMDevice): the #GPtrArray containing #NMDevices. * This is the internal copy used by the connection, and must not be modified. **/ const GPtrArray * @@ -662,11 +662,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_CONNECTION, - g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, - "Connection", - "Connection", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:id: @@ -677,11 +676,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_ID, - g_param_spec_string (NM_ACTIVE_CONNECTION_ID, - "ID", - "ID", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_ID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:uuid: @@ -690,11 +688,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_UUID, - g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, - "UUID", - "UUID", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:type: @@ -705,11 +702,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_TYPE, - g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, - "Type", - "Type", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:specific-object: @@ -718,11 +714,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_SPECIFIC_OBJECT, - g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, - "Specific object", - "Specific object", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:device: @@ -731,11 +726,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_DEVICES, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, - "Devices", - "Devices", - NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "", "", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:state: @@ -744,13 +738,12 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, - "State", - "State", - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE)); + g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, "", "", + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:default: @@ -759,11 +752,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_DEFAULT, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, - "Default", - "Is the default IPv4 active connection", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:ip4-config: @@ -774,11 +766,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_IP4_CONFIG, - g_param_spec_object (NM_ACTIVE_CONNECTION_IP4_CONFIG, - "IP4 Config", - "IP4 Config", + g_param_spec_object (NM_ACTIVE_CONNECTION_IP4_CONFIG, "", "", NM_TYPE_IP4_CONFIG, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:dhcp4-config: @@ -789,11 +780,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_DHCP4_CONFIG, - g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, "", "", NM_TYPE_DHCP4_CONFIG, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:default6: @@ -802,11 +792,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_DEFAULT6, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, - "Default6", - "Is the default IPv6 active connection", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:ip6-config: @@ -817,11 +806,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_IP6_CONFIG, - g_param_spec_object (NM_ACTIVE_CONNECTION_IP6_CONFIG, - "IP6 Config", - "IP6 Config", + g_param_spec_object (NM_ACTIVE_CONNECTION_IP6_CONFIG, "", "", NM_TYPE_IP6_CONFIG, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:dhcp6-config: @@ -832,11 +820,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_DHCP6_CONFIG, - g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, "", "", NM_TYPE_DHCP6_CONFIG, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:vpn: @@ -847,11 +834,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_VPN, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, - "VPN", - "Is a VPN connection", + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMActiveConnection:master: @@ -860,9 +846,8 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) **/ g_object_class_install_property (object_class, PROP_MASTER, - g_param_spec_string (NM_ACTIVE_CONNECTION_MASTER, - "Master", - "Path of the master device", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_ACTIVE_CONNECTION_MASTER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-active-connection.h b/libnm-glib/nm-active-connection.h index b15e8340..e2941564 100644 --- a/libnm-glib/nm-active-connection.h +++ b/libnm-glib/nm-active-connection.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2014 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_ACTIVE_CONNECTION_H diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 379c7879..a29664c6 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -116,10 +116,10 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; static void proxy_name_owner_changed (DBusGProxy *proxy, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data); + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data); /**********************************************************************/ @@ -360,11 +360,11 @@ client_recheck_permissions (DBusGProxy *proxy, gpointer user_data) * @client: a #NMClient * * Gets all the known network devices. Use nm_device_get_type() or the - * NM_IS_DEVICE_XXXX() functions to determine what kind of device member of the - * returned array is, and then you may use device-specific methods such as - * nm_device_ethernet_get_hw_address(). + * NM_IS_DEVICE_XXXX functions to determine what kind of + * device member of the returned array is, and then you may use device-specific + * methods such as nm_device_ethernet_get_hw_address(). * - * Returns: (transfer none) (element-type NMClient.Device): a #GPtrArray + * Returns: (transfer none) (element-type NMDevice): a #GPtrArray * containing all the #NMDevices. The returned array is owned by the * #NMClient object and should not be modified. **/ @@ -607,6 +607,11 @@ activate_nm_not_running (gpointer user_data) * * If @connection is not given for a device-based activation, NetworkManager * picks the best available connection for the device and activates it. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. **/ void nm_client_activate_connection (NMClient *client, @@ -691,6 +696,11 @@ add_activate_cb (DBusGProxy *proxy, * automatically filling in missing settings with the capabilities of the * given device and specific object. The new connection is then activated. * Cannot be used for VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. **/ void nm_client_add_and_activate_connection (NMClient *client, @@ -783,11 +793,11 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) * * Gets the active connections. * - * Returns: (transfer none) (element-type NMClient.ActiveConnection): a #GPtrArray + * Returns: (transfer none) (element-type NMActiveConnection): a #GPtrArray * containing all the active #NMActiveConnections. * The returned array is owned by the client and should not be modified. **/ -const GPtrArray * +const GPtrArray * nm_client_get_active_connections (NMClient *client) { NMClientPrivate *priv; @@ -1341,10 +1351,10 @@ updated_properties (GObject *object, GAsyncResult *result, gpointer user_data) static void proxy_name_owner_changed (DBusGProxy *proxy, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) { NMClient *client = NM_CLIENT (user_data); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); @@ -1385,7 +1395,7 @@ proxy_name_owner_changed (DBusGProxy *proxy, /* Clear object cache to ensure bad refcounting by clients doesn't * keep objects in the cache. */ - _nm_object_cache_clear (NM_OBJECT (client)); + _nm_object_cache_clear (); } else { _nm_object_suppress_property_updates (NM_OBJECT (client), FALSE); _nm_object_reload_properties_async (NM_OBJECT (client), updated_properties, client); @@ -1483,6 +1493,11 @@ check_connectivity_cb (DBusGProxy *proxy, CheckConnectivityData *ccd = g_simple_async_result_get_op_res_gpointer (simple); GError *error = NULL; + if (ccd->cancellable) { + g_signal_handler_disconnect (ccd->cancellable, ccd->cancelled_id); + ccd->cancelled_id = 0; + } + if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_UINT, &ccd->connectivity, G_TYPE_INVALID)) @@ -1701,50 +1716,6 @@ nm_client_new_finish (GAsyncResult *result, GError **error) return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); } -/* - * Validate D-Bus object path. - * The function is copied and adjusted version of - * g_variant_serialiser_is_object_path() from glib. - * FIXME: The function can be replaced by g_variant_is_object_path() - * when we start using GLib >= 2.24 - */ -static gboolean -_nm_client_is_object_path (const char *string) -{ - gsize i; - - if (!g_utf8_validate (string, -1, NULL)) - return FALSE; - - /* The path must begin with an ASCII '/' (integer 47) character */ - if (string[0] != '/') - return FALSE; - - for (i = 1; string[i]; i++) { - /* Each element must only contain the ASCII characters - * "[A-Z][a-z][0-9]_" - */ - if (g_ascii_isalnum (string[i]) || string[i] == '_') - ; - /* must consist of elements separated by slash characters. */ - else if (string[i] == '/') { - /* No element may be the empty string. */ - /* Multiple '/' characters cannot occur in sequence. */ - if (string[i - 1] == '/') - return FALSE; - } else - return FALSE; - } - - /* A trailing '/' character is not allowed unless the path is the - * root path (a single '/' character). - */ - if (i > 1 && string[i - 1] == '/') - return FALSE; - - return TRUE; -} - /* * constructor() shouldn't be overriden in most cases, rather constructed() * method is preferred and more useful. @@ -1782,9 +1753,9 @@ constructor (GType type, if (dbus_path == NULL) { g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH); } else { - if (!_nm_client_is_object_path (dbus_path)) { - g_warning ("Passsed D-Bus object path '%s' is invalid; using default '%s' instead", - dbus_path, NM_DBUS_PATH); + if (!g_variant_is_object_path (dbus_path)) { + g_warning ("Passed D-Bus object path '%s' is invalid; using default '%s' instead", + dbus_path, NM_DBUS_PATH); g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH); } } @@ -1968,8 +1939,8 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, static void init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { NMClientInitData *init_data; NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable); @@ -1985,10 +1956,10 @@ init_async (GAsyncInitable *initable, int io_priority, else { /* Check if NM is running */ dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", - init_async_got_manager_running, - init_data, NULL, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID); + init_async_got_manager_running, + init_data, NULL, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID); } } @@ -2043,7 +2014,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); gboolean b; @@ -2171,12 +2142,12 @@ nm_client_class_init (NMClientClass *client_class) * * The NetworkManager version. **/ - g_object_class_install_property (object_class, PROP_VERSION, - g_param_spec_string (NM_CLIENT_VERSION, - "Version", - "NetworkManager version", - NULL, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VERSION, + g_param_spec_string (NM_CLIENT_VERSION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:state: @@ -2185,11 +2156,10 @@ nm_client_class_init (NMClientClass *client_class) **/ g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_CLIENT_STATE, - "State", - "NetworkManager state", - NM_STATE_UNKNOWN, NM_STATE_CONNECTED_GLOBAL, NM_STATE_UNKNOWN, - G_PARAM_READABLE)); + g_param_spec_uint (NM_CLIENT_STATE, "", "", + NM_STATE_UNKNOWN, NM_STATE_CONNECTED_GLOBAL, NM_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:startup: @@ -2200,129 +2170,119 @@ nm_client_class_init (NMClientClass *client_class) **/ g_object_class_install_property (object_class, PROP_STARTUP, - g_param_spec_boolean (NM_CLIENT_STARTUP, - "Startup", - "Whether the daemon is still starting up", + g_param_spec_boolean (NM_CLIENT_STARTUP, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::manager-running: + * NMClient:manager-running: * * Whether the daemon is running. **/ g_object_class_install_property (object_class, PROP_MANAGER_RUNNING, - g_param_spec_boolean (NM_CLIENT_MANAGER_RUNNING, - "ManagerRunning", - "Whether NetworkManager is running", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_CLIENT_MANAGER_RUNNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::networking-enabled: + * NMClient:networking-enabled: * * Whether networking is enabled. **/ g_object_class_install_property (object_class, PROP_NETWORKING_ENABLED, - g_param_spec_boolean (NM_CLIENT_NETWORKING_ENABLED, - "NetworkingEnabled", - "Is networking enabled", - TRUE, - G_PARAM_READWRITE)); + g_param_spec_boolean (NM_CLIENT_NETWORKING_ENABLED, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wireless-enabled: + * NMClient:wireless-enabled: * * Whether wireless is enabled. **/ g_object_class_install_property (object_class, PROP_WIRELESS_ENABLED, - g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, - "WirelessEnabled", - "Is wireless enabled", - FALSE, - G_PARAM_READWRITE)); + g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wireless-hardware-enabled: + * NMClient:wireless-hardware-enabled: * * Whether the wireless hardware is enabled. **/ g_object_class_install_property (object_class, PROP_WIRELESS_HARDWARE_ENABLED, - g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, - "WirelessHardwareEnabled", - "Is wireless hardware enabled", - TRUE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, "", "", + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wwan-enabled: + * NMClient:wwan-enabled: * * Whether WWAN functionality is enabled. **/ g_object_class_install_property (object_class, PROP_WWAN_ENABLED, - g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED, - "WwanEnabled", - "Is WWAN enabled", + g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED, "", "", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wwan-hardware-enabled: + * NMClient:wwan-hardware-enabled: * * Whether the WWAN hardware is enabled. **/ g_object_class_install_property (object_class, PROP_WWAN_HARDWARE_ENABLED, - g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED, - "WwanHardwareEnabled", - "Is WWAN hardware enabled", + g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wimax-enabled: + * NMClient:wimax-enabled: * * Whether WiMAX functionality is enabled. **/ g_object_class_install_property (object_class, PROP_WIMAX_ENABLED, - g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, - "WimaxEnabled", - "Is WiMAX enabled", + g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, "", "", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::wimax-hardware-enabled: + * NMClient:wimax-hardware-enabled: * * Whether the WiMAX hardware is enabled. **/ g_object_class_install_property (object_class, PROP_WIMAX_HARDWARE_ENABLED, - g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, - "WimaxHardwareEnabled", - "Is WiMAX hardware enabled", + g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** - * NMClient::active-connections: + * NMClient:active-connections: * * The active connections. - * Type: GPtrArray + * Type: GLib.PtrArray **/ g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTIONS, - g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, - "Active connections", - "Active connections", - NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, "", "", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:connectivity: @@ -2333,11 +2293,10 @@ nm_client_class_init (NMClientClass *client_class) */ g_object_class_install_property (object_class, PROP_CONNECTIVITY, - g_param_spec_uint (NM_CLIENT_CONNECTIVITY, - "Connectivity", - "Connectivity state", + g_param_spec_uint (NM_CLIENT_CONNECTIVITY, "", "", NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:primary-connection: @@ -2349,11 +2308,10 @@ nm_client_class_init (NMClientClass *client_class) **/ g_object_class_install_property (object_class, PROP_PRIMARY_CONNECTION, - g_param_spec_object (NM_CLIENT_PRIMARY_CONNECTION, - "Primary connection", - "Primary connection", + g_param_spec_object (NM_CLIENT_PRIMARY_CONNECTION, "", "", NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:activating-connection: @@ -2365,11 +2323,10 @@ nm_client_class_init (NMClientClass *client_class) **/ g_object_class_install_property (object_class, PROP_ACTIVATING_CONNECTION, - g_param_spec_object (NM_CLIENT_ACTIVATING_CONNECTION, - "Activating connection", - "Activating connection", + g_param_spec_object (NM_CLIENT_ACTIVATING_CONNECTION, "", "", NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMClient:devices: @@ -2380,34 +2337,33 @@ nm_client_class_init (NMClientClass *client_class) **/ g_object_class_install_property (object_class, PROP_DEVICES, - g_param_spec_boxed (NM_CLIENT_DEVICES, - "Devices", - "Devices", + g_param_spec_boxed (NM_CLIENT_DEVICES, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ /** * NMClient::device-added: * @client: the client that received the signal - * @device: (type NMClient.Device): the new device + * @device: (type NMDevice): the new device * * Notifies that a #NMDevice is added. **/ signals[DEVICE_ADDED] = g_signal_new ("device-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMClientClass, device_added), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); /** * NMClient::device-removed: * @client: the client that received the signal - * @device: (type NMClient.Device): the removed device + * @device: (type NMDevice): the removed device * * Notifies that a #NMDevice is removed. **/ diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 1baabecc..ffe513cb 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ #ifndef NM_CLIENT_H diff --git a/libnm-glib/nm-dbus-helpers-private.h b/libnm-glib/nm-dbus-helpers-private.h index 81c77203..8a350e78 100644 --- a/libnm-glib/nm-dbus-helpers-private.h +++ b/libnm-glib/nm-dbus-helpers-private.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright 2013 Red Hat, Inc. */ #ifndef NM_DBUS_HELPERS_PRIVATE_H diff --git a/libnm-glib/nm-dbus-helpers.c b/libnm-glib/nm-dbus-helpers.c index 731ad0c8..00e04ab4 100644 --- a/libnm-glib/nm-dbus-helpers.c +++ b/libnm-glib/nm-dbus-helpers.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright 2013 Red Hat, Inc. */ +#include "config.h" + #include -#include #include #include #include @@ -70,13 +69,8 @@ _nm_dbus_new_connection (GError **error) } #endif - if (connection == NULL) { -#ifdef LIBNM_GLIB_TEST - connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); -#else + if (connection == NULL) connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, error); -#endif - } return connection; } @@ -104,4 +98,3 @@ _nm_dbus_new_proxy_for_connection (DBusGConnection *connection, return dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, interface); } - diff --git a/libnm-glib/nm-device-adsl.c b/libnm-glib/nm-device-adsl.c index b3f9691e..68121683 100644 --- a/libnm-glib/nm-device-adsl.c +++ b/libnm-glib/nm-device-adsl.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -21,6 +19,8 @@ * Copyright 2009 - 2011 Red Hat, Inc. */ +#include "config.h" + #include "nm-device-adsl.h" #include "nm-device-private.h" #include "nm-object-private.h" @@ -237,9 +237,8 @@ nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_ADSL_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_ADSL_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-device-adsl.h b/libnm-glib/nm-device-adsl.h index 702d16dc..35d2731a 100644 --- a/libnm-glib/nm-device-adsl.h +++ b/libnm-glib/nm-device-adsl.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Pantelis Koukousoulas + * Copyright 2011 Pantelis Koukousoulas */ #ifndef NM_DEVICE_ADSL_H diff --git a/libnm-glib/nm-device-bond.c b/libnm-glib/nm-device-bond.c index b2af2ec3..786d4f16 100644 --- a/libnm-glib/nm-device-bond.c +++ b/libnm-glib/nm-device-bond.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -91,9 +90,9 @@ nm_device_bond_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_BOND, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; } @@ -139,7 +138,7 @@ nm_device_bond_get_carrier (NMDeviceBond *device) * * Gets the devices currently slaved to @device. * - * Returns: (element-type NMClient.Device): the #GPtrArray containing + * Returns: (element-type NMDevice): the #GPtrArray containing * #NMDevices that are slaves of @device. This is the internal * copy used by the device, and must not be modified. * @@ -291,12 +290,12 @@ get_property (GObject *object, } static void -nm_device_bond_class_init (NMDeviceBondClass *eth_class) +nm_device_bond_class_init (NMDeviceBondClass *bond_class) { - GObjectClass *object_class = G_OBJECT_CLASS (eth_class); - NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + GObjectClass *object_class = G_OBJECT_CLASS (bond_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (bond_class); - g_type_class_add_private (eth_class, sizeof (NMDeviceBondPrivate)); + g_type_class_add_private (bond_class, sizeof (NMDeviceBondPrivate)); /* virtual methods */ object_class->constructed = constructed; @@ -316,11 +315,10 @@ nm_device_bond_class_init (NMDeviceBondClass *eth_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", + g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBond:carrier: @@ -329,11 +327,10 @@ nm_device_bond_class_init (NMDeviceBondClass *eth_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_BOND_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_BOND_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBond:slaves: @@ -344,9 +341,8 @@ nm_device_bond_class_init (NMDeviceBondClass *eth_class) **/ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-device-bond.h b/libnm-glib/nm-device-bond.h index a495689a..cd1a6027 100644 --- a/libnm-glib/nm-device-bond.h +++ b/libnm-glib/nm-device-bond.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_BOND_H diff --git a/libnm-glib/nm-device-bridge.c b/libnm-glib/nm-device-bridge.c index c8967e20..ef69fb26 100644 --- a/libnm-glib/nm-device-bridge.c +++ b/libnm-glib/nm-device-bridge.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -147,7 +146,7 @@ nm_device_bridge_get_carrier (NMDeviceBridge *device) * * Gets the devices currently slaved to @device. * - * Returns: (element-type NMClient.Device): the #GPtrArray containing + * Returns: (element-type NMDevice): the #GPtrArray containing * #NMDevices that are slaves of @device. This is the internal * copy used by the device, and must not be modified. * @@ -326,11 +325,10 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_BRIDGE_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", + g_param_spec_string (NM_DEVICE_BRIDGE_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBridge:carrier: @@ -341,11 +339,10 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_BRIDGE_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_BRIDGE_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBridge:slaves: @@ -356,9 +353,8 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) **/ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-device-bridge.h b/libnm-glib/nm-device-bridge.h index 67e08df7..2eaf475d 100644 --- a/libnm-glib/nm-device-bridge.h +++ b/libnm-glib/nm-device-bridge.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_BRIDGE_H diff --git a/libnm-glib/nm-device-bt.c b/libnm-glib/nm-device-bt.c index 4c39ad04..58d48344 100644 --- a/libnm-glib/nm-device-bt.c +++ b/libnm-glib/nm-device-bt.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -343,11 +342,10 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_BT_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", + g_param_spec_string (NM_DEVICE_BT_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBt:name: @@ -356,11 +354,10 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) **/ g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_DEVICE_BT_NAME, - "Name", - "Device name", + g_param_spec_string (NM_DEVICE_BT_NAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceBt:bt-capabilities: @@ -369,11 +366,9 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) **/ g_object_class_install_property (object_class, PROP_BT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, - "BtCapabilities", - "Bluetooth capabilities", + g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, "", "", NM_BT_CAPABILITY_NONE, G_MAXUINT32, NM_BT_CAPABILITY_NONE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-bt.h b/libnm-glib/nm-device-bt.h index 113b5eca..51dc86e3 100644 --- a/libnm-glib/nm-device-bt.h +++ b/libnm-glib/nm-device-bt.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2012 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_DEVICE_BT_H diff --git a/libnm-glib/nm-device-ethernet.c b/libnm-glib/nm-device-ethernet.c index 8f317115..d27a980f 100644 --- a/libnm-glib/nm-device-ethernet.c +++ b/libnm-glib/nm-device-ethernet.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -93,9 +92,9 @@ nm_device_ethernet_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_ETHERNET, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; } @@ -350,11 +349,10 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceEthernet:perm-hw-address: @@ -363,11 +361,10 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) **/ g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceEthernet:speed: @@ -376,11 +373,10 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) **/ g_object_class_install_property (object_class, PROP_SPEED, - g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, - "Speed", - "Speed", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceEthernet:carrier: @@ -389,11 +385,9 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER, - "Carrier", - "Carrier", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-ethernet.h b/libnm-glib/nm-device-ethernet.h index a68a97ec..be289cdf 100644 --- a/libnm-glib/nm-device-ethernet.h +++ b/libnm-glib/nm-device-ethernet.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_ETHERNET_H diff --git a/libnm-glib/nm-device-generic.c b/libnm-glib/nm-device-generic.c index 2a45294f..a17a6735 100644 --- a/libnm-glib/nm-device-generic.c +++ b/libnm-glib/nm-device-generic.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -20,7 +18,7 @@ * Copyright 2013 Red Hat, Inc. */ -#include +#include "config.h" #include @@ -266,11 +264,10 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, - "Hardware Address", - "Hardware address", + g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceGeneric:type-description: @@ -280,10 +277,8 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) **/ g_object_class_install_property (object_class, PROP_TYPE_DESCRIPTION, - g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, - "Type Description", - "Type description", + g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-generic.h b/libnm-glib/nm-device-generic.h index a343d988..5bff1e3f 100644 --- a/libnm-glib/nm-device-generic.h +++ b/libnm-glib/nm-device-generic.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 diff --git a/libnm-glib/nm-device-infiniband.c b/libnm-glib/nm-device-infiniband.c index b60b2d82..663b3651 100644 --- a/libnm-glib/nm-device-infiniband.c +++ b/libnm-glib/nm-device-infiniband.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include @@ -89,9 +88,9 @@ nm_device_infiniband_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; } @@ -268,12 +267,12 @@ get_property (GObject *object, } static void -nm_device_infiniband_class_init (NMDeviceInfinibandClass *eth_class) +nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class) { - GObjectClass *object_class = G_OBJECT_CLASS (eth_class); - NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + GObjectClass *object_class = G_OBJECT_CLASS (ib_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (ib_class); - g_type_class_add_private (eth_class, sizeof (NMDeviceInfinibandPrivate)); + g_type_class_add_private (ib_class, sizeof (NMDeviceInfinibandPrivate)); /* virtual methods */ object_class->constructed = constructed; @@ -293,11 +292,10 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *eth_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_INFINIBAND_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", + g_param_spec_string (NM_DEVICE_INFINIBAND_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceInfiniband:carrier: @@ -306,11 +304,9 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *eth_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_INFINIBAND_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_INFINIBAND_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-infiniband.h b/libnm-glib/nm-device-infiniband.h index 72d8fc6c..ba587d93 100644 --- a/libnm-glib/nm-device-infiniband.h +++ b/libnm-glib/nm-device-infiniband.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_INFINIBAND_H diff --git a/libnm-glib/nm-device-modem.c b/libnm-glib/nm-device-modem.c index b3b357cf..524d86ce 100644 --- a/libnm-glib/nm-device-modem.c +++ b/libnm-glib/nm-device-modem.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include "nm-glib-compat.h" @@ -36,9 +35,7 @@ G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) -#define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_DEVICE_MODEM, \ - NMDeviceModemPrivate)) +#define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MODEM, NMDeviceModemPrivate)) typedef struct { DBusGProxy *proxy; @@ -273,12 +270,12 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class) * a firmware reload or other reinitialization to switch between eg * CDMA/EVDO and GSM/UMTS. **/ - g_object_class_install_property (object_class, PROP_MODEM_CAPS, - g_param_spec_uint (NM_DEVICE_MODEM_MODEM_CAPABILITIES, - "Modem capabilities", - "Modem capabilities", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_MODEM_CAPS, + g_param_spec_uint (NM_DEVICE_MODEM_MODEM_CAPABILITIES, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceModem:current-capabilities: @@ -286,11 +283,10 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class) * The generic family of access technologies the modem currently supports * without a firmware reload or reinitialization. **/ - g_object_class_install_property (object_class, PROP_CURRENT_CAPS, - g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, - "Current capabilities", - "Current capabilities", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_CURRENT_CAPS, + g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-modem.h b/libnm-glib/nm-device-modem.h index 62719e2b..226cd046 100644 --- a/libnm-glib/nm-device-modem.h +++ b/libnm-glib/nm-device-modem.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_DEVICE_MODEM_H diff --git a/libnm-glib/nm-device-olpc-mesh.c b/libnm-glib/nm-device-olpc-mesh.c index d1789eb9..e68fda62 100644 --- a/libnm-glib/nm-device-olpc-mesh.c +++ b/libnm-glib/nm-device-olpc-mesh.c @@ -1,8 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ /* - * libnm-glib -- Access network status & information from glib applications - * * 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 @@ -18,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include "nm-glib-compat.h" @@ -90,9 +88,9 @@ nm_device_olpc_mesh_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_OLPC_MESH, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; @@ -297,11 +295,10 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_OLPC_MESH_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", + g_param_spec_string (NM_DEVICE_OLPC_MESH_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceOlpcMesh:companion: @@ -310,11 +307,10 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) **/ g_object_class_install_property (object_class, PROP_COMPANION, - g_param_spec_object (NM_DEVICE_OLPC_MESH_COMPANION, - "Companion device", - "Companion device", - NM_TYPE_DEVICE_WIFI, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_OLPC_MESH_COMPANION, "", "", + NM_TYPE_DEVICE_WIFI, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceOlpcMesh:active-channel: @@ -323,11 +319,9 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) **/ g_object_class_install_property (object_class, PROP_ACTIVE_CHANNEL, - g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, - "Active channel", - "Active channel", + g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-device-olpc-mesh.h b/libnm-glib/nm-device-olpc-mesh.h index 93cb2cde..fcef83bc 100644 --- a/libnm-glib/nm-device-olpc-mesh.h +++ b/libnm-glib/nm-device-olpc-mesh.h @@ -1,8 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ /* - * libnm-glib -- Access network status & information from glib applications - * * 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 @@ -18,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_OLPC_MESH_H diff --git a/libnm-glib/nm-device-private.h b/libnm-glib/nm-device-private.h index 5c674f2f..82d676f9 100644 --- a/libnm-glib/nm-device-private.h +++ b/libnm-glib/nm-device-private.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_PRIVATE_H diff --git a/libnm-glib/nm-device-team.c b/libnm-glib/nm-device-team.c index f739e1d8..d9a5fce0 100644 --- a/libnm-glib/nm-device-team.c +++ b/libnm-glib/nm-device-team.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,9 +14,12 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ -#include +#include "config.h" + #include #include @@ -93,9 +94,9 @@ nm_device_team_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_TEAM, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; } @@ -145,7 +146,7 @@ nm_device_team_get_carrier (NMDeviceTeam *device) * * Gets the devices currently enslaved to @device. * - * Returns: (element-type NMClient.Device): the #GPtrArray containing + * Returns: (element-type NMDevice): the #GPtrArray containing * #NMDevices that are slaves of @device. This is the internal * copy used by the device, and must not be modified. * @@ -297,12 +298,12 @@ get_property (GObject *object, } static void -nm_device_team_class_init (NMDeviceTeamClass *eth_class) +nm_device_team_class_init (NMDeviceTeamClass *team_class) { - GObjectClass *object_class = G_OBJECT_CLASS (eth_class); - NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + GObjectClass *object_class = G_OBJECT_CLASS (team_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (team_class); - g_type_class_add_private (eth_class, sizeof (NMDeviceTeamPrivate)); + g_type_class_add_private (team_class, sizeof (NMDeviceTeamPrivate)); /* virtual methods */ object_class->constructed = constructed; @@ -322,11 +323,10 @@ nm_device_team_class_init (NMDeviceTeamClass *eth_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_TEAM_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", + g_param_spec_string (NM_DEVICE_TEAM_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceTeam:carrier: @@ -335,11 +335,10 @@ nm_device_team_class_init (NMDeviceTeamClass *eth_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_TEAM_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_TEAM_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceTeam:slaves: @@ -348,9 +347,8 @@ nm_device_team_class_init (NMDeviceTeamClass *eth_class) **/ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-device-team.h b/libnm-glib/nm-device-team.h index 054f9ae2..46e910ba 100644 --- a/libnm-glib/nm-device-team.h +++ b/libnm-glib/nm-device-team.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,6 +14,8 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ #ifndef NM_DEVICE_TEAM_H diff --git a/libnm-glib/nm-device-vlan.c b/libnm-glib/nm-device-vlan.c index 2a84b946..26c234bd 100644 --- a/libnm-glib/nm-device-vlan.c +++ b/libnm-glib/nm-device-vlan.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -43,6 +42,7 @@ typedef struct { char *hw_address; gboolean carrier; + NMDevice *parent; guint vlan_id; } NMDeviceVlanPrivate; @@ -50,6 +50,7 @@ enum { PROP_0, PROP_HW_ADDRESS, PROP_CARRIER, + PROP_PARENT, PROP_VLAN_ID, LAST_PROP @@ -132,6 +133,23 @@ nm_device_vlan_get_carrier (NMDeviceVlan *device) return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier; } +/** + * nm_device_vlan_get_parent: + * @device: a #NMDeviceVlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.0 + **/ +NMDevice * +nm_device_vlan_get_parent (NMDeviceVlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent; +} + /** * nm_device_vlan_get_vlan_id: * @device: a #NMDeviceVlan @@ -232,6 +250,7 @@ register_properties (NMDeviceVlan *device) const NMPropertiesInfo property_info[] = { { NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address }, { NM_DEVICE_VLAN_CARRIER, &priv->carrier }, + { NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE }, { NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id }, { NULL }, }; @@ -257,6 +276,7 @@ dispose (GObject *object) { NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + g_clear_object (&priv->parent); g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object); @@ -289,6 +309,9 @@ get_property (GObject *object, case PROP_CARRIER: g_value_set_boolean (value, nm_device_vlan_get_carrier (device)); break; + case PROP_PARENT: + g_value_set_object (value, nm_device_vlan_get_parent (device)); + break; case PROP_VLAN_ID: g_value_set_uint (value, nm_device_vlan_get_vlan_id (device)); break; @@ -299,12 +322,12 @@ get_property (GObject *object, } static void -nm_device_vlan_class_init (NMDeviceVlanClass *eth_class) +nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class) { - GObjectClass *object_class = G_OBJECT_CLASS (eth_class); - NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + GObjectClass *object_class = G_OBJECT_CLASS (vlan_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (vlan_class); - g_type_class_add_private (eth_class, sizeof (NMDeviceVlanPrivate)); + g_type_class_add_private (vlan_class, sizeof (NMDeviceVlanPrivate)); /* virtual methods */ object_class->constructed = constructed; @@ -324,11 +347,10 @@ nm_device_vlan_class_init (NMDeviceVlanClass *eth_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", + g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceVlan:carrier: @@ -337,11 +359,24 @@ nm_device_vlan_class_init (NMDeviceVlanClass *eth_class) **/ g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVlan:parent: + * + * The devices's parent device. + * + * Since: 1.0 + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceVlan:vlan-id: @@ -350,9 +385,8 @@ nm_device_vlan_class_init (NMDeviceVlanClass *eth_class) **/ g_object_class_install_property (object_class, PROP_VLAN_ID, - g_param_spec_uint (NM_DEVICE_VLAN_VLAN_ID, - "VLAN ID", - "VLAN ID", + g_param_spec_uint (NM_DEVICE_VLAN_VLAN_ID, "", "", 0, 4095, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-device-vlan.h b/libnm-glib/nm-device-vlan.h index 96087109..107cfea8 100644 --- a/libnm-glib/nm-device-vlan.h +++ b/libnm-glib/nm-device-vlan.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 Red Hat, Inc. + * Copyright 2012 - 2014 Red Hat, Inc. */ #ifndef NM_DEVICE_VLAN_H @@ -57,6 +55,7 @@ GQuark nm_device_vlan_error_quark (void); #define NM_DEVICE_VLAN_HW_ADDRESS "hw-address" #define NM_DEVICE_VLAN_CARRIER "carrier" +#define NM_DEVICE_VLAN_PARENT "parent" #define NM_DEVICE_VLAN_VLAN_ID "vlan-id" typedef struct { @@ -81,6 +80,8 @@ GObject *nm_device_vlan_new (DBusGConnection *connection, const char *path); const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device); gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device); +NM_AVAILABLE_IN_1_0 +NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device); guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device); G_END_DECLS diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c index b9cc31d8..28609c79 100644 --- a/libnm-glib/nm-device-wifi.c +++ b/libnm-glib/nm-device-wifi.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -270,7 +269,7 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device) * * Gets all the scanned access points of the #NMDeviceWifi. * - * Returns: (element-type NMClient.AccessPoint): a #GPtrArray containing all the + * Returns: (element-type NMAccessPoint): a #GPtrArray containing all the * scanned #NMAccessPoints. * The returned array is owned by the client and should not be modified. **/ @@ -419,7 +418,7 @@ clean_up_aps (NMDeviceWifi *self, gboolean notify) **/ void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, - gboolean enabled) + gboolean enabled) { g_return_if_fail (NM_IS_DEVICE_WIFI (device)); @@ -723,11 +722,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS, - "Active MAC Address", - "Currently set hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:perm-hw-address: @@ -736,11 +734,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:mode: @@ -749,11 +746,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_DEVICE_WIFI_MODE, - "Mode", - "Mode", - NM_802_11_MODE_UNKNOWN, NM_802_11_MODE_AP, NM_802_11_MODE_INFRA, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", + NM_802_11_MODE_UNKNOWN, NM_802_11_MODE_AP, NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:bitrate: @@ -762,11 +758,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_BITRATE, - g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, - "Bit Rate", - "Bit Rate", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:active-access-point: @@ -775,11 +770,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_ACTIVE_ACCESS_POINT, - g_param_spec_object (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, - "Active Access Point", - "Active Access Point", - NM_TYPE_ACCESS_POINT, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", + NM_TYPE_ACCESS_POINT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:wireless-capabilities: @@ -788,11 +782,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_WIRELESS_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, - "Wireless Capabilities", - "Wireless Capabilities", + g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWifi:access-points: @@ -803,11 +796,10 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ g_object_class_install_property (object_class, PROP_ACCESS_POINTS, - g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, - "AccessPoints", - "Access Points", + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ @@ -820,13 +812,13 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ signals[ACCESS_POINT_ADDED] = g_signal_new ("access-point-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); /** * NMDeviceWifi::access-point-removed: @@ -837,11 +829,11 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) **/ signals[ACCESS_POINT_REMOVED] = g_signal_new ("access-point-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - G_TYPE_OBJECT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); } diff --git a/libnm-glib/nm-device-wifi.h b/libnm-glib/nm-device-wifi.h index f9b30d92..2bb432a7 100644 --- a/libnm-glib/nm-device-wifi.h +++ b/libnm-glib/nm-device-wifi.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ #ifndef NM_DEVICE_WIFI_H diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c index 0b052804..f0187fdc 100644 --- a/libnm-glib/nm-device-wimax.c +++ b/libnm-glib/nm-device-wimax.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,11 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2009 Novell, Inc. */ -#include +#include "config.h" + #include #include @@ -114,9 +113,9 @@ nm_device_wimax_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); device = g_object_new (NM_TYPE_DEVICE_WIMAX, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return device; } @@ -180,7 +179,7 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) * * Gets all the scanned NSPs of the #NMDeviceWimax. * - * Returns: (element-type NMClient.WimaxNsp): a #GPtrArray containing + * Returns: (element-type NMWimaxNsp): a #GPtrArray containing * all the scanned #NMWimaxNsps. * The returned array is owned by the client and should not be modified. **/ @@ -204,7 +203,7 @@ nm_device_wimax_get_nsps (NMDeviceWimax *wimax) **/ NMWimaxNsp * nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, - const char *path) + const char *path) { const GPtrArray *nsps; int i; @@ -618,11 +617,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIMAX_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", + g_param_spec_string (NM_DEVICE_WIMAX_HW_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:active-nsp: @@ -631,11 +629,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_ACTIVE_NSP, - g_param_spec_object (NM_DEVICE_WIMAX_ACTIVE_NSP, - "Active NSP", - "Active NSP", - NM_TYPE_WIMAX_NSP, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_WIMAX_ACTIVE_NSP, "", "", + NM_TYPE_WIMAX_NSP, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:center-frequency: @@ -646,11 +643,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_CENTER_FREQ, - g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, - "Center frequency", - "Center frequency", + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, "", "", 0, G_MAXUINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:rssi: @@ -662,11 +658,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_RSSI, - g_param_spec_int (NM_DEVICE_WIMAX_RSSI, - "RSSI", - "RSSI", + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:cinr: @@ -677,11 +672,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_CINR, - g_param_spec_int (NM_DEVICE_WIMAX_CINR, - "CINR", - "CINR", + g_param_spec_int (NM_DEVICE_WIMAX_CINR, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:tx-power: @@ -692,11 +686,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_TX_POWER, - g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, - "TX Power", - "TX Power", + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:bsid: @@ -706,11 +699,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_BSID, - g_param_spec_string (NM_DEVICE_WIMAX_BSID, - "BSID", - "BSID", + g_param_spec_string (NM_DEVICE_WIMAX_BSID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDeviceWimax:nsps: @@ -721,11 +713,10 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ g_object_class_install_property (object_class, PROP_NSPS, - g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, - "NSPs", - "Network Service Providers", + g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, "", "", NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ @@ -738,13 +729,13 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ 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); + 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); /** * NMDeviceWimax::nsp-removed: @@ -755,11 +746,11 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) **/ 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); + 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); } diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h index b2282d4f..1b889d95 100644 --- a/libnm-glib/nm-device-wimax.h +++ b/libnm-glib/nm-device-wimax.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2012 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2009 Novell, Inc. */ #ifndef NM_DEVICE_WIMAX_H @@ -79,12 +77,12 @@ typedef struct { GType nm_device_wimax_get_type (void); GObject *nm_device_wimax_new (DBusGConnection *connection, - const char *path); + const char *path); const char *nm_device_wimax_get_hw_address (NMDeviceWimax *wimax); NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax); NMWimaxNsp *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, - const char *path); + const char *path); const GPtrArray *nm_device_wimax_get_nsps (NMDeviceWimax *wimax); diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index b328ba3b..bd5d1637 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,13 +15,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ +#include "config.h" + #include -#include +#include #include #include "NetworkManager.h" @@ -346,9 +346,9 @@ constructed (GObject *object) register_properties (NM_DEVICE (object)); dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, - G_TYPE_INVALID); + G_TYPE_NONE, + G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, + G_TYPE_INVALID); dbus_g_proxy_add_signal (priv->proxy, "StateChanged", @@ -356,9 +356,9 @@ constructed (GObject *object) G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "StateChanged", - G_CALLBACK (device_state_changed), - NM_DEVICE (object), - NULL); + G_CALLBACK (device_state_changed), + NM_DEVICE (object), + NULL); } static void @@ -552,11 +552,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE, - g_param_spec_string (NM_DEVICE_INTERFACE, - "Interface", - "Interface name", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_INTERFACE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:ip-interface: @@ -566,11 +565,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_IP_INTERFACE, - g_param_spec_string (NM_DEVICE_IP_INTERFACE, - "IP Interface", - "IP Interface name", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_IP_INTERFACE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:device-type: @@ -579,11 +577,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_DEVICE_TYPE, - g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, - "Device Type", - "Numeric device type (ie Ethernet, Wi-Fi, etc)", - NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "", + NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:udi: * @@ -596,11 +593,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_UDI, - g_param_spec_string (NM_DEVICE_UDI, - "UDI", - "Unique Device Identifier", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_UDI, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:driver: @@ -609,11 +605,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_DEVICE_DRIVER, - "Driver", - "Driver", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_DRIVER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:driver-version: @@ -622,11 +617,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_DRIVER_VERSION, - g_param_spec_string (NM_DEVICE_DRIVER_VERSION, - "Driver Version", - "Driver Version", + g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:firmware-version: @@ -635,11 +629,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_FIRMWARE_VERSION, - g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, - "Firmware Version", - "Firmware Version", + g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:capabilities: @@ -648,11 +641,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_CAPABILITIES, - "Capabilities", - "Capabilities", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:managed: @@ -661,11 +653,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_MANAGED, - g_param_spec_boolean (NM_DEVICE_MANAGED, - "Managed", - "Managed", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:autoconnect: @@ -674,11 +665,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_AUTOCONNECT, - g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, - "Autoconnect", - "Autoconnect", + g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:firmware-missing: @@ -688,11 +678,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_FIRMWARE_MISSING, - g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, - "FirmwareMissing", - "Firmware missing", - FALSE, - G_PARAM_READABLE)); + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:ip4-config: @@ -701,11 +690,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_IP4_CONFIG, - g_param_spec_object (NM_DEVICE_IP4_CONFIG, - "IP4 Config", - "IP4 Config", - NM_TYPE_IP4_CONFIG, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_IP4_CONFIG, "", "", + NM_TYPE_IP4_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:dhcp4-config: @@ -714,11 +702,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_DHCP4_CONFIG, - g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", - NM_TYPE_DHCP4_CONFIG, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, "", "", + NM_TYPE_DHCP4_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:ip6-config: @@ -727,11 +714,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_IP6_CONFIG, - g_param_spec_object (NM_DEVICE_IP6_CONFIG, - "IP6 Config", - "IP6 Config", + g_param_spec_object (NM_DEVICE_IP6_CONFIG, "", "", NM_TYPE_IP6_CONFIG, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:dhcp6-config: @@ -740,11 +726,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_DHCP6_CONFIG, - g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", - NM_TYPE_DHCP6_CONFIG, - G_PARAM_READABLE)); + g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, "", "", + NM_TYPE_DHCP6_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:state: @@ -753,11 +738,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_DEVICE_STATE, - "State", - "State", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_STATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:state-reason: @@ -766,11 +750,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_STATE_REASON, - g_param_spec_boxed (NM_DEVICE_STATE_REASON, - "StateReason", - "StateReason", + g_param_spec_boxed (NM_DEVICE_STATE_REASON, "", "", DBUS_G_TYPE_UINT_STRUCT, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:active-connection: @@ -779,11 +762,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTION, - g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION, - "ActiveConnection", - "Active Connection", + g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION, "", "", NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:available-connections: @@ -794,11 +776,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_AVAILABLE_CONNECTIONS, - g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, - "AvailableConnections", - "Available Connections", - NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:vendor: @@ -807,11 +788,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_VENDOR, - g_param_spec_string (NM_DEVICE_VENDOR, - "Vendor", - "Vendor string", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_VENDOR, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:product: @@ -820,11 +800,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_PRODUCT, - g_param_spec_string (NM_DEVICE_PRODUCT, - "Product", - "Product string", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_PRODUCT, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:physical-port-id: @@ -836,11 +815,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_PHYSICAL_PORT_ID, - g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, - "Physical Port ID", - "Physical port ID", + g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMDevice:mtu: @@ -851,11 +829,10 @@ nm_device_class_init (NMDeviceClass *device_class) **/ g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_DEVICE_MTU, - "MTU", - "MTU", + g_param_spec_uint (NM_DEVICE_MTU, "", "", 0, G_MAXUINT32, 1500, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ @@ -870,12 +847,12 @@ nm_device_class_init (NMDeviceClass *device_class) **/ signals[STATE_CHANGED] = g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceClass, state_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 3, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 3, + G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); } /** @@ -1448,7 +1425,7 @@ nm_device_get_active_connection (NMDevice *device) * Gets the #NMRemoteConnections currently known to the daemon that could * be activated on @device. * - * Returns: (element-type NMClient.RemoteConnection): the #GPtrArray + * Returns: (element-type NMRemoteConnection): the #GPtrArray * containing #NMRemoteConnections. This is the internal copy used by * the connection, and must not be modified. * @@ -1782,8 +1759,7 @@ get_short_vendor (NMDevice *device) * nm_device_get_description: * @device: an #NMDevice * - * Gets a description of @device, incorporating the results of - * nm_device_get_short_vendor() and nm_device_get_short_product(). + * Gets a description of @device, based on its vendor and product names. * * Returns: a description of @device. If either the vendor or the * product name is unknown, this returns the interface name. @@ -2090,18 +2066,38 @@ nm_device_get_mtu (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->mtu; } +/** + * nm_device_is_software: + * @device: a #NMDevice + * + * Whether the device is a software device. + * + * Returns: %TRUE if @device is a software device, %FALSE if it is a hardware device. + * + * Since: 1.0 + **/ +gboolean +nm_device_is_software (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + _nm_object_ensure_inited (NM_OBJECT (device)); + return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); +} + typedef struct { NMDevice *device; - NMDeviceDeactivateFn fn; + NMDeviceCallbackFn fn; gpointer user_data; -} DeactivateInfo; + const char *method; +} DeviceCallbackInfo; static void -deactivate_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) +device_operation_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) { - DeactivateInfo *info = user_data; + DeviceCallbackInfo *info = user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, @@ -2109,16 +2105,17 @@ deactivate_cb (DBusGProxy *proxy, if (info->fn) info->fn (info->device, error, info->user_data); else if (error) { - g_warning ("%s: device %s deactivation failed: (%d) %s", + g_warning ("%s: device %s %s failed: (%d) %s", __func__, nm_object_get_path (NM_OBJECT (info->device)), + info->method, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } g_clear_error (&error); g_object_unref (info->device); - g_slice_free (DeactivateInfo, info); + g_slice_free (DeviceCallbackInfo, info); } /** @@ -2134,20 +2131,52 @@ deactivate_cb (DBusGProxy *proxy, **/ void nm_device_disconnect (NMDevice *device, - NMDeviceDeactivateFn callback, + NMDeviceCallbackFn callback, gpointer user_data) { - DeactivateInfo *info; + DeviceCallbackInfo *info; g_return_if_fail (NM_IS_DEVICE (device)); - info = g_slice_new (DeactivateInfo); + info = g_slice_new (DeviceCallbackInfo); info->fn = callback; info->user_data = user_data; + info->method = "Disconnect"; info->device = g_object_ref (device); dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Disconnect", - deactivate_cb, info, NULL, + device_operation_cb, info, NULL, + G_TYPE_INVALID); +} + +/** + * nm_device_delete: + * @device: a #NMDevice + * @callback: (scope async) (allow-none): callback to be called when delete + * operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Deletes the software device. Hardware devices can't be deleted. + * + * Since: 1.0 + **/ +void +nm_device_delete (NMDevice *device, + NMDeviceCallbackFn callback, + gpointer user_data) +{ + DeviceCallbackInfo *info; + + g_return_if_fail (NM_IS_DEVICE (device)); + + info = g_slice_new (DeviceCallbackInfo); + info->fn = callback; + info->user_data = user_data; + info->method = "Delete"; + info->device = g_object_ref (device); + + dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Delete", + device_operation_cb, info, NULL, G_TYPE_INVALID); } @@ -2186,7 +2215,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro device_iface = nm_device_get_iface (device); if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INTERFACE_MISMATCH, - "The interface names of the device and the connection didn't match."); + "The interface names of the device and the connection didn't match."); return FALSE; } @@ -2227,7 +2256,7 @@ nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GEr /** * nm_device_filter_connections: * @device: an #NMDevice to filter connections for - * @connections: (element-type NetworkManager.Connection): a list of #NMConnection objects to filter + * @connections: (element-type NMConnection): a list of #NMConnection objects to filter * * Filters a given list of connections for a given #NMDevice object and return * connections which may be activated with the device. For example if @device @@ -2238,7 +2267,7 @@ nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GEr * incompatible with the device. To get the full list of connections see * nm_remote_settings_list_connections(). * - * Returns: (transfer container) (element-type NetworkManager.Connection): a + * Returns: (transfer container) (element-type NMConnection): a * list of #NMConnection objects that could be activated with the given @device. * The elements of the list are owned by their creator and should not be freed * by the caller, but the returned list itself is owned by the caller and should diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h index ed0f6876..707fddf8 100644 --- a/libnm-glib/nm-device.h +++ b/libnm-glib/nm-device.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. */ #ifndef NM_DEVICE_H @@ -144,6 +142,8 @@ NM_AVAILABLE_IN_0_9_10 const char * nm_device_get_physical_port_id (NMDevice *device); NM_AVAILABLE_IN_0_9_10 guint32 nm_device_get_mtu (NMDevice *device); +NM_AVAILABLE_IN_1_0 +gboolean nm_device_is_software (NMDevice *device); const char * nm_device_get_product (NMDevice *device); const char * nm_device_get_vendor (NMDevice *device); @@ -153,10 +153,15 @@ NM_AVAILABLE_IN_0_9_10 char ** nm_device_disambiguate_names (NMDevice **devices, int num_devices); -typedef void (*NMDeviceDeactivateFn) (NMDevice *device, GError *error, gpointer user_data); +typedef void (*NMDeviceCallbackFn) (NMDevice *device, GError *error, gpointer user_data); void nm_device_disconnect (NMDevice *device, - NMDeviceDeactivateFn callback, + NMDeviceCallbackFn callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_0 +void nm_device_delete (NMDevice *device, + NMDeviceCallbackFn callback, gpointer user_data); GSList * nm_device_filter_connections (NMDevice *device, @@ -172,6 +177,10 @@ gboolean nm_device_connection_compatible (NMDevice *device, NM_AVAILABLE_IN_0_9_10 GType nm_device_get_setting_type (NMDevice *device); +/* Deprecated */ +NM_DEPRECATED_IN_1_0 +typedef void (*NMDeviceDeactivateFn) (NMDevice *device, GError *error, gpointer user_data); + G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/libnm-glib/nm-dhcp4-config.c b/libnm-glib/nm-dhcp4-config.c index a861d982..58479374 100644 --- a/libnm-glib/nm-dhcp4-config.c +++ b/libnm-glib/nm-dhcp4-config.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2011 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ +#include "config.h" + #include #include "nm-dhcp4-config.h" @@ -156,11 +156,10 @@ nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_OPTIONS, - g_param_spec_boxed (NM_DHCP4_CONFIG_OPTIONS, - "Options", - "Options", - G_TYPE_HASH_TABLE, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_DHCP4_CONFIG_OPTIONS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } /** @@ -176,9 +175,9 @@ GObject * nm_dhcp4_config_new (DBusGConnection *connection, const char *object_path) { return (GObject *) g_object_new (NM_TYPE_DHCP4_CONFIG, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, object_path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, object_path, + NULL); } /** @@ -216,4 +215,3 @@ nm_dhcp4_config_get_one_option (NMDHCP4Config *config, const char *option) return g_hash_table_lookup (nm_dhcp4_config_get_options (config), option); } - diff --git a/libnm-glib/nm-dhcp4-config.h b/libnm-glib/nm-dhcp4-config.h index 9ca1a769..c64e9a9c 100644 --- a/libnm-glib/nm-dhcp4-config.h +++ b/libnm-glib/nm-dhcp4-config.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_DHCP4_CONFIG_H diff --git a/libnm-glib/nm-dhcp6-config.c b/libnm-glib/nm-dhcp6-config.c index ef6006b0..e55c1416 100644 --- a/libnm-glib/nm-dhcp6-config.c +++ b/libnm-glib/nm-dhcp6-config.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2011 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ +#include "config.h" + #include #include "nm-dhcp6-config.h" @@ -156,11 +156,10 @@ nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_OPTIONS, - g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS, - "Options", - "Options", - G_TYPE_HASH_TABLE, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } /** @@ -176,9 +175,9 @@ GObject * nm_dhcp6_config_new (DBusGConnection *connection, const char *object_path) { return (GObject *) g_object_new (NM_TYPE_DHCP6_CONFIG, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, object_path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, object_path, + NULL); } /** @@ -216,4 +215,3 @@ nm_dhcp6_config_get_one_option (NMDHCP6Config *config, const char *option) return g_hash_table_lookup (nm_dhcp6_config_get_options (config), option); } - diff --git a/libnm-glib/nm-dhcp6-config.h b/libnm-glib/nm-dhcp6-config.h index 44002940..939b3fdb 100644 --- a/libnm-glib/nm-dhcp6-config.h +++ b/libnm-glib/nm-dhcp6-config.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2010 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_DHCP6_CONFIG_H diff --git a/libnm-glib/nm-ip4-config.c b/libnm-glib/nm-ip4-config.c index ec523a03..ffaef741 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2011 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2007 - 2011 Novell, Inc. + * Copyright 2008 Red Hat, Inc. */ +#include "config.h" + #include #include @@ -240,11 +240,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_GATEWAY, - g_param_spec_string (NM_IP4_CONFIG_GATEWAY, - "Gateway", - "Gateway", + g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:addresses: @@ -253,10 +252,9 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_ADDRESSES, - g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES, - "Addresses", - "Addresses", - G_PARAM_READABLE)); + g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES, "", "", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:routes: @@ -265,10 +263,9 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_ROUTES, - g_param_spec_pointer (NM_IP4_CONFIG_ROUTES, - "Routes", - "Routes", - G_PARAM_READABLE)); + g_param_spec_pointer (NM_IP4_CONFIG_ROUTES, "", "", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:nameservers: @@ -277,11 +274,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_NAMESERVERS, - g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, - "Nameservers", - "Nameservers", + g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, "", "", NM_TYPE_UINT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:domains: @@ -290,11 +286,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_DOMAINS, - g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, - "Domains", - "Domains", + g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, "", "", NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:searches: @@ -305,11 +300,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_SEARCHES, - g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, - "Searches", - "DNS searches", + g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, "", "", NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP4Config:wins-servers: @@ -318,11 +312,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_WINS_SERVERS, - g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, - "WINS Servers", - "WINS Servers", + g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, "", "", NM_TYPE_UINT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } /** @@ -368,7 +361,7 @@ nm_ip4_config_get_gateway (NMIP4Config *config) * * Gets the IP4 addresses (containing the address, prefix, and gateway). * - * Returns: (element-type NetworkManager.IP4Address): the #GSList containing #NMIP4Addresses. + * Returns: (element-type NMIP4Address): the #GSList containing #NMIP4Addresses. * This is the internal copy used by the configuration and must not be modified. **/ const GSList * @@ -405,7 +398,7 @@ nm_ip4_config_get_nameservers (NMIP4Config *config) * * Gets the domain names. * - * Returns: (element-type utf8): the #GPtrArray containing domains as strings. This is the + * Returns: (element-type utf8): the #GPtrArray containing domains as strings. This is the * internal copy used by the configuration, and must not be modified. **/ const GPtrArray * @@ -462,7 +455,7 @@ nm_ip4_config_get_wins_servers (NMIP4Config *config) * * Gets the routes. * - * Returns: (element-type NetworkManager.IP4Route): the #GSList containing + * Returns: (element-type NMIP4Route): the #GSList containing * #NMIP4Routes. This is the internal copy used by the configuration, * and must not be modified. **/ @@ -474,4 +467,3 @@ nm_ip4_config_get_routes (NMIP4Config *config) _nm_object_ensure_inited (NM_OBJECT (config)); return NM_IP4_CONFIG_GET_PRIVATE (config)->routes; } - diff --git a/libnm-glib/nm-ip4-config.h b/libnm-glib/nm-ip4-config.h index aa2e66eb..58b6b371 100644 --- a/libnm-glib/nm-ip4-config.h +++ b/libnm-glib/nm-ip4-config.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 Red Hat, Inc. */ #ifndef NM_IP4_CONFIG_H diff --git a/libnm-glib/nm-ip6-config.c b/libnm-glib/nm-ip6-config.c index 7c9cfca7..d44056a1 100644 --- a/libnm-glib/nm-ip6-config.c +++ b/libnm-glib/nm-ip6-config.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include @@ -70,9 +70,9 @@ GObject * nm_ip6_config_new (DBusGConnection *connection, const char *object_path) { return (GObject *) g_object_new (NM_TYPE_IP6_CONFIG, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, object_path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, object_path, + NULL); } static gboolean @@ -179,7 +179,7 @@ nm_ip6_config_get_gateway (NMIP6Config *config) * * Gets the IP6 addresses (containing the address, prefix, and gateway). * - * Returns: (element-type NetworkManager.IP6Address): the #GSList containing + * Returns: (element-type NMIP6Address): the #GSList containing * #NMIP6Addresses. This is the internal copy used by the configuration * and must not be modified. **/ @@ -306,7 +306,7 @@ nm_ip6_config_get_searches (NMIP6Config *config) * * Gets the routes. * - * Returns: (element-type NetworkManager.IP6Route): the #GSList containing + * Returns: (element-type NMIP6Route): the #GSList containing * #NMIP6Routes. This is the internal copy used by the configuration, * and must not be modified. **/ @@ -420,11 +420,10 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_GATEWAY, - g_param_spec_string (NM_IP6_CONFIG_GATEWAY, - "Gateway", - "Gateway", + g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP6Config:addresses: @@ -435,11 +434,10 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_ADDRESSES, - g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, - "Addresses", - "Addresses", + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, "", "", NM_TYPE_IP6_ADDRESS_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP6Config:routes: @@ -450,11 +448,10 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_ROUTES, - g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, - "Routes", - "Routes", + g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, "", "", NM_TYPE_IP6_ROUTE_OBJECT_ARRAY, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP6Config:nameservers: @@ -464,11 +461,10 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_NAMESERVERS, - g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, - "Nameservers", - "Nameservers", - NM_TYPE_IP6_ADDRESS_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, "", "", + NM_TYPE_IP6_ADDRESS_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP6Config:domains: @@ -477,11 +473,10 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_DOMAINS, - g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, - "Domains", - "Domains", - NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMIP6Config:searches: @@ -492,11 +487,9 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) **/ g_object_class_install_property (object_class, PROP_SEARCHES, - g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, - "Searches", - "DNS Searches", - NM_TYPE_STRING_ARRAY, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-glib/nm-ip6-config.h b/libnm-glib/nm-ip6-config.h index feef69f1..7a64805b 100644 --- a/libnm-glib/nm-ip6-config.h +++ b/libnm-glib/nm-ip6-config.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2008 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. */ #ifndef NM_IP6_CONFIG_H diff --git a/libnm-glib/nm-object-cache.c b/libnm-glib/nm-object-cache.c index 2748b1df..752c606a 100644 --- a/libnm-glib/nm-object-cache.c +++ b/libnm-glib/nm-object-cache.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,9 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2008 Red Hat, Inc. */ +#include "config.h" + #include #include #include "nm-object-cache.h" @@ -65,27 +65,26 @@ _nm_object_cache_get (const char *path) } void -_nm_object_cache_clear (NMObject *except) +_nm_object_cache_clear (void) { GHashTableIter iter; - NMObject *obj; + GObject *obj; const char *path; char *foo; - _init_cache (); + if (!cache) + return; + g_hash_table_iter_init (&iter, cache); while (g_hash_table_iter_next (&iter, (gpointer) &path, (gpointer) &obj)) { - if (obj != except) { - /* Remove the callback so that if the object isn't yet released - * by a client, when it does finally get unrefed, it won't trigger - * the cache removal for a new object with the same path as the - * one being released. - */ - foo = g_object_steal_data (G_OBJECT (obj), "nm-object-cache-tag"); - g_free (foo); + /* Remove the callback so that if the object isn't yet released + * by a client, when it does finally get unrefed, it won't trigger + * the cache removal for a new object with the same path as the + * one being released. + */ + foo = g_object_steal_data (obj, "nm-object-cache-tag"); + g_free (foo); - g_hash_table_iter_remove (&iter); - } + g_hash_table_iter_remove (&iter); } } - diff --git a/libnm-glib/nm-object-cache.h b/libnm-glib/nm-object-cache.h index 84752134..7aca3b4f 100644 --- a/libnm-glib/nm-object-cache.h +++ b/libnm-glib/nm-object-cache.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2008 Red Hat, Inc. */ #ifndef NM_OBJECT_CACHE_H @@ -32,7 +30,7 @@ G_BEGIN_DECLS /* Returns referenced object from the cache */ NMObject *_nm_object_cache_get (const char *path); void _nm_object_cache_add (NMObject *object); -void _nm_object_cache_clear (NMObject *except); +void _nm_object_cache_clear (void); G_END_DECLS diff --git a/libnm-glib/nm-object-private.h b/libnm-glib/nm-object-private.h index 3253c2ec..75e63b2e 100644 --- a/libnm-glib/nm-object-private.h +++ b/libnm-glib/nm-object-private.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2011 Red Hat, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. */ #ifndef NM_OBJECT_PRIVATE_H @@ -47,8 +45,8 @@ DBusGProxy *_nm_object_new_proxy (NMObject *self, gboolean _nm_object_is_connection_private (NMObject *self); void _nm_object_register_properties (NMObject *object, - DBusGProxy *proxy, - const NMPropertiesInfo *info); + DBusGProxy *proxy, + const NMPropertiesInfo *info); gboolean _nm_object_reload_properties (NMObject *object, GError **error); diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index 61282cfb..fb25c1ac 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -41,15 +41,17 @@ static gboolean debug = FALSE; static void nm_object_initable_iface_init (GInitableIface *iface); static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface); +static GHashTable *type_funcs, *type_async_funcs; + G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT, + type_funcs = g_hash_table_new (NULL, NULL); + type_async_funcs = g_hash_table_new (NULL, NULL); G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init); G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init); ) #define NM_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OBJECT, NMObjectPrivate)) -static GHashTable *type_funcs, *type_async_funcs; - typedef struct { PropertyMarshalFunc func; GType object_type; @@ -82,8 +84,8 @@ typedef struct { enum { PROP_0, - PROP_CONNECTION, - PROP_PATH, + PROP_DBUS_CONNECTION, + PROP_DBUS_PATH, LAST_PROP }; @@ -159,8 +161,6 @@ constructor (GType type, return NULL; } - _nm_object_cache_add (NM_OBJECT (object)); - return object; } @@ -336,18 +336,18 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); switch (prop_id) { - case PROP_CONNECTION: + case PROP_DBUS_CONNECTION: /* Construct only */ priv->connection = g_value_dup_boxed (value); if (!priv->connection) priv->connection = _nm_dbus_new_connection (NULL); break; - case PROP_PATH: + case PROP_DBUS_PATH: /* Construct only */ priv->path = g_value_dup_string (value); break; @@ -359,15 +359,15 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); switch (prop_id) { - case PROP_CONNECTION: + case PROP_DBUS_CONNECTION: g_value_set_boxed (value, priv->connection); break; - case PROP_PATH: + case PROP_DBUS_PATH: g_value_set_string (value, priv->path); break; default: @@ -383,11 +383,6 @@ nm_object_class_init (NMObjectClass *nm_object_class) g_type_class_add_private (nm_object_class, sizeof (NMObjectPrivate)); - if (!type_funcs) { - type_funcs = g_hash_table_new (NULL, NULL); - type_async_funcs = g_hash_table_new (NULL, NULL); - } - /* virtual methods */ object_class->constructor = constructor; object_class->constructed = constructed; @@ -396,7 +391,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) object_class->dispose = dispose; object_class->finalize = finalize; - /* porperties */ + /* Properties */ /** * NMObject:connection: @@ -404,12 +399,12 @@ nm_object_class_init (NMObjectClass *nm_object_class) * The #DBusGConnection of the object. **/ g_object_class_install_property - (object_class, PROP_CONNECTION, - g_param_spec_boxed (NM_OBJECT_DBUS_CONNECTION, - "Connection", - "Connection", - DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + (object_class, PROP_DBUS_CONNECTION, + g_param_spec_boxed (NM_OBJECT_DBUS_CONNECTION, "", "", + DBUS_TYPE_G_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /** * NMObject:path: @@ -417,12 +412,12 @@ nm_object_class_init (NMObjectClass *nm_object_class) * The DBus object path. **/ g_object_class_install_property - (object_class, PROP_PATH, - g_param_spec_string (NM_OBJECT_DBUS_PATH, - "Object Path", - "DBus Object Path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + (object_class, PROP_DBUS_PATH, + g_param_spec_string (NM_OBJECT_DBUS_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* signals */ @@ -578,6 +573,8 @@ _nm_object_create (GType type, DBusGConnection *connection, const char *path) NM_OBJECT_DBUS_CONNECTION, connection, NM_OBJECT_DBUS_PATH, path, NULL); + if (NM_IS_OBJECT (object)) + _nm_object_cache_add (NM_OBJECT (object)); if (!g_initable_init (G_INITABLE (object), NULL, &error)) { dbgmsg ("Could not create object for %s: %s", path, error->message); g_error_free (error); @@ -661,6 +658,8 @@ async_got_type (GType type, gpointer user_data) NM_OBJECT_DBUS_PATH, async_data->path, NULL); g_warn_if_fail (object != NULL); + if (NM_IS_OBJECT (object)) + _nm_object_cache_add (NM_OBJECT (object)); g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT, NULL, async_inited, async_data); } @@ -1189,10 +1188,10 @@ _nm_object_register_properties (NMObject *object, dbus_g_proxy_add_signal (proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (proxy, - "PropertiesChanged", - G_CALLBACK (properties_changed_proxy), - object, - NULL); + "PropertiesChanged", + G_CALLBACK (properties_changed_proxy), + object, + NULL); instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->property_tables = g_slist_prepend (priv->property_tables, instance); @@ -1446,4 +1445,3 @@ _nm_object_is_connection_private (NMObject *self) { return _nm_dbus_is_connection_private (NM_OBJECT_GET_PRIVATE (self)->connection); } - diff --git a/libnm-glib/nm-object.h b/libnm-glib/nm-object.h index ae97184f..07348f24 100644 --- a/libnm-glib/nm-object.h +++ b/libnm-glib/nm-object.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ #ifndef NM_OBJECT_H diff --git a/libnm-glib/nm-remote-connection-private.h b/libnm-glib/nm-remote-connection-private.h index 3df57606..e3f35428 100644 --- a/libnm-glib/nm-remote-connection-private.h +++ b/libnm-glib/nm-remote-connection-private.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright 2009 Red Hat, Inc. */ #ifndef __NM_REMOTE_CONNECTION_PRIVATE_H__ @@ -33,4 +31,3 @@ typedef enum { } NMRemoteConnectionInitResult; #endif /* __NM_REMOTE_CONNECTION_PRIVATE__ */ - diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 38911a43..3a70e81e 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,13 +15,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include -#include +#include #include #include @@ -70,13 +70,13 @@ typedef struct RemoteCall RemoteCall; typedef void (*RemoteCallFetchResultCb) (RemoteCall *call, DBusGProxyCall *proxy_call, GError *error); -typedef struct RemoteCall { +struct RemoteCall { NMRemoteConnection *self; DBusGProxyCall *call; RemoteCallFetchResultCb fetch_result_cb; GFunc callback; gpointer user_data; -} RemoteCall; +}; typedef struct { DBusGConnection *bus; @@ -125,7 +125,7 @@ _nm_remote_connection_ensure_inited (NMRemoteConnection *self) */ if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) { g_warning ("%s: (NMRemoteConnection) error initializing: %s\n", - __func__, error->message); + __func__, error->message); } g_error_free (error); } @@ -712,8 +712,8 @@ init_get_settings_cb (DBusGProxy *proxy, static void init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteConnectionInitData *init_data; NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); @@ -864,29 +864,34 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) object_class->constructed = constructed; /* Properties */ + /** + * NMRemoteConnection:bus: + * + * The #DBusGConnection that the #NMRemoteConnection is connected to. + */ g_object_class_install_property (object_class, PROP_BUS, - g_param_spec_boxed (NM_REMOTE_CONNECTION_BUS, - "DBusGConnection", - "DBusGConnection", - DBUS_TYPE_G_CONNECTION, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_boxed (NM_REMOTE_CONNECTION_BUS, "", "", + DBUS_TYPE_G_CONNECTION, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* These are needed so _nm_object_create() can create NMRemoteConnections */ g_object_class_install_property (object_class, PROP_DBUS_CONNECTION, - g_param_spec_boxed (NM_REMOTE_CONNECTION_DBUS_CONNECTION, - "DBusGConnection", - "DBusGConnection", + g_param_spec_boxed (NM_REMOTE_CONNECTION_DBUS_CONNECTION, "", "", DBUS_TYPE_G_CONNECTION, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DBUS_PATH, - g_param_spec_string (NM_REMOTE_CONNECTION_DBUS_PATH, - "Object Path", - "DBus Object Path", + g_param_spec_string (NM_REMOTE_CONNECTION_DBUS_PATH, "", "", NULL, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /** * NMRemoteConnection:unsaved: @@ -896,12 +901,12 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) * * Since: 0.9.10 **/ - g_object_class_install_property (object_class, PROP_UNSAVED, - g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, - "Unsaved", - "Unsaved", + g_object_class_install_property + (object_class, PROP_UNSAVED, + g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ /** @@ -911,7 +916,7 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) * This signal is emitted when a connection changes, and it is * still visible to the user. */ - signals[UPDATED] = + signals[UPDATED] = g_signal_new (NM_REMOTE_CONNECTION_UPDATED, G_TYPE_FROM_CLASS (remote_class), G_SIGNAL_RUN_FIRST, @@ -927,12 +932,12 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) * This signal is emitted when a connection is either deleted or becomes * invisible to the current user. */ - signals[REMOVED] = + signals[REMOVED] = g_signal_new (NM_REMOTE_CONNECTION_REMOVED, G_TYPE_FROM_CLASS (remote_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMRemoteConnectionClass, removed), - NULL, NULL, + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index 911885c4..8292c235 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ #ifndef __NM_REMOTE_CONNECTION_H__ @@ -149,4 +147,3 @@ gboolean nm_remote_connection_get_unsaved (NMRemoteConnection *connection); G_END_DECLS #endif /* __NM_REMOTE_CONNECTION__ */ - diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 3a2a3e68..74ed083f 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2009 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + * Copyright 2009 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -143,7 +143,7 @@ typedef struct { /* AddConnectionInfo objects that are waiting for the connection to become initialized */ GSList *add_list; - + DBusGProxy *props_proxy; char *hostname; gboolean can_modify; @@ -206,7 +206,7 @@ _nm_remote_settings_ensure_inited (NMRemoteSettings *self) */ if (!g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) { g_warning ("%s: (NMRemoteSettings) error initializing: %s\n", - __func__, error->message); + __func__, error->message); } g_error_free (error); } @@ -559,7 +559,7 @@ fetch_connections_done (DBusGProxy *proxy, g_warn_if_fail (priv->listcon_call == call); priv->listcon_call = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, + if (!dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &connections, G_TYPE_INVALID)) { if ( !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) @@ -567,8 +567,8 @@ fetch_connections_done (DBusGProxy *proxy, && priv->service_running) { g_warning ("%s: error fetching connections: (%d) %s.", __func__, - error->code, - error->message ? error->message : "(unknown)"); + error->code, + error->message ? error->message : "(unknown)"); } g_clear_error (&error); @@ -597,7 +597,7 @@ fetch_connections_done (DBusGProxy *proxy, * nm_remote_settings_list_connections: * @settings: the %NMRemoteSettings * - * Returns: (transfer container) (element-type NMClient.RemoteConnection): a + * Returns: (transfer container) (element-type NMRemoteConnection): a * list containing all connections provided by the remote settings service. * Each element of the returned list is a %NMRemoteConnection instance, which is * owned by the %NMRemoteSettings object and should not be freed by the caller. @@ -939,7 +939,7 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (hostname != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); - + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); _nm_remote_settings_ensure_inited (settings); @@ -1354,8 +1354,8 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, static void init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteSettingsInitData *init_data; NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (initable); @@ -1365,9 +1365,10 @@ init_async (GAsyncInitable *initable, int io_priority, init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); - if (priv->private_bus) + if (priv->private_bus) { + priv->service_running = TRUE; init_get_properties (init_data); - else { + } else { /* Check if NM is running */ dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner", init_async_got_manager_running, @@ -1484,54 +1485,74 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) object_class->dispose = dispose; /* Properties */ + + /** + * NMRemoteSettings:bus: + * + * The #DBusGConnection that the #NMRemoteSettings is connected to. Defaults + * to the system bus if not specified. + */ g_object_class_install_property (object_class, PROP_BUS, - g_param_spec_boxed (NM_REMOTE_SETTINGS_BUS, - "DBusGConnection", - "DBusGConnection", + g_param_spec_boxed (NM_REMOTE_SETTINGS_BUS, "", "", DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMRemoteSettings:service-running: + * + * Whether the settings service is running. + */ g_object_class_install_property (object_class, PROP_SERVICE_RUNNING, - g_param_spec_boolean (NM_REMOTE_SETTINGS_SERVICE_RUNNING, - "Service running", - "Is service running", + g_param_spec_boolean (NM_REMOTE_SETTINGS_SERVICE_RUNNING, "", "", FALSE, - G_PARAM_READABLE)); - + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMRemoteSettings:hostname: + * + * The machine hostname stored in persistent configuration. This can be + * modified by calling nm_remote_settings_save_hostname(). + */ g_object_class_install_property (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, - "Hostname", - "Persistent hostname", + g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * NMRemoteSettings:can-modify: + * + * If %TRUE, adding and modifying connections is supported. + */ g_object_class_install_property (object_class, PROP_CAN_MODIFY, - g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, - "CanModify", - "Can modify anything (hostname, connections, etc)", + g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ - signals[NEW_CONNECTION] = - g_signal_new (NM_REMOTE_SETTINGS_NEW_CONNECTION, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMRemoteSettingsClass, new_connection), - NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONNECTIONS_READ] = - g_signal_new (NM_REMOTE_SETTINGS_CONNECTIONS_READ, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMRemoteSettingsClass, connections_read), - NULL, NULL, NULL, - G_TYPE_NONE, 0); + signals[NEW_CONNECTION] = + g_signal_new (NM_REMOTE_SETTINGS_NEW_CONNECTION, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, new_connection), + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTIONS_READ] = + g_signal_new (NM_REMOTE_SETTINGS_CONNECTIONS_READ, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, connections_read), + NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 5ca646e6..92049ade 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2009 - 2011 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + * Copyright 2009 - 2011 Red Hat, Inc. */ #ifndef NM_REMOTE_SETTINGS_H diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index f58f95fe..04f8dd8b 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -15,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 - 2011 Red Hat, Inc. + * Copyright 2010 - 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -55,9 +56,7 @@ static void impl_secret_agent_delete_secrets (NMSecretAgent *self, G_DEFINE_ABSTRACT_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)) +#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT, NMSecretAgentPrivate)) static gboolean auto_register_cb (gpointer user_data); @@ -124,11 +123,11 @@ get_nm_owner (NMSecretAgent *self) if (!priv->nm_owner) { if (!dbus_g_proxy_call_with_timeout (priv->dbus_proxy, - "GetNameOwner", 2000, &error, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_INVALID, - G_TYPE_STRING, &owner, - G_TYPE_INVALID)) + "GetNameOwner", 2000, &error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_STRING, &owner, + G_TYPE_INVALID)) return NULL; priv->nm_owner = g_strdup (owner); @@ -704,7 +703,8 @@ auto_register_cb (gpointer user_data) NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); priv->auto_register_id = 0; - if (priv->auto_register && !priv->suppress_auto && (priv->reg_call == NULL)) + if (priv->auto_register && !priv->suppress_auto && + (priv->reg_call == NULL && !priv->registered)) nm_secret_agent_register (self); return FALSE; } @@ -1004,11 +1004,11 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) **/ g_object_class_install_property (object_class, PROP_IDENTIFIER, - g_param_spec_string (NM_SECRET_AGENT_IDENTIFIER, - "Identifier", - "Identifier", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_string (NM_SECRET_AGENT_IDENTIFIER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /** * NMSecretAgent:auto-register: @@ -1023,11 +1023,11 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) **/ g_object_class_install_property (object_class, PROP_AUTO_REGISTER, - g_param_spec_boolean (NM_SECRET_AGENT_AUTO_REGISTER, - "Auto Register", - "Auto Register", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SECRET_AGENT_AUTO_REGISTER, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSecretAgent:registered: @@ -1036,11 +1036,10 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) **/ g_object_class_install_property (object_class, PROP_REGISTERED, - g_param_spec_boolean (NM_SECRET_AGENT_REGISTERED, - "Registered", - "Registered", + g_param_spec_boolean (NM_SECRET_AGENT_REGISTERED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSecretAgent:capabilities: @@ -1049,12 +1048,12 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) **/ g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_flags (NM_SECRET_AGENT_CAPABILITIES, - "Capabilities", - "Capabilities", + g_param_spec_flags (NM_SECRET_AGENT_CAPABILITIES, "", "", NM_TYPE_SECRET_AGENT_CAPABILITIES, NM_SECRET_AGENT_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSecretAgent::registration-result: @@ -1066,10 +1065,10 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) **/ signals[REGISTRATION_RESULT] = g_signal_new (NM_SECRET_AGENT_REGISTRATION_RESULT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_POINTER); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_POINTER); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_secret_agent_object_info); @@ -1078,4 +1077,3 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) NM_DBUS_INTERFACE_SECRET_AGENT, NM_TYPE_SECRET_AGENT_ERROR); } - diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index c70f8d07..b7df8745 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -1,5 +1,5 @@ /* -*- 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 @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 - 2011 Red Hat, Inc. + * Copyright 2010 - 2011 Red Hat, Inc. */ #ifndef NM_SECRET_AGENT_H @@ -59,7 +59,7 @@ typedef enum { * NMSecretAgentCapabilities: * @NM_SECRET_AGENT_CAPABILITY_NONE: the agent supports no special capabilities * @NM_SECRET_AGENT_CAPABILITY_VPN_HINTS: the agent supports sending hints given - * by the NMSecretAgentClass::get_secrets() class method to VPN plugin + * by the get_secrets class method to VPN plugin * authentication dialogs. * @NM_SECRET_AGENT_CAPABILITY_LAST: bounds checking value; should not be used. * diff --git a/libnm-glib/nm-types-private.h b/libnm-glib/nm-types-private.h index 178890da..c34d9a8f 100644 --- a/libnm-glib/nm-types-private.h +++ b/libnm-glib/nm-types-private.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. */ #ifndef NM_TYPES_PRIVATE_H @@ -31,9 +29,9 @@ gboolean _nm_ssid_demarshal (GValue *value, GByteArray **dest); gboolean _nm_uint_array_demarshal (GValue *value, GArray **dest); gboolean _nm_string_array_demarshal (GValue *value, GPtrArray **dest); gboolean _nm_object_array_demarshal (GValue *value, - GPtrArray **dest, - DBusGConnection *connection, - NMObjectCreatorFunc func); + GPtrArray **dest, + DBusGConnection *connection, + NMObjectCreatorFunc func); gboolean _nm_ip6_address_array_demarshal (GValue *value, GSList **dest); #endif /* NM_TYPES_PRIVATE_H */ diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c index f9ba6d24..5b434aa9 100644 --- a/libnm-glib/nm-types.c +++ b/libnm-glib/nm-types.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,9 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2008 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -232,9 +232,9 @@ nm_object_array_get_type (void) gboolean _nm_object_array_demarshal (GValue *value, - GPtrArray **dest, - DBusGConnection *connection, - NMObjectCreatorFunc func) + GPtrArray **dest, + DBusGConnection *connection, + NMObjectCreatorFunc func) { GPtrArray *temp = NULL; GPtrArray *array; @@ -419,4 +419,3 @@ nm_ip6_route_object_array_get_type (void) (GBoxedFreeFunc) _nm_ip6_route_object_array_free); return our_type; } - diff --git a/libnm-glib/nm-types.h b/libnm-glib/nm-types.h index adccafb7..81bd299e 100644 --- a/libnm-glib/nm-types.h +++ b/libnm-glib/nm-types.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. + * Copyright 2008 Red Hat, Inc. */ #ifndef NM_TYPES_H diff --git a/libnm-glib/nm-vpn-connection.c b/libnm-glib/nm-vpn-connection.c index 12814cf2..16e8db5e 100644 --- a/libnm-glib/nm-vpn-connection.c +++ b/libnm-glib/nm-vpn-connection.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2012 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include "nm-vpn-connection.h" #include "NetworkManager.h" @@ -70,7 +70,7 @@ nm_vpn_connection_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - return g_object_new (NM_TYPE_VPN_CONNECTION, + return g_object_new (NM_TYPE_VPN_CONNECTION, NM_OBJECT_DBUS_CONNECTION, connection, NM_OBJECT_DBUS_PATH, path, NULL); @@ -176,10 +176,10 @@ constructed (GObject *object) G_TYPE_INVALID); dbus_g_proxy_add_signal (priv->proxy, "VpnStateChanged", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, - "VpnStateChanged", - G_CALLBACK (vpn_state_changed_proxy), - object, - NULL); + "VpnStateChanged", + G_CALLBACK (vpn_state_changed_proxy), + object, + NULL); register_properties (NM_VPN_CONNECTION (object)); } @@ -237,34 +237,34 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) * * The VPN state of the active VPN connection. **/ - g_object_class_install_property (object_class, PROP_VPN_STATE, - g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, - "VpnState", - "Current VPN state", - NM_VPN_CONNECTION_STATE_UNKNOWN, - NM_VPN_CONNECTION_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VPN_STATE, + g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "", + NM_VPN_CONNECTION_STATE_UNKNOWN, + NM_VPN_CONNECTION_STATE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMVPNConnection:banner: * * The VPN login banner of the active VPN connection. **/ - g_object_class_install_property (object_class, PROP_BANNER, - g_param_spec_string (NM_VPN_CONNECTION_BANNER, - "Banner", - "Login Banner", - NULL, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_BANNER, + g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[VPN_STATE_CHANGED] = g_signal_new ("vpn-state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMVPNConnectionClass, vpn_state_changed), - NULL, NULL, NULL, - G_TYPE_NONE, 2, - G_TYPE_UINT, G_TYPE_UINT); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVPNConnectionClass, vpn_state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); } diff --git a/libnm-glib/nm-vpn-connection.h b/libnm-glib/nm-vpn-connection.h index 8727bb86..0495310f 100644 --- a/libnm-glib/nm-vpn-connection.h +++ b/libnm-glib/nm-vpn-connection.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2010 Red Hat, Inc. */ #ifndef NM_VPN_CONNECTION_H diff --git a/libnm-glib/nm-vpn-plugin-ui-interface.c b/libnm-glib/nm-vpn-plugin-ui-interface.c index f82c1270..b94084e2 100644 --- a/libnm-glib/nm-vpn-plugin-ui-interface.c +++ b/libnm-glib/nm-vpn-plugin-ui-interface.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2010 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ +#include "config.h" + #include "nm-vpn-plugin-ui-interface.h" static void @@ -32,26 +32,39 @@ interface_init (gpointer g_iface) return; /* Properties */ - g_object_interface_install_property (g_iface, - g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_NAME, - "Name", - "VPN Plugin name", - NULL, - G_PARAM_READABLE)); + /** + * NMVPNPluginUiInterface:name: + * + * Short display name of the VPN plugin. + */ g_object_interface_install_property (g_iface, - g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_DESC, - "Desc", - "VPN Plugin description", - NULL, - G_PARAM_READABLE)); - + g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVPNPluginUiInterface:desc: + * + * Longer description of the VPN plugin. + */ + g_object_interface_install_property (g_iface, + g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_DESC, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVPNPluginUiInterface:service: + * + * D-Bus service name of the plugin's VPN service. + */ g_object_interface_install_property (g_iface, - g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_SERVICE, - "Service", - "VPN Plugin D-Bus service name", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_VPN_PLUGIN_UI_INTERFACE_SERVICE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); initialized = TRUE; } @@ -76,9 +89,9 @@ nm_vpn_plugin_ui_interface_get_type (void) }; vpn_plugin_ui_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "NMVpnPluginUiInterface", - &vpn_plugin_ui_interface_info, - 0); + "NMVpnPluginUiInterface", + &vpn_plugin_ui_interface_info, + 0); g_type_interface_add_prerequisite (vpn_plugin_ui_interface_type, G_TYPE_OBJECT); } @@ -166,12 +179,12 @@ widget_interface_init (gpointer g_iface) /* Signals */ g_signal_new ("changed", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMVpnPluginUiWidgetInterface, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginUiWidgetInterface, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); initialized = TRUE; } @@ -234,4 +247,3 @@ nm_vpn_plugin_ui_widget_interface_save_secrets (NMVpnPluginUiWidgetInterface *if /* Deprecated and no longer used */ return TRUE; } - diff --git a/libnm-glib/nm-vpn-plugin-ui-interface.h b/libnm-glib/nm-vpn-plugin-ui-interface.h index 2753de44..9c6e49eb 100644 --- a/libnm-glib/nm-vpn-plugin-ui-interface.h +++ b/libnm-glib/nm-vpn-plugin-ui-interface.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. - * Copyright (C) 2008 Novell, Inc. + * Copyright 2008 - 2010 Red Hat, Inc. + * Copyright 2008 Novell, Inc. */ #ifndef NM_VPN_PLUGIN_UI_INTERFACE_H diff --git a/libnm-glib/nm-vpn-plugin-utils.c b/libnm-glib/nm-vpn-plugin-utils.c index b9838df9..9aafb19f 100644 --- a/libnm-glib/nm-vpn-plugin-utils.c +++ b/libnm-glib/nm-vpn-plugin-utils.c @@ -15,9 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Red Hat, Inc. + * Copyright 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include diff --git a/libnm-glib/nm-vpn-plugin-utils.h b/libnm-glib/nm-vpn-plugin-utils.h index aab73c4e..d87ef16a 100644 --- a/libnm-glib/nm-vpn-plugin-utils.h +++ b/libnm-glib/nm-vpn-plugin-utils.h @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Red Hat, Inc. + * Copyright 2011 Red Hat, Inc. */ #ifndef NM_VPN_PLUGIN_UTILS_H diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c index d5241696..7848c131 100644 --- a/libnm-glib/nm-vpn-plugin.c +++ b/libnm-glib/nm-vpn-plugin.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. */ +#include "config.h" + #include #include "nm-glib-compat.h" #include "nm-vpn-plugin.h" @@ -125,7 +125,7 @@ GQuark nm_vpn_plugin_error_quark (void) { static GQuark quark = 0; - + if (!quark) quark = g_quark_from_static_string ("nm_vpn_plugin_error"); @@ -729,8 +729,8 @@ nm_vpn_plugin_init (NMVPNPlugin *plugin) { active_plugins = g_slist_append (active_plugins, plugin); g_object_weak_ref (G_OBJECT (plugin), - one_plugin_destroyed, - NULL); + one_plugin_destroyed, + NULL); } static GObject * @@ -747,8 +747,8 @@ constructor (GType type, GError *err = NULL; object = G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->constructor (type, - n_construct_params, - construct_params); + n_construct_params, + construct_params); if (!object) return NULL; @@ -823,7 +823,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object); @@ -953,23 +953,33 @@ nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class) plugin_class->state_changed = state_changed; /* properties */ + + /** + * NMVPNPlugin:service-name: + * + * The D-Bus service name of this plugin. + */ g_object_class_install_property (object_class, PROP_DBUS_SERVICE_NAME, - g_param_spec_string (NM_VPN_PLUGIN_DBUS_SERVICE_NAME, - "DBus service name", - "DBus service name", + g_param_spec_string (NM_VPN_PLUGIN_DBUS_SERVICE_NAME, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVPNPlugin:state: + * + * The state of the plugin. + */ g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_VPN_PLUGIN_STATE, - "State", - "Current VPN service state", + g_param_spec_uint (NM_VPN_PLUGIN_STATE, "", "", NM_VPN_SERVICE_STATE_UNKNOWN, NM_VPN_SERVICE_STATE_STOPPED, NM_VPN_SERVICE_STATE_INIT, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[STATE_CHANGED] = diff --git a/libnm-glib/nm-vpn-plugin.h b/libnm-glib/nm-vpn-plugin.h index 4f020f31..323017f0 100644 --- a/libnm-glib/nm-vpn-plugin.h +++ b/libnm-glib/nm-vpn-plugin.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. */ #ifndef NM_VPN_PLUGIN_H diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c index f747aff3..1735ab3e 100644 --- a/libnm-glib/nm-wimax-nsp.c +++ b/libnm-glib/nm-wimax-nsp.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,10 +15,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Red Hat, Inc. + * Copyright 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include "nm-glib-compat.h" @@ -71,9 +70,9 @@ nm_wimax_nsp_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); return (GObject *) g_object_new (NM_TYPE_WIMAX_NSP, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NULL); + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } /** @@ -173,14 +172,14 @@ nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, NMConnection *connection) /** * nm_wimax_nsp_filter_connections: * @nsp: an #NMWimaxNsp to filter connections for - * @connections: (element-type NetworkManager.Connection): a list of + * @connections: (element-type NMConnection): a list of * #NMConnection objects to filter * * Filters a given list of connections for a given #NMWimaxNsp object and * return connections which may be activated with the access point. Any * returned connections will match the @nsp's network name and other attributes. * - * Returns: (transfer container) (element-type NetworkManager.Connection): a + * Returns: (transfer container) (element-type NMConnection): a * list of #NMConnection objects that could be activated with the given @nsp. * The elements of the list are owned by their creator and should not be freed * by the caller, but the returned list itself is owned by the caller and should @@ -305,11 +304,10 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) **/ g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_WIMAX_NSP_NAME, - "Name", - "Name", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_WIMAX_NSP_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMWimaxNsp:signal-quality: @@ -318,11 +316,10 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) **/ g_object_class_install_property (object_class, PROP_SIGNAL_QUALITY, - g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, - "Signal Quality", - "Signal Quality", + g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, "", "", 0, 100, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /** * NMWimaxNsp:network-type: @@ -331,9 +328,8 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) **/ g_object_class_install_property (object_class, PROP_NETWORK_TYPE, - g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, - "Network Type", - "Network Type", + g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-glib/nm-wimax-nsp.h b/libnm-glib/nm-wimax-nsp.h index b8e91079..74008d18 100644 --- a/libnm-glib/nm-wimax-nsp.h +++ b/libnm-glib/nm-wimax-nsp.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * libnm_glib -- Access network status & information from glib applications - * * 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 @@ -17,8 +15,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. + * Copyright 2011 Red Hat, Inc. + * Copyright 2009 Novell, Inc. */ #ifndef NM_WIMAX_NSP_H @@ -42,6 +40,15 @@ G_BEGIN_DECLS #define NM_WIMAX_NSP_SIGNAL_QUALITY "signal-quality" #define NM_WIMAX_NSP_NETWORK_TYPE "network-type" +/** + * NMWimaxNspNetworkType: + * @NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN: unknown network type + * @NM_WIMAX_NSP_NETWORK_TYPE_HOME: home network + * @NM_WIMAX_NSP_NETWORK_TYPE_PARTNER: partner network + * @NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER: roaming partner network + * + * WiMAX network type. + */ typedef enum { NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN = 0, NM_WIMAX_NSP_NETWORK_TYPE_HOME = 1, diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am index 38f449ac..7b8f3627 100644 --- a/libnm-glib/tests/Makefile.am +++ b/libnm-glib/tests/Makefile.am @@ -2,52 +2,48 @@ if ENABLE_TESTS AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) -noinst_PROGRAMS = test-nm-client test-remote-settings-client +noinst_PROGRAMS = $(TESTS) + +TESTS = test-nm-client test-remote-settings-client ####### NMClient and non-settings tests ####### test_nm_client_SOURCES = \ + common.c \ + common.h \ test-nm-client.c test_nm_client_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib-test.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) ####### remote settings client test ####### test_remote_settings_client_SOURCES = \ + common.c \ + common.h \ test-remote-settings-client.c test_remote_settings_client_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib-test.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) ########################################### -TEST_NM_BIN = test-fake-nm.py -TEST_RSS_BIN = test-remote-settings-service.py - -EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) - -check-local: test-nm-client test-remote-settings-client - if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \ - dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ - dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ - else \ - $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ - $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ - fi; +TESTS_ENVIRONMENT = $(srcdir)/libnm-glib-test-launch.sh endif + +EXTRA_DIST = libnm-glib-test-launch.sh diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in index 28acdea0..7dd74031 100644 --- a/libnm-glib/tests/Makefile.in +++ b/libnm-glib/tests/Makefile.in @@ -78,7 +78,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-nm-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = $(am__EXEEXT_1) +@ENABLE_TESTS_TRUE@TESTS = test-nm-client$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) subdir = libnm-glib/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -103,29 +104,32 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +@ENABLE_TESTS_TRUE@am__EXEEXT_1 = test-nm-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) -am__test_nm_client_SOURCES_DIST = test-nm-client.c -@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = \ +am__test_nm_client_SOURCES_DIST = common.c common.h test-nm-client.c +@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = common.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test-nm-client.$(OBJEXT) test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS) am__DEPENDENCIES_1 = @ENABLE_TESTS_TRUE@test_nm_client_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am__test_remote_settings_client_SOURCES_DIST = \ +am__test_remote_settings_client_SOURCES_DIST = common.c common.h \ test-remote-settings-client.c @ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ common.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.$(OBJEXT) test_remote_settings_client_OBJECTS = \ $(am_test_remote_settings_client_OBJECTS) @ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -189,6 +193,28 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ @@ -199,6 +225,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -322,6 +350,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -341,6 +370,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -367,7 +397,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -448,41 +478,44 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) ####### NMClient and non-settings tests ####### @ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \ +@ENABLE_TESTS_TRUE@ common.c \ +@ENABLE_TESTS_TRUE@ common.h \ @ENABLE_TESTS_TRUE@ test-nm-client.c @ENABLE_TESTS_TRUE@test_nm_client_LDADD = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) ####### remote settings client test ####### @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \ +@ENABLE_TESTS_TRUE@ common.c \ +@ENABLE_TESTS_TRUE@ common.h \ @ENABLE_TESTS_TRUE@ test-remote-settings-client.c @ENABLE_TESTS_TRUE@test_remote_settings_client_LDADD = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib-test.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) ########################################### -@ENABLE_TESTS_TRUE@TEST_NM_BIN = test-fake-nm.py -@ENABLE_TESTS_TRUE@TEST_RSS_BIN = test-remote-settings-service.py -@ENABLE_TESTS_TRUE@EXTRA_DIST = $(TEST_RSS_BIN) $(TEST_NM_BIN) +@ENABLE_TESTS_TRUE@TESTS_ENVIRONMENT = $(srcdir)/libnm-glib-test-launch.sh +EXTRA_DIST = libnm-glib-test-launch.sh all: all-am .SUFFIXES: @@ -541,6 +574,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@ @@ -623,6 +657,99 @@ cscopelist-am: $(am__tagged_files) 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 $(AM_TESTS_FD_REDIRECT); 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 \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -653,9 +780,8 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done -@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: @@ -762,7 +888,7 @@ uninstall-am: .MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ @@ -777,15 +903,6 @@ uninstall-am: tags tags-am uninstall uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-nm-client test-remote-settings-client -@ENABLE_TESTS_TRUE@ if test -z "$$DBUS_SESSION_BUS_ADDRESS" ; then \ -@ENABLE_TESTS_TRUE@ dbus-launch --exit-with-session $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ -@ENABLE_TESTS_TRUE@ dbus-launch --exit-with-session $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ -@ENABLE_TESTS_TRUE@ else \ -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-nm-client $(abs_srcdir) $(TEST_NM_BIN); \ -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN); \ -@ENABLE_TESTS_TRUE@ fi; - # 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/libnm-glib/tests/common.c b/libnm-glib/tests/common.c new file mode 100644 index 00000000..540d43af --- /dev/null +++ b/libnm-glib/tests/common.c @@ -0,0 +1,121 @@ +/* -*- 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 2010 - 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include + +#include "NetworkManager.h" + +#include "common.h" + +static gboolean +name_exists (GDBusConnection *c, const char *name) +{ + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync (c, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new ("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref (reply); + } + + return exists; +} + +NMTestServiceInfo * +nm_test_service_init (void) +{ + NMTestServiceInfo *info; + const char *args[2] = { TEST_NM_SERVICE, NULL }; + GError *error = NULL; + int i; + + info = g_malloc0 (sizeof (*info)); + + info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + /* Spawn the test service. info->keepalive_fd will be a pipe to the service's + * stdin; if it closes, the service will exit immediately. We use this to + * make sure the service exits if the test program crashes. + */ + g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL, + &info->pid, &info->keepalive_fd, NULL, NULL, &error); + g_assert_no_error (error); + + /* Wait until the service is registered on the bus */ + for (i = 100; i > 0; i--) { + if (name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + /* Grab a proxy to our fake NM service to trigger tests */ + info->proxy = g_dbus_proxy_new_sync (info->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, &error); + g_assert_no_error (error); + + return info; +} + +void +nm_test_service_cleanup (NMTestServiceInfo *info) +{ + int i; + + g_object_unref (info->proxy); + kill (info->pid, SIGTERM); + + /* Wait until the bus notices the service is gone */ + for (i = 100; i > 0; i--) { + if (!name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + g_object_unref (info->bus); + close (info->keepalive_fd); + + memset (info, 0, sizeof (*info)); + g_free (info); +} diff --git a/libnm-glib/tests/common.h b/libnm-glib/tests/common.h new file mode 100644 index 00000000..7c49d253 --- /dev/null +++ b/libnm-glib/tests/common.h @@ -0,0 +1,31 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include + +typedef struct { + GDBusConnection *bus; + GDBusProxy *proxy; + GPid pid; + int keepalive_fd; +} NMTestServiceInfo; + +NMTestServiceInfo *nm_test_service_init (void); +void nm_test_service_cleanup (NMTestServiceInfo *info); diff --git a/libnm-glib/tests/libnm-glib-test-launch.sh b/libnm-glib/tests/libnm-glib-test-launch.sh new file mode 100755 index 00000000..42d9fbe2 --- /dev/null +++ b/libnm-glib/tests/libnm-glib-test-launch.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Spawn DBus if there's none +if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then + eval `dbus-launch --sh-syntax` + trap "kill $DBUS_SESSION_BUS_PID" EXIT +fi + +"$@" diff --git a/libnm-glib/tests/test-fake-nm.py b/libnm-glib/tests/test-fake-nm.py deleted file mode 100755 index 46ca3ff0..00000000 --- a/libnm-glib/tests/test-fake-nm.py +++ /dev/null @@ -1,776 +0,0 @@ -#!/usr/bin/env python -# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - -from __future__ import print_function - -from gi.repository import GLib, GObject -import sys -import dbus -import dbus.service -import dbus.mainloop.glib -import random - -mainloop = GObject.MainLoop() -quit_id = 0 - -# NM State -NM_STATE_UNKNOWN = 0 -NM_STATE_ASLEEP = 10 -NM_STATE_DISCONNECTED = 20 -NM_STATE_DISCONNECTING = 30 -NM_STATE_CONNECTING = 40 -NM_STATE_CONNECTED_LOCAL = 50 -NM_STATE_CONNECTED_SITE = 60 -NM_STATE_CONNECTED_GLOBAL = 70 - -# Device state -NM_DEVICE_STATE_UNKNOWN = 0 -NM_DEVICE_STATE_UNMANAGED = 10 -NM_DEVICE_STATE_UNAVAILABLE = 20 -NM_DEVICE_STATE_DISCONNECTED = 30 -NM_DEVICE_STATE_PREPARE = 40 -NM_DEVICE_STATE_CONFIG = 50 -NM_DEVICE_STATE_NEED_AUTH = 60 -NM_DEVICE_STATE_IP_CONFIG = 70 -NM_DEVICE_STATE_IP_CHECK = 80 -NM_DEVICE_STATE_SECONDARIES = 90 -NM_DEVICE_STATE_ACTIVATED = 100 -NM_DEVICE_STATE_DEACTIVATING = 110 -NM_DEVICE_STATE_FAILED = 120 - -NM_DEVICE_TYPE_UNKNOWN = 0 -NM_DEVICE_TYPE_ETHERNET = 1 -NM_DEVICE_TYPE_WIFI = 2 -NM_DEVICE_TYPE_UNUSED1 = 3 -NM_DEVICE_TYPE_UNUSED2 = 4 -NM_DEVICE_TYPE_BT = 5 -NM_DEVICE_TYPE_OLPC_MESH = 6 -NM_DEVICE_TYPE_WIMAX = 7 -NM_DEVICE_TYPE_MODEM = 8 -NM_DEVICE_TYPE_INFINIBAND = 9 -NM_DEVICE_TYPE_BOND = 10 -NM_DEVICE_TYPE_VLAN = 11 -NM_DEVICE_TYPE_ADSL = 12 -NM_DEVICE_TYPE_BRIDGE = 13 -NM_DEVICE_TYPE_GENERIC = 14 -NM_DEVICE_TYPE_TEAM = 15 - -######################################################### -IFACE_DBUS = 'org.freedesktop.DBus' - -class UnknownInterfaceException(dbus.DBusException): - _dbus_error_name = IFACE_DBUS + '.UnknownInterface' - -class UnknownPropertyException(dbus.DBusException): - _dbus_error_name = IFACE_DBUS + '.UnknownProperty' - -def to_path_array(src): - array = dbus.Array([], signature=dbus.Signature('o')) - for o in src: - array.append(o.path) - return array - -def to_path(src): - if src: - return dbus.ObjectPath(src.path) - return dbus.ObjectPath("/") - -class ExportedObj(dbus.service.Object): - def __init__(self, bus, object_path): - dbus.service.Object.__init__(self, bus, object_path) - self._bus = bus - self.path = object_path - self.__dbus_ifaces = {} - - def add_dbus_interface(self, dbus_iface, get_props_func): - self.__dbus_ifaces[dbus_iface] = get_props_func - - def _get_dbus_properties(self, iface): - return self.__dbus_ifaces[iface]() - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') - def GetAll(self, iface): - if iface not in self.__dbus_ifaces.keys(): - raise UnknownInterfaceException() - return self._get_dbus_properties(iface) - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') - def Get(self, iface, name): - if iface not in self.__dbus_ifaces.keys(): - raise UnknownInterfaceException() - props = self._get_dbus_properties(iface) - if not name in props.keys(): - raise UnknownPropertyException() - return props[name] - -################################################################### -IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device' - -PD_UDI = "Udi" -PD_IFACE = "Interface" -PD_DRIVER = "Driver" -PD_STATE = "State" -PD_ACTIVE_CONNECTION = "ActiveConnection" -PD_IP4_CONFIG = "Ip4Config" -PD_IP6_CONFIG = "Ip6Config" -PD_DHCP4_CONFIG = "Dhcp4Config" -PD_DHCP6_CONFIG = "Dhcp6Config" -PD_MANAGED = "Managed" -PD_AUTOCONNECT = "Autoconnect" -PD_DEVICE_TYPE = "DeviceType" -PD_AVAILABLE_CONNECTIONS = "AvailableConnections" - -class Device(ExportedObj): - counter = 1 - - def __init__(self, bus, iface, devtype): - object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter - Device.counter = Device.counter + 1 - ExportedObj.__init__(self, bus, object_path) - self.add_dbus_interface(IFACE_DEVICE, self.__get_props) - - self.iface = iface - self.udi = "/sys/devices/virtual/%s" % iface - self.devtype = devtype - self.active_connection = None - self.state = NM_DEVICE_STATE_UNAVAILABLE - self.ip4_config = None - self.ip6_config = None - self.dhcp4_config = None - self.dhcp6_config = None - self.available_connections = [] - - # Properties interface - def __get_props(self): - props = {} - props[PD_UDI] = self.udi - props[PD_IFACE] = self.iface - props[PD_DRIVER] = "virtual" - props[PD_STATE] = dbus.UInt32(self.state) - props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection) - props[PD_IP4_CONFIG] = to_path(self.ip4_config) - props[PD_IP6_CONFIG] = to_path(self.ip6_config) - props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config) - props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config) - props[PD_MANAGED] = True - props[PD_AUTOCONNECT] = True - props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype) - props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections) - return props - - # methods - @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='') - def Disconnect(self): - pass - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_DEVICE) - changed = { propname: props[propname] } - Device.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_DEVICE, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - - -################################################################### - -def random_mac(): - return '%02X:%02X:%02X:%02X:%02X:%02X' % ( - random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), - random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) - ) - -################################################################### -IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired' - -PE_HW_ADDRESS = "HwAddress" -PE_PERM_HW_ADDRESS = "PermHwAddress" -PE_SPEED = "Speed" -PE_CARRIER = "Carrier" - -class WiredDevice(Device): - def __init__(self, bus, iface): - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET) - self.add_dbus_interface(IFACE_WIRED, self.__get_props) - - self.mac = random_mac() - self.carrier = False - - # Properties interface - def __get_props(self): - props = {} - props[PE_HW_ADDRESS] = self.mac - props[PE_PERM_HW_ADDRESS] = self.mac - props[PE_SPEED] = dbus.UInt32(100) - props[PE_CARRIER] = self.carrier - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_WIRED) - changed = { propname: props[propname] } - WiredDevice.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_WIRED, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - -################################################################### -IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint' - -PP_FLAGS = "Flags" -PP_WPA_FLAGS = "WpaFlags" -PP_RSN_FLAGS = "RsnFlags" -PP_SSID = "Ssid" -PP_FREQUENCY = "Frequency" -PP_HW_ADDRESS = "HwAddress" -PP_MODE = "Mode" -PP_MAX_BITRATE = "MaxBitrate" -PP_STRENGTH = "Strength" - -class WifiAp(ExportedObj): - counter = 0 - - def __init__(self, bus, ssid, mac, flags, wpaf, rsnf, freq): - path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter - WifiAp.counter = WifiAp.counter + 1 - ExportedObj.__init__(self, bus, path) - self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props) - - self.ssid = ssid - if mac: - self.bssid = mac - else: - self.bssid = random_mac() - self.flags = flags - self.wpaf = wpaf - self.rsnf = rsnf - self.freq = freq - self.strength = random.randint(0, 100) - self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) - - def __del__(self): - if self.strength_id > 0: - GLib.source_remove(self.strength_id) - self.strength_id = 0 - - def strength_cb(self, ignored): - self.strength = random.randint(0, 100) - self.__notify(PP_STRENGTH) - return True - - # Properties interface - def __get_props(self): - props = {} - props[PP_FLAGS] = dbus.UInt32(self.flags) - props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf) - props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf) - props[PP_SSID] = dbus.ByteArray(self.ssid) - props[PP_FREQUENCY] = dbus.UInt32(self.freq) - props[PP_HW_ADDRESS] = self.bssid - props[PP_MODE] = dbus.UInt32(2) # NM_802_11_MODE_INFRA - props[PP_MAX_BITRATE] = dbus.UInt32(54000) - props[PP_STRENGTH] = dbus.Byte(self.strength) - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_WIFI_AP) - changed = { propname: props[propname] } - WifiAp.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - -################################################################### -IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless' - -class ApNotFoundException(dbus.DBusException): - _dbus_error_name = IFACE_WIFI + '.AccessPointNotFound' - -PW_HW_ADDRESS = "HwAddress" -PW_PERM_HW_ADDRESS = "PermHwAddress" -PW_MODE = "Mode" -PW_BITRATE = "Bitrate" -PW_ACCESS_POINTS = "AccessPoints" -PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint" -PW_WIRELESS_CAPABILITIES = "WirelessCapabilities" - -class WifiDevice(Device): - def __init__(self, bus, iface): - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI) - self.add_dbus_interface(IFACE_WIFI, self.__get_props) - - self.mac = random_mac() - self.aps = [] - self.active_ap = None - - # methods - @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') - def GetAccessPoints(self): - # only include non-hidden APs - array = [] - for a in self.aps: - if a.ssid(): - array.append(a) - return to_path_array(array) - - @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') - def GetAllAccessPoints(self): - # include all APs including hidden ones - return to_path_array(self.aps) - - @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='') - def RequestScan(self, props): - pass - - @dbus.service.signal(IFACE_WIFI, signature='o') - def AccessPointAdded(self, ap_path): - pass - - def add_ap(self, ap): - self.aps.append(ap) - self.__notify(PW_ACCESS_POINTS) - self.AccessPointAdded(to_path(ap)) - - @dbus.service.signal(IFACE_WIFI, signature='o') - def AccessPointRemoved(self, ap_path): - pass - - def remove_ap(self, ap): - self.aps.remove(ap) - self.__notify(PW_ACCESS_POINTS) - self.AccessPointRemoved(to_path(ap)) - - # Properties interface - def __get_props(self): - props = {} - props[PW_HW_ADDRESS] = self.mac - props[PW_PERM_HW_ADDRESS] = self.mac - props[PW_MODE] = dbus.UInt32(3) # NM_802_11_MODE_INFRA - props[PW_BITRATE] = dbus.UInt32(21000) - props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF) - props[PW_ACCESS_POINTS] = to_path_array(self.aps) - props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap) - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_WIFI) - changed = { propname: props[propname] } - WifiDevice.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_WIFI, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - - # test functions - def add_test_ap(self, ssid, mac): - ap = WifiAp(self._bus, ssid, mac, 0x1, 0x1cc, 0x1cc, 2412) - self.add_ap(ap) - return ap.path - - def remove_ap_by_path(self, path): - for ap in self.aps: - if ap.path == path: - self.remove_ap(ap) - return - raise ApNotFoundException("AP %s not found" % path) - - -################################################################### -IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp' - -PN_NAME = "Name" -PN_SIGNAL_QUALITY = "SignalQuality" -PN_NETWORK_TYPE = "NetworkType" - -class WimaxNsp(ExportedObj): - counter = 0 - - def __init__(self, bus, name): - path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter - WimaxNsp.counter = WimaxNsp.counter + 1 - ExportedObj.__init__(self, bus, path) - self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props) - - self.name = name - self.strength = random.randint(0, 100) - self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) - - def __del__(self): - if self.strength_id > 0: - GLib.source_remove(self.strength_id) - self.strength_id = 0 - - def strength_cb(self, ignored): - self.strength = random.randint(0, 100) - self.__notify(PN_SIGNAL_QUALITY) - return True - - # Properties interface - def __get_props(self): - props = {} - props[PN_NAME] = self.name - props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength) - props[PN_NETWORK_TYPE] = dbus.UInt32(0x1) # NM_WIMAX_NSP_NETWORK_TYPE_HOME - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_WIMAX_NSP) - changed = { propname: props[propname] } - WimaxNsp.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - -################################################################### -IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax' - -class NspNotFoundException(dbus.DBusException): - _dbus_error_name = IFACE_WIMAX + '.NspNotFound' - -PX_NSPS = "Nsps" -PX_HW_ADDRESS = "HwAddress" -PX_CENTER_FREQUENCY = "CenterFrequency" -PX_RSSI = "Rssi" -PX_CINR = "Cinr" -PX_TX_POWER = "TxPower" -PX_BSID = "Bsid" -PX_ACTIVE_NSP = "ActiveNsp" - -class WimaxDevice(Device): - def __init__(self, bus, iface): - Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX) - self.add_dbus_interface(IFACE_WIMAX, self.__get_props) - - self.mac = random_mac() - self.bsid = random_mac() - self.nsps = [] - self.active_nsp = None - - # methods - @dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao') - def GetNspList(self): - # include all APs including hidden ones - return to_path_array(self.nsps) - - @dbus.service.signal(IFACE_WIMAX, signature='o') - def NspAdded(self, nsp_path): - pass - - def add_nsp(self, nsp): - self.nsps.append(nsp) - self.__notify(PX_NSPS) - self.NspAdded(to_path(nsp)) - - @dbus.service.signal(IFACE_WIMAX, signature='o') - def NspRemoved(self, nsp_path): - pass - - def remove_nsp(self, nsp): - self.nsps.remove(nsp) - self.__notify(PX_NSPS) - self.NspRemoved(to_path(nsp)) - - # Properties interface - def __get_props(self): - props = {} - props[PX_HW_ADDRESS] = self.mac - props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525) - props[PX_RSSI] = dbus.Int32(-48) - props[PX_CINR] = dbus.Int32(24) - props[PX_TX_POWER] = dbus.Int32(9) - props[PX_BSID] = self.bsid - props[PX_NSPS] = to_path_array(self.nsps) - props[PX_ACTIVE_NSP] = to_path(self.active_nsp) - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_WIMAX) - changed = { propname: props[propname] } - WimaxDevice.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_WIMAX, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - - # test functions - def add_test_nsp(self, name): - nsp = WimaxNsp(self._bus, name) - self.add_nsp(nsp) - return nsp.path - - def remove_nsp_by_path(self, path): - for nsp in self.nsps: - if nsp.path == path: - self.remove_nsp(nsp) - return - raise NspNotFoundException("NSP %s not found" % path) - -################################################################### -IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest' -IFACE_NM = 'org.freedesktop.NetworkManager' - -class PermissionDeniedException(dbus.DBusException): - _dbus_error_name = IFACE_NM + '.PermissionDenied' - -class UnknownDeviceException(dbus.DBusException): - _dbus_error_name = IFACE_NM + '.UnknownDevice' - -PM_DEVICES = 'Devices' -PM_NETWORKING_ENABLED = 'NetworkingEnabled' -PM_WWAN_ENABLED = 'WwanEnabled' -PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled' -PM_WIRELESS_ENABLED = 'WirelessEnabled' -PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled' -PM_WIMAX_ENABLED = 'WimaxEnabled' -PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled' -PM_ACTIVE_CONNECTIONS = 'ActiveConnections' -PM_PRIMARY_CONNECTION = 'PrimaryConnection' -PM_ACTIVATING_CONNECTION = 'ActivatingConnection' -PM_STARTUP = 'Startup' -PM_STATE = 'State' -PM_VERSION = 'Version' -PM_CONNECTIVITY = 'Connectivity' - -class NetworkManager(ExportedObj): - def __init__(self, bus, object_path): - ExportedObj.__init__(self, bus, object_path) - self.add_dbus_interface(IFACE_NM, self.__get_props) - - self.devices = [] - self.active_connections = [] - self.primary_connection = None - self.activating_connection = None - self.state = NM_STATE_DISCONNECTED - self.connectivity = 1 - - @dbus.service.signal(IFACE_NM, signature='u') - def StateChanged(self, new_state): - pass - - def set_state(self, new_state): - self.state = new_state - self.__notify(PM_STATE) - self.StateChanged(dbus.UInt32(self.state)) - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') - def GetDevices(self): - return self._get_dbus_properties(IFACE_NM)[PM_DEVICES] - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o') - def GetDeviceByIpIface(self, ip_iface): - for d in self.devices: - # ignore iface/ip_iface distinction for now - if d.iface == ip_iface: - return d.path - raise UnknownDeviceException("No device found for the requested iface.") - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o') - def ActivateConnection(self, conpath, devpath, specific_object): - device = None - for d in self.devices: - if d.path == devpath: - device = d - break - if not device: - raise UnknownDeviceException("No device found for the requested iface.") - raise PermissionDeniedException("Not yet implemented") - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo') - def AddAndActivateConnection(self, connection, devpath, specific_object): - device = None - for d in self.devices: - if d.path == devpath: - device = d - break - if not device: - raise UnknownDeviceException("No device found for the requested iface.") - raise PermissionDeniedException("Not yet implemented") - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='') - def DeactivateConnection(self, active_connection): - pass - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') - def Sleep(self, do_sleep): - if do_sleep: - self.state = NM_STATE_ASLEEP - else: - self.state = NM_STATE_DISCONNECTED - self.__notify(PM_STATE) - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') - def Enable(self, do_enable): - pass - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='a{ss}') - def GetPermissions(self): - return { "org.freedesktop.NetworkManager.enable-disable-network": "yes", - "org.freedesktop.NetworkManager.sleep-wake": "no", - "org.freedesktop.NetworkManager.enable-disable-wifi": "yes", - "org.freedesktop.NetworkManager.enable-disable-wwan": "yes", - "org.freedesktop.NetworkManager.enable-disable-wimax": "yes", - "org.freedesktop.NetworkManager.network-control": "yes", - "org.freedesktop.NetworkManager.wifi.share.protected": "yes", - "org.freedesktop.NetworkManager.wifi.share.open": "yes", - "org.freedesktop.NetworkManager.settings.modify.own": "yes", - "org.freedesktop.NetworkManager.settings.modify.system": "yes", - "org.freedesktop.NetworkManager.settings.modify.hostname": "yes" } - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ss', out_signature='') - def SetLogging(self, level, domains): - pass - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ss') - def GetLogging(self): - return ("info", "HW,RFKILL,CORE,DEVICE,WIFI,ETHER") - - @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='u') - def CheckConnectivity(self): - raise PermissionDeniedException("You fail") - - @dbus.service.signal(IFACE_NM, signature='o') - def DeviceAdded(self, devpath): - pass - - def add_device(self, device): - self.devices.append(device) - self.__notify(PM_DEVICES) - self.DeviceAdded(to_path(device)) - - @dbus.service.signal(IFACE_NM, signature='o') - def DeviceRemoved(self, devpath): - pass - - def remove_device(self, device): - self.devices.remove(device) - self.__notify(PM_DEVICES) - self.DeviceRemoved(to_path(device)) - - ################# D-Bus Properties interface - def __get_props(self): - props = {} - props[PM_DEVICES] = to_path_array(self.devices) - props[PM_NETWORKING_ENABLED] = True - props[PM_WWAN_ENABLED] = True - props[PM_WWAN_HARDWARE_ENABLED] = True - props[PM_WIRELESS_ENABLED] = True - props[PM_WIRELESS_HARDWARE_ENABLED] = True - props[PM_WIMAX_ENABLED] = True - props[PM_WIMAX_HARDWARE_ENABLED] = True - props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections) - props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection) - props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection) - props[PM_STARTUP] = False - props[PM_STATE] = dbus.UInt32(self.state) - props[PM_VERSION] = "0.9.9.0" - props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity) - return props - - def __notify(self, propname): - props = self._get_dbus_properties(IFACE_NM) - changed = { propname: props[propname] } - NetworkManager.PropertiesChanged(self, changed) - - @dbus.service.signal(IFACE_NM, signature='a{sv}') - def PropertiesChanged(self, changed): - pass - - ################# Testing methods - @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') - def Quit(self): - mainloop.quit() - - @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') - def AddWiredDevice(self, ifname): - for d in self.devices: - if d.iface == ifname: - raise PermissionDeniedError("Device already added") - dev = WiredDevice(self._bus, ifname) - self.add_device(dev) - return dbus.ObjectPath(dev.path) - - @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') - def AddWifiDevice(self, ifname): - for d in self.devices: - if d.iface == ifname: - raise PermissionDeniedError("Device already added") - dev = WifiDevice(self._bus, ifname) - self.add_device(dev) - return dbus.ObjectPath(dev.path) - - @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') - def AddWimaxDevice(self, ifname): - for d in self.devices: - if d.iface == ifname: - raise PermissionDeniedError("Device already added") - dev = WimaxDevice(self._bus, ifname) - self.add_device(dev) - return dbus.ObjectPath(dev.path) - - @dbus.service.method(IFACE_TEST, in_signature='o', out_signature='') - def RemoveDevice(self, path): - for d in self.devices: - if d.path == path: - self.remove_device(d) - return - raise UnknownDeviceException("Device not found") - - @dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o') - def AddWifiAp(self, ifname, ssid, mac): - for d in self.devices: - if d.iface == ifname: - return dbus.ObjectPath(d.add_test_ap(ssid, mac)) - raise UnknownDeviceException("Device not found") - - @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') - def RemoveWifiAp(self, ifname, ap_path): - for d in self.devices: - if d.iface == ifname: - d.remove_ap_by_path(ap_path) - return - raise UnknownDeviceException("Device not found") - - @dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o') - def AddWimaxNsp(self, ifname, name): - for d in self.devices: - if d.iface == ifname: - return dbus.ObjectPath(d.add_test_nsp(name)) - raise UnknownDeviceException("Device not found") - - @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') - def RemoveWimaxNsp(self, ifname, nsp_path): - for d in self.devices: - if d.iface == ifname: - d.remove_nsp_by_path(nsp_path) - return - raise UnknownDeviceException("Device not found") - -def quit_cb(user_data): - mainloop.quit() - -def main(): - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - - random.seed() - - bus = dbus.SessionBus() - nm = NetworkManager(bus, "/org/freedesktop/NetworkManager") - if not bus.request_name("org.freedesktop.NetworkManager"): - sys.exit(1) - - # quit after inactivity to ensure we don't stick around if tests fail - quit_id = GLib.timeout_add_seconds(20, quit_cb, None) - - try: - mainloop.run() - except Exception as e: - pass - - sys.exit(0) - -if __name__ == '__main__': - main() - diff --git a/libnm-glib/tests/test-nm-client.c b/libnm-glib/tests/test-nm-client.c index b181c8fa..af3722eb 100644 --- a/libnm-glib/tests/test-nm-client.c +++ b/libnm-glib/tests/test-nm-client.c @@ -14,10 +14,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) 2010 - 2014 Red Hat, Inc. + * Copyright 2010 - 2014 Red Hat, Inc. * */ +#include "config.h" + #include #include #include @@ -33,153 +35,39 @@ #include "nm-device-wimax.h" #include "nm-glib-compat.h" -static const char *fake_path; -static const char *fake_bin; -static const char *fake_exec; +#include "common.h" + static GMainLoop *loop = NULL; +static NMTestServiceInfo *sinfo; /*******************************************************************/ -typedef struct { - GDBusConnection *bus; - GDBusProxy *proxy; - GPid pid; - NMClient *client; -} ServiceInfo; - -#define test_assert(condition) \ -do { \ - if (!G_LIKELY (condition)) \ - service_cleanup (); \ - g_assert (condition); \ -} while (0) - -#define test_assert_cmpint(a, b, c) \ -do { \ - if (!G_LIKELY (a b c)) \ - service_cleanup (); \ - g_assert_cmpint (a, b, c); \ -} while (0) - -#define test_assert_cmpstr(a, b, c) \ -do { \ - if (!G_LIKELY (g_str_hash (a) b g_str_hash (c))) \ - service_cleanup (); \ - g_assert_cmpstr (a, b, c); \ -} while (0) - -#define test_assert_no_error(e) \ -do { \ - if (G_UNLIKELY (e)) \ - service_cleanup (); \ - g_assert_no_error (e); \ -} while (0) - -static ServiceInfo * sinfo_static = NULL; - -static void -service_cleanup (void) -{ - ServiceInfo *info = sinfo_static; - - sinfo_static = NULL; - - if (info) { - if (info->proxy) - g_object_unref (info->proxy); - if (info->bus) - g_object_unref (info->bus); - if (info->client) - g_object_unref (info->client); - if (info->pid) - kill (info->pid, SIGTERM); - memset (info, 0, sizeof (*info)); - g_free (info); - } else - g_assert_not_reached (); -} - -static gboolean -name_exists (GDBusConnection *c, const char *name) -{ - GVariant *reply; - gboolean exists = FALSE; - - reply = g_dbus_connection_call_sync (c, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetNameOwner", - g_variant_new ("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - NULL, - NULL); - if (reply != NULL) { - exists = TRUE; - g_variant_unref (reply); - } - - return exists; -} - -static ServiceInfo * -service_init (void) +static NMClient * +test_client_new (void) { - ServiceInfo *sinfo; - const char *args[2] = { fake_exec, NULL }; + NMClient *client; + DBusGConnection *bus; GError *error = NULL; - int i = 100; + gboolean success; - g_assert (!sinfo_static); + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + g_assert_no_error (error); - sinfo = g_malloc0 (sizeof (*sinfo)); + client = g_object_new (NM_TYPE_CLIENT, + NM_OBJECT_DBUS_CONNECTION, bus, + NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, + NULL); + g_assert (client != NULL); - sinfo_static = sinfo; + dbus_g_connection_unref (bus); - sinfo->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - test_assert (sinfo->bus); + success = g_initable_init (G_INITABLE (client), NULL, &error); + g_assert_no_error (error); + g_assert (success == TRUE); - if (!g_spawn_async (fake_path, (char **) args, NULL, 0, NULL, NULL, &sinfo->pid, &error)) - test_assert_no_error (error); - - /* Wait until the service is registered on the bus */ - while (i > 0) { - g_usleep (G_USEC_PER_SEC / 50); - if (name_exists (sinfo->bus, "org.freedesktop.NetworkManager")) - break; - i--; - } - test_assert (i > 0); - - /* Grab a proxy to our fake NM service to trigger tests */ - sinfo->proxy = g_dbus_proxy_new_sync (sinfo->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - NM_DBUS_SERVICE, - NM_DBUS_PATH, - "org.freedesktop.NetworkManager.LibnmGlibTest", - NULL, NULL); - test_assert (sinfo->proxy); - - sinfo->client = nm_client_new (); - test_assert (sinfo->client != NULL); - - return sinfo; -} - -static ServiceInfo * -service_get (void) -{ - g_assert (sinfo_static); - return sinfo_static; + return client; } -#define _sinfo (service_get ()) - /*******************************************************************/ static gboolean @@ -195,16 +83,16 @@ add_device (const char *method, const char *ifname, char **out_path) GError *error = NULL; GVariant *ret; - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, method, g_variant_new ("(s)", ifname), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); - test_assert (ret); - test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); if (out_path) g_variant_get (ret, "(o)", out_path); g_variant_unref (ret); @@ -237,8 +125,8 @@ device_added_cb (NMClient *c, NMDevice *device, DeviceAddedInfo *info) { - test_assert (device); - test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); info->signaled = TRUE; device_add_check_quit (info); } @@ -252,12 +140,12 @@ devices_notify_cb (NMClient *c, NMDevice *device; devices = nm_client_get_devices (c); - test_assert (devices); - test_assert_cmpint (devices->len, ==, 1); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); device = g_ptr_array_index (devices, 0); - test_assert (device); - test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); info->notified = TRUE; @@ -267,29 +155,27 @@ devices_notify_cb (NMClient *c, static void test_device_added (void) { + NMClient *client; const GPtrArray *devices; NMDevice *device; DeviceAddedInfo info = { loop, FALSE, FALSE, 0, 0 }; - service_init (); - - /* Give NMClient a chance to initialize */ - g_timeout_add_seconds (5, loop_quit, loop); - g_main_loop_run (loop); + sinfo = nm_test_service_init (); + client = test_client_new (); - devices = nm_client_get_devices (_sinfo->client); - test_assert (devices == NULL); + devices = nm_client_get_devices (client); + g_assert (devices == NULL); /* Tell the test service to add a new device */ add_device ("AddWiredDevice", "eth0", NULL); - g_signal_connect (_sinfo->client, + g_signal_connect (client, "device-added", (GCallback) device_added_cb, &info); info.quit_count++; - g_signal_connect (_sinfo->client, + g_signal_connect (client, "notify::devices", (GCallback) devices_notify_cb, &info); @@ -299,21 +185,22 @@ test_device_added (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.signaled); - test_assert (info.notified); + g_assert (info.signaled); + g_assert (info.notified); - g_signal_handlers_disconnect_by_func (_sinfo->client, device_added_cb, &info); - g_signal_handlers_disconnect_by_func (_sinfo->client, devices_notify_cb, &info); + g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); + g_signal_handlers_disconnect_by_func (client, devices_notify_cb, &info); - devices = nm_client_get_devices (_sinfo->client); - test_assert (devices); - test_assert_cmpint (devices->len, ==, 1); + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); device = g_ptr_array_index (devices, 0); - test_assert (device); - test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); - service_cleanup (); + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); } /*******************************************************************/ @@ -346,7 +233,7 @@ wifi_device_added_cb (NMClient *c, NMDevice *device, WifiApInfo *info) { - test_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0"); + g_assert_cmpstr (nm_device_get_iface (device), ==, "wlan0"); info->found = TRUE; wifi_check_quit (info); } @@ -355,7 +242,7 @@ static void got_ap_path (WifiApInfo *info, const char *path) { if (info->ap_path) - test_assert_cmpstr (info->ap_path, ==, path); + g_assert_cmpstr (info->ap_path, ==, path); else info->ap_path = g_strdup (path); } @@ -365,8 +252,8 @@ wifi_ap_added_cb (NMDeviceWifi *w, NMAccessPoint *ap, WifiApInfo *info) { - test_assert (ap); - test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid); + g_assert (ap); + g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid); got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); info->signaled = TRUE; @@ -382,12 +269,12 @@ wifi_ap_add_notify_cb (NMDeviceWifi *w, NMAccessPoint *ap; aps = nm_device_wifi_get_access_points (w); - test_assert (aps); - test_assert_cmpint (aps->len, ==, 1); + g_assert (aps); + g_assert_cmpint (aps->len, ==, 1); ap = g_ptr_array_index (aps, 0); - test_assert (ap); - test_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11"); + g_assert (ap); + g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11"); got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); info->notified = TRUE; @@ -399,8 +286,8 @@ wifi_ap_removed_cb (NMDeviceWifi *w, NMAccessPoint *ap, WifiApInfo *info) { - test_assert (ap); - test_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap))); + g_assert (ap); + g_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap))); info->signaled = TRUE; wifi_check_quit (info); @@ -414,7 +301,7 @@ wifi_ap_remove_notify_cb (NMDeviceWifi *w, const GPtrArray *aps; aps = nm_device_wifi_get_access_points (w); - test_assert (aps == NULL); + g_assert (aps == NULL); info->notified = TRUE; wifi_check_quit (info); @@ -423,23 +310,21 @@ wifi_ap_remove_notify_cb (NMDeviceWifi *w, static void test_wifi_ap_added_removed (void) { + NMClient *client; NMDeviceWifi *wifi; WifiApInfo info = { loop, FALSE, FALSE, 0, 0 }; GVariant *ret; GError *error = NULL; char *expected_path = NULL; - service_init (); - - /* Give NMClient a chance to initialize */ - g_timeout_add_seconds (5, loop_quit, loop); - g_main_loop_run (loop); + sinfo = nm_test_service_init (); + client = test_client_new (); /*************************************/ /* Add the wifi device */ add_device ("AddWifiDevice", "wlan0", NULL); - g_signal_connect (_sinfo->client, + g_signal_connect (client, "device-added", (GCallback) wifi_device_added_cb, &info); @@ -449,11 +334,11 @@ test_wifi_ap_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.found); - g_signal_handlers_disconnect_by_func (_sinfo->client, wifi_device_added_cb, &info); + g_assert (info.found); + g_signal_handlers_disconnect_by_func (client, wifi_device_added_cb, &info); - wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (_sinfo->client, "wlan0"); - test_assert (NM_IS_DEVICE_WIFI (wifi)); + wifi = (NMDeviceWifi *) nm_client_get_device_by_iface (client, "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (wifi)); /*************************************/ /* Add the wifi device */ @@ -461,16 +346,16 @@ test_wifi_ap_added_removed (void) info.notified = FALSE; info.quit_id = 0; - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, "AddWifiAp", g_variant_new ("(sss)", "wlan0", "test-ap", expected_bssid), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); - test_assert (ret); - test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); g_variant_get (ret, "(o)", &expected_path); g_variant_unref (ret); @@ -490,10 +375,10 @@ test_wifi_ap_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.signaled); - test_assert (info.notified); - test_assert (info.ap_path); - test_assert_cmpstr (info.ap_path, ==, expected_path); + g_assert (info.signaled); + g_assert (info.notified); + g_assert (info.ap_path); + g_assert_cmpstr (info.ap_path, ==, expected_path); g_signal_handlers_disconnect_by_func (wifi, wifi_ap_added_cb, &info); g_signal_handlers_disconnect_by_func (wifi, wifi_ap_add_notify_cb, &info); @@ -503,14 +388,14 @@ test_wifi_ap_added_removed (void) info.notified = FALSE; info.quit_id = 0; - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, "RemoveWifiAp", g_variant_new ("(so)", "wlan0", expected_path), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); + g_assert_no_error (error); g_clear_pointer (&ret, g_variant_unref); g_signal_connect (wifi, @@ -529,14 +414,16 @@ test_wifi_ap_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.signaled); - test_assert (info.notified); + g_assert (info.signaled); + g_assert (info.notified); g_signal_handlers_disconnect_by_func (wifi, wifi_ap_removed_cb, &info); g_signal_handlers_disconnect_by_func (wifi, wifi_ap_remove_notify_cb, &info); g_free (info.ap_path); g_free (expected_path); - service_cleanup (); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); } /*******************************************************************/ @@ -569,7 +456,7 @@ wimax_device_added_cb (NMClient *c, NMDevice *device, WimaxNspInfo *info) { - test_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0"); + g_assert_cmpstr (nm_device_get_iface (device), ==, "wmx0"); info->found = TRUE; wimax_check_quit (info); } @@ -578,7 +465,7 @@ static void got_nsp_path (WimaxNspInfo *info, const char *path) { if (info->nsp_path) - test_assert_cmpstr (info->nsp_path, ==, path); + g_assert_cmpstr (info->nsp_path, ==, path); else info->nsp_path = g_strdup (path); } @@ -588,8 +475,8 @@ wimax_nsp_added_cb (NMDeviceWimax *w, NMWimaxNsp *nsp, WimaxNspInfo *info) { - test_assert (nsp); - test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + g_assert (nsp); + g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); info->signaled = TRUE; @@ -605,12 +492,12 @@ wimax_nsp_add_notify_cb (NMDeviceWimax *w, NMWimaxNsp *nsp; nsps = nm_device_wimax_get_nsps (w); - test_assert (nsps); - test_assert_cmpint (nsps->len, ==, 1); + g_assert (nsps); + g_assert_cmpint (nsps->len, ==, 1); nsp = g_ptr_array_index (nsps, 0); - test_assert (nsp); - test_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + g_assert (nsp); + g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); info->notified = TRUE; @@ -622,8 +509,8 @@ wimax_nsp_removed_cb (NMDeviceWimax *w, NMWimaxNsp *nsp, WimaxNspInfo *info) { - test_assert (nsp); - test_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp))); + g_assert (nsp); + g_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp))); info->signaled = TRUE; wimax_check_quit (info); @@ -637,7 +524,7 @@ wimax_nsp_remove_notify_cb (NMDeviceWimax *w, const GPtrArray *nsps; nsps = nm_device_wimax_get_nsps (w); - test_assert (nsps == NULL); + g_assert (nsps == NULL); info->notified = TRUE; wimax_check_quit (info); @@ -646,23 +533,21 @@ wimax_nsp_remove_notify_cb (NMDeviceWimax *w, static void test_wimax_nsp_added_removed (void) { + NMClient *client; NMDeviceWimax *wimax; WimaxNspInfo info = { loop, FALSE, FALSE, 0, 0 }; GVariant *ret; GError *error = NULL; char *expected_path = NULL; - service_init (); - - /* Give NMClient a chance to initialize */ - g_timeout_add_seconds (5, loop_quit, loop); - g_main_loop_run (loop); + sinfo = nm_test_service_init (); + client = test_client_new (); /*************************************/ /* Add the wimax device */ add_device ("AddWimaxDevice", "wmx0", NULL); - g_signal_connect (_sinfo->client, + g_signal_connect (client, "device-added", (GCallback) wimax_device_added_cb, &info); @@ -672,11 +557,11 @@ test_wimax_nsp_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.found); - g_signal_handlers_disconnect_by_func (_sinfo->client, wimax_device_added_cb, &info); + g_assert (info.found); + g_signal_handlers_disconnect_by_func (client, wimax_device_added_cb, &info); - wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (_sinfo->client, "wmx0"); - test_assert (NM_IS_DEVICE_WIMAX (wimax)); + wimax = (NMDeviceWimax *) nm_client_get_device_by_iface (client, "wmx0"); + g_assert (NM_IS_DEVICE_WIMAX (wimax)); /*************************************/ /* Add the wimax NSP */ @@ -684,16 +569,16 @@ test_wimax_nsp_added_removed (void) info.notified = FALSE; info.quit_id = 0; - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, "AddWimaxNsp", g_variant_new ("(ss)", "wmx0", expected_nsp_name), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); - test_assert (ret); - test_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); g_variant_get (ret, "(o)", &expected_path); g_variant_unref (ret); @@ -713,10 +598,10 @@ test_wimax_nsp_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.signaled); - test_assert (info.notified); - test_assert (info.nsp_path); - test_assert_cmpstr (info.nsp_path, ==, expected_path); + g_assert (info.signaled); + g_assert (info.notified); + g_assert (info.nsp_path); + g_assert_cmpstr (info.nsp_path, ==, expected_path); g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_added_cb, &info); g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_add_notify_cb, &info); @@ -726,14 +611,14 @@ test_wimax_nsp_added_removed (void) info.notified = FALSE; info.quit_id = 0; - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, "RemoveWimaxNsp", g_variant_new ("(so)", "wmx0", expected_path), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); + g_assert_no_error (error); g_clear_pointer (&ret, g_variant_unref); g_signal_connect (wimax, @@ -752,14 +637,16 @@ test_wimax_nsp_added_removed (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert (info.signaled); - test_assert (info.notified); + g_assert (info.signaled); + g_assert (info.notified); g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_removed_cb, &info); g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_remove_notify_cb, &info); g_free (info.nsp_path); g_free (expected_path); - service_cleanup (); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); } /*******************************************************************/ @@ -796,7 +683,7 @@ da_device_removed_cb (NMClient *c, NMDevice *device, DaInfo *info) { - test_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); info->signaled = TRUE; da_check_quit (info); } @@ -812,14 +699,14 @@ da_devices_notify_cb (NMClient *c, const char *iface; devices = nm_client_get_devices (c); - test_assert (devices); - test_assert_cmpint (devices->len, ==, 2); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 2); for (i = 0; i < devices->len; i++) { device = g_ptr_array_index (devices, i); iface = nm_device_get_iface (device); - test_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1")); + g_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1")); } info->notified = TRUE; @@ -829,6 +716,7 @@ da_devices_notify_cb (NMClient *c, static void test_devices_array (void) { + NMClient *client; DaInfo info = { loop }; char *paths[3] = { NULL, NULL, NULL }; NMDevice *device; @@ -836,11 +724,8 @@ test_devices_array (void) GError *error = NULL; GVariant *ret; - service_init (); - - /* Give NMClient a chance to initialize */ - g_timeout_add_seconds (5, loop_quit, loop); - g_main_loop_run (loop); + sinfo = nm_test_service_init (); + client = test_client_new (); /*************************************/ /* Add some devices */ @@ -849,7 +734,7 @@ test_devices_array (void) add_device ("AddWiredDevice", "eth1", &paths[2]); info.quit_count = 3; - g_signal_connect (_sinfo->client, + g_signal_connect (client, "device-added", (GCallback) da_device_added_cb, &info); @@ -858,42 +743,42 @@ test_devices_array (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert_cmpint (info.quit_count, ==, 0); - g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_added_cb, &info); + g_assert_cmpint (info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func (client, da_device_added_cb, &info); /* Ensure the devices now exist */ - devices = nm_client_get_devices (_sinfo->client); - test_assert (devices); - test_assert_cmpint (devices->len, ==, 3); + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 3); - device = nm_client_get_device_by_iface (_sinfo->client, "wlan0"); - test_assert (NM_IS_DEVICE_WIFI (device)); + device = nm_client_get_device_by_iface (client, "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (device)); - device = nm_client_get_device_by_iface (_sinfo->client, "eth0"); - test_assert (NM_IS_DEVICE_ETHERNET (device)); + device = nm_client_get_device_by_iface (client, "eth0"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); - device = nm_client_get_device_by_iface (_sinfo->client, "eth1"); - test_assert (NM_IS_DEVICE_ETHERNET (device)); + device = nm_client_get_device_by_iface (client, "eth1"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); /********************************/ /* Now remove the device in the middle */ - ret = g_dbus_proxy_call_sync (_sinfo->proxy, + ret = g_dbus_proxy_call_sync (sinfo->proxy, "RemoveDevice", g_variant_new ("(o)", paths[1]), G_DBUS_CALL_FLAGS_NO_AUTO_START, 3000, NULL, &error); - test_assert_no_error (error); - test_assert (ret); + g_assert_no_error (error); + g_assert (ret); g_variant_unref (ret); - g_signal_connect (_sinfo->client, + g_signal_connect (client, "device-removed", (GCallback) da_device_removed_cb, &info); - g_signal_connect (_sinfo->client, + g_signal_connect (client, "notify::devices", (GCallback) da_devices_notify_cb, &info); @@ -903,25 +788,94 @@ test_devices_array (void) info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); g_main_loop_run (loop); - test_assert_cmpint (info.quit_count, ==, 0); - g_signal_handlers_disconnect_by_func (_sinfo->client, da_device_removed_cb, &info); - g_signal_handlers_disconnect_by_func (_sinfo->client, da_devices_notify_cb, &info); + g_assert_cmpint (info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func (client, da_device_removed_cb, &info); + g_signal_handlers_disconnect_by_func (client, da_devices_notify_cb, &info); /* Ensure only two are left */ - devices = nm_client_get_devices (_sinfo->client); - test_assert (devices); - test_assert_cmpint (devices->len, ==, 2); + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 2); - device = nm_client_get_device_by_iface (_sinfo->client, "wlan0"); - test_assert (NM_IS_DEVICE_WIFI (device)); + device = nm_client_get_device_by_iface (client, "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (device)); - device = nm_client_get_device_by_iface (_sinfo->client, "eth1"); - test_assert (NM_IS_DEVICE_ETHERNET (device)); + device = nm_client_get_device_by_iface (client, "eth1"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); g_free (paths[0]); g_free (paths[1]); g_free (paths[2]); - service_cleanup (); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +static void +manager_running_changed (GObject *client, + GParamSpec *pspec, + gpointer user_data) +{ + int *running_changed = user_data; + + (*running_changed)++; + g_main_loop_quit (loop); +} + +static void +test_client_manager_running (void) +{ + NMClient *client1, *client2; + guint quit_id; + int running_changed = 0; + GError *error = NULL; + + client1 = test_client_new (); + + g_assert (!nm_client_get_manager_running (client1)); + g_assert_cmpstr (nm_client_get_version (client1), ==, NULL); + + g_assert (!nm_client_networking_get_enabled (client1)); + /* This will have no effect, but it shouldn't cause any warnings either. */ + nm_client_networking_set_enabled (client1, TRUE); + g_assert (!nm_client_networking_get_enabled (client1)); + + /* OTOH, this should result in an error */ + nm_client_set_logging (client1, "DEFAULT", "INFO", &error); + g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_MANAGER_NOT_RUNNING); + g_clear_error (&error); + + /* Now start the test service. */ + sinfo = nm_test_service_init (); + client2 = test_client_new (); + + /* client2 should know that NM is running, but the previously-created + * client1 hasn't gotten the news yet. + */ + g_assert (!nm_client_get_manager_running (client1)); + g_assert (nm_client_get_manager_running (client2)); + + g_signal_connect (client1, "notify::" NM_CLIENT_MANAGER_RUNNING, + G_CALLBACK (manager_running_changed), &running_changed); + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 1); + g_assert (nm_client_get_manager_running (client1)); + g_source_remove (quit_id); + + /* And kill it */ + g_clear_pointer (&sinfo, nm_test_service_cleanup); + + g_assert (nm_client_get_manager_running (client1)); + + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 2); + g_assert (!nm_client_get_manager_running (client1)); + g_source_remove (quit_id); + + g_object_unref (client1); + g_object_unref (client2); } /*******************************************************************/ @@ -929,24 +883,19 @@ test_devices_array (void) int main (int argc, char **argv) { - g_assert (argc == 3); - #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); #endif g_test_init (&argc, &argv, NULL); - fake_path = argv[1]; - fake_bin = argv[2]; - fake_exec = g_strdup_printf ("%s/%s", argv[1], argv[2]); - loop = g_main_loop_new (NULL, FALSE); g_test_add_func ("/libnm-glib/device-added", test_device_added); g_test_add_func ("/libnm-glib/wifi-ap-added-removed", test_wifi_ap_added_removed); g_test_add_func ("/libnm-glib/wimax-nsp-added-removed", test_wimax_nsp_added_removed); g_test_add_func ("/libnm-glib/devices-array", test_devices_array); + g_test_add_func ("/libnm-glib/client-manager-running", test_client_manager_running); return g_test_run (); } diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c index e3ef7f22..237e287f 100644 --- a/libnm-glib/tests/test-remote-settings-client.c +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -14,10 +14,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) 2010 - 2011 Red Hat, Inc. + * Copyright 2010 - 2011 Red Hat, Inc. * */ +#include "config.h" + #include #include #include @@ -33,31 +35,15 @@ #include #include "nm-remote-settings.h" +#include "common.h" -static GPid spid = 0; +static NMTestServiceInfo *sinfo; static NMRemoteSettings *settings = NULL; DBusGConnection *bus = NULL; NMRemoteConnection *remote = NULL; /*******************************************************************/ -static void -cleanup (void) -{ - if (settings) - g_object_unref (settings); - kill (spid, SIGTERM); -} - -#define test_assert(condition) \ -do { \ - if (!G_LIKELY (condition)) \ - cleanup (); \ - g_assert (condition); \ -} while (0) - -/*******************************************************************/ - static void add_cb (NMRemoteSettings *s, NMRemoteConnection *connection, @@ -69,6 +55,7 @@ add_cb (NMRemoteSettings *s, *((gboolean *) user_data) = TRUE; remote = connection; + g_object_add_weak_pointer (G_OBJECT (connection), (void **) &remote); } #define TEST_CON_ID "blahblahblah" @@ -103,20 +90,20 @@ test_add_connection (void) connection, add_cb, &done); - test_assert (success == TRUE); + g_assert (success == TRUE); start = time (NULL); do { now = time (NULL); g_main_context_iteration (NULL, FALSE); } while ((done == FALSE) && (now - start < 5)); - test_assert (done == TRUE); - test_assert (remote != NULL); + g_assert (done == TRUE); + g_assert (remote != NULL); /* Make sure the connection is the same as what we added */ - test_assert (nm_connection_compare (connection, - NM_CONNECTION (remote), - NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); + g_assert (nm_connection_compare (connection, + NM_CONNECTION (remote), + NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); } /*******************************************************************/ @@ -130,10 +117,8 @@ set_visible_cb (DBusGProxy *proxy, gboolean success; success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); - if (!success) - g_warning ("Failed to change connection visibility: %s", error->message); - test_assert (success == TRUE); - test_assert (error == NULL); + g_assert_no_error (error); + g_assert (success == TRUE); } static void @@ -161,7 +146,7 @@ test_make_invisible (void) gboolean done = FALSE, has_settings = FALSE; char *path; - test_assert (remote != NULL); + g_assert (remote != NULL); /* Listen for the remove event when the connection becomes invisible */ g_signal_connect (remote, "removed", G_CALLBACK (invis_removed_cb), &done); @@ -171,7 +156,7 @@ test_make_invisible (void) NM_DBUS_SERVICE, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); - test_assert (proxy != NULL); + g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, @@ -183,22 +168,26 @@ test_make_invisible (void) now = time (NULL); g_main_context_iteration (NULL, FALSE); } while ((done == FALSE) && (now - start < 5)); - test_assert (done == TRUE); + g_assert (done == TRUE); + + g_assert (remote); + g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (invis_removed_cb), &done); /* Ensure NMRemoteSettings no longer has the connection */ list = nm_remote_settings_list_connections (settings); for (iter = list; iter; iter = g_slist_next (iter)) { NMConnection *candidate = NM_CONNECTION (iter->data); - test_assert ((gpointer) remote != (gpointer) candidate); - test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + g_assert ((gpointer) remote != (gpointer) candidate); + g_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); } /* And ensure the invisible connection no longer has any settings */ + g_assert (remote); nm_connection_for_each_setting_value (NM_CONNECTION (remote), invis_has_settings_cb, &has_settings); - test_assert (has_settings == FALSE); + g_assert (has_settings == FALSE); g_free (path); g_object_unref (proxy); @@ -224,7 +213,7 @@ test_make_visible (void) char *path; NMRemoteConnection *new = NULL; - test_assert (remote != NULL); + g_assert (remote != NULL); /* Wait for the new-connection signal when the connection is visible again */ g_signal_connect (settings, NM_REMOTE_SETTINGS_NEW_CONNECTION, @@ -235,7 +224,7 @@ test_make_visible (void) NM_DBUS_SERVICE, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); - test_assert (proxy != NULL); + g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, @@ -250,7 +239,10 @@ test_make_visible (void) } while ((new == NULL) && (now - start < 5)); /* Ensure the new connection is the same as the one we made visible again */ - test_assert (new == remote); + g_assert (new); + g_assert (new == remote); + + g_signal_handlers_disconnect_by_func (settings, G_CALLBACK (vis_new_connection_cb), &new); /* Ensure NMRemoteSettings has the connection */ list = nm_remote_settings_list_connections (settings); @@ -258,13 +250,13 @@ test_make_visible (void) NMConnection *candidate = NM_CONNECTION (iter->data); if ((gpointer) remote == (gpointer) candidate) { - test_assert (strcmp (path, nm_connection_get_path (candidate)) == 0); - test_assert (strcmp (TEST_CON_ID, nm_connection_get_id (candidate)) == 0); + g_assert_cmpstr (path, ==, nm_connection_get_path (candidate)); + g_assert_cmpstr (TEST_CON_ID, ==, nm_connection_get_id (candidate)); found = TRUE; break; } } - test_assert (found == TRUE); + g_assert (found == TRUE); g_free (path); g_object_unref (proxy); @@ -281,10 +273,8 @@ deleted_cb (DBusGProxy *proxy, gboolean success; success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); - if (!success) - g_warning ("Failed to delete connection: %s", error->message); - test_assert (success == TRUE); - test_assert (error == NULL); + g_assert_no_error (error); + g_assert (success == TRUE); } static void @@ -305,9 +295,11 @@ test_remove_connection (void) /* Find a connection to delete */ list = nm_remote_settings_list_connections (settings); - test_assert (g_slist_length (list) > 0); + g_assert_cmpint (g_slist_length (list), >, 0); connection = NM_REMOTE_CONNECTION (list->data); + g_assert (connection); + g_assert (remote == connection); path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); g_signal_connect (connection, "removed", G_CALLBACK (removed_cb), &done); @@ -315,7 +307,7 @@ test_remove_connection (void) NM_DBUS_SERVICE, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); - test_assert (proxy != NULL); + g_assert (proxy != NULL); /* Bypass the NMRemoteSettings object so we can test it independently */ dbus_g_proxy_begin_call (proxy, "Delete", deleted_cb, NULL, NULL, G_TYPE_INVALID); @@ -325,15 +317,17 @@ test_remove_connection (void) now = time (NULL); g_main_context_iteration (NULL, FALSE); } while ((done == FALSE) && (now - start < 5)); - test_assert (done == TRUE); + g_assert (done == TRUE); + + g_assert (!remote); /* Ensure NMRemoteSettings no longer has the connection */ list = nm_remote_settings_list_connections (settings); for (iter = list; iter; iter = g_slist_next (iter)) { NMConnection *candidate = NM_CONNECTION (iter->data); - test_assert ((gpointer) connection != (gpointer) candidate); - test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + g_assert ((gpointer) connection != (gpointer) candidate); + g_assert_cmpstr (path, ==, nm_connection_get_path (candidate)); } g_free (path); @@ -342,15 +336,93 @@ test_remove_connection (void) /*******************************************************************/ +static GMainLoop *loop; + +static gboolean +loop_quit (gpointer user_data) +{ + g_main_loop_quit (loop); + return G_SOURCE_REMOVE; +} + +static void +settings_service_running_changed (GObject *client, + GParamSpec *pspec, + gpointer user_data) +{ + int *running_changed = user_data; + + (*running_changed)++; + g_main_loop_quit (loop); +} + +static void +test_service_running (void) +{ + NMRemoteSettings *settings2; + guint quit_id; + int running_changed = 0; + gboolean running; + + loop = g_main_loop_new (NULL, FALSE); + + g_object_get (G_OBJECT (settings), + NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, + NULL); + g_assert (running == TRUE); + + /* Now kill the test service. */ + nm_test_service_cleanup (sinfo); + + settings2 = nm_remote_settings_new (bus); + + /* settings2 should know that NM is running, but the previously-created + * settings hasn't gotten the news yet. + */ + g_object_get (G_OBJECT (settings2), + NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, + NULL); + g_assert (running == FALSE); + g_object_get (G_OBJECT (settings), + NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, + NULL); + g_assert (running == TRUE); + + g_signal_connect (settings, "notify::" NM_REMOTE_SETTINGS_SERVICE_RUNNING, + G_CALLBACK (settings_service_running_changed), &running_changed); + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 1); + g_source_remove (quit_id); + + g_object_get (G_OBJECT (settings2), + NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, + NULL); + g_assert (running == FALSE); + + /* Now restart it */ + sinfo = nm_test_service_init (); + + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 2); + g_source_remove (quit_id); + + g_object_get (G_OBJECT (settings2), + NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, + NULL); + g_assert (running == TRUE); + + g_object_unref (settings2); +} + +/*******************************************************************/ + int main (int argc, char **argv) { - char *service_argv[3] = { NULL, NULL, NULL }; int ret; GError *error = NULL; - int i = 100; - - g_assert (argc == 3); #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); @@ -359,39 +431,27 @@ main (int argc, char **argv) g_test_init (&argc, &argv, NULL); bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) { - g_warning ("Error connecting to D-Bus: %s", error->message); - g_assert (error == NULL); - } - - service_argv[0] = g_strdup_printf ("%s/%s", argv[1], argv[2]); - if (!g_spawn_async (argv[1], service_argv, NULL, 0, NULL, NULL, &spid, &error)) { - g_warning ("Error spawning %s: %s", argv[2], error->message); - g_assert (error == NULL); - } + g_assert_no_error (error); - /* Wait until the service is registered on the bus */ - while (i > 0) { - g_usleep (G_USEC_PER_SEC / 50); - if (dbus_bus_name_has_owner (dbus_g_connection_get_connection (bus), - "org.freedesktop.NetworkManager", - NULL)) - break; - i--; - } - test_assert (i > 0); + sinfo = nm_test_service_init (); settings = nm_remote_settings_new (bus); - test_assert (settings != NULL); + g_assert (settings != NULL); + /* FIXME: these tests assume that they get run in order, but g_test_run() + * does not actually guarantee that! + */ g_test_add_func ("/remote_settings/add_connection", test_add_connection); g_test_add_func ("/remote_settings/make_invisible", test_make_invisible); g_test_add_func ("/remote_settings/make_visible", test_make_visible); g_test_add_func ("/remote_settings/remove_connection", test_remove_connection); + g_test_add_func ("/remote_settings/service_running", test_service_running); ret = g_test_run (); - cleanup (); + nm_test_service_cleanup (sinfo); + g_object_unref (settings); + dbus_g_connection_unref (bus); return ret; } diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py deleted file mode 100755 index 439073ad..00000000 --- a/libnm-glib/tests/test-remote-settings-service.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python -# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - -from __future__ import print_function - -from gi.repository import GLib, GObject -import sys -import dbus -import dbus.service -import dbus.mainloop.glib - -IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings' -IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection' -IFACE_DBUS = 'org.freedesktop.DBus' - -class UnknownInterfaceException(dbus.DBusException): - _dbus_error_name = IFACE_DBUS + '.UnknownInterface' - -class UnknownPropertyException(dbus.DBusException): - _dbus_error_name = IFACE_DBUS + '.UnknownProperty' - -class PermissionDeniedException(dbus.DBusException): - _dbus_error_name = IFACE_SETTINGS + '.PermissionDenied' - -mainloop = GObject.MainLoop() - -class Connection(dbus.service.Object): - def __init__(self, bus, object_path, settings, remove_func): - dbus.service.Object.__init__(self, bus, object_path) - self.path = object_path - self.settings = settings - self.remove_func = remove_func - self.visible = True - self.props = {} - self.props['Unsaved'] = False - - # Properties interface - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') - def GetAll(self, iface): - if iface != IFACE_CONNECTION: - raise UnknownInterfaceException() - return self.props - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') - def Get(self, iface, name): - if iface != IFACE_CONNECTION: - raise UnknownInterfaceException() - if not name in self.props.keys(): - raise UnknownPropertyException() - return self.props[name] - - # Connection methods - @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') - def GetSettings(self): - if not self.visible: - raise PermissionDeniedException() - return self.settings - - @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='b', out_signature='') - def SetVisible(self, vis): - self.visible = vis - self.Updated() - - @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='') - def Delete(self): - self.remove_func(self) - self.Removed() - - @dbus.service.signal(IFACE_CONNECTION, signature='') - def Removed(self): - pass - - @dbus.service.signal(IFACE_CONNECTION, signature='') - def Updated(self): - pass - -class Settings(dbus.service.Object): - def __init__(self, bus, object_path): - dbus.service.Object.__init__(self, bus, object_path) - self.connections = {} - self.bus = bus - self.counter = 1 - self.props = {} - self.props['Hostname'] = "foobar.baz" - self.props['CanModify'] = True - - @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='', out_signature='ao') - def ListConnections(self): - connections = [] - return self.connections.keys() - - @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o') - def AddConnection(self, settings): - path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter) - self.counter = self.counter + 1 - self.connections[path] = Connection(self.bus, path, settings, self.delete_connection) - print("Added connection {0}".format(path)) - return path - - def delete_connection(self, connection): - del self.connections[connection.path] - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') - def GetAll(self, iface): - if iface != IFACE_SETTINGS: - raise UnknownInterfaceException() - return self.props - - @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') - def Get(self, iface, name): - if iface != IFACE_SETTINGS: - raise UnknownInterfaceException() - if not name in self.props.keys(): - raise UnknownPropertyException() - return self.props[name] - - @dbus.service.signal(IFACE_SETTINGS, signature='o') - def NewConnection(self, path): - pass - - @dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='') - def Quit(self): - mainloop.quit() - -def quit_cb(user_data): - mainloop.quit() - -def main(): - dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - - bus = dbus.SessionBus() - obj = Settings(bus, "/org/freedesktop/NetworkManager/Settings") - if not bus.request_name("org.freedesktop.NetworkManager"): - sys.exit(1) - - print("Service started") - - GLib.timeout_add_seconds(20, quit_cb, None) - - try: - mainloop.run() - except Exception as e: - pass - - print("Service stopped") - sys.exit(0) - -if __name__ == '__main__': - main() - diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 01b2026a..3fdc79e5 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -5,8 +5,8 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/include \ -DG_LOG_DOMAIN=\""libnm-util"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ @@ -23,6 +23,8 @@ endif lib_LTLIBRARIES=libnm-util.la libnm_util_include_HEADERS = \ + NetworkManager.h \ + NetworkManagerVPN.h \ nm-connection.h \ nm-setting.h \ nm-setting-8021x.h \ @@ -51,9 +53,12 @@ libnm_util_include_HEADERS = \ nm-setting-wireless.h \ nm-setting-wireless-security.h \ nm-setting-vpn.h \ - nm-utils-enum-types.h \ nm-utils.h +nodist_libnm_util_include_HEADERS = \ + nm-utils-enum-types.h \ + nm-version.h + libnm_util_la_private_headers = \ crypto.h \ nm-param-spec-specialized.h \ @@ -101,7 +106,7 @@ libnm_util_la_SOURCES = \ GLIB_GENERATED = nm-utils-enum-types.h nm-utils-enum-types.c BUILT_SOURCES = $(GLIB_GENERATED) -nm_utils_enum_types_sources = $(libnm_util_include_HEADERS) +nm_utils_enum_types_sources = $(filter-out NetworkManager%,$(libnm_util_include_HEADERS)) GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM @@ -110,7 +115,7 @@ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) SYMBOL_VIS_FILE=$(srcdir)/libnm-util.ver libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "8:0:6" + -version-info "9:0:7" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c @@ -150,9 +155,9 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc DISTCLEANFILES = libnm-util.pc -CLEANFILES = +CLEANFILES = nm-version.h -EXTRA_DIST = libnm-util.pc.in libnm-util.ver +EXTRA_DIST = libnm-util.pc.in libnm-util.ver nm-version.h.in -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = @@ -160,7 +165,7 @@ INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) if HAVE_INTROSPECTION -introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) $(top_srcdir)/include/NetworkManager.h $(top_srcdir)/include/NetworkManagerVPN.h +introspection_sources = $(libnm_util_include_HEADERS) $(nodist_libnm_util_include_HEADERS) $(libnm_util_la_csources) NetworkManager-1.0.gir: libnm-util.la NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 @@ -179,6 +184,7 @@ typelibdir = $(libdir)/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) CLEANFILES += $(gir_DATA) $(typelib_DATA) + endif if ENABLE_TESTS diff --git a/libnm-util/Makefile.in b/libnm-util/Makefile.in index fa461f1f..5dea1b42 100644 --- a/libnm-util/Makefile.in +++ b/libnm-util/Makefile.in @@ -94,8 +94,9 @@ host_triplet = @host@ @HAVE_INTROSPECTION_TRUE@am__append_12 = $(gir_DATA) $(typelib_DATA) subdir = libnm-util DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(srcdir)/libnm-util.pc.in $(top_srcdir)/build-aux/depcomp \ - $(libnm_util_include_HEADERS) COPYING + $(srcdir)/libnm-util.pc.in $(srcdir)/nm-version.h.in \ + $(top_srcdir)/build-aux/depcomp $(libnm_util_include_HEADERS) \ + COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -114,7 +115,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = libnm-util.pc +CONFIG_CLEAN_FILES = libnm-util.pc nm-version.h CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -145,6 +146,7 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" \ "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" \ + "$(DESTDIR)$(libnm_util_includedir)" \ "$(DESTDIR)$(libnm_util_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @@ -253,7 +255,8 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA) -HEADERS = $(libnm_util_include_HEADERS) +HEADERS = $(libnm_util_include_HEADERS) \ + $(nodist_libnm_util_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ @@ -317,6 +320,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -440,6 +445,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -459,6 +465,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -485,7 +492,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -566,11 +573,14 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/include \ - -I${top_builddir}/include -DG_LOG_DOMAIN=\""libnm-util"\" \ + -DG_LOG_DOMAIN=\""libnm-util"\" \ + -DLOCALEDIR=\"$(datadir)/locale\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) $(UUID_CFLAGS) $(am__append_1) $(am__append_2) lib_LTLIBRARIES = libnm-util.la libnm_util_include_HEADERS = \ + NetworkManager.h \ + NetworkManagerVPN.h \ nm-connection.h \ nm-setting.h \ nm-setting-8021x.h \ @@ -599,9 +609,12 @@ libnm_util_include_HEADERS = \ nm-setting-wireless.h \ nm-setting-wireless-security.h \ nm-setting-vpn.h \ - nm-utils-enum-types.h \ nm-utils.h +nodist_libnm_util_include_HEADERS = \ + nm-utils-enum-types.h \ + nm-version.h + libnm_util_la_private_headers = \ crypto.h \ nm-param-spec-specialized.h \ @@ -648,14 +661,14 @@ libnm_util_la_SOURCES = $(libnm_util_la_csources) \ $(am__append_5) GLIB_GENERATED = nm-utils-enum-types.h nm-utils-enum-types.c BUILT_SOURCES = $(GLIB_GENERATED) -nm_utils_enum_types_sources = $(libnm_util_include_HEADERS) +nm_utils_enum_types_sources = $(filter-out NetworkManager%,$(libnm_util_include_HEADERS)) GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) \ $(am__append_4) $(am__append_6) SYMBOL_VIS_FILE = $(srcdir)/libnm-util.ver libnm_util_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ - -version-info "8:0:6" + -version-info "9:0:7" libnm_util_includedir = $(includedir)/NetworkManager @@ -669,12 +682,12 @@ libtest_crypto_la_LIBADD = $(GLIB_LIBS) $(am__append_8) \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc DISTCLEANFILES = libnm-util.pc -CLEANFILES = $(am__append_12) -EXTRA_DIST = libnm-util.pc.in libnm-util.ver +CLEANFILES = nm-version.h $(am__append_12) +EXTRA_DIST = libnm-util.pc.in libnm-util.ver nm-version.h.in INTROSPECTION_GIRS = $(am__append_11) INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) -@HAVE_INTROSPECTION_TRUE@introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) $(top_srcdir)/include/NetworkManager.h $(top_srcdir)/include/NetworkManagerVPN.h +@HAVE_INTROSPECTION_TRUE@introspection_sources = $(libnm_util_include_HEADERS) $(nodist_libnm_util_include_HEADERS) $(libnm_util_la_csources) @HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 @HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 @HAVE_INTROSPECTION_TRUE@NetworkManager_1_0_gir_EXPORT_PACKAGES = libnm-util @@ -723,6 +736,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): libnm-util.pc: $(top_builddir)/config.status $(srcdir)/libnm-util.pc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +nm-version.h: $(top_builddir)/config.status $(srcdir)/nm-version.h.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -928,6 +943,27 @@ uninstall-libnm_util_includeHEADERS: @list='$(libnm_util_include_HEADERS)'; test -n "$(libnm_util_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libnm_util_includedir)'; $(am__uninstall_files_from_dir) +install-nodist_libnm_util_includeHEADERS: $(nodist_libnm_util_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nodist_libnm_util_include_HEADERS)'; test -n "$(libnm_util_includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libnm_util_includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libnm_util_includedir)" || exit 1; \ + fi; \ + 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_HEADER) $$files '$(DESTDIR)$(libnm_util_includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libnm_util_includedir)" || exit $$?; \ + done + +uninstall-nodist_libnm_util_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nodist_libnm_util_include_HEADERS)'; test -n "$(libnm_util_includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libnm_util_includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. @@ -1091,7 +1127,7 @@ check: $(BUILT_SOURCES) all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libnm_util_includedir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libnm_util_includedir)" "$(DESTDIR)$(libnm_util_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1152,7 +1188,8 @@ info: info-recursive info-am: install-data-am: install-girDATA install-libnm_util_includeHEADERS \ - install-pkgconfigDATA install-typelibDATA + install-nodist_libnm_util_includeHEADERS install-pkgconfigDATA \ + install-typelibDATA install-dvi: install-dvi-recursive @@ -1199,8 +1236,9 @@ ps: ps-recursive ps-am: uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ - uninstall-libnm_util_includeHEADERS uninstall-pkgconfigDATA \ - uninstall-typelibDATA + uninstall-libnm_util_includeHEADERS \ + uninstall-nodist_libnm_util_includeHEADERS \ + uninstall-pkgconfigDATA uninstall-typelibDATA .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-strip @@ -1214,7 +1252,8 @@ uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-girDATA install-html install-html-am \ install-info install-info-am install-libLTLIBRARIES \ - install-libnm_util_includeHEADERS install-man install-pdf \ + install-libnm_util_includeHEADERS install-man \ + install-nodist_libnm_util_includeHEADERS install-pdf \ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ install-strip install-typelibDATA installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ @@ -1222,6 +1261,7 @@ uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-girDATA \ uninstall-libLTLIBRARIES uninstall-libnm_util_includeHEADERS \ + uninstall-nodist_libnm_util_includeHEADERS \ uninstall-pkgconfigDATA uninstall-typelibDATA include $(GLIB_MAKEFILE) diff --git a/libnm-util/NetworkManager.h b/libnm-util/NetworkManager.h new file mode 100644 index 00000000..08b4e6cf --- /dev/null +++ b/libnm-util/NetworkManager.h @@ -0,0 +1,563 @@ +/* -*- 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. + * + * Copyright 2004 - 2014 Red Hat, Inc. + */ + +/* Definitions related to NetworkManager's D-Bus interfaces. + * + * Note that although this header is installed as part of libnm-util, it is also + * used by some external code that does not link to libnm-util. + */ + +#ifndef NETWORK_MANAGER_H +#define NETWORK_MANAGER_H + +#include "nm-version.h" + +/* + * dbus services details + */ +#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" + +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device" +#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired" +#define NM_DBUS_INTERFACE_DEVICE_ADSL NM_DBUS_INTERFACE_DEVICE ".Adsl" +#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless" +#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH NM_DBUS_INTERFACE_DEVICE ".Bluetooth" +#define NM_DBUS_INTERFACE_DEVICE_OLPC_MESH NM_DBUS_INTERFACE_DEVICE ".OlpcMesh" +#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint" +#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint" +#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem" +#define NM_DBUS_INTERFACE_DEVICE_WIMAX NM_DBUS_INTERFACE_DEVICE ".WiMax" +#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp" +#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp" +#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active" +#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config" +#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config" +#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config" +#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" +#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband" +#define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond" +#define NM_DBUS_INTERFACE_DEVICE_TEAM NM_DBUS_INTERFACE_DEVICE ".Team" +#define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan" +#define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge" +#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic" +#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth" +#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun" +#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan" +#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan" +#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre" + + +#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" +#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" + +#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManager.Settings.Connection" +#define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManager/Settings/Connection" +#define NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS "org.freedesktop.NetworkManager.Settings.Connection.Secrets" + +#define NM_DBUS_INTERFACE_AGENT_MANAGER NM_DBUS_INTERFACE ".AgentManager" +#define NM_DBUS_PATH_AGENT_MANAGER "/org/freedesktop/NetworkManager/AgentManager" + +#define NM_DBUS_INTERFACE_SECRET_AGENT NM_DBUS_INTERFACE ".SecretAgent" +#define NM_DBUS_PATH_SECRET_AGENT "/org/freedesktop/NetworkManager/SecretAgent" + +/** + * NMState: + * @NM_STATE_UNKNOWN: networking state is unknown + * @NM_STATE_ASLEEP: networking is not enabled + * @NM_STATE_DISCONNECTED: there is no active network connection + * @NM_STATE_DISCONNECTING: network connections are being cleaned up + * @NM_STATE_CONNECTING: a network connection is being started + * @NM_STATE_CONNECTED_LOCAL: there is only local IPv4 and/or IPv6 connectivity + * @NM_STATE_CONNECTED_SITE: there is only site-wide IPv4 and/or IPv6 connectivity + * @NM_STATE_CONNECTED_GLOBAL: there is global IPv4 and/or IPv6 Internet connectivity + * + * #NMState values indicate the current overall networking state. + * + * (Corresponds to the NM_STATE type in nm-manager.xml.) + **/ +typedef enum { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70 +} NMState; + +/* For backwards compat */ +#define NM_STATE_CONNECTED NM_STATE_CONNECTED_GLOBAL + +/** + * NMConnectivityState: + * @NM_CONNECTIVITY_UNKNOWN: Network connectivity is unknown. + * @NM_CONNECTIVITY_NONE: The host is not connected to any network. + * @NM_CONNECTIVITY_PORTAL: The host is behind a captive portal and + * cannot reach the full Internet. + * @NM_CONNECTIVITY_LIMITED: The host is connected to a network, but + * does not appear to be able to reach the full Internet. + * @NM_CONNECTIVITY_FULL: The host is connected to a network, and + * appears to be able to reach the full Internet. + * + * (Corresponds to the NM_CONNECTIVITY type in nm-manager.xml.) + * + * Since: 0.9.8.6 + */ +typedef enum { + NM_CONNECTIVITY_UNKNOWN, + NM_CONNECTIVITY_NONE, + NM_CONNECTIVITY_PORTAL, + NM_CONNECTIVITY_LIMITED, + NM_CONNECTIVITY_FULL +} NMConnectivityState; + +/** + * NMDeviceType: + * @NM_DEVICE_TYPE_UNKNOWN: unknown device + * @NM_DEVICE_TYPE_GENERIC: generic support for unrecognized device types + * @NM_DEVICE_TYPE_ETHERNET: a wired ethernet device + * @NM_DEVICE_TYPE_WIFI: an 802.11 WiFi device + * @NM_DEVICE_TYPE_UNUSED1: not used + * @NM_DEVICE_TYPE_UNUSED2: not used + * @NM_DEVICE_TYPE_BT: a Bluetooth device supporting PAN or DUN access protocols + * @NM_DEVICE_TYPE_OLPC_MESH: an OLPC XO mesh networking device + * @NM_DEVICE_TYPE_WIMAX: an 802.16e Mobile WiMAX broadband device + * @NM_DEVICE_TYPE_MODEM: a modem supporting analog telephone, CDMA/EVDO, + * GSM/UMTS, or LTE network access protocols + * @NM_DEVICE_TYPE_INFINIBAND: an IP-over-InfiniBand device + * @NM_DEVICE_TYPE_BOND: a bond master interface + * @NM_DEVICE_TYPE_VLAN: an 802.1Q VLAN interface + * @NM_DEVICE_TYPE_ADSL: ADSL modem + * @NM_DEVICE_TYPE_BRIDGE: a bridge master interface + * @NM_DEVICE_TYPE_TEAM: a team master interface + * + * #NMDeviceType values indicate the type of hardware represented by + * an #NMDevice. + * + * (Corresponds to the NM_DEVICE_TYPE type in nm-device.xml.) + **/ +typedef enum { + NM_DEVICE_TYPE_UNKNOWN = 0, + NM_DEVICE_TYPE_ETHERNET = 1, + NM_DEVICE_TYPE_WIFI = 2, + NM_DEVICE_TYPE_UNUSED1 = 3, + NM_DEVICE_TYPE_UNUSED2 = 4, + NM_DEVICE_TYPE_BT = 5, /* Bluetooth */ + NM_DEVICE_TYPE_OLPC_MESH = 6, + NM_DEVICE_TYPE_WIMAX = 7, + NM_DEVICE_TYPE_MODEM = 8, + NM_DEVICE_TYPE_INFINIBAND = 9, + NM_DEVICE_TYPE_BOND = 10, + NM_DEVICE_TYPE_VLAN = 11, + NM_DEVICE_TYPE_ADSL = 12, + NM_DEVICE_TYPE_BRIDGE = 13, + NM_DEVICE_TYPE_GENERIC = 14, + NM_DEVICE_TYPE_TEAM = 15, +} NMDeviceType; + +/** + * NMDeviceCapabilities: + * @NM_DEVICE_CAP_NONE: device has no special capabilities + * @NM_DEVICE_CAP_NM_SUPPORTED: NetworkManager supports this device + * @NM_DEVICE_CAP_CARRIER_DETECT: this device can indicate carrier status + * @NM_DEVICE_CAP_IS_SOFTWARE: this device is a software device + * + * General device capability flags. + * + * (Corresponds to the NM_DEVICE_CAP type in nm-device-wifi.xml.) + **/ +typedef enum { + NM_DEVICE_CAP_NONE = 0x00000000, + NM_DEVICE_CAP_NM_SUPPORTED = 0x00000001, + NM_DEVICE_CAP_CARRIER_DETECT = 0x00000002, + NM_DEVICE_CAP_IS_SOFTWARE = 0x00000004, +} NMDeviceCapabilities; + + +/** + * NMDeviceWifiCapabilities: + * @NM_WIFI_DEVICE_CAP_NONE: device has no encryption/authentication capabilities + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP40: device supports 40/64-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_WEP104: device supports 104/128-bit WEP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_TKIP: device supports TKIP encryption + * @NM_WIFI_DEVICE_CAP_CIPHER_CCMP: device supports AES/CCMP encryption + * @NM_WIFI_DEVICE_CAP_WPA: device supports WPA1 authentication + * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication + * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode + * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode + * + * 802.11 specific device encryption and authentication capabilities. + * + * (Corresponds to the NM_802_11_DEVICE_CAP type in nm-device-wifi.xml.) + **/ +typedef enum { + NM_WIFI_DEVICE_CAP_NONE = 0x00000000, + NM_WIFI_DEVICE_CAP_CIPHER_WEP40 = 0x00000001, + NM_WIFI_DEVICE_CAP_CIPHER_WEP104 = 0x00000002, + NM_WIFI_DEVICE_CAP_CIPHER_TKIP = 0x00000004, + NM_WIFI_DEVICE_CAP_CIPHER_CCMP = 0x00000008, + NM_WIFI_DEVICE_CAP_WPA = 0x00000010, + NM_WIFI_DEVICE_CAP_RSN = 0x00000020, + NM_WIFI_DEVICE_CAP_AP = 0x00000040, + NM_WIFI_DEVICE_CAP_ADHOC = 0x00000080 +} NMDeviceWifiCapabilities; + + +/** + * NM80211ApFlags: + * @NM_802_11_AP_FLAGS_NONE: access point has no special capabilities + * @NM_802_11_AP_FLAGS_PRIVACY: access point requires authentication and + * encryption (usually means WEP) + * + * 802.11 access point flags. + * + * (Corresponds to the NM_802_11_AP_FLAGS type in nm-access-point.xml.) + **/ +typedef enum { + NM_802_11_AP_FLAGS_NONE = 0x00000000, + NM_802_11_AP_FLAGS_PRIVACY = 0x00000001 +} NM80211ApFlags; + +/** + * NM80211ApSecurityFlags: + * @NM_802_11_AP_SEC_NONE: the access point has no special security requirements + * @NM_802_11_AP_SEC_PAIR_WEP40: 40/64-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_WEP104: 104/128-bit WEP is supported for + * pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_TKIP: TKIP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_PAIR_CCMP: AES/CCMP is supported for pairwise/unicast encryption + * @NM_802_11_AP_SEC_GROUP_WEP40: 40/64-bit WEP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_GROUP_WEP104: 104/128-bit WEP is supported for + * group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_TKIP: TKIP is supported for group/broadcast encryption + * @NM_802_11_AP_SEC_GROUP_CCMP: AES/CCMP is supported for group/broadcast + * encryption + * @NM_802_11_AP_SEC_KEY_MGMT_PSK: WPA/RSN Pre-Shared Key encryption is + * supported + * @NM_802_11_AP_SEC_KEY_MGMT_802_1X: 802.1x authentication and key management + * is supported + * + * 802.11 access point security and authentication flags. These flags describe + * the current security requirements of an access point as determined from the + * access point's beacon. + * + * (Corresponds to the NM_802_11_AP_SEC type in nm-access-point.xml.) + **/ +typedef enum { + NM_802_11_AP_SEC_NONE = 0x00000000, + NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001, + NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002, + NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004, + NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008, + NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010, + NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020, + NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040, + NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080, + NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100, + NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200 +} NM80211ApSecurityFlags; + +/** + * NM80211Mode: + * @NM_802_11_MODE_UNKNOWN: the device or access point mode is unknown + * @NM_802_11_MODE_ADHOC: for both devices and access point objects, indicates + * the object is part of an Ad-Hoc 802.11 network without a central + * coordinating access point. + * @NM_802_11_MODE_INFRA: the device or access point is in infrastructure mode. + * For devices, this indicates the device is an 802.11 client/station. For + * access point objects, this indicates the object is an access point that + * provides connectivity to clients. + * @NM_802_11_MODE_AP: the device is an access point/hotspot. Not valid for + * access point objects; used only for hotspot mode on the local machine. + * + * Indicates the 802.11 mode an access point or device is currently in. + * + * (Corresponds to the NM_802_11_MODE type in generic-types.xml.) + **/ +typedef enum { + NM_802_11_MODE_UNKNOWN = 0, + NM_802_11_MODE_ADHOC, + NM_802_11_MODE_INFRA, + NM_802_11_MODE_AP +} NM80211Mode; + +/** + * NMBluetoothCapabilities: + * @NM_BT_CAPABILITY_NONE: device has no usable capabilities + * @NM_BT_CAPABILITY_DUN: device provides Dial-Up Networking capability + * @NM_BT_CAPABILITY_NAP: device provides Network Access Point capability + * + * #NMBluetoothCapabilities values indicate the usable capabilities of a + * Bluetooth device. + * + * (Corresponds to the NM_BT_CAPABILITY type in nm-device-bt.xml.) + **/ +typedef enum { + NM_BT_CAPABILITY_NONE = 0x00000000, + NM_BT_CAPABILITY_DUN = 0x00000001, + NM_BT_CAPABILITY_NAP = 0x00000002, +} NMBluetoothCapabilities; + +/** + * NMDeviceModemCapabilities: + * @NM_DEVICE_MODEM_CAPABILITY_NONE: modem has no usable capabilities + * @NM_DEVICE_MODEM_CAPABILITY_POTS: modem uses the analog wired telephone + * network and is not a wireless/cellular device + * @NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO: modem supports at least one of CDMA + * 1xRTT, EVDO revision 0, EVDO revision A, or EVDO revision B + * @NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS: modem supports at least one of GSM, + * GPRS, EDGE, UMTS, HSDPA, HSUPA, or HSPA+ packet switched data capability + * @NM_DEVICE_MODEM_CAPABILITY_LTE: modem has LTE data capability + * + * #NMDeviceModemCapabilities values indicate the generic radio access + * technology families a modem device supports. For more information on the + * specific access technologies the device supports use the ModemManager D-Bus + * API. + * + * (Corresponds to the NM_DEVICE_MODEM_CAPABILITY type in nm-device-modem.xml.) + **/ +typedef enum { + NM_DEVICE_MODEM_CAPABILITY_NONE = 0x00000000, + NM_DEVICE_MODEM_CAPABILITY_POTS = 0x00000001, + NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO = 0x00000002, + NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS = 0x00000004, + NM_DEVICE_MODEM_CAPABILITY_LTE = 0x00000008, +} NMDeviceModemCapabilities; + + +/** + * NMDeviceState: + * @NM_DEVICE_STATE_UNKNOWN: the device's state is unknown + * @NM_DEVICE_STATE_UNMANAGED: the device is recognized, but not managed by + * NetworkManager + * @NM_DEVICE_STATE_UNAVAILABLE: the device is managed by NetworkManager, but + * is not available for use. Reasons may include the wireless switched off, + * missing firmware, no ethernet carrier, missing supplicant or modem manager, + * etc. + * @NM_DEVICE_STATE_DISCONNECTED: the device can be activated, but is currently + * idle and not connected to a network. + * @NM_DEVICE_STATE_PREPARE: the device is preparing the connection to the + * network. This may include operations like changing the MAC address, + * setting physical link properties, and anything else required to connect + * to the requested network. + * @NM_DEVICE_STATE_CONFIG: the device is connecting to the requested network. + * This may include operations like associating with the WiFi AP, dialing + * the modem, connecting to the remote Bluetooth device, etc. + * @NM_DEVICE_STATE_NEED_AUTH: the device requires more information to continue + * connecting to the requested network. This includes secrets like WiFi + * passphrases, login passwords, PIN codes, etc. + * @NM_DEVICE_STATE_IP_CONFIG: the device is requesting IPv4 and/or IPv6 + * addresses and routing information from the network. + * @NM_DEVICE_STATE_IP_CHECK: the device is checking whether further action is + * required for the requested network connection. This may include checking + * whether only local network access is available, whether a captive portal + * is blocking access to the Internet, etc. + * @NM_DEVICE_STATE_SECONDARIES: the device is waiting for a secondary + * connection (like a VPN) which must activated before the device can be + * activated + * @NM_DEVICE_STATE_ACTIVATED: the device has a network connection, either local + * or global. + * @NM_DEVICE_STATE_DEACTIVATING: a disconnection from the current network + * connection was requested, and the device is cleaning up resources used for + * that connection. The network connection may still be valid. + * @NM_DEVICE_STATE_FAILED: the device failed to connect to the requested + * network and is cleaning up the connection request + * + * (Corresponds to the NM_DEVICE_STATE type in nm-device.xml.) + **/ +typedef enum { + NM_DEVICE_STATE_UNKNOWN = 0, + NM_DEVICE_STATE_UNMANAGED = 10, + NM_DEVICE_STATE_UNAVAILABLE = 20, + NM_DEVICE_STATE_DISCONNECTED = 30, + NM_DEVICE_STATE_PREPARE = 40, + NM_DEVICE_STATE_CONFIG = 50, + NM_DEVICE_STATE_NEED_AUTH = 60, + NM_DEVICE_STATE_IP_CONFIG = 70, + NM_DEVICE_STATE_IP_CHECK = 80, + NM_DEVICE_STATE_SECONDARIES = 90, + NM_DEVICE_STATE_ACTIVATED = 100, + NM_DEVICE_STATE_DEACTIVATING = 110, + NM_DEVICE_STATE_FAILED = 120 +} NMDeviceState; + + +/** + * NMDeviceStateReason: + * @NM_DEVICE_STATE_REASON_NONE: No reason given + * @NM_DEVICE_STATE_REASON_UNKNOWN: Unknown error + * @NM_DEVICE_STATE_REASON_NOW_MANAGED: Device is now managed + * @NM_DEVICE_STATE_REASON_NOW_UNMANAGED: Device is now unmanaged + * @NM_DEVICE_STATE_REASON_CONFIG_FAILED: The device could not be readied for configuration + * @NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE: IP configuration could not be reserved (no available address, timeout, etc) + * @NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED: The IP config is no longer valid + * @NM_DEVICE_STATE_REASON_NO_SECRETS: Secrets were required, but not provided + * @NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT: 802.1x supplicant disconnected + * @NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED: 802.1x supplicant configuration failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED: 802.1x supplicant failed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT: 802.1x supplicant took too long to authenticate + * @NM_DEVICE_STATE_REASON_PPP_START_FAILED: PPP service failed to start + * @NM_DEVICE_STATE_REASON_PPP_DISCONNECT: PPP service disconnected + * @NM_DEVICE_STATE_REASON_PPP_FAILED: PPP failed + * @NM_DEVICE_STATE_REASON_DHCP_START_FAILED: DHCP client failed to start + * @NM_DEVICE_STATE_REASON_DHCP_ERROR: DHCP client error + * @NM_DEVICE_STATE_REASON_DHCP_FAILED: DHCP client failed + * @NM_DEVICE_STATE_REASON_SHARED_START_FAILED: Shared connection service failed to start + * @NM_DEVICE_STATE_REASON_SHARED_FAILED: Shared connection service failed + * @NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED: AutoIP service failed to start + * @NM_DEVICE_STATE_REASON_AUTOIP_ERROR: AutoIP service error + * @NM_DEVICE_STATE_REASON_AUTOIP_FAILED: AutoIP service failed + * @NM_DEVICE_STATE_REASON_MODEM_BUSY: The line is busy + * @NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE: No dial tone + * @NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER: No carrier could be established + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT: The dialing request timed out + * @NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED: The dialing attempt failed + * @NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED: Modem initialization failed + * @NM_DEVICE_STATE_REASON_GSM_APN_FAILED: Failed to select the specified APN + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING: Not searching for networks + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED: Network registration denied + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT: Network registration timed out + * @NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED: Failed to register with the requested network + * @NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED: PIN check failed + * @NM_DEVICE_STATE_REASON_FIRMWARE_MISSING: Necessary firmware for the device may be missing + * @NM_DEVICE_STATE_REASON_REMOVED: The device was removed + * @NM_DEVICE_STATE_REASON_SLEEPING: NetworkManager went to sleep + * @NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: The device's active connection disappeared + * @NM_DEVICE_STATE_REASON_USER_REQUESTED: Device disconnected by user or client + * @NM_DEVICE_STATE_REASON_CARRIER: Carrier/link changed + * @NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: The device's existing connection was assumed + * @NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE: The supplicant is now available + * @NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND: The modem could not be found + * @NM_DEVICE_STATE_REASON_BT_FAILED: The Bluetooth connection failed or timed out + * @NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED: GSM Modem's SIM Card not inserted + * @NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: GSM Modem's SIM Pin required + * @NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED: GSM Modem's SIM Puk required + * @NM_DEVICE_STATE_REASON_GSM_SIM_WRONG: GSM Modem's SIM wrong + * @NM_DEVICE_STATE_REASON_INFINIBAND_MODE: InfiniBand device does not support connected mode + * @NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: A dependency of the connection failed + * @NM_DEVICE_STATE_REASON_BR2684_FAILED: Problem with the RFC 2684 Ethernet over ADSL bridge + * @NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE: ModemManager not running + * @NM_DEVICE_STATE_REASON_SSID_NOT_FOUND: The WiFi network could not be found + * @NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED: A secondary connection of the base connection failed + * @NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED: DCB or FCoE setup failed + * @NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED: teamd control failed + * @NM_DEVICE_STATE_REASON_MODEM_FAILED: Modem failed or no longer available + * @NM_DEVICE_STATE_REASON_MODEM_AVAILABLE: Modem now ready and available + * @NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT: SIM PIN was incorrect + * + * Device state change reason codes + * + * (Corresponds to the NM_DEVICE_STATE_REASON type in nm-device.xml.) + */ +typedef enum { + NM_DEVICE_STATE_REASON_NONE = 0, + NM_DEVICE_STATE_REASON_UNKNOWN = 1, + NM_DEVICE_STATE_REASON_NOW_MANAGED = 2, + NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3, + NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE = 5, + NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED = 6, + NM_DEVICE_STATE_REASON_NO_SECRETS = 7, + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8, + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10, + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11, + NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12, + NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13, + NM_DEVICE_STATE_REASON_PPP_FAILED = 14, + NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15, + NM_DEVICE_STATE_REASON_DHCP_ERROR = 16, + NM_DEVICE_STATE_REASON_DHCP_FAILED = 17, + NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18, + NM_DEVICE_STATE_REASON_SHARED_FAILED = 19, + NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20, + NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21, + NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22, + NM_DEVICE_STATE_REASON_MODEM_BUSY = 23, + NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24, + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25, + NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26, + NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27, + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28, + NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32, + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33, + NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34, + NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35, + NM_DEVICE_STATE_REASON_REMOVED = 36, + NM_DEVICE_STATE_REASON_SLEEPING = 37, + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38, + NM_DEVICE_STATE_REASON_USER_REQUESTED = 39, + NM_DEVICE_STATE_REASON_CARRIER = 40, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED = 41, + NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE = 42, + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND = 43, + NM_DEVICE_STATE_REASON_BT_FAILED = 44, + NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED = 45, + NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED = 46, + NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED = 47, + NM_DEVICE_STATE_REASON_GSM_SIM_WRONG = 48, + NM_DEVICE_STATE_REASON_INFINIBAND_MODE = 49, + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED = 50, + NM_DEVICE_STATE_REASON_BR2684_FAILED = 51, + NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE = 52, + NM_DEVICE_STATE_REASON_SSID_NOT_FOUND = 53, + NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED = 54, + NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55, + NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED = 56, + NM_DEVICE_STATE_REASON_MODEM_FAILED = 57, + NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58, + NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59, + + NM_DEVICE_STATE_REASON_LAST = 0xFFFF +} NMDeviceStateReason; + + +/** + * NMActiveConnectionState: + * @NM_ACTIVE_CONNECTION_STATE_UNKNOWN: the state of the connection is unknown + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATING: a network connection is being prepared + * @NM_ACTIVE_CONNECTION_STATE_ACTIVATED: there is a connection to the network + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATING: the network connection is being + * torn down and cleaned up + * @NM_ACTIVE_CONNECTION_STATE_DEACTIVATED: the network connection is disconnected + * and will be removed + * + * #NMActiveConnectionState values indicate the state of a connection to a + * specific network while it is starting, connected, or disconnecting from that + * network. + * + * (Corresponds to the NM_ACTIVE_CONNECTION_STATE type in nm-active-connection.xml.) + **/ +typedef enum { + NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, + NM_ACTIVE_CONNECTION_STATE_ACTIVATING, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATED +} NMActiveConnectionState; + +#endif /* NETWORK_MANAGER_H */ diff --git a/libnm-util/NetworkManagerVPN.h b/libnm-util/NetworkManagerVPN.h new file mode 100644 index 00000000..882d3973 --- /dev/null +++ b/libnm-util/NetworkManagerVPN.h @@ -0,0 +1,307 @@ +/* -*- 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. + * + * Copyright 2004 Red Hat, Inc. + */ + +/* D-Bus-related definitions for NetworkManager VPN plugins. + * + * Note that although this header is installed as part of libnm-util, it is also + * used by some external code that does not link to libnm-util. + */ + +#ifndef NETWORK_MANAGER_VPN_H +#define NETWORK_MANAGER_VPN_H + +/* + * dbus services details + */ +#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPN/Manager" +#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPN.Manager" + +#define NM_DBUS_PATH_VPN_CONNECTION "/org/freedesktop/NetworkManager/VPN/Connection" +#define NM_DBUS_INTERFACE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPN.Connection" + +#define NM_VPN_DBUS_PLUGIN_PATH "/org/freedesktop/NetworkManager/VPN/Plugin" +#define NM_VPN_DBUS_PLUGIN_INTERFACE "org.freedesktop.NetworkManager.VPN.Plugin" + +/* + * VPN Errors + */ +#define NM_DBUS_NO_ACTIVE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPNConnections.NoActiveVPNConnection" +#define NM_DBUS_NO_VPN_CONNECTIONS "org.freedesktop.NetworkManager.VPNConnections.NoVPNConnections" +#define NM_DBUS_INVALID_VPN_CONNECTION "org.freedesktop.NetworkManager.VPNConnections.InvalidVPNConnection" + +#define NM_DBUS_VPN_ERROR_PREFIX "org.freedesktop.NetworkManager.VPN.Error" +#define NM_DBUS_VPN_STARTING_IN_PROGRESS "StartingInProgress" +#define NM_DBUS_VPN_ALREADY_STARTED "AlreadyStarted" +#define NM_DBUS_VPN_STOPPING_IN_PROGRESS "StoppingInProgress" +#define NM_DBUS_VPN_ALREADY_STOPPED "AlreadyStopped" +#define NM_DBUS_VPN_WRONG_STATE "WrongState" +#define NM_DBUS_VPN_BAD_ARGUMENTS "BadArguments" +#define NM_DBUS_VPN_INTERACTIVE_NOT_SUPPORTED "InteractiveNotSupported" + + +/* + * VPN daemon signals + */ +#define NM_DBUS_VPN_SIGNAL_LOGIN_BANNER "LoginBanner" +#define NM_DBUS_VPN_SIGNAL_LOGIN_FAILED "LoginFailed" +#define NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED "LaunchFailed" +#define NM_DBUS_VPN_SIGNAL_CONNECT_FAILED "ConnectFailed" +#define NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD "VPNConfigBad" +#define NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD "IPConfigBad" +#define NM_DBUS_VPN_SIGNAL_STATE_CHANGE "StateChange" +#define NM_DBUS_VPN_SIGNAL_IP4_CONFIG "IP4Config" + +/** + * NMVPNServiceState: + * @NM_VPN_SERVICE_STATE_UNKNOWN: The state of the VPN plugin is unknown. + * @NM_VPN_SERVICE_STATE_INIT: The VPN plugin is initialized. + * @NM_VPN_SERVICE_STATE_SHUTDOWN: Not used. + * @NM_VPN_SERVICE_STATE_STARTING: The plugin is attempting to connect to a VPN server. + * @NM_VPN_SERVICE_STATE_STARTED: The plugin has connected to a VPN server. + * @NM_VPN_SERVICE_STATE_STOPPING: The plugin is disconnecting from the VPN server. + * @NM_VPN_SERVICE_STATE_STOPPED: The plugin has disconnected from the VPN server. + * + * VPN daemon states + * + * (Corresponds to the NM_VPN_SERVICE_STATE type in nm-vpn-connection.xml.) + */ +typedef enum NMVPNServiceState { + NM_VPN_SERVICE_STATE_UNKNOWN = 0, + NM_VPN_SERVICE_STATE_INIT, + NM_VPN_SERVICE_STATE_SHUTDOWN, + NM_VPN_SERVICE_STATE_STARTING, + NM_VPN_SERVICE_STATE_STARTED, + NM_VPN_SERVICE_STATE_STOPPING, + NM_VPN_SERVICE_STATE_STOPPED +} NMVPNServiceState; + + +/** + * NMVPNConnectionState: + * @NM_VPN_CONNECTION_STATE_UNKNOWN: The state of the VPN connection is + * unknown. + * @NM_VPN_CONNECTION_STATE_PREPARE: The VPN connection is preparing to + * connect. + * @NM_VPN_CONNECTION_STATE_NEED_AUTH: The VPN connection needs authorization + * credentials. + * @NM_VPN_CONNECTION_STATE_CONNECT: The VPN connection is being established. + * @NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: The VPN connection is getting an IP + * address. + * @NM_VPN_CONNECTION_STATE_ACTIVATED: The VPN connection is active. + * @NM_VPN_CONNECTION_STATE_FAILED: The VPN connection failed. + * @NM_VPN_CONNECTION_STATE_DISCONNECTED: The VPN connection is disconnected. + * + * VPN connection states + * + * (Corresponds to the NM_VPN_CONNECTION_STATE type in nm-vpn-connection.xml.) + */ +typedef enum NMVPNConnectionState { + NM_VPN_CONNECTION_STATE_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_PREPARE, + NM_VPN_CONNECTION_STATE_NEED_AUTH, + NM_VPN_CONNECTION_STATE_CONNECT, + NM_VPN_CONNECTION_STATE_IP_CONFIG_GET, + NM_VPN_CONNECTION_STATE_ACTIVATED, + NM_VPN_CONNECTION_STATE_FAILED, + NM_VPN_CONNECTION_STATE_DISCONNECTED +} NMVPNConnectionState; + +/** + * NMVPNConnectionStateReason: + * @NM_VPN_CONNECTION_STATE_REASON_UNKNOWN: The reason for the VPN connection + * state change is unknown. + * @NM_VPN_CONNECTION_STATE_REASON_NONE: No reason was given for the VPN + * connection state change. + * @NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED: The VPN connection changed + * state because the user disconnected it. + * @NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: The VPN connection + * changed state because the device it was using was disconnected. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED: The service providing the + * VPN connection was stopped. + * @NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: The IP config of the VPN + * connection was invalid. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: The connection attempt to + * the VPN service timed out. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: A timeout occurred + * while starting the service providing the VPN connection. + * @NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED: Starting the service + * starting the service providing the VPN connection failed. + * @NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS: Necessary secrets for the VPN + * connection were not provided. + * @NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED: Authentication to the VPN + * server failed. + * @NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED: The connection was + * deleted from settings. + * + * VPN connection state reasons + * + * (Corresponds to the NM_VPN_CONNECTION_STATE_REASON type in nm-vpn-connection.xml.) + */ +typedef enum NMVPNConnectionStateReason { + NM_VPN_CONNECTION_STATE_REASON_UNKNOWN = 0, + NM_VPN_CONNECTION_STATE_REASON_NONE, + NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED, + NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED, + NM_VPN_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, + NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED, + NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, + NM_VPN_CONNECTION_STATE_REASON_LOGIN_FAILED, + NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED +} NMVPNConnectionStateReason; + +/** + * NMVPNPluginFailure: + * @NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED: Login failed. + * @NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED: Connect failed. + * @NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG: Invalid IP configuration returned from + * the VPN plugin. + * + * VPN plugin failure reasons + * + * (Corresponds to the NM_VPN_PLUGIN_FAILURE type in nm-vpn-plugin.xml.) + */ +typedef enum { + NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED, + NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED, + NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG +} NMVPNPluginFailure; + + +/*** Generic config ***/ + +/* string: VPN interface name (tun0, tap0, etc) */ +#define NM_VPN_PLUGIN_CONFIG_TUNDEV "tundev" + +/* string: Login message */ +#define NM_VPN_PLUGIN_CONFIG_BANNER "banner" + +/* uint32 / array of uint8: IP address of the public external VPN gateway (network byte order) */ +#define NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY "gateway" + +/* uint32: Maximum Transfer Unit that the VPN interface should use */ +#define NM_VPN_PLUGIN_CONFIG_MTU "mtu" + +/* boolean: Has IP4 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP4 "has-ip4" + +/* boolean: Has IP6 configuration? */ +#define NM_VPN_PLUGIN_CONFIG_HAS_IP6 "has-ip6" + +/* boolean: If %TRUE the VPN plugin can persist/reconnect the connection over + * link changes and VPN server dropouts. + */ +#define NM_VPN_PLUGIN_CAN_PERSIST "can-persist" + + +/*** Ip4Config ***/ + +/* uint32: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY "internal-gateway" + +/* uint32: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address" + +/* uint32: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PTP "ptp" + +/* uint32: IP prefix of the VPN interface; 1 - 32 inclusive */ +#define NM_VPN_PLUGIN_IP4_CONFIG_PREFIX "prefix" + +/* array of uint32: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DNS "dns" + +/* array of uint32: IP addresses of NBNS/WINS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NBNS "nbns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP4_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS "domains" + +/* [ip4 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip4_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP4_CONFIG_ROUTES "routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT "never-default" + +/* Deprecated */ +#define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY + +/* Legacy IP4 items; these are included in the IP4 config by older plugins, + * but in the generic config by newer plugins. + */ + +#define NM_VPN_PLUGIN_IP4_CONFIG_BANNER NM_VPN_PLUGIN_CONFIG_BANNER +#define NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY +#define NM_VPN_PLUGIN_IP4_CONFIG_MTU NM_VPN_PLUGIN_CONFIG_MTU +#define NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV NM_VPN_PLUGIN_CONFIG_TUNDEV + + +/*** Ip6Config ***/ + +/* array of uint8: IP address of the internal gateway of the subnet the VPN interface is + * on, if the VPN uses subnet configuration (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY "internal-gateway" + +/* array of uint8: internal IP address of the local VPN interface (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ADDRESS "address" + +/* array of uint8: IP address of the other side of Point-to-Point connection if the VPN + * uses Point-to-Point configuration. (network byte order) + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PTP "ptp" + +/* uint32: prefix length of the VPN interface; 1 - 128 inclusive */ +#define NM_VPN_PLUGIN_IP6_CONFIG_PREFIX "prefix" + +/* array of array of uint8: IP addresses of DNS servers for the VPN (network byte order) */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DNS "dns" + +/* uint32: Message Segment Size that the VPN interface should use */ +#define NM_VPN_PLUGIN_IP6_CONFIG_MSS "mss" + +/* string: DNS domain name */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN "domain" + +/* array of strings: DNS domain names */ +#define NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS "domains" + +/* [ip6 routes]: custom routes the client should apply, in the format used + * by nm_utils_ip6_routes_to/from_gvalue + */ +#define NM_VPN_PLUGIN_IP6_CONFIG_ROUTES "routes" + +/* boolean: prevent this VPN connection from ever getting the default route */ +#define NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT "never-default" + +#endif /* NETWORK_MANAGER_VPN_H */ diff --git a/libnm-util/crypto.c b/libnm-util/crypto.c index 0ac4fbac..8a10af94 100644 --- a/libnm-util/crypto.c +++ b/libnm-util/crypto.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ #include "config.h" @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "crypto.h" @@ -360,8 +360,8 @@ convert_iv (const char *src, conv[2] = '\0'; for (i = 0; i < num; i++) { - conv[0] = src[(i * 2)]; - conv[1] = src[(i * 2) + 1]; + conv[0] = src[(i * 2)]; + conv[1] = src[(i * 2) + 1]; if (!g_ascii_isxdigit (conv[0]) || !g_ascii_isxdigit (conv[1])) { g_set_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERR_RAW_IV_INVALID, @@ -526,11 +526,11 @@ crypto_decrypt_private_key_data (const GByteArray *contents, if (password) { decrypted = decrypt_key (cipher, - key_type, - data, - iv, - password, - error); + key_type, + data, + iv, + password, + error); } g_byte_array_free (data, TRUE); } @@ -569,18 +569,18 @@ extract_pem_cert_data (GByteArray *contents, GError **error) if (!find_tag (PEM_CERT_BEGIN, contents, 0, &start)) { g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_FILE_FORMAT_INVALID, - _("PEM certificate had no start tag '%s'."), - PEM_CERT_BEGIN); + NM_CRYPTO_ERR_FILE_FORMAT_INVALID, + _("PEM certificate had no start tag '%s'."), + PEM_CERT_BEGIN); goto done; } start += strlen (PEM_CERT_BEGIN); if (!find_tag (PEM_CERT_END, contents, start, &end)) { g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_FILE_FORMAT_INVALID, - _("PEM certificate had no end tag '%s'."), - PEM_CERT_END); + NM_CRYPTO_ERR_FILE_FORMAT_INVALID, + _("PEM certificate had no end tag '%s'."), + PEM_CERT_END); goto done; } @@ -596,8 +596,8 @@ extract_pem_cert_data (GByteArray *contents, GError **error) g_assert (cert->len == length); } else { g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_DECODE_FAILED, - _("Failed to decode certificate.")); + NM_CRYPTO_ERR_DECODE_FAILED, + _("Failed to decode certificate.")); } done: @@ -747,4 +747,3 @@ crypto_verify_private_key (const char *filename, } return format; } - diff --git a/libnm-util/crypto.h b/libnm-util/crypto.h index 1cbf61c1..315d8fec 100644 --- a/libnm-util/crypto.h +++ b/libnm-util/crypto.h @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef __CRYPTO_H__ @@ -70,8 +70,6 @@ GQuark _nm_crypto_error_quark (void); gboolean crypto_init (GError **error); -void crypto_deinit (void); - GByteArray *crypto_decrypt_private_key_data (const GByteArray *contents, const char *password, NMCryptoKeyType *out_key_type, diff --git a/libnm-util/crypto_gnutls.c b/libnm-util/crypto_gnutls.c index e829c23c..3bec24ad 100644 --- a/libnm-util/crypto_gnutls.c +++ b/libnm-util/crypto_gnutls.c @@ -18,12 +18,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * Copyright 2007 - 2009 Red Hat, Inc. */ #include "config.h" + #include -#include +#include #include #include @@ -55,11 +56,6 @@ crypto_init (GError **error) return TRUE; } -void -crypto_deinit (void) -{ -} - gboolean crypto_md5_hash (const char *salt, const gsize salt_len, @@ -105,7 +101,7 @@ crypto_md5_hash (const char *salt, gcry_md_final (ctx); memcpy (digest, gcry_md_read (ctx, 0), digest_len); gcry_md_reset (ctx); - + while (nkey && (i < digest_len)) { *(p++) = digest[i++]; nkey--; @@ -347,7 +343,7 @@ crypto_verify_cert (const unsigned char *data, GError **error) { gnutls_x509_crt_t der; - gnutls_datum dt; + gnutls_datum_t dt; int err; err = gnutls_x509_crt_init (&der); @@ -387,7 +383,7 @@ crypto_verify_pkcs12 (const GByteArray *data, GError **error) { gnutls_pkcs12_t p12; - gnutls_datum dt; + gnutls_datum_t dt; gboolean success = FALSE; int err; @@ -441,7 +437,7 @@ crypto_verify_pkcs8 (const GByteArray *data, GError **error) { gnutls_x509_privkey_t p8; - gnutls_datum dt; + gnutls_datum_t dt; int err; g_return_val_if_fail (data != NULL, FALSE); @@ -475,9 +471,9 @@ crypto_verify_pkcs8 (const GByteArray *data, */ } else { g_set_error (error, NM_CRYPTO_ERROR, - NM_CRYPTO_ERR_FILE_FORMAT_INVALID, - _("Couldn't decode PKCS#8 file: %s"), - gnutls_strerror (err)); + NM_CRYPTO_ERR_FILE_FORMAT_INVALID, + _("Couldn't decode PKCS#8 file: %s"), + gnutls_strerror (err)); return FALSE; } } @@ -491,4 +487,3 @@ crypto_randomize (void *buffer, gsize buffer_len, GError **error) gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM); return TRUE; } - diff --git a/libnm-util/crypto_nss.c b/libnm-util/crypto_nss.c index af3de666..edd19b54 100644 --- a/libnm-util/crypto_nss.c +++ b/libnm-util/crypto_nss.c @@ -18,13 +18,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * Copyright 2007 - 2009 Red Hat, Inc. */ #include "config.h" #include -#include +#include #include #include @@ -71,11 +71,6 @@ crypto_init (GError **error) return TRUE; } -void -crypto_deinit (void) -{ -} - gboolean crypto_md5_hash (const char *salt, const gsize salt_len, @@ -560,4 +555,3 @@ crypto_randomize (void *buffer, gsize buffer_len, GError **error) } return TRUE; } - diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index e14f08d9..9d78e502 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -13,6 +13,7 @@ global: nm_connection_for_each_setting_value; nm_connection_get_connection_type; nm_connection_get_id; + nm_connection_get_interface_name; nm_connection_get_path; nm_connection_get_setting; nm_connection_get_setting_802_1x; @@ -52,6 +53,7 @@ global: nm_connection_need_secrets; nm_connection_new; nm_connection_new_from_hash; + nm_connection_normalize; nm_connection_remove_setting; nm_connection_replace_settings; nm_connection_replace_settings_from_connection; @@ -365,6 +367,7 @@ global: nm_setting_ip4_config_get_num_dns_searches; nm_setting_ip4_config_get_num_routes; nm_setting_ip4_config_get_route; + nm_setting_ip4_config_get_route_metric; nm_setting_ip4_config_get_type; nm_setting_ip4_config_new; nm_setting_ip4_config_remove_address; @@ -400,6 +403,7 @@ global: nm_setting_ip6_config_get_num_dns_searches; nm_setting_ip6_config_get_num_routes; nm_setting_ip6_config_get_route; + nm_setting_ip6_config_get_route_metric; nm_setting_ip6_config_get_type; nm_setting_ip6_config_new; nm_setting_ip6_config_privacy_get_type; @@ -608,6 +612,7 @@ global: nm_utils_deinit; nm_utils_escape_ssid; nm_utils_file_is_pkcs12; + nm_utils_file_search_in_paths; nm_utils_get_private; nm_utils_gvalue_hash_dup; nm_utils_hex2byte; diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index b0b683bd..a1350f54 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include -#include +#include #include #include #include "nm-connection.h" @@ -122,6 +121,10 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; + +static NMSettingVerifyResult _nm_connection_verify (NMConnection *connection, GError **error); + + /*************************************************************/ /** @@ -184,12 +187,23 @@ setting_changed_cb (NMSetting *setting, g_signal_emit (self, signals[CHANGED], 0); } +static gboolean +_setting_release (gpointer key, gpointer value, gpointer user_data) +{ + g_signal_handlers_disconnect_by_func (user_data, setting_changed_cb, value); + return TRUE; +} + static void _nm_connection_add_setting (NMConnection *connection, NMSetting *setting) { - g_hash_table_insert (NM_CONNECTION_GET_PRIVATE (connection)->settings, - (gpointer) G_OBJECT_TYPE_NAME (setting), - setting); + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + const char *name = G_OBJECT_TYPE_NAME (setting); + NMSetting *s_old; + + if ((s_old = g_hash_table_lookup (priv->settings, (gpointer) name))) + g_signal_handlers_disconnect_by_func (s_old, setting_changed_cb, connection); + g_hash_table_insert (priv->settings, (gpointer) name, setting); /* Listen for property changes so we can emit the 'changed' signal */ g_signal_connect (setting, "notify", (GCallback) setting_changed_cb, connection); } @@ -346,7 +360,7 @@ hash_to_connection (NMConnection *connection, GHashTable *new, GError **error) NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); if ((changed = g_hash_table_size (priv->settings) > 0)) - g_hash_table_remove_all (priv->settings); + g_hash_table_foreach_remove (priv->settings, _setting_release, connection); g_hash_table_iter_init (&iter, new); while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { @@ -434,7 +448,7 @@ nm_connection_replace_settings_from_connection (NMConnection *connection, priv = NM_CONNECTION_GET_PRIVATE (connection); if ((changed = g_hash_table_size (priv->settings) > 0)) - g_hash_table_remove_all (priv->settings); + g_hash_table_foreach_remove (priv->settings, _setting_release, connection); if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (new_connection)->settings)) { g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (new_connection)->settings); @@ -476,7 +490,7 @@ nm_connection_compare (NMConnection *a, /* B / A: ensure settings in B that are not in A make the comparison fail */ if (g_hash_table_size (NM_CONNECTION_GET_PRIVATE (a)->settings) != - g_hash_table_size (NM_CONNECTION_GET_PRIVATE (b)->settings)) + g_hash_table_size (NM_CONNECTION_GET_PRIVATE (b)->settings)) return FALSE; /* A / B: ensure all settings in A match corresponding ones in B */ @@ -575,6 +589,113 @@ nm_connection_diff (NMConnection *a, return *out_settings ? FALSE : TRUE; } +static gboolean +_normalize_virtual_iface_name (NMConnection *self) +{ + NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (self); + GHashTableIter h_iter; + NMSetting *setting; + NMSettingConnection *s_con; + const char *interface_name; + char *virtual_iface_name = NULL; + gboolean was_modified = FALSE; + const char *prop_name = NULL; + + /* search for settings that might need normalization of the interface name. */ + g_hash_table_iter_init (&h_iter, priv->settings); + while ( !prop_name + && g_hash_table_iter_next (&h_iter, NULL, (void **) &setting)) { + if (NM_IS_SETTING_BOND (setting)) + prop_name = NM_SETTING_BOND_INTERFACE_NAME; + else if (NM_IS_SETTING_BRIDGE (setting)) + prop_name = NM_SETTING_BRIDGE_INTERFACE_NAME; + else if (NM_IS_SETTING_TEAM (setting)) + prop_name = NM_SETTING_TEAM_INTERFACE_NAME; + else if (NM_IS_SETTING_VLAN (setting)) + prop_name = NM_SETTING_VLAN_INTERFACE_NAME; + } + if (!prop_name) + return FALSE; + + s_con = nm_connection_get_setting_connection (self); + g_return_val_if_fail (s_con, FALSE); + + interface_name = nm_setting_connection_get_interface_name (s_con); + + /* read the potential virtual_iface_name from the setting. */ + g_object_get (setting, prop_name, &virtual_iface_name, NULL); + + if (g_strcmp0 (interface_name, virtual_iface_name) != 0) { + if (interface_name) { + /* interface_name is set and overwrites the virtual_iface_name. */ + g_object_set (setting, prop_name, interface_name, NULL); + } else { + /* interface in NMSettingConnection must be set. */ + g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, virtual_iface_name, NULL); + } + was_modified = TRUE; + } + + g_free (virtual_iface_name); + + return was_modified; +} + +static gboolean +_normalize_ip_config (NMConnection *self, GHashTable *parameters) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + const char *default_ip6_method = NULL; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSetting *setting; + + if (parameters) + default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD); + if (!default_ip6_method) + default_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + + s_ip4 = nm_connection_get_setting_ip4_config (self); + s_ip6 = nm_connection_get_setting_ip6_config (self); + + if (nm_setting_connection_get_master (s_con)) { + /* Slave connections don't have IP configuration. */ + + if (s_ip4) + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP4_CONFIG); + + if (s_ip6) + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP6_CONFIG); + + return s_ip4 || s_ip6; + } else { + /* Ensure all non-slave connections have IP4 and IP6 settings objects. If no + * IP6 setting was specified, then assume that means IP6 config is allowed + * to fail. But if no IP4 setting was specified, assume the caller was just + * being lazy. + */ + if (!s_ip4) { + setting = nm_setting_ip4_config_new (); + + g_object_set (setting, + NM_SETTING_IP4_CONFIG_METHOD, default_ip4_method, + NULL); + nm_connection_add_setting (self, setting); + } + if (!s_ip6) { + setting = nm_setting_ip6_config_new (); + + g_object_set (setting, + NM_SETTING_IP6_CONFIG_METHOD, default_ip6_method, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + nm_connection_add_setting (self, setting); + } + return !s_ip4 || !s_ip6; + } +} + /** * nm_connection_verify: * @connection: the #NMConnection to verify @@ -584,7 +705,7 @@ nm_connection_diff (NMConnection *a, * have allowed values, and some values are dependent on other values. For * example, if a Wi-Fi connection is security enabled, the #NMSettingWireless * setting object's 'security' property must contain the setting name of the - * #NMSettingWirelessSecurity object, which must also be present in the + * #NMSettingWirelessSecurity object, which must also be present in the * connection for the connection to be valid. As another example, the * #NMSettingWired object's 'mac-address' property must be a validly formatted * MAC address. The returned #GError contains information about which @@ -594,25 +715,43 @@ nm_connection_diff (NMConnection *a, **/ gboolean nm_connection_verify (NMConnection *connection, GError **error) +{ + NMSettingVerifyResult result; + + result = _nm_connection_verify (connection, error); + + /* we treat normalizable connections as valid. */ + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error (error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +static NMSettingVerifyResult +_nm_connection_verify (NMConnection *connection, GError **error) { NMConnectionPrivate *priv; NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; GHashTableIter iter; gpointer value; - GSList *all_settings = NULL; - gboolean success = TRUE; + GSList *all_settings = NULL, *setting_i; + NMSettingVerifyResult success = NM_SETTING_VERIFY_ERROR; NMSetting *base; const char *ctype; + GError *normalizable_error = NULL; + NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS; if (error) - g_return_val_if_fail (*error == NULL, FALSE); + g_return_val_if_fail (*error == NULL, NM_SETTING_VERIFY_ERROR); if (!NM_IS_CONNECTION (connection)) { g_set_error_literal (error, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_UNKNOWN, "invalid connection; failed verification"); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR); } priv = NM_CONNECTION_GET_PRIVATE (connection); @@ -624,23 +763,62 @@ nm_connection_verify (NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "connection setting not found"); - return FALSE; + goto EXIT; } /* Build up the list of settings */ g_hash_table_iter_init (&iter, priv->settings); - while (g_hash_table_iter_next (&iter, NULL, &value)) - all_settings = g_slist_append (all_settings, value); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + /* Order NMSettingConnection so that it will be verified first. + * The reason is, that NMSettingConnection:verify() modifies the connection + * by setting NMSettingConnection:interface_name. So we want to call that + * verify() first, because the order can affect the outcome. + * Another reason is, that errors in this setting might be more fundamental + * and should be checked and reported with higher priority. + * Another reason is, that some settings look especially at the + * NMSettingConnection, so they find it first in the all_settings list. */ + if (value == s_con) + all_settings = g_slist_append (all_settings, value); + else + all_settings = g_slist_prepend (all_settings, value); + } + all_settings = g_slist_reverse (all_settings); /* Now, run the verify function of each setting */ - g_hash_table_iter_init (&iter, priv->settings); - while (g_hash_table_iter_next (&iter, NULL, &value) && success) - success = nm_setting_verify (NM_SETTING (value), all_settings, error); + for (setting_i = all_settings; setting_i; setting_i = setting_i->next) { + GError *verify_error = NULL; + NMSettingVerifyResult verify_result; + + /* verify all settings. We stop if we find the first non-normalizable + * @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue + * but remember the error to return it to the user. + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR has a higher priority then + * @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type, + * we remember it instead (to return it as output). + **/ + verify_result = _nm_setting_verify (NM_SETTING (setting_i->data), all_settings, &verify_error); + if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE || + verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) { + if ( verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR + && normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE) { + /* NORMALIZABLE_ERROR has higher priority. */ + g_clear_error (&normalizable_error); + } + if (!normalizable_error) { + g_propagate_error (&normalizable_error, verify_error); + verify_error = NULL; + normalizable_error_type = verify_result; + } + } else if (verify_result != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error (error, verify_error); + g_slist_free (all_settings); + g_return_val_if_fail (verify_result == NM_SETTING_VERIFY_ERROR, success); + goto EXIT; + } + g_clear_error (&verify_error); + } g_slist_free (all_settings); - if (success == FALSE) - return FALSE; - /* Now make sure the given 'type' setting can actually be the base setting * of the connection. Can't have type=ppp for example. */ @@ -650,7 +828,7 @@ nm_connection_verify (NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "connection type missing"); - return FALSE; + goto EXIT; } base = nm_connection_get_setting_by_name (connection, ctype); @@ -659,19 +837,125 @@ nm_connection_verify (NMConnection *connection, GError **error) NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "base setting GType not found"); - return FALSE; + goto EXIT; } if (!_nm_setting_is_base_type (base)) { g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, - "connection type '%s' is not a base type", - ctype); - return FALSE; + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, + "connection type '%s' is not a base type", + ctype); + goto EXIT; } - return TRUE; + s_ip4 = nm_connection_get_setting_ip4_config (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + + if (nm_setting_connection_get_master (s_con)) { + if ((normalizable_error_type == NM_SETTING_VERIFY_SUCCESS || + (normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE)) && (s_ip4 || s_ip6)) { + g_clear_error (&normalizable_error); + g_set_error (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + "slave connection cannot have an IP%c setting", + s_ip4 ? '4' : '6'); + /* having a slave with IP config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } else { + if (normalizable_error_type == NM_SETTING_VERIFY_SUCCESS && (!s_ip4 || !s_ip6)) { + g_set_error (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "connection needs an IP%c setting", + !s_ip4 ? '4' : '6'); + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } + + if (normalizable_error_type != NM_SETTING_VERIFY_SUCCESS) { + g_propagate_error (error, normalizable_error); + normalizable_error = NULL; + success = normalizable_error_type; + } else + success = NM_SETTING_VERIFY_SUCCESS; + +EXIT: + g_clear_error (&normalizable_error); + return success; +} + +/** + * nm_connection_normalize: + * @connection: the #NMConnection to normalize + * @parameters: (allow-none) (element-type utf8 gpointer): a #GHashTable with + * normalization parameters to allow customization of the normalization by providing + * specific arguments. Unknown arguments will be ignored and the default will be + * used. The keys must be strings, hashed by g_str_hash() and g_str_equal() functions. + * The values are opaque and depend on the parameter name. + * @modified: (out) (allow-none): outputs whether any settings were modified. + * @error: location to store error, or %NULL. Contains the reason, + * why the connection is invalid, if the function returns an error. + * + * Does some basic normalization and fixup of well known inconsistencies + * and deprecated fields. If the connection was modified in any way, + * the output parameter @modified is set %TRUE. + * + * Finally the connection will be verified and %TRUE returns if the connection + * is valid. As this function only performs some specific normalization steps + * it cannot repair all connections. If the connection has errors that + * cannot be normalized, the connection will not be modified. + * + * Returns: %TRUE if the connection is valid, %FALSE if it is not + * + * Since: 1.0 + **/ +gboolean +nm_connection_normalize (NMConnection *connection, + GHashTable *parameters, + gboolean *modified, + GError **error) +{ + NMSettingVerifyResult success; + gboolean was_modified = FALSE; + GError *normalizable_error = NULL; + + success = _nm_connection_verify (connection, &normalizable_error); + + if (success == NM_SETTING_VERIFY_ERROR || + success == NM_SETTING_VERIFY_SUCCESS) { + if (normalizable_error) + g_propagate_error (error, normalizable_error); + goto EXIT; + } + g_assert (success == NM_SETTING_VERIFY_NORMALIZABLE || success == NM_SETTING_VERIFY_NORMALIZABLE_ERROR); + g_clear_error (&normalizable_error); + + /* Try to perform all kind of normalizations on the settings to fix it. + * We only do this, after verifying that the connection contains no un-normalizable + * errors, because in that case we rather fail without touching the settings. */ + + was_modified |= _normalize_virtual_iface_name (connection); + was_modified |= _normalize_ip_config (connection, parameters); + + /* Verify anew. */ + success = _nm_connection_verify (connection, error); + + /* we would expect, that after normalization, the connection can be verified. */ + g_return_val_if_fail (success == NM_SETTING_VERIFY_SUCCESS, success); + + /* we would expect, that the connection was modified during normalization. */ + g_return_val_if_fail (was_modified, success); + +EXIT: + if (modified) + *modified = was_modified; + + return success == NM_SETTING_VERIFY_SUCCESS; } /** @@ -751,8 +1035,8 @@ nm_connection_update_secrets (NMConnection *connection, g_signal_handlers_block_by_func (setting, (GCallback) setting_changed_cb, connection); success_detail = _nm_setting_update_secrets (setting, - setting_hash ? setting_hash : secrets, - error); + setting_hash ? setting_hash : secrets, + error); g_signal_handlers_unblock_by_func (setting, (GCallback) setting_changed_cb, connection); if (success_detail == NM_SETTING_UPDATE_SECRET_ERROR) @@ -983,7 +1267,7 @@ nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) /** * nm_connection_is_type: * @connection: the #NMConnection - * @type: a setting name to check the connection's type against (like + * @type: a setting name to check the connection's type against (like * %NM_SETTING_WIRELESS_SETTING_NAME or %NM_SETTING_WIRED_SETTING_NAME) * * A convenience function to check if the given @connection is a particular @@ -1105,6 +1389,33 @@ nm_connection_get_path (NMConnection *connection) return NM_CONNECTION_GET_PRIVATE (connection)->path; } +/** + * nm_connection_get_interface_name: + * @connection: The #NMConnection + * + * Returns the interface name as stored in NMSettingConnection:interface_name. + * If the connection contains no NMSettingConnection, it will return %NULL. + * + * For hardware devices and software devices created outside of NetworkManager, + * this name is used to match the device. for software devices created by + * NetworkManager, this is the name of the created interface. + * + * Returns: Name of the kernel interface or %NULL + * + * Since: 1.0 + */ +const char * +nm_connection_get_interface_name (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = nm_connection_get_setting_connection (connection); + + return s_con ? nm_setting_connection_get_interface_name (s_con) : NULL; +} + /** * nm_connection_get_virtual_iface_name: * @connection: The #NMConnection @@ -1196,7 +1507,7 @@ nm_connection_duplicate (NMConnection *connection) g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) - nm_connection_add_setting (dup, nm_setting_duplicate (setting)); + _nm_connection_add_setting (dup, nm_setting_duplicate (setting)); return dup; } @@ -1750,14 +2061,8 @@ dispose (GObject *object) { NMConnection *self = NM_CONNECTION (object); NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (self); - GHashTableIter iter; - NMSetting *setting; - g_hash_table_iter_init (&iter, priv->settings); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &setting)) { - g_signal_handlers_disconnect_by_func (setting, setting_changed_cb, self); - g_hash_table_iter_remove (&iter); - } + g_hash_table_foreach_remove (priv->settings, _setting_release, self); G_OBJECT_CLASS (nm_connection_parent_class)->dispose (object); } @@ -1768,6 +2073,7 @@ finalize (GObject *object) NMConnection *connection = NM_CONNECTION (object); NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); + g_assert (g_hash_table_size (priv->settings) == 0); g_hash_table_destroy (priv->settings); g_free (priv->path); @@ -1776,7 +2082,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMConnection *connection = NM_CONNECTION (object); @@ -1792,7 +2098,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMConnection *connection = NM_CONNECTION (object); @@ -1829,40 +2135,40 @@ nm_connection_class_init (NMConnectionClass *klass) **/ g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_CONNECTION_PATH, - "Path", - "Path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_string (NM_CONNECTION_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /* Signals */ /** - * NMConnection::secrets-updated: - * @connection: the object on which the signal is emitted - * @setting_name: the setting name of the #NMSetting for which secrets were - * updated - * - * The ::secrets-updated signal is emitted when the secrets of a setting - * have been changed. - */ + * NMConnection::secrets-updated: + * @connection: the object on which the signal is emitted + * @setting_name: the setting name of the #NMSetting for which secrets were + * updated + * + * The ::secrets-updated signal is emitted when the secrets of a setting + * have been changed. + */ signals[SECRETS_UPDATED] = g_signal_new (NM_CONNECTION_SECRETS_UPDATED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMConnectionClass, secrets_updated), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMConnectionClass, secrets_updated), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); /** - * NMConnection::secrets-cleared: - * @connection: the object on which the signal is emitted - * - * The ::secrets-cleared signal is emitted when the secrets of a connection - * are cleared. - */ + * NMConnection::secrets-cleared: + * @connection: the object on which the signal is emitted + * + * The ::secrets-cleared signal is emitted when the secrets of a connection + * are cleared. + */ signals[SECRETS_CLEARED] = g_signal_new (NM_CONNECTION_SECRETS_CLEARED, G_OBJECT_CLASS_TYPE (object_class), @@ -1872,15 +2178,15 @@ nm_connection_class_init (NMConnectionClass *klass) G_TYPE_NONE, 0); /** - * NMConnection::changed: - * @connection: the object on which the signal is emitted - * - * The ::changed signal is emitted when any property of any property - * (including secrets) of any setting of the connection is modified, - * or when settings are added or removed. - * - * Since: 0.9.10 - */ + * NMConnection::changed: + * @connection: the object on which the signal is emitted + * + * The ::changed signal is emitted when any property of any property + * (including secrets) of any setting of the connection is modified, + * or when settings are added or removed. + * + * Since: 0.9.10 + */ signals[CHANGED] = g_signal_new (NM_CONNECTION_CHANGED, G_OBJECT_CLASS_TYPE (object_class), @@ -1889,4 +2195,3 @@ nm_connection_class_init (NMConnectionClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } - diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 4524c8f6..2cee2be5 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_CONNECTION_H @@ -86,6 +83,8 @@ G_BEGIN_DECLS * #NMSettingWireless. * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object * did not contain the specified #NMSetting object + *@NM_CONNECTION_ERROR_INVALID_SETTING: the #NMConnection object contains + * a conflicting setting object * * Describes errors that may result from operations involving a #NMConnection. * @@ -95,9 +94,17 @@ typedef enum NM_CONNECTION_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, /*< nick=ConnectionSettingNotFound >*/ NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, /*< nick=ConnectionTypeInvalid >*/ - NM_CONNECTION_ERROR_SETTING_NOT_FOUND /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ } NMConnectionError; +/* + * NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD: overwrite the ip6 method + * when normalizing ip6 configuration. If omited, this defaults to + * @NM_SETTING_IP6_CONFIG_METHOD_AUTO. + */ +#define NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD "ip6-config-method" + #define NM_CONNECTION_ERROR nm_connection_error_quark () GQuark nm_connection_error_quark (void); @@ -159,6 +166,11 @@ gboolean nm_connection_diff (NMConnection *a, GHashTable **out_settings); gboolean nm_connection_verify (NMConnection *connection, GError **error); +NM_AVAILABLE_IN_1_0 +gboolean nm_connection_normalize (NMConnection *connection, + GHashTable *parameters, + gboolean *modified, + GError **error); const char * nm_connection_need_secrets (NMConnection *connection, GPtrArray **hints); @@ -181,6 +193,9 @@ const char * nm_connection_get_path (NMConnection *connection); const char * nm_connection_get_virtual_iface_name (NMConnection *connection); +NM_AVAILABLE_IN_1_0 +const char * nm_connection_get_interface_name (NMConnection *connection); + gboolean nm_connection_is_type (NMConnection *connection, const char *type); void nm_connection_for_each_setting_value (NMConnection *connection, diff --git a/libnm-util/nm-param-spec-specialized.c b/libnm-util/nm-param-spec-specialized.c index 27e498b5..acb8aec3 100644 --- a/libnm-util/nm-param-spec-specialized.c +++ b/libnm-util/nm-param-spec-specialized.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,10 +16,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include "nm-param-spec-specialized.h" #include "nm-glib-compat.h" @@ -246,7 +245,7 @@ static void iterate_collection (const GValue *value, gpointer user_data) { GSList **list = (GSList **) user_data; - + *list = g_slist_prepend (*list, _gvalue_dup (value)); } @@ -286,8 +285,8 @@ _gvalues_compare_collection (const GValue *value1, const GValue *value2) GSList *iter2; for (iter1 = list1, iter2 = list2, ret = 0; - ret == 0 && iter1 && iter2; - iter1 = iter1->next, iter2 = iter2->next) + ret == 0 && iter1 && iter2; + iter1 = iter1->next, iter2 = iter2->next) ret = _gvalues_compare ((GValue *) iter1->data, (GValue *) iter2->data); } @@ -300,8 +299,8 @@ _gvalues_compare_collection (const GValue *value1, const GValue *value2) static void iterate_map (const GValue *key_val, - const GValue *value_val, - gpointer user_data) + const GValue *value_val, + gpointer user_data) { GHashTable **hash = (GHashTable **) user_data; @@ -340,7 +339,7 @@ _gvalues_compare_map (const GValue *value1, const GValue *value2) if (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)) != G_TYPE_STRING) { g_warning ("Can not compare maps with '%s' for keys", - g_type_name (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)))); + g_type_name (dbus_g_type_get_map_key_specialization (G_VALUE_TYPE (value1)))); return 0; } @@ -528,7 +527,7 @@ _gvalues_compare (const GValue *value1, const GValue *value2) if (type_is_fixed_size (type1, NULL)) ret = _gvalues_compare_fixed (value1, value2); - else if (type1 == G_TYPE_STRING) + else if (type1 == G_TYPE_STRING) ret = _gvalues_compare_string (value1, value2); else if (G_VALUE_HOLDS_BOXED (value1)) { gpointer p1 = g_value_get_boxed (value1); @@ -592,8 +591,8 @@ param_specialized_validate (GParamSpec *pspec, GValue *value) static gint param_specialized_values_cmp (GParamSpec *pspec, - const GValue *value1, - const GValue *value2) + const GValue *value1, + const GValue *value2) { return _gvalues_compare (value1, value2); } @@ -622,17 +621,17 @@ _nm_param_spec_specialized_get_type (void) GParamSpec * _nm_param_spec_specialized (const char *name, - const char *nick, - const char *blurb, - GType specialized_type, - GParamFlags flags) + const char *nick, + const char *blurb, + GType specialized_type, + GParamFlags flags) { NMParamSpecSpecialized *pspec; g_return_val_if_fail (g_type_is_a (specialized_type, G_TYPE_BOXED), NULL); pspec = g_param_spec_internal (NM_TYPE_PARAM_SPEC_SPECIALIZED, - name, nick, blurb, flags); + name, nick, blurb, flags); G_PARAM_SPEC (pspec)->value_type = specialized_type; diff --git a/libnm-util/nm-param-spec-specialized.h b/libnm-util/nm-param-spec-specialized.h index a6173674..7803e919 100644 --- a/libnm-util/nm-param-spec-specialized.h +++ b/libnm-util/nm-param-spec-specialized.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_PARAM_SPEC_SPECIALIZED_H @@ -38,9 +35,9 @@ typedef struct _NMParamSpecSpecialized NMParamSpecSpecialized; GType _nm_param_spec_specialized_get_type (void); GParamSpec *_nm_param_spec_specialized (const char *name, - const char *nick, - const char *blurb, - GType specialized_type, - GParamFlags flags); + const char *nick, + const char *blurb, + GType specialized_type, + GParamFlags flags); #endif /* NM_PARAM_SPEC_SPECIALIZED_H */ diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index d85b87b8..6d5268a1 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,13 +16,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include -#include +#include #include "nm-setting-8021x.h" #include "nm-param-spec-specialized.h" @@ -92,6 +91,11 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_802_1X) #define NM_SETTING_802_1X_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_UNKNOWN == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_UNKNOWN) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_X509 == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_X509) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_RAW_KEY == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_RAW_KEY) ); +G_STATIC_ASSERT ( (NM_SETTING_802_1X_CK_FORMAT_PKCS12 == (NMSetting8021xCKFormat) NM_CRYPTO_FILE_FORMAT_PKCS12) ); + typedef struct { GSList *eap; /* GSList of strings */ char *identity; @@ -408,7 +412,7 @@ nm_setting_802_1x_get_ca_path (NMSetting8021x *setting) * properties are ignored if the #NMSetting8021x:system-ca-certs property is * %TRUE, in which case a system-wide CA certificate directory specified at * compile time (using the --system-ca-path configure option) is used in place - * of these properties. + * of these properties. * * Returns: %TRUE if a system CA certificate path should be used, %FALSE if not **/ @@ -836,7 +840,7 @@ nm_setting_802_1x_get_client_cert_path (NMSetting8021x *setting) * @setting: the #NMSetting8021x * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the client - * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with * any @scheme clears the client certificate. * @scheme: desired storage scheme for the certificate @@ -1421,7 +1425,7 @@ nm_setting_802_1x_get_phase2_client_cert_path (NMSetting8021x *setting) * @setting: the #NMSetting8021x * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH * or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" client - * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 + * certificate file (PEM, DER, or PKCS#12 format). The path must be UTF-8 * encoded; use g_filename_to_utf8() to convert if needed. Passing %NULL with * any @scheme clears the "phase2" client certificate. * @scheme: desired storage scheme for the certificate @@ -1696,7 +1700,7 @@ file_to_byte_array (const char *filename) * @setting: the #NMSetting8021x * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the private key file - * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use + * (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; use * g_filename_to_utf8() to convert if needed. Passing %NULL with any @scheme * clears the private key. * @password: password used to decrypt the private key, or %NULL if the password @@ -1824,7 +1828,7 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *setting, g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); if (out_format) - *out_format = format; + *out_format = (NMSetting8021xCKFormat) format; return priv->private_key != NULL; } @@ -2007,7 +2011,7 @@ nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting) * @setting: the #NMSetting8021x * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or * %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private - * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; + * key file (PEM, DER, or PKCS#12 format). The path must be UTF-8 encoded; * use g_filename_to_utf8() to convert if needed. Passing %NULL with any * @scheme clears the private key. * @password: password used to decrypt the private key, or %NULL if the password @@ -2135,7 +2139,7 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); if (out_format) - *out_format = format; + *out_format = (NMSetting8021xCKFormat) format; return priv->phase2_private_key != NULL; } @@ -2819,7 +2823,7 @@ set_cert_prop_helper (const GValue *value, const char *prop_name, GError **error static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSetting8021x *setting = NM_SETTING_802_1X (object); NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting); @@ -3005,7 +3009,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSetting8021x *setting = NM_SETTING_802_1X (object); NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting); @@ -3143,17 +3147,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_EAP, - _nm_param_spec_specialized (NM_SETTING_802_1X_EAP, - "EAP", - "The allowed EAP method to be used when " - "authenticating to the network with 802.1x. " - "Valid methods are: 'leap', 'md5', 'tls', 'peap', " - "'ttls', 'pwd', and 'fast'. Each method requires " - "different configuration using the properties of " - "this setting; refer to wpa_supplicant " - "documentation for the allowed combinations.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_EAP, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:identity: @@ -3163,12 +3160,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IDENTITY, - g_param_spec_string (NM_SETTING_802_1X_IDENTITY, - "Identity", - "Identity string for EAP authentication methods. " - "Often the user's user or login name.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_IDENTITY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:anonymous-identity: @@ -3179,14 +3174,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ANONYMOUS_IDENTITY, - g_param_spec_string (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, - "Anonymous identity", - "Anonymous identity string for EAP authentication " - "methods. Used as the unencrypted identity with EAP " - "types that support different tunneled identity like " - "EAP-TTLS.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:pac-file: @@ -3195,11 +3186,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PAC_FILE, - g_param_spec_string (NM_SETTING_802_1X_PAC_FILE, - "PAC file", - "UTF-8 encoded file path containing PAC for EAP-FAST.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PAC_FILE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:ca-cert: @@ -3221,24 +3211,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CA_CERT, - _nm_param_spec_specialized (NM_SETTING_802_1X_CA_CERT, - "CA certificate", - "Contains the CA certificate if used by the EAP " - "method specified in the 'eap' property. " - "Certificate data is specified using a 'scheme'; " - "two are currently supported: blob and path. " - "When using the blob scheme (which is backwards " - "compatible with NM 0.7.x) this property should " - "be set to the certificate's DER encoded data. " - "When using the path scheme, this property should " - "be set to the full UTF-8 encoded path of the " - "certificate, prefixed with the string 'file://' " - "and ending with a terminating NULL byte. This " - "property can be unset even if the EAP method " - "supports CA certificates, but this allows " - "man-in-the-middle attacks and is NOT recommended.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_CA_CERT, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:ca-path: @@ -3249,14 +3225,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CA_PATH, - g_param_spec_string (NM_SETTING_802_1X_CA_PATH, - "CA path", - "UTF-8 encoded path to a directory containing PEM or " - "DER formatted certificates to be added to the " - "verification chain in addition to the certificate " - "specified in the 'ca-cert' property.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_CA_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:subject-match: @@ -3267,15 +3239,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SUBJECT_MATCH, - g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH, - "Subject match", - "Substring to be matched against the subject of " - "the certificate presented by the authentication " - "server. When unset, no verification of the " - "authentication server certificate's subject is " - "performed.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:altsubject-matches: @@ -3284,18 +3251,12 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * certificate presented by the authentication server. If the list is empty, * no verification of the server certificate's altSubjectName is performed. **/ - g_object_class_install_property - (object_class, PROP_ALTSUBJECT_MATCHES, - _nm_param_spec_specialized (NM_SETTING_802_1X_ALTSUBJECT_MATCHES, - "altSubjectName matches", - "List of strings to be matched against " - "the altSubjectName of the certificate " - "presented by the authentication server. " - "If the list is empty, no verification " - "of the server certificate's " - "altSubjectName is performed.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, PROP_ALTSUBJECT_MATCHES, + _nm_param_spec_specialized (NM_SETTING_802_1X_ALTSUBJECT_MATCHES, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:client-cert: @@ -3315,21 +3276,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CLIENT_CERT, - _nm_param_spec_specialized (NM_SETTING_802_1X_CLIENT_CERT, - "Client certificate", - "Contains the client certificate if used by the " - "EAP method specified in the 'eap' property. " - "Certificate data is specified using a 'scheme'; " - "two are currently supported: blob and path. " - "When using the blob scheme (which is backwards " - "compatible with NM 0.7.x) this property should " - "be set to the certificate's DER encoded data. " - "When using the path scheme, this property should " - "be set to the full UTF-8 encoded path of the " - "certificate, prefixed with the string 'file://' " - "and ending with a terminating NULL byte.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_CLIENT_CERT, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase1-peapver: @@ -3343,17 +3293,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE1_PEAPVER, - g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPVER, - "Phase1 PEAPVER", - "Forces which PEAP version is used when PEAP is set " - "as the EAP method in 'eap' property. When unset, " - "the version reported by the server will be used. " - "Sometimes when using older RADIUS servers, it is " - "necessary to force the client to use a particular " - "PEAP version. To do so, this property may be set to " - "'0' or '1' to force that specific PEAP version.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPVER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase1-peaplabel: @@ -3365,15 +3308,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE1_PEAPLABEL, - g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPLABEL, - "Phase1 PEAP label", - "Forces use of the new PEAP label during key " - "derivation. Some RADIUS servers may require forcing " - "the new PEAP label to interoperate with PEAPv1. " - "Set to '1' to force use of the new PEAP label. See " - "the wpa_supplicant documentation for more details.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPLABEL, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase1-fast-provisioning: @@ -3387,18 +3325,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE1_FAST_PROVISIONING, - g_param_spec_string (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, - "Phase1 fast provisioning", - "Enables or disables in-line provisioning of EAP-FAST " - "credentials when FAST is specified as the EAP method " - "in the #NMSetting8021x:eap property. Allowed values " - "are '0' (disabled), '1' (allow unauthenticated " - "provisioning), '2' (allow authenticated provisioning), " - "and '3' (allow both authenticated and unauthenticated " - "provisioning). See the wpa_supplicant documentation " - "for more details.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-auth: @@ -3412,18 +3342,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_AUTH, - g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTH, - "Phase2 auth", - "Specifies the allowed 'phase 2' inner non-EAP " - "authentication methods when an EAP method that uses " - "an inner TLS tunnel is specified in the 'eap' " - "property. Recognized non-EAP phase2 methods are 'pap', " - "'chap', 'mschap', 'mschapv2', 'gtc', 'otp', 'md5', " - "and 'tls'. Each 'phase 2' inner method requires " - "specific parameters for successful authentication; " - "see the wpa_supplicant documentation for more details.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-autheap: @@ -3437,18 +3359,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_AUTHEAP, - g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTHEAP, - "Phase2 autheap", - "Specifies the allowed 'phase 2' inner EAP-based " - "authentication methods when an EAP method that uses " - "an inner TLS tunnel is specified in the 'eap' " - "property. Recognized EAP-based 'phase 2' methods are " - "'md5', 'mschapv2', 'otp', 'gtc', and 'tls'. Each " - "'phase 2' inner method requires specific parameters " - "for successful authentication; see the wpa_supplicant " - "documentation for more details.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTHEAP, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-ca-cert: @@ -3471,25 +3385,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_CA_CERT, - _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CA_CERT, - "Phase2 CA certificate", - "Contains the 'phase 2' CA certificate if used by " - "the EAP method specified in the 'phase2-auth' or " - "'phase2-autheap' properties. Certificate data " - "is specified using a 'scheme'; two are currently" - "supported: blob and path. When using the blob " - "scheme (which is backwards compatible with NM " - "0.7.x) this property should be set to the " - "certificate's DER encoded data. When using the " - "path scheme, this property should be set to the " - "full UTF-8 encoded path of the certificate, " - "prefixed with the string 'file://' and ending " - "with a terminating NULL byte. This property can " - "be unset even if the EAP method supports CA " - "certificates, but this allows man-in-the-middle " - "attacks and is NOT recommended.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CA_CERT, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-ca-path: @@ -3500,14 +3399,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_CA_PATH, - g_param_spec_string (NM_SETTING_802_1X_PHASE2_CA_PATH, - "Phase2 auth CA path", - "UTF-8 encoded path to a directory containing PEM or " - "DER formatted certificates to be added to the " - "verification chain in addition to the certificate " - "specified in the 'phase2-ca-cert' property.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE2_CA_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-subject-match: @@ -3519,16 +3414,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_SUBJECT_MATCH, - g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, - "Phase2 subject match", - "Substring to be matched against the subject of " - "the certificate presented by the authentication " - "server during the inner 'phase2' " - "authentication. When unset, no verification of " - "the authentication server certificate's subject " - "is performed.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-altsubject-matches: @@ -3538,20 +3427,12 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * "phase 2" authentication. If the list is empty, no verification of the * server certificate's altSubjectName is performed. **/ - g_object_class_install_property - (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES, - _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, - "altSubjectName matches", - "List of strings to be matched against " - "List of strings to be matched against " - "the altSubjectName of the certificate " - "presented by the authentication server " - "during the inner 'phase 2' " - "authentication. If the list is empty, no " - "verification of the server certificate's " - "altSubjectName is performed.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + g_object_class_install_property + (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES, + _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-client-cert: @@ -3574,22 +3455,10 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PHASE2_CLIENT_CERT, - _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, - "Phase2 client certificate", - "Contains the 'phase 2' client certificate if " - "used by the EAP method specified in the " - "'phase2-auth' or 'phase2-autheap' properties. " - "Certificate data is specified using a 'scheme'; " - "two are currently supported: blob and path. " - "When using the blob scheme (which is backwards " - "compatible with NM 0.7.x) this property should " - "be set to the certificate's DER encoded data. " - "When using the path scheme, this property should " - "be set to the full UTF-8 encoded path of the " - "certificate, prefixed with the string 'file://' " - "and ending with a terminating NULL byte.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:password: @@ -3600,25 +3469,25 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD, - g_param_spec_string (NM_SETTING_802_1X_PASSWORD, - "Password", - "UTF-8 encoded password used for EAP authentication methods.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_802_1X_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:password-flags: * * Flags indicating how to handle the #NMSetting8021x:password property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS, - "Password Flags", - "Flags indicating how to handle the 802.1x password.", + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:password-raw: @@ -3630,30 +3499,25 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD_RAW, - _nm_param_spec_specialized (NM_SETTING_802_1X_PASSWORD_RAW, - "Password byte array", - "Password used for EAP authentication " - "methods, given as a byte array to allow " - "passwords in other encodings than UTF-8 " - "to be used. If both 'password' and " - "'password-raw' are given, 'password' is " - "preferred.", + _nm_param_spec_specialized (NM_SETTING_802_1X_PASSWORD_RAW, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:password-raw-flags: * * Flags indicating how to handle the #NMSetting8021x:password-raw property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_RAW_FLAGS, - g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, - "Password byte array Flags", - "Flags indicating how to handle the 802.1x password byte array.", + g_object_class_install_property + (object_class, PROP_PASSWORD_RAW_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:private-key: @@ -3666,15 +3530,15 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * should be set to the key's encrypted PEM encoded data. When using private * keys with the path scheme, this property should be set to the full UTF-8 * encoded path of the key, prefixed with the string "file://" and ending - * with a terminating NUL byte. When using PKCS#12 format private keys and - * the blob scheme, this property should be set to the PKCS#12 data and the + * with a terminating NUL byte. When using PKCS#12 format private keys and + * the blob scheme, this property should be set to the PKCS#12 data and the * #NMSetting8021x:private-key-password property must be set to password - * used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files + * used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files * and the path scheme, this property should be set to the full UTF-8 * encoded path of the key, prefixed with the string "file://" and and * ending with a terminating NUL byte, and as with the blob scheme the * "private-key-password" property must be set to the password used to - * decode the PKCS#12 private key and certificate. + * decode the PKCS#12 private key and certificate. * * Setting this property directly is discouraged; use the * nm_setting_802_1x_set_private_key() function instead. @@ -3687,54 +3551,28 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIVATE_KEY, - _nm_param_spec_specialized (NM_SETTING_802_1X_PRIVATE_KEY, - "Private key", - "Contains the private key when the 'eap' property " - "is set to 'tls'. Key data is specified using a " - "'scheme'; two are currently supported: blob and " - "path. When using the blob scheme and private " - "keys, this property should be set to the key's " - "encrypted PEM encoded data. When using private " - "keys with the path scheme, this property should " - "be set to the full UTF-8 encoded path of the key, " - "prefixed with the string 'file://' and ending " - "with a terminating NULL byte. When using " - "PKCS#12 format private keys and the blob " - "scheme, this property should be set to the " - "PKCS#12 data and the 'private-key-password' " - "property must be set to password used to " - "decrypt the PKCS#12 certificate and key. When " - "using PKCS#12 files and the path scheme, this " - "property should be set to the full UTF-8 encoded " - "path of the key, prefixed with the string " - "'file://' and and ending with a terminating NULL " - "byte, and as with the blob scheme the " - "'private-key-password' property must be set to " - "the password used to decode the PKCS#12 private " - "key and certificate.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_PRIVATE_KEY, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:private-key-password: * * The password used to decrypt the private key specified in the * #NMSetting8021x:private-key property when the private key either uses the - * path scheme, or if the private key is a PKCS#12 format key. Setting this + * path scheme, or if the private key is a PKCS#12 format key. Setting this * property directly is not generally necessary except when returning * secrets to NetworkManager; it is generally set automatically when setting * the private key by the nm_setting_802_1x_set_private_key() function. **/ g_object_class_install_property (object_class, PROP_PRIVATE_KEY_PASSWORD, - g_param_spec_string (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, - "Private key password", - "The password used to decrypt the private key " - "specified in the 'private-key' property when the " - "private key either uses the path scheme, or if the " - "private key is a PKCS#12 format key.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:private-key-password-flags: @@ -3742,15 +3580,14 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * Flags indicating how to handle the #NMSetting8021x:private-key-password * property. **/ - g_object_class_install_property (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, - "Private Key Password Flags", - "Flags indicating how to handle the 802.1x private " - "key password.", + g_object_class_install_property + (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-private-key: @@ -3764,70 +3601,43 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * should be set to the key's encrypted PEM encoded data. When using private * keys with the path scheme, this property should be set to the full UTF-8 * encoded path of the key, prefixed with the string "file://" and ending - * with a terminating NUL byte. When using PKCS#12 format private keys and - * the blob scheme, this property should be set to the PKCS#12 data and the + * with a terminating NUL byte. When using PKCS#12 format private keys and + * the blob scheme, this property should be set to the PKCS#12 data and the * #NMSetting8021x:phase2-private-key-password property must be set to - * password used to decrypt the PKCS#12 certificate and key. When using - * PKCS#12 files and the path scheme, this property should be set to the + * password used to decrypt the PKCS#12 certificate and key. When using + * PKCS#12 files and the path scheme, this property should be set to the * full UTF-8 encoded path of the key, prefixed with the string "file://" * and and ending with a terminating NUL byte, and as with the blob scheme * the #NMSetting8021x:phase2-private-key-password property must be set to - * the password used to decode the PKCS#12 private key and certificate. + * the password used to decode the PKCS#12 private key and certificate. * * Setting this property directly is discouraged; use the * nm_setting_802_1x_set_phase2_private_key() function instead. **/ g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY, - _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, - "Phase2 private key", - "Contains the 'phase 2' inner private key when " - "the 'phase2-auth' or 'phase2-autheap' property " - "is set to 'tls'. Key data is specified using a " - "'scheme'; two are currently supported: blob and " - "path. When using the blob scheme and private " - "keys, this property should be set to the key's " - "encrypted PEM encoded data. When using private " - "keys with the path scheme, this property should " - "be set to the full UTF-8 encoded path of the key, " - "prefixed with the string 'file://' and ending " - "with a terminating NULL byte. When using " - "PKCS#12 format private keys and the blob " - "scheme, this property should be set to the " - "PKCS#12 data and the 'phase2-private-key-password' " - "property must be set to password used to " - "decrypt the PKCS#12 certificate and key. When " - "using PKCS#12 files and the path scheme, this " - "property should be set to the full UTF-8 encoded " - "path of the key, prefixed with the string " - "'file://' and and ending with a terminating NULL " - "byte, and as with the blob scheme the " - "'phase2-private-key-password' property must be " - "set to the password used to decode the PKCS#12 " - "private key and certificate.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-private-key-password: * * The password used to decrypt the "phase 2" private key specified in the * #NMSetting8021x:phase2-private-key property when the private key either - * uses the path scheme, or is a PKCS#12 format key. Setting this property + * uses the path scheme, or is a PKCS#12 format key. Setting this property * directly is not generally necessary except when returning secrets to * NetworkManager; it is generally set automatically when setting the * private key by the nm_setting_802_1x_set_phase2_private_key() function. **/ g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD, - g_param_spec_string (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, - "Phase2 private key password", - "The password used to decrypt the 'phase 2' private " - "key specified in the 'private-key' property when the " - "phase2 private key either uses the path scheme, or " - "if the phase2 private key is a PKCS#12 format key.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:phase2-private-key-password-flags: @@ -3835,15 +3645,14 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * Flags indicating how to handle the * #NMSetting8021x:phase2-private-key-password property. **/ - g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, - "Phase2 Private Key Password Flags", - "Flags indicating how to handle the 802.1x phase2 " - "private key password.", + g_object_class_install_property + (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:pin: @@ -3852,25 +3661,25 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PIN, - g_param_spec_string (NM_SETTING_802_1X_PIN, - "PIN", - "PIN used for EAP authentication methods.", + g_param_spec_string (NM_SETTING_802_1X_PIN, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:pin-flags: * * Flags indicating how to handle the #NMSetting8021x:pin property. **/ - g_object_class_install_property (object_class, PROP_PIN_FLAGS, - g_param_spec_uint (NM_SETTING_802_1X_PIN_FLAGS, - "PIN Flags", - "Flags indicating how to handle the 802.1x PIN.", + g_object_class_install_property + (object_class, PROP_PIN_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PIN_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSetting8021x:system-ca-certs: @@ -3884,17 +3693,11 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SYSTEM_CA_CERTS, - g_param_spec_boolean (NM_SETTING_802_1X_SYSTEM_CA_CERTS, - "Use system CA certificates", - "When TRUE, overrides 'ca-path' and 'phase2-ca-path' " - "properties using the system CA directory " - "specified at configure time with the " - "--system-ca-path switch. The certificates in " - "this directory are added to the verification " - "chain in addition to any certificates specified " - "by the 'ca-cert' and 'phase2-ca-cert' properties.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_802_1X_SYSTEM_CA_CERTS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /* Initialize crypto lbrary. */ if (!nm_utils_init (&error)) { @@ -3902,5 +3705,4 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) error->code, error->message); g_error_free (error); } - } diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 263630ec..62b43905 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_8021X_H @@ -36,7 +33,7 @@ G_BEGIN_DECLS * @NM_SETTING_802_1X_CK_FORMAT_X509: file contains an X.509 format certificate * @NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: file contains an old-style OpenSSL PEM * or DER private key - * @NM_SETTING_802_1X_CK_FORMAT_PKCS12: file contains a PKCS#12 certificate + * @NM_SETTING_802_1X_CK_FORMAT_PKCS12: file contains a PKCS#12 certificate * and private key * * #NMSetting8021xCKFormat values indicate the general type of a certificate diff --git a/libnm-util/nm-setting-adsl.c b/libnm-util/nm-setting-adsl.c index 00cbb4af..601ebc2b 100644 --- a/libnm-util/nm-setting-adsl.c +++ b/libnm-util/nm-setting-adsl.c @@ -1,10 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Hicham HAOUARI - * Pantelis Koukousoulas - * * 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 @@ -20,11 +16,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2011 - 2013 Red Hat, Inc. */ +#include "config.h" + #include -#include +#include #include "nm-setting-adsl.h" #include "nm-setting-ppp.h" @@ -230,20 +228,22 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) && - strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) && - strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM)) { + if ( !priv->protocol + || ( strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) + && strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) + && strcmp (priv->protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM))){ g_set_error (error, NM_SETTING_ADSL_ERROR, NM_SETTING_ADSL_ERROR_INVALID_PROPERTY, _("'%s' is not a valid value for the property"), - priv->protocol); + priv->protocol ? priv->protocol : "(null)"); g_prefix_error (error, "%s.%s: ", NM_SETTING_ADSL_SETTING_NAME, NM_SETTING_ADSL_PROTOCOL); return FALSE; } - if (strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) && - strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_LLC) ) { + if ( priv->encapsulation + && ( strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) + && strcmp (priv->encapsulation, NM_SETTING_ADSL_ENCAPSULATION_LLC) )) { g_set_error (error, NM_SETTING_ADSL_ERROR, NM_SETTING_ADSL_ERROR_INVALID_PROPERTY, @@ -387,11 +387,10 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_USERNAME, - g_param_spec_string (NM_SETTING_ADSL_USERNAME, - "Username", - "Username used to authenticate with the pppoa service.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_ADSL_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:password: @@ -400,25 +399,25 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD, - g_param_spec_string (NM_SETTING_ADSL_PASSWORD, - "Password", - "Password used to authenticate with the pppoa service.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_ADSL_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:password-flags: * * Flags indicating how to handle the #NMSettingAdsl:password property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_ADSL_PASSWORD_FLAGS, - "Password Flags", - "Flags indicating how to handle the ADSL password.", + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_ADSL_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:protocol: @@ -427,11 +426,10 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PROTOCOL, - g_param_spec_string (NM_SETTING_ADSL_PROTOCOL, - "Protocol", - "ADSL connection protocol.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_ADSL_PROTOCOL, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:encapsulation: @@ -440,11 +438,10 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ENCAPSULATION, - g_param_spec_string (NM_SETTING_ADSL_ENCAPSULATION, - "Encapsulation", - "Encapsulation of ADSL connection", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_ADSL_ENCAPSULATION, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:vpi: @@ -453,11 +450,10 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_VPI, - g_param_spec_uint (NM_SETTING_ADSL_VPI, - "VPI", - "VPI of ADSL connection", - 0, 65536, 0, - G_PARAM_READWRITE)); + g_param_spec_uint (NM_SETTING_ADSL_VPI, "", "", + 0, 65536, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingAdsl:vci: @@ -466,9 +462,8 @@ nm_setting_adsl_class_init (NMSettingAdslClass *setting_class) **/ g_object_class_install_property (object_class, PROP_VCI, - g_param_spec_uint (NM_SETTING_ADSL_VCI, - "VCI", - "VCI of ADSL connection", - 0, 65536, 0, - G_PARAM_READWRITE)); + g_param_spec_uint (NM_SETTING_ADSL_VCI, "", "", + 0, 65536, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-adsl.h b/libnm-util/nm-setting-adsl.h index 484e8a39..82af6ebd 100644 --- a/libnm-util/nm-setting-adsl.h +++ b/libnm-util/nm-setting-adsl.h @@ -1,10 +1,6 @@ /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Hicham HAOUARI - * Pantelis Koukousoulas - * * 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 @@ -20,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. */ #ifndef NM_SETTING_ADSL_H diff --git a/libnm-util/nm-setting-bluetooth.c b/libnm-util/nm-setting-bluetooth.c index 5c13257c..2867d73b 100644 --- a/libnm-util/nm-setting-bluetooth.c +++ b/libnm-util/nm-setting-bluetooth.c @@ -1,10 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Bastien Nocera - * Dan Williams - * Tambet Ingo - * * 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 @@ -20,13 +16,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include -#include +#include #include "nm-param-spec-specialized.h" #include "nm-dbus-glib-types.h" @@ -105,7 +103,8 @@ NMSetting *nm_setting_bluetooth_new (void) * Returns the connection method for communicating with the remote device (i.e. * either DUN to a DUN-capable device or PANU to a NAP-capable device). * - * Returns: the type, either %NM_SETTING_BLUETOOTH_PANU or %NM_SETTING_BLUETOOTH_DUN + * Returns: the type, either %NM_SETTING_BLUETOOTH_TYPE_PANU or + * %NM_SETTING_BLUETOOTH_TYPE_DUN **/ const char * nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting) @@ -163,7 +162,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } else if (!g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN) && - !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { + !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { g_set_error (error, NM_SETTING_BLUETOOTH_ERROR, NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, @@ -217,7 +216,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (object); @@ -239,7 +238,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingBluetooth *setting = NM_SETTING_BLUETOOTH (object); @@ -279,11 +278,11 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BDADDR, - _nm_param_spec_specialized (NM_SETTING_BLUETOOTH_BDADDR, - "Bluetooth address", - "The Bluetooth address of the device", + _nm_param_spec_specialized (NM_SETTING_BLUETOOTH_BDADDR, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBluetooth:type: @@ -293,12 +292,9 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class) **/ g_object_class_install_property (object_class, PROP_TYPE, - g_param_spec_string (NM_SETTING_BLUETOOTH_TYPE, - "Connection type", - "Either '" NM_SETTING_BLUETOOTH_TYPE_DUN "' for " - "Dial-Up Networking connections or " - "'" NM_SETTING_BLUETOOTH_TYPE_PANU "' for " - "Personal Area Networking connections.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_BLUETOOTH_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-bluetooth.h b/libnm-util/nm-setting-bluetooth.h index 95a8852a..caf12158 100644 --- a/libnm-util/nm-setting-bluetooth.h +++ b/libnm-util/nm-setting-bluetooth.h @@ -1,10 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Bastien Nocera - * Dan Williams - * Tambet Ingo - * * 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 @@ -20,8 +16,8 @@ * 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. + * Copyright 2007 - 2009 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_BLUETOOTH_H diff --git a/libnm-util/nm-setting-bond.c b/libnm-util/nm-setting-bond.c index 5f919027..fa12cf0e 100644 --- a/libnm-util/nm-setting-bond.c +++ b/libnm-util/nm-setting-bond.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Thomas Graf - * * 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 @@ -18,16 +16,18 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2011 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include #include #include -#include +#include #include "nm-setting-bond.h" #include "nm-param-spec-specialized.h" @@ -122,6 +122,8 @@ static const BondDefault defaults[] = { { NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, "0", TYPE_BOTH, 0, 2, { "layer2", "layer3+4", "layer2+3", NULL } }, { NM_SETTING_BOND_OPTION_RESEND_IGMP, "1", TYPE_INT, 0, 255 }, + { NM_SETTING_BOND_OPTION_LACP_RATE, "0", TYPE_BOTH, 0, 1, + { "slow", "fast", NULL } }, }; /** @@ -313,8 +315,8 @@ nm_setting_bond_validate_option (const char *name, case TYPE_STR: return validate_list (name, value, &defaults[i]); case TYPE_BOTH: - return validate_int (name, value, &defaults[i]) - || validate_list (name, value, &defaults[i]); + return ( validate_int (name, value, &defaults[i]) + || validate_list (name, value, &defaults[i])); case TYPE_IP: return validate_ip (name, value); case TYPE_IFNAME: @@ -489,26 +491,9 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) NULL }; int miimon = 0, arp_interval = 0; const char *arp_ip_target = NULL; + const char *lacp_rate; const char *primary; - if (!priv->interface_name || !strlen(priv->interface_name)) { - g_set_error_literal (error, - NM_SETTING_BOND_ERROR, - NM_SETTING_BOND_ERROR_MISSING_PROPERTY, - _("property is missing")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME); - return FALSE; - } - - if (!nm_utils_iface_valid_name (priv->interface_name)) { - g_set_error_literal (error, - NM_SETTING_BOND_ERROR, - NM_SETTING_BOND_ERROR_INVALID_PROPERTY, - _("property is invalid")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME); - return FALSE; - } - g_hash_table_iter_init (&iter, priv->options); while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) { if (!value[0] || !nm_setting_bond_validate_option (key, value)) { @@ -688,7 +673,26 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } } - return TRUE; + lacp_rate = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_LACP_RATE); + if ( lacp_rate + && (g_strcmp0 (value, "802.3ad") != 0 && g_strcmp0 (value, "4") != 0) + && (strcmp (lacp_rate, "slow") != 0 && strcmp (lacp_rate, "0") != 0)) { + g_set_error (error, + NM_SETTING_BOND_ERROR, + NM_SETTING_BOND_ERROR_INVALID_OPTION, + _("'%s' option is only valid with mode '%s'"), + NM_SETTING_BOND_OPTION_LACP_RATE, "802.3ad"); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + return FALSE; + } + + return _nm_setting_verify_deprecated_virtual_iface_name ( + priv->interface_name, FALSE, + NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME, + NM_SETTING_BOND_ERROR, + NM_SETTING_BOND_ERROR_INVALID_PROPERTY, + NM_SETTING_BOND_ERROR_MISSING_PROPERTY, + all_settings, error); } static const char * @@ -765,7 +769,7 @@ get_property (GObject *object, guint prop_id, break; case PROP_OPTIONS: g_value_set_boxed (value, priv->options); - break; + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -795,11 +799,11 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE_NAME, - g_param_spec_string (NM_SETTING_BOND_INTERFACE_NAME, - "InterfaceName", - "The name of the virtual in-kernel bonding network interface", + g_param_spec_string (NM_SETTING_BOND_INTERFACE_NAME, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBond:options: @@ -810,12 +814,9 @@ nm_setting_bond_class_init (NMSettingBondClass *setting_class) **/ g_object_class_install_property (object_class, PROP_OPTIONS, - _nm_param_spec_specialized (NM_SETTING_BOND_OPTIONS, - "Options", - "Dictionary of key/value pairs of bonding " - "options. Both keys and values must be " - "strings. Option names must contain only " - "alphanumeric characters (ie, [a-zA-Z0-9]).", + _nm_param_spec_specialized (NM_SETTING_BOND_OPTIONS, "", "", DBUS_TYPE_G_MAP_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-bond.h b/libnm-util/nm-setting-bond.h index f3358c7f..cf969995 100644 --- a/libnm-util/nm-setting-bond.h +++ b/libnm-util/nm-setting-bond.h @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Thomas Graf - * * 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 @@ -18,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2011 - 2013 Red Hat, Inc. */ #ifndef NM_SETTING_BOND_H @@ -73,6 +71,7 @@ GQuark nm_setting_bond_error_quark (void); #define NM_SETTING_BOND_OPTION_AD_SELECT "ad_select" #define NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY "xmit_hash_policy" #define NM_SETTING_BOND_OPTION_RESEND_IGMP "resend_igmp" +#define NM_SETTING_BOND_OPTION_LACP_RATE "lacp_rate" typedef struct { NMSetting parent; diff --git a/libnm-util/nm-setting-bridge-port.c b/libnm-util/nm-setting-bridge-port.c index 64be5662..b3afa500 100644 --- a/libnm-util/nm-setting-bridge-port.c +++ b/libnm-util/nm-setting-bridge-port.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * * 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 @@ -18,14 +16,16 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2012 - 2013 Red Hat, Inc. + * Copyright 2012 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include -#include +#include #include "nm-setting-bridge-port.h" #include "nm-utils.h" @@ -264,11 +264,12 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY, - g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PRIORITY, - "Priority", - "The Spanning Tree Protocol (STP) priority of this bridge port", + g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PRIORITY, "", "", 0, BR_MAX_PORT_PRIORITY, BR_DEF_PRIORITY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridgePort:path-cost: @@ -278,14 +279,14 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_PATH_COST, - g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PATH_COST, - "Path Cost", - "The Spanning Tree Protocol (STP) port cost for " - "destinations via this port.", + g_object_class_install_property + (object_class, PROP_PATH_COST, + g_param_spec_uint (NM_SETTING_BRIDGE_PORT_PATH_COST, "", "", 0, BR_MAX_PATH_COST, 100, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridgePort:hairpin-mode: @@ -295,13 +296,11 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_HAIRPIN_MODE, - g_param_spec_boolean (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, - "Hairpin Mode", - "Enables or disabled 'hairpin mode' for the " - "port, which allows frames to be sent back out " - "through the port the frame was received on.", + g_object_class_install_property + (object_class, PROP_HAIRPIN_MODE, + g_param_spec_boolean (NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "", "", FALSE, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-bridge-port.h b/libnm-util/nm-setting-bridge-port.h index 7848b75f..fcaf22ed 100644 --- a/libnm-util/nm-setting-bridge-port.h +++ b/libnm-util/nm-setting-bridge-port.h @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * * 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 @@ -18,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2012 Red Hat, Inc. + * Copyright 2012 Red Hat, Inc. */ #ifndef NM_SETTING_BRIDGE_PORT_H diff --git a/libnm-util/nm-setting-bridge.c b/libnm-util/nm-setting-bridge.c index 0908573d..bdaa75f9 100644 --- a/libnm-util/nm-setting-bridge.c +++ b/libnm-util/nm-setting-bridge.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Thomas Graf - * * 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 @@ -18,14 +16,16 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2011 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include -#include +#include #include #include "nm-setting-bridge.h" @@ -280,25 +280,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting); - if (!priv->interface_name || !strlen(priv->interface_name)) { - g_set_error_literal (error, - NM_SETTING_BRIDGE_ERROR, - NM_SETTING_BRIDGE_ERROR_MISSING_PROPERTY, - _("property is missing")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_INTERFACE_NAME); - return FALSE; - } - - if (!nm_utils_iface_valid_name (priv->interface_name)) { - g_set_error (error, - NM_SETTING_BRIDGE_ERROR, - NM_SETTING_BRIDGE_ERROR_INVALID_PROPERTY, - _("'%s' is not a valid interface name"), - priv->interface_name); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_INTERFACE_NAME); - return FALSE; - } - if (priv->mac_address && priv->mac_address->len != ETH_ALEN) { g_set_error_literal (error, NM_SETTING_BRIDGE_ERROR, @@ -336,7 +317,13 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) error)) return FALSE; - return TRUE; + return _nm_setting_verify_deprecated_virtual_iface_name ( + priv->interface_name, FALSE, + NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_INTERFACE_NAME, + NM_SETTING_BRIDGE_ERROR, + NM_SETTING_BRIDGE_ERROR_INVALID_PROPERTY, + NM_SETTING_BRIDGE_ERROR_MISSING_PROPERTY, + all_settings, error); } static const char * @@ -468,11 +455,11 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE_NAME, - g_param_spec_string (NM_SETTING_BRIDGE_INTERFACE_NAME, - "InterfaceName", - "The name of the virtual in-kernel bridging network interface", + g_param_spec_string (NM_SETTING_BRIDGE_INTERFACE_NAME, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:mac-address: @@ -484,12 +471,12 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * Since: 0.9.10 **/ g_object_class_install_property - (object_class, PROP_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_BRIDGE_MAC_ADDRESS, - "MAC Address", - "The MAC address of the bridge", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + (object_class, PROP_MAC_ADDRESS, + _nm_param_spec_specialized (NM_SETTING_BRIDGE_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:stp: @@ -498,14 +485,14 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_STP, - g_param_spec_boolean (NM_SETTING_BRIDGE_STP, - "STP", - "Controls whether Spanning Tree Protocol (STP) " - "is enabled for this bridge.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_STP, + g_param_spec_boolean (NM_SETTING_BRIDGE_STP, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:priority: @@ -516,16 +503,14 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_PRIORITY, - g_param_spec_uint (NM_SETTING_BRIDGE_PRIORITY, - "Priority", - "Sets the Spanning Tree Protocol (STP) priority " - "for this bridge. Lower values are 'better'; the " - "lowest priority bridge will be elected the root " - "bridge.", - 0, G_MAXUINT16, 0x8000, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_PRIORITY, + g_param_spec_uint (NM_SETTING_BRIDGE_PRIORITY, "", "", + 0, G_MAXUINT16, 0x8000, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:forward-delay: @@ -534,14 +519,14 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_FORWARD_DELAY, - g_param_spec_uint (NM_SETTING_BRIDGE_FORWARD_DELAY, - "ForwardDelay", - "The Spanning Tree Protocol (STP) forwarding " - "delay, in seconds.", - 0, BR_MAX_FORWARD_DELAY, 15, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_FORWARD_DELAY, + g_param_spec_uint (NM_SETTING_BRIDGE_FORWARD_DELAY, "", "", + 0, BR_MAX_FORWARD_DELAY, 15, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:hello-time: @@ -550,14 +535,14 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_HELLO_TIME, - g_param_spec_uint (NM_SETTING_BRIDGE_HELLO_TIME, - "HelloTime", - "The Spanning Tree Protocol (STP) hello time, in " - "seconds.", - 0, BR_MAX_HELLO_TIME, 2, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_HELLO_TIME, + g_param_spec_uint (NM_SETTING_BRIDGE_HELLO_TIME, "", "", + 0, BR_MAX_HELLO_TIME, 2, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:max-age: @@ -566,14 +551,14 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_MAX_AGE, - g_param_spec_uint (NM_SETTING_BRIDGE_MAX_AGE, - "MaxAge", - "The Spanning Tree Protocol (STP) maximum message " - "age, in seconds.", - 0, BR_MAX_MAX_AGE, 20, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_MAX_AGE, + g_param_spec_uint (NM_SETTING_BRIDGE_MAX_AGE, "", "", + 0, BR_MAX_MAX_AGE, 20, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingBridge:ageing-time: @@ -582,12 +567,12 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class) * * Since: 0.9.8 **/ - g_object_class_install_property - (object_class, PROP_AGEING_TIME, - g_param_spec_uint (NM_SETTING_BRIDGE_AGEING_TIME, - "AgeingTime", - "The Ethernet MAC address aging time, in seconds.", - 0, BR_MAX_AGEING_TIME, 300, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_object_class_install_property + (object_class, PROP_AGEING_TIME, + g_param_spec_uint (NM_SETTING_BRIDGE_AGEING_TIME, "", "", + 0, BR_MAX_AGEING_TIME, 300, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-util/nm-setting-bridge.h b/libnm-util/nm-setting-bridge.h index 1e895704..f6b59262 100644 --- a/libnm-util/nm-setting-bridge.h +++ b/libnm-util/nm-setting-bridge.h @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Thomas Graf - * * 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 @@ -18,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2011 - 2012 Red Hat, Inc. */ #ifndef NM_SETTING_BRIDGE_H diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index 7acfe852..44a893c7 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * * 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 @@ -18,11 +16,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. */ +#include "config.h" + #include -#include +#include #include "nm-setting-cdma.h" #include "nm-utils.h" @@ -231,7 +231,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingCdmaPrivate *priv = NM_SETTING_CDMA_GET_PRIVATE (object); @@ -259,7 +259,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingCdma *setting = NM_SETTING_CDMA (object); @@ -308,14 +308,10 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NUMBER, - g_param_spec_string (NM_SETTING_CDMA_NUMBER, - "Number", - "Number to dial when establishing a PPP data session " - "with the CDMA-based mobile broadband network. If not " - "specified, the default number (#777) is used when " - "required.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_CDMA_NUMBER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingCdma:username: @@ -326,13 +322,10 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) **/ g_object_class_install_property (object_class, PROP_USERNAME, - g_param_spec_string (NM_SETTING_CDMA_USERNAME, - "Username", - "Username used to authenticate with the network, if " - "required. Note that many providers do not require " - "a username or accept any username.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_CDMA_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingCdma:password: @@ -343,25 +336,23 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD, - g_param_spec_string (NM_SETTING_CDMA_PASSWORD, - "Password", - "Password used to authenticate with the network, if " - "required. Note that many providers do not require " - "a password or accept any password.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_CDMA_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingCdma:password-flags: * * Flags indicating how to handle the #NMSettingCdma:password property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_CDMA_PASSWORD_FLAGS, - "Password Flags", - "Flags indicating how to handle the CDMA password.", + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_CDMA_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-cdma.h b/libnm-util/nm-setting-cdma.h index 0dc290da..eee44205 100644 --- a/libnm-util/nm-setting-cdma.h +++ b/libnm-util/nm-setting-cdma.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_CDMA_H diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 56e87a4d..162ae7cb 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include -#include +#include #include "nm-utils.h" #include "nm-dbus-glib-types.h" @@ -459,7 +458,7 @@ nm_setting_connection_remove_permission (NMSettingConnection *setting, * be a username. See #NMSettingConnection:permissions: for more details. * * Returns: %TRUE if the permission was found and removed; %FALSE if it was not. - * + * * Since: 0.9.10 */ gboolean @@ -796,29 +795,35 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - /* If the connection has a virtual interface name, it must match - * the connection setting's interface name. + /* FIXME: previously, verify() set the NMSettingConnection:interface_name property, + * thus modifying the setting. verify() should not do this, but keep this not to change + * behaviour. */ - for (iter = all_settings; iter; iter = iter->next) { - const char *virtual_iface; - - virtual_iface = nm_setting_get_virtual_iface_name (iter->data); - if (virtual_iface) { - if (priv->interface_name) { - if (strcmp (priv->interface_name, virtual_iface) != 0) { - g_set_error (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, - _("'%s' doesn't match the virtual interface name '%s'"), - priv->interface_name, virtual_iface); - g_prefix_error (error, "%s.%s: ", - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_INTERFACE_NAME); - return FALSE; + if (!priv->interface_name) { + for (iter = all_settings; iter; iter = iter->next) { + NMSetting *s_current = iter->data; + char *virtual_iface_name = NULL; + + if (NM_IS_SETTING_BOND (s_current)) + g_object_get (s_current, NM_SETTING_BOND_INTERFACE_NAME, &virtual_iface_name, NULL); + else if (NM_IS_SETTING_BRIDGE (s_current)) + g_object_get (s_current, NM_SETTING_BRIDGE_INTERFACE_NAME, &virtual_iface_name, NULL); + else if (NM_IS_SETTING_TEAM (s_current)) + g_object_get (s_current, NM_SETTING_TEAM_INTERFACE_NAME, &virtual_iface_name, NULL); + else if (NM_IS_SETTING_VLAN (s_current)) + g_object_get (s_current, NM_SETTING_VLAN_INTERFACE_NAME, &virtual_iface_name, NULL); + /* For NMSettingInfiniband, virtual_iface_name has no backing field. + * No need to set the (unset) interface_name to the default value. + **/ + + if (virtual_iface_name) { + if (nm_utils_iface_valid_name (virtual_iface_name)) { + /* found a new interface name. */ + priv->interface_name = virtual_iface_name; + break; } - } else - priv->interface_name = g_strdup (virtual_iface); - break; + g_free (virtual_iface_name); + } } } @@ -861,39 +866,37 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - is_slave = ( !g_strcmp0 (priv->slave_type, NM_SETTING_BOND_SETTING_NAME) - || !g_strcmp0 (priv->slave_type, NM_SETTING_BRIDGE_SETTING_NAME) - || !g_strcmp0 (priv->slave_type, NM_SETTING_TEAM_SETTING_NAME)); + is_slave = ( priv->slave_type + && ( !strcmp (priv->slave_type, NM_SETTING_BOND_SETTING_NAME) + || !strcmp (priv->slave_type, NM_SETTING_BRIDGE_SETTING_NAME) + || !strcmp (priv->slave_type, NM_SETTING_TEAM_SETTING_NAME))); + + if (priv->slave_type && !is_slave) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown slave type '%s'"), priv->slave_type); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return NM_SETTING_VERIFY_ERROR; + } - /* Bond/bridge/team slaves are not allowed to have any IP configuration. */ if (is_slave) { - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_find_in_list (all_settings, NM_SETTING_IP4_CONFIG_SETTING_NAME)); - if (s_ip4) { - if (strcmp (nm_setting_ip4_config_get_method (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { - g_set_error_literal (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED, - _("IPv4 configuration is not allowed for slave")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); - return FALSE; - } + if (!priv->master) { + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + _("Slave connections need a valid '" NM_SETTING_CONNECTION_MASTER "' property")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER); + return NM_SETTING_VERIFY_ERROR; } - - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_find_in_list (all_settings, NM_SETTING_IP6_CONFIG_SETTING_NAME)); - if (s_ip6) { - if (strcmp (nm_setting_ip6_config_get_method (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { - g_set_error_literal (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED, - _("IPv6 configuration is not allowed for slave")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); - return FALSE; - } + } else { + if (priv->master) { + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + _("Cannot set '" NM_SETTING_CONNECTION_MASTER "' without '" NM_SETTING_CONNECTION_SLAVE_TYPE "'")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); + return NM_SETTING_VERIFY_ERROR; } } @@ -1103,13 +1106,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ID, - g_param_spec_string (NM_SETTING_CONNECTION_ID, - "ID", - "User-readable connection identifier/name. Must be " - "one or more characters and may change over the lifetime " - "of the connection if the user decides to rename it.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_string (NM_SETTING_CONNECTION_ID, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:uuid: @@ -1129,20 +1130,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_UUID, - g_param_spec_string (NM_SETTING_CONNECTION_UUID, - "UUID", - "Universally unique connection identifier. Must be " - "in the format '2815492f-7e56-435e-b2e9-246bd7cdc664' " - "(ie, contains only hexadecimal characters and '-'). " - "The UUID should be assigned when the connection is " - "created and never changed as long as the connection " - "still applies to the same network. For example, " - "it should not be changed when the user changes the " - "connection's 'id', but should be recreated when the " - "Wi-Fi SSID, mobile broadband network provider, or the " - "connection type changes.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_string (NM_SETTING_CONNECTION_UUID, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:interface-name: @@ -1151,6 +1143,8 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * set, then the connection can be attached to any interface of the * appropriate type (subject to restrictions imposed by other settings). * + * For software devices this specifies the name of the created device. + * * For connection types where interface names cannot easily be made * persistent (e.g. mobile broadband or USB Ethernet), this property should * not be used. Setting this property restricts the interfaces a connection @@ -1161,21 +1155,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE_NAME, - g_param_spec_string (NM_SETTING_CONNECTION_INTERFACE_NAME, - "Interface name", - "Interface name this connection is bound to. " - "If not set, then the connection can be attached " - "to any interface of the appropriate type (subject " - "to restrictions imposed by other settings). For " - "connection types where interface names cannot easily " - "be made persistent (e.g. mobile broadband or USB " - "Ethernet), this property should not be used. Setting " - "this property restricts the interfaces a connection can " - "be used with, and if interface names change or are " - "reordered the connection may be applied to the wrong " - "interface.", + g_param_spec_string (NM_SETTING_CONNECTION_INTERFACE_NAME, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:type: @@ -1188,21 +1172,15 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_TYPE, - g_param_spec_string (NM_SETTING_CONNECTION_TYPE, - "Type", - "Base type of the connection. For hardware-dependent " - "connections, should contain the setting name of the " - "hardware-type specific setting (ie, '802-3-ethernet' " - "or '802-11-wireless' or 'bluetooth', etc), and for " - "non-hardware dependent connections like VPN or " - "otherwise, should contain the setting name of that " - "setting type (ie, 'vpn' or 'bridge', etc).", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:permissions: - * + * * An array of strings defining what access a given user has to this * connection. If this is %NULL or empty, all users are allowed to access * this connection. Otherwise a user is allowed to access this connection @@ -1217,25 +1195,10 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) */ g_object_class_install_property (object_class, PROP_PERMISSIONS, - _nm_param_spec_specialized (NM_SETTING_CONNECTION_PERMISSIONS, - "Permissions", - "An array of strings defining what access a given " - "user has to this connection. If this is NULL or " - "empty, all users are allowed to access this " - "connection. Otherwise a user is allowed to access " - "this connection if and only if they are in this " - "array. Each entry is of the form " - "\"[type]:[id]:[reserved]\", for example: " - "\"user:dcbw:blah\" At this time only the 'user' " - "[type] is allowed. Any other values are ignored and " - "reserved for future use. [id] is the username that " - "this permission refers to, which may not contain the " - "':' character. Any [reserved] information (if " - "present) must be ignored and is reserved for future " - "use. All of [type], [id], and [reserved] must be " - "valid UTF-8.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_CONNECTION_PERMISSIONS, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:autoconnect: @@ -1247,14 +1210,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_AUTOCONNECT, - g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, - "Autoconnect", - "If TRUE, NetworkManager will activate this connection " - "when its network resources are available. If FALSE, " - "the connection must be manually activated by the user " - "or some other mechanism.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:timestamp: @@ -1269,16 +1230,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_TIMESTAMP, - g_param_spec_uint64 (NM_SETTING_CONNECTION_TIMESTAMP, - "Timestamp", - "Timestamp (in seconds since the Unix Epoch) that the " - "connection was last successfully activated. NetworkManager " - "updates the connection timestamp periodically when the " - "connection is active to ensure that an active connection " - "has the latest timestamp. The property is only meant for " - "reading (changes to this property will not be preserved).", + g_param_spec_uint64 (NM_SETTING_CONNECTION_TIMESTAMP, "", "", 0, G_MAXUINT64, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:read-only: @@ -1288,15 +1245,13 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * connection is read-only and cannot be modified. **/ g_object_class_install_property - (object_class, PROP_READ_ONLY, - g_param_spec_boolean (NM_SETTING_CONNECTION_READ_ONLY, - "Read-Only", - "If TRUE, the connection is read-only and cannot be " - "changed by the user or any other mechanism. This is " - "normally set for system connections whose plugin " - "cannot yet write updated connections back out.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + (object_class, PROP_READ_ONLY, + g_param_spec_boolean (NM_SETTING_CONNECTION_READ_ONLY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:zone: @@ -1308,16 +1263,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ZONE, - g_param_spec_string (NM_SETTING_CONNECTION_ZONE, - "Zone", - "The trust level of a the connection." - "Free form case-insensitive string (for example " - "\"Home\", \"Work\", \"Public\"). NULL or " - "unspecified zone means the connection will be " - "placed in the default zone as defined by the " - "firewall.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_string (NM_SETTING_CONNECTION_ZONE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:master: @@ -1326,12 +1277,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MASTER, - g_param_spec_string (NM_SETTING_CONNECTION_MASTER, - "Master", - "Interface name of the master device or UUID of " - "the master connection", + g_param_spec_string (NM_SETTING_CONNECTION_MASTER, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:slave-type: @@ -1342,13 +1293,12 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SLAVE_TYPE, - g_param_spec_string (NM_SETTING_CONNECTION_SLAVE_TYPE, - "Slave-Type", - "Setting name describing the type of slave " - "this connection is (ie, 'bond') or NULL if this " - "connection is not a slave.", + g_param_spec_string (NM_SETTING_CONNECTION_SLAVE_TYPE, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:secondaries: @@ -1361,13 +1311,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SECONDARIES, - _nm_param_spec_specialized (NM_SETTING_CONNECTION_SECONDARIES, - "Secondaries", - "List of connection UUIDs that should be activated " - "when the base connection itself is activated. " - "Currently only VPN connections are supported.", + _nm_param_spec_specialized (NM_SETTING_CONNECTION_SECONDARIES, "", "", DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingConnection:gateway-ping-timeout: @@ -1379,11 +1327,9 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) **/ g_object_class_install_property (object_class, PROP_GATEWAY_PING_TIMEOUT, - g_param_spec_uint (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, - "Gateway Ping Timeout", - "If greater than zero, delay success of IP " - "addressing until either the timeout is reached, or " - "an IP gateway replies to a ping.", + g_param_spec_uint (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, "", "", 0, 30, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index ff2af7a2..143fa11d 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_CONNECTION_H @@ -136,7 +133,7 @@ gboolean nm_setting_connection_remove_permission_by_value (NMSettingConnectio const char *nm_setting_connection_get_master (NMSettingConnection *setting); gboolean nm_setting_connection_is_slave_type (NMSettingConnection *setting, - const char *type); + const char *type); const char *nm_setting_connection_get_slave_type (NMSettingConnection *setting); guint32 nm_setting_connection_get_num_secondaries (NMSettingConnection *setting); diff --git a/libnm-util/nm-setting-dcb.c b/libnm-util/nm-setting-dcb.c index 54b115dd..2376581e 100644 --- a/libnm-util/nm-setting-dcb.c +++ b/libnm-util/nm-setting-dcb.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * * 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 @@ -18,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2013 Red Hat, Inc. + * Copyright 2013 Red Hat, Inc. */ +#include "config.h" + #include #include -#include +#include #include "nm-setting-dcb.h" #include "nm-param-spec-specialized.h" @@ -969,13 +969,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_FCOE_FLAGS, - g_param_spec_uint (NM_SETTING_DCB_APP_FCOE_FLAGS, - "App FCoE Flags", - "Specifies the flags for the DCB FCoE application. " - "Flags may be any combination of 0x1 (enable), 0x2 " - "(advertise), and 0x4 (willing).", + g_param_spec_uint (NM_SETTING_DCB_APP_FCOE_FLAGS, "", "", 0, DCB_FLAGS_ALL, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-fcoe-priority: @@ -988,14 +985,11 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_FCOE_PRIORITY, - g_param_spec_int (NM_SETTING_DCB_APP_FCOE_PRIORITY, - "App FCoE Priority", - "The highest User Priority (0 - 7) which FCoE " - "frames should use, or -1 for default priority. Only " - "used when the 'app-fcoe-flags' property includes " - "the 'enabled' flag.", + g_param_spec_int (NM_SETTING_DCB_APP_FCOE_PRIORITY, "", "", -1, 7, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-fcoe-mode: @@ -1007,12 +1001,11 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_FCOE_MODE, - g_param_spec_string (NM_SETTING_DCB_APP_FCOE_MODE, - "App FCoE Mode", - "The FCoe controller mode; either 'fabric' (default) " - "or 'vn2vn'.", + g_param_spec_string (NM_SETTING_DCB_APP_FCOE_MODE, "", "", NM_SETTING_DCB_FCOE_MODE_FABRIC, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-iscsi-flags: @@ -1025,13 +1018,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_ISCSI_FLAGS, - g_param_spec_uint (NM_SETTING_DCB_APP_ISCSI_FLAGS, - "App iSCSI Flags", - "Specifies the flags for the DCB iSCSI application. " - "Flags may be any combination of 0x1 (enable), 0x2 " - "(advertise), and 0x4 (willing).", + g_param_spec_uint (NM_SETTING_DCB_APP_ISCSI_FLAGS, "", "", 0, DCB_FLAGS_ALL, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-iscsi-priority: @@ -1044,14 +1034,11 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_ISCSI_PRIORITY, - g_param_spec_int (NM_SETTING_DCB_APP_ISCSI_PRIORITY, - "App iSCSI Priority", - "The highest User Priority (0 - 7) which iSCSI " - "frames should use, or -1 for default priority. Only " - "used when the 'app-iscsi-flags' property includes " - "the 'enabled' flag.", + g_param_spec_int (NM_SETTING_DCB_APP_ISCSI_PRIORITY, "", "", -1, 7, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-fip-flags: @@ -1064,13 +1051,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_FIP_FLAGS, - g_param_spec_uint (NM_SETTING_DCB_APP_FIP_FLAGS, - "App FIP Flags", - "Specifies the flags for the DCB FIP application. " - "Flags may be any combination of 0x1 (enable), 0x2 " - "(advertise), and 0x4 (willing).", + g_param_spec_uint (NM_SETTING_DCB_APP_FIP_FLAGS, "", "", 0, DCB_FLAGS_ALL, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:app-fip-priority: @@ -1083,14 +1067,11 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APP_FIP_PRIORITY, - g_param_spec_int (NM_SETTING_DCB_APP_FIP_PRIORITY, - "App FIP Priority", - "The highest User Priority (0 - 7) which FIP " - "frames should use, or -1 for default priority. Only " - "used when the 'app-fip-flags' property includes " - "the 'enabled' flag.", + g_param_spec_int (NM_SETTING_DCB_APP_FIP_PRIORITY, "", "", -1, 7, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-flow-control-flags: @@ -1103,13 +1084,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PFC_FLAGS, - g_param_spec_uint (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, - "Priority Flow Control Flags", - "Specifies the flags for DCB Priority Flow Control. " - "Flags may be any combination of 0x1 (enable), 0x2 " - "(advertise), and 0x4 (willing).", + g_param_spec_uint (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, "", "", 0, DCB_FLAGS_ALL, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-flow-control: @@ -1123,16 +1101,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PFC, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, - "Priority Flow Control", - "An array of 8 uint values, where the array index " - "corresponds to the User Priority (0 - 7) and the " - "value indicates whether or not the corresponding " - "priority should transmit priority pause. Allowed " - "values are 0 (do not transmit pause) and 1 " - "(transmit pause).", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-group-flags: @@ -1145,13 +1117,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_GROUP_FLAGS, - g_param_spec_uint (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, - "Priority Group Flags", - "Specifies the flags for DCB Priority Groups. " - "Flags may be any combination of 0x1 (enable), 0x2 " - "(advertise), and 0x4 (willing).", + g_param_spec_uint (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, "", "", 0, DCB_FLAGS_ALL, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-group-id: @@ -1164,15 +1133,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_GROUP_ID, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_GROUP_ID, - "Priority Group ID", - "An array of 8 uint values, where the array " - "index corresponds to the User Priority (0 - 7) " - "and the value indicates the Priority Group ID. " - "Allowed Priority Group ID values are 0 - 7 or " - "15 for the unrestricted group.", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_GROUP_ID, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-group-bandwidth: @@ -1186,15 +1150,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_GROUP_BANDWIDTH, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, - "Priority Group Bandwidth", - "An array of 8 uint values, where the array index " - "corresponds to the Priority Group ID (0 - 7) and " - "the value indicates the percentage of link bandwidth " - "allocated to that group. Allowed values are 0 - 100, " - "and the sum of all values must total 100 percent.", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-bandwidth: @@ -1209,16 +1168,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_BANDWIDTH, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_BANDWIDTH, - "Priority Bandwidth", - "An array of 8 uint values, where the array index " - "corresponds to the User Priority (0 - 7) and the " - "value indicates the percentage of bandwidth of " - "the priority's assigned group that the priority may " - "use. The sum of all percentages for priorities which " - "belong to the same group must total 100 percent.", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_BANDWIDTH, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-strict-bandwidth: @@ -1233,17 +1186,10 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_STRICT, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, - "Priority Strict Bandwidth", - "An array of 8 uint values, where the array index " - "corresponds to the User Priority (0 - 7) and the " - "value indicates whether or not the priority may " - "use all of the bandwidth allocated to its assigned " - "group. Allowed values are 0 (the priority may not " - "utilize all bandwidth) or 1 (the priority may " - "utilize all bandwidth).", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingDcb:priority-traffic-class: @@ -1256,13 +1202,8 @@ nm_setting_dcb_class_init (NMSettingDcbClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PRIORITY_TRAFFIC_CLASS, - _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, - "Priority Traffic Class", - "An array of 8 uint values, where the array index " - "corresponds to the User Priority (0 - 7) and the " - "value indicates the traffic class (0 - 7) to which " - "the priority is mapped.", + _nm_param_spec_specialized (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-util/nm-setting-dcb.h b/libnm-util/nm-setting-dcb.h index 37dd36e7..ac34521e 100644 --- a/libnm-util/nm-setting-dcb.h +++ b/libnm-util/nm-setting-dcb.h @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * * 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 @@ -18,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2013 Red Hat, Inc. + * Copyright 2013 Red Hat, Inc. */ #ifndef NM_SETTING_DCB_H diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index f96a997b..a17d18b7 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include -#include +#include #include "nm-setting-gsm.h" #include "nm-utils.h" @@ -424,7 +423,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object); char *tmp; @@ -483,7 +482,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingGsm *setting = NM_SETTING_GSM (object); @@ -554,16 +553,10 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NUMBER, - g_param_spec_string (NM_SETTING_GSM_NUMBER, - "Number", - "Number to dial when establishing a PPP data session " - "with the GSM-based mobile broadband network. Many " - "modems do not require PPP for connections to the " - "mobile network and thus this property should be left " - "blank, which allows NetworkManager to select the " - "appropriate settings automatically.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_GSM_NUMBER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:username: @@ -574,13 +567,10 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_USERNAME, - g_param_spec_string (NM_SETTING_GSM_USERNAME, - "Username", - "Username used to authenticate with the network, if " - "required. Note that many providers do not require " - "a username or accept any username.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_GSM_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:password: @@ -591,27 +581,25 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD, - g_param_spec_string (NM_SETTING_GSM_PASSWORD, - "Password", - "Password used to authenticate with the network, if " - "required. Note that many providers do not require " - "a password or accept any password.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_GSM_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:password-flags: * * Flags indicating how to handle the #NMSettingGsm:password property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_GSM_PASSWORD_FLAGS, - "Password Flags", - "Flags indicating how to handle the GSM password.", + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:apn: @@ -626,19 +614,10 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_APN, - g_param_spec_string (NM_SETTING_GSM_APN, - "APN", - "The GPRS Access Point Name specifying the APN used " - "when establishing a data session with the GSM-based " - "network. The APN often determines how the user will " - "be billed for their network usage and whether the " - "user has access to the Internet or just a provider-" - "specific walled-garden, so it is important to use " - "the correct APN for the user's mobile broadband " - "plan. The APN may only be composed of the characters " - "a-z, 0-9, ., and - per GSM 03.60 Section 14.9.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_GSM_APN, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:network-id: @@ -651,17 +630,10 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NETWORK_ID, - g_param_spec_string (NM_SETTING_GSM_NETWORK_ID, - "Network ID", - "The Network ID (GSM LAI format, ie MCC-MNC) to force " - "specific network registration. If the Network ID is " - "specified, NetworkManager will attempt to force the " - "device to register only on the specified network. " - "This can be used to ensure that the device does not " - "roam when direct roaming control of the device is " - "not otherwise possible.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_GSM_NETWORK_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:network-type: @@ -681,19 +653,13 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NETWORK_TYPE, - g_param_spec_int (NM_SETTING_GSM_NETWORK_TYPE, - "Network type", - "Network preference to force the device to only use " - "specific network technologies. The permitted values " - "are: -1: any, 0: 3G only, 1: GPRS/EDGE only, " - "2: prefer 3G, 3: prefer 2G, 4: prefer 4G/LTE, 5: 4G/LTE only. " - "Notes: This property is deprecated and NetworkManager from 0.9.10 " - "onwards doesn't use this property when talking to ModemManager." - "Also, not all devices allow network preference control.", + g_param_spec_int (NM_SETTING_GSM_NETWORK_TYPE, "", "", NM_SETTING_GSM_NETWORK_TYPE_ANY, NM_SETTING_GSM_NETWORK_TYPE_4G, NM_SETTING_GSM_NETWORK_TYPE_ANY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:allowed-bands: @@ -707,16 +673,13 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ALLOWED_BANDS, - g_param_spec_uint (NM_SETTING_GSM_ALLOWED_BANDS, - "Allowed Bands", - "Bitfield of allowed frequency bands." - "Notes: This property is deprecated and NetworkManager from 0.9.10 " - "onwards doesn't use this property when talking to ModemManager." - "Also, not all devices allow frequency band control.", + g_param_spec_uint (NM_SETTING_GSM_ALLOWED_BANDS, "", "", NM_SETTING_GSM_BAND_UNKNOWN, NM_SETTING_GSM_BANDS_MAX, NM_SETTING_GSM_BAND_ANY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:pin: @@ -727,27 +690,25 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PIN, - g_param_spec_string (NM_SETTING_GSM_PIN, - "PIN", - "If the SIM is locked with a PIN it must be unlocked " - "before any other operations are requested. Specify " - "the PIN here to allow operation of the device.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_GSM_PIN, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:pin-flags: * * Flags indicating how to handle the #NMSettingGsm:pin property. **/ - g_object_class_install_property (object_class, PROP_PIN_FLAGS, - g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS, - "PIN Flags", - "Flags indicating how to handle the GSM SIM PIN.", + g_object_class_install_property + (object_class, PROP_PIN_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingGsm:home-only: @@ -757,11 +718,8 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) **/ g_object_class_install_property (object_class, PROP_HOME_ONLY, - g_param_spec_boolean (NM_SETTING_GSM_HOME_ONLY, - "Home Only", - "When TRUE, only connections to the home network will " - "be allowed. Connections to roaming networks will " - "not be made.", - FALSE, - G_PARAM_READWRITE)); + g_param_spec_boolean (NM_SETTING_GSM_HOME_ONLY, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h index 6d8e46d0..564a8b4b 100644 --- a/libnm-util/nm-setting-gsm.h +++ b/libnm-util/nm-setting-gsm.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_GSM_H diff --git a/libnm-util/nm-setting-infiniband.c b/libnm-util/nm-setting-infiniband.c index 5af50448..1036702f 100644 --- a/libnm-util/nm-setting-infiniband.c +++ b/libnm-util/nm-setting-infiniband.c @@ -19,10 +19,12 @@ * Copyright 2011 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include -#include +#include #include "nm-setting-infiniband.h" #include "nm-param-spec-specialized.h" @@ -194,6 +196,7 @@ get_virtual_iface_name (NMSetting *setting) static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { + NMSettingConnection *s_con; NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting); if (priv->mac_address && priv->mac_address->len != INFINIBAND_ALEN) { @@ -205,6 +208,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + /* FIXME: verify() should not modify the setting, but return NORMALIZABLE success. */ if (!g_strcmp0 (priv->transport_mode, "datagram")) { if (priv->mtu > 2044) priv->mtu = 2044; @@ -249,6 +253,45 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } } + s_con = NM_SETTING_CONNECTION (nm_setting_find_in_list (all_settings, NM_SETTING_CONNECTION_SETTING_NAME)); + if (s_con) { + const char *interface_name = nm_setting_connection_get_interface_name (s_con); + + if (!interface_name) + ; + else if (!nm_utils_iface_valid_name (interface_name)) { + /* report the error for NMSettingConnection:interface-name, because + * it's that property that is invalid -- although we currently verify() + * NMSettingInfiniband. + **/ + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + interface_name); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } else { + if (priv->p_key != -1) { + if (!priv->virtual_iface_name) + priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key); + + if (strcmp (interface_name, priv->virtual_iface_name) != 0) { + /* We don't support renaming software infiniband devices. Later we might, but + * for now just reject such connections. + **/ + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + _("interface name of software infiniband device must be '%s' or unset (instead it is '%s')"), + priv->virtual_iface_name, interface_name); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } + } + } + return TRUE; } @@ -359,14 +402,11 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_INFINIBAND_MAC_ADDRESS, - "Device MAC Address", - "If specified, this connection will only apply to " - "the IPoIB device whose permanent MAC address matches. " - "This property does not change the MAC address " - "of the device (i.e. MAC spoofing).", + _nm_param_spec_specialized (NM_SETTING_INFINIBAND_MAC_ADDRESS, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingInfiniband:mtu: @@ -376,13 +416,12 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_SETTING_INFINIBAND_MTU, - "MTU", - "If non-zero, only transmit packets of the specified " - "size or smaller, breaking larger packets up into " - "multiple frames.", + g_param_spec_uint (NM_SETTING_INFINIBAND_MTU, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingInfiniband:transport-mode: @@ -392,11 +431,12 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) **/ g_object_class_install_property (object_class, PROP_TRANSPORT_MODE, - g_param_spec_string (NM_SETTING_INFINIBAND_TRANSPORT_MODE, - "Transport Mode", - "The IPoIB transport mode. Either 'datagram' or 'connected'.", + g_param_spec_string (NM_SETTING_INFINIBAND_TRANSPORT_MODE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingInfiniband:p-key: @@ -408,12 +448,12 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) **/ g_object_class_install_property (object_class, PROP_P_KEY, - g_param_spec_int (NM_SETTING_INFINIBAND_P_KEY, - "P_Key", - "The InfiniBand P_Key. Either -1 for the " - "default, or a 16-bit unsigned integer.", + g_param_spec_int (NM_SETTING_INFINIBAND_P_KEY, "", "", -1, 0xFFFF, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingInfiniband:parent: @@ -425,10 +465,11 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_string (NM_SETTING_INFINIBAND_PARENT, - "Parent", - "The interface name of the parent device, or NULL", + g_param_spec_string (NM_SETTING_INFINIBAND_PARENT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index a2c104d5..532231ab 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,13 +16,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include -#include +#include #include "nm-setting-ip4-config.h" #include "nm-param-spec-specialized.h" @@ -78,8 +77,8 @@ typedef struct { GArray *dns; /* array of guint32; elements in network byte order */ GSList *dns_search; /* list of strings */ GSList *addresses; /* array of NMIP4Address */ - GSList *address_labels; /* list of strings */ GSList *routes; /* array of NMIP4Route */ + gint64 route_metric; gboolean ignore_auto_routes; gboolean ignore_auto_dns; char *dhcp_client_id; @@ -95,8 +94,8 @@ enum { PROP_DNS, PROP_DNS_SEARCH, PROP_ADDRESSES, - PROP_ADDRESS_LABELS, PROP_ROUTES, + PROP_ROUTE_METRIC, PROP_IGNORE_AUTO_ROUTES, PROP_IGNORE_AUTO_DNS, PROP_DHCP_CLIENT_ID, @@ -442,19 +441,6 @@ nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i) return (NMIP4Address *) g_slist_nth_data (priv->addresses, i); } -const char * -nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i) -{ - NMSettingIP4ConfigPrivate *priv; - - g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), NULL); - - priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); - g_return_val_if_fail (i <= g_slist_length (priv->address_labels), NULL); - - return (const char *) g_slist_nth_data (priv->address_labels, i); -} - /** * nm_setting_ip4_config_add_address: * @setting: the #NMSettingIP4Config @@ -469,14 +455,6 @@ nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i) gboolean nm_setting_ip4_config_add_address (NMSettingIP4Config *setting, NMIP4Address *address) -{ - return nm_setting_ip4_config_add_address_with_label (setting, address, NULL); -} - -gboolean -nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting, - NMIP4Address *address, - const char *label) { NMSettingIP4ConfigPrivate *priv; NMIP4Address *copy; @@ -493,8 +471,6 @@ nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting, copy = nm_ip4_address_dup (address); priv->addresses = g_slist_append (priv->addresses, copy); - priv->address_labels = g_slist_append (priv->address_labels, g_strdup (label)); - g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES); return TRUE; } @@ -510,21 +486,16 @@ void nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i) { NMSettingIP4ConfigPrivate *priv; - GSList *addr, *label; + GSList *elt; g_return_if_fail (NM_IS_SETTING_IP4_CONFIG (setting)); priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); - addr = g_slist_nth (priv->addresses, i); - label = g_slist_nth (priv->address_labels, i); - g_return_if_fail (addr != NULL && label != NULL); - - nm_ip4_address_unref ((NMIP4Address *) addr->data); - priv->addresses = g_slist_delete_link (priv->addresses, addr); - if (label->data) - g_free (label->data); - priv->address_labels = g_slist_delete_link (priv->address_labels, label); + elt = g_slist_nth (priv->addresses, i); + g_return_if_fail (elt != NULL); + nm_ip4_address_unref ((NMIP4Address *) elt->data); + priv->addresses = g_slist_delete_link (priv->addresses, elt); g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES); } @@ -576,8 +547,6 @@ nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting) g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); priv->addresses = NULL; - g_slist_free_full (priv->address_labels, g_free); - priv->address_labels = NULL; g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ADDRESSES); } @@ -723,6 +692,26 @@ nm_setting_ip4_config_clear_routes (NMSettingIP4Config *setting) g_object_notify (G_OBJECT (setting), NM_SETTING_IP4_CONFIG_ROUTES); } +/** + * nm_setting_ip4_config_get_route_metric: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:route-metric + * property. + * + * Returns: the route metric that is used for IPv4 routes that don't explicitly + * specify a metric. See #NMSettingIP4Config:route-metric for more details. + * + * Since: 1.0 + **/ +gint64 +nm_setting_ip4_config_get_route_metric (NMSettingIP4Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), -1); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->route_metric; +} + /** * nm_setting_ip4_config_get_ignore_auto_routes: * @setting: the #NMSettingIP4Config @@ -849,35 +838,11 @@ nm_setting_ip4_config_get_may_fail (NMSettingIP4Config *setting) return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->may_fail; } -static gboolean -verify_label (const char *label) -{ - const char *p; - char *iface; - - p = strchr (label, ':'); - if (!p) - return FALSE; - iface = g_strndup (label, p - label); - if (!nm_utils_iface_valid_name (iface)) { - g_free (iface); - return FALSE; - } - g_free (iface); - - for (p++; *p; p++) { - if (!g_ascii_isalnum (*p) && *p != '_') - return FALSE; - } - - return TRUE; -} - static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); - GSList *iter, *l_iter; + GSList *iter; int i; if (!priv->method) { @@ -964,11 +929,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } /* Validate addresses */ - for (iter = priv->addresses, l_iter = priv->address_labels, i = 0; - iter && l_iter; - iter = g_slist_next (iter), l_iter = g_slist_next (l_iter), i++) { + for (iter = priv->addresses, i = 0; iter; iter = g_slist_next (iter), i++) { NMIP4Address *addr = (NMIP4Address *) iter->data; - const char *label = (const char *) l_iter->data; guint32 prefix = nm_ip4_address_get_prefix (addr); if (!nm_ip4_address_get_address (addr)) { @@ -990,27 +952,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_ADDRESSES); return FALSE; } - - if (label && !verify_label (label)) { - g_set_error (error, - NM_SETTING_IP4_CONFIG_ERROR, - NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY, - _("%d. IPv4 address has invalid label '%s'"), - i+1, label); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels"); - return FALSE; - } - } - - if (iter || l_iter) { - g_set_error (error, - NM_SETTING_IP4_CONFIG_ERROR, - NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY, - _("IPv4 address / label count mismatch (%d vs %d)"), - g_slist_length (priv->addresses), - g_slist_length (priv->address_labels)); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels"); - return FALSE; } /* Validate routes */ @@ -1066,7 +1007,6 @@ finalize (GObject *object) g_slist_free_full (priv->dns_search, g_free); g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); - g_slist_free_full (priv->address_labels, g_free); g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object); @@ -1074,11 +1014,10 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingIP4Config *setting = NM_SETTING_IP4_CONFIG (object); NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); - GSList *iter; switch (prop_id) { case PROP_METHOD: @@ -1098,29 +1037,14 @@ set_property (GObject *object, guint prop_id, case PROP_ADDRESSES: g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip4_address_unref); priv->addresses = nm_utils_ip4_addresses_from_gvalue (value); - - if (g_slist_length (priv->addresses) != g_slist_length (priv->address_labels)) { - g_slist_free_full (priv->address_labels, g_free); - priv->address_labels = NULL; - for (iter = priv->addresses; iter; iter = iter->next) - priv->address_labels = g_slist_prepend (priv->address_labels, NULL); - } - break; - case PROP_ADDRESS_LABELS: - g_slist_free_full (priv->address_labels, g_free); - priv->address_labels = g_value_dup_boxed (value); - /* NULLs get converted to "" when this is sent over D-Bus. */ - for (iter = priv->address_labels; iter; iter = iter->next) { - if (!g_strcmp0 (iter->data, "")) { - g_free (iter->data); - iter->data = NULL; - } - } break; case PROP_ROUTES: g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip4_route_unref); priv->routes = nm_utils_ip4_routes_from_gvalue (value); break; + case PROP_ROUTE_METRIC: + priv->route_metric = g_value_get_int64 (value); + break; case PROP_IGNORE_AUTO_ROUTES: priv->ignore_auto_routes = g_value_get_boolean (value); break; @@ -1152,7 +1076,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingIP4Config *setting = NM_SETTING_IP4_CONFIG (object); NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting); @@ -1170,12 +1094,12 @@ get_property (GObject *object, guint prop_id, case PROP_ADDRESSES: nm_utils_ip4_addresses_to_gvalue (priv->addresses, value); break; - case PROP_ADDRESS_LABELS: - g_value_set_boxed (value, priv->address_labels); - break; case PROP_ROUTES: nm_utils_ip4_routes_to_gvalue (priv->routes, value); break; + case PROP_ROUTE_METRIC: + g_value_set_int64 (value, priv->route_metric); + break; case PROP_IGNORE_AUTO_ROUTES: g_value_set_boolean (value, nm_setting_ip4_config_get_ignore_auto_routes (setting)); break; @@ -1236,27 +1160,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_METHOD, - g_param_spec_string (NM_SETTING_IP4_CONFIG_METHOD, - "Method", - "IPv4 configuration method. If 'auto' is specified " - "then the appropriate automatic method (DHCP, PPP, " - "etc) is used for the interface and most other " - "properties can be left unset. If 'link-local' " - "is specified, then a link-local address in the " - "169.254/16 range will be assigned to the " - "interface. If 'manual' is specified, static IP " - "addressing is used and at least one IP address " - "must be given in the 'addresses' property. If " - "'shared' is specified (indicating that this " - "connection will provide network access to other " - "computers) then the interface is assigned an " - "address in the 10.42.x.1/24 range and a DHCP and " - "forwarding DNS server are started, and the " - "interface is NAT-ed to the current default network " - "connection. 'disabled' means IPv4 will not be " - "used on this connection. This property must be set.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_IP4_CONFIG_METHOD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:dns: @@ -1270,18 +1178,10 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DNS, - _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS, - "DNS", - "List of DNS servers (network byte order). For " - "the 'auto' method, these DNS servers are " - "appended to those (if any) returned by automatic " - "configuration. DNS servers cannot be used with " - "the 'shared', 'link-local', or 'disabled' " - "methods as there is no upstream network. In all " - "other methods, these DNS servers are used as the " - "only DNS servers for this connection.", - DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS, "", "", + DBUS_TYPE_G_UINT_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:dns-search: @@ -1294,18 +1194,10 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DNS_SEARCH, - _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS_SEARCH, - "DNS search", - "List of DNS search domains. For the 'auto' " - "method, these search domains are appended to " - "those returned by automatic configuration. " - "Search domains cannot be used with the 'shared', " - "'link-local', or 'disabled' methods as there is " - "no upstream network. In all other methods, these " - "search domains are used as the only search domains " - "for this connection.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_DNS_SEARCH, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:addresses: @@ -1321,35 +1213,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ADDRESSES, - _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ADDRESSES, - "Addresses", - "Array of IPv4 address structures. Each IPv4 " - "address structure is composed of 3 32-bit values; " - "the first being the IPv4 address (network byte " - "order), the second the prefix (1 - 32), and " - "last the IPv4 gateway (network byte order). The " - "gateway may be left as 0 if no gateway exists " - "for that subnet. For the 'auto' method, given " - "IP addresses are appended to those returned by " - "automatic configuration. Addresses cannot be " - "used with the 'shared', 'link-local', or " - "'disabled' methods as addressing is either " - "automatic or disabled with these methods.", - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); - - /** - * NMSettingIP4Config:address-labels: - * - * Internal use only. - **/ - g_object_class_install_property - (object_class, PROP_ADDRESS_LABELS, - _nm_param_spec_specialized ("address-labels", - "Address labels", - "Internal use only", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ADDRESSES, "", "", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:routes: @@ -1365,22 +1233,33 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ROUTES, - _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ROUTES, - "Routes", - "Array of IPv4 route structures. Each IPv4 route " - "structure is composed of 4 32-bit values; the " - "first being the destination IPv4 network or " - "address (network byte order), the second the " - "destination network or address prefix (1 - 32), " - "the third being the next-hop (network byte order) " - "if any, and the fourth being the route metric. " - "For the 'auto' method, given IP routes are " - "appended to those returned by automatic " - "configuration. Routes cannot be used with the " - "'shared', 'link-local', or 'disabled', methods " - "as there is no upstream network.", - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ROUTES, "", "", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIP4Config:route-metric: + * + * The default metric for routes that don't explicitly specify a metric. + * The default value -1 means that the metric is choosen automatically + * based on the device type. + * The metric applies to dynamic routes, manual (static) routes that + * don't have an explicit metric setting, address prefix routes, and + * the default route. + * As the linux kernel accepts zero (0) as a valid metric, zero is + * a valid value. + * + * Since: 1.0 + **/ + g_object_class_install_property + (object_class, PROP_ROUTE_METRIC, + g_param_spec_int64 (NM_SETTING_IP4_CONFIG_ROUTE_METRIC, "", "", + -1, G_MAXUINT32, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:ignore-auto-routes: @@ -1391,14 +1270,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IGNORE_AUTO_ROUTES, - g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, - "Ignore automatic routes", - "When the method is set to 'auto' and this property " - "to TRUE, automatically configured routes are " - "ignored and only routes specified in the 'routes' " - "property, if any, are used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:ignore-auto-dns: @@ -1411,15 +1287,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IGNORE_AUTO_DNS, - g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, - "Ignore automatic DNS", - "When the method is set to 'auto' and this property " - "to TRUE, automatically configured nameservers and " - "search domains are ignored and only nameservers and " - "search domains specified in the 'dns' and 'dns-search' " - "properties, if any, are used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:dhcp-client-id: @@ -1429,13 +1301,10 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DHCP_CLIENT_ID, - g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, - "DHCP Client ID", - "A string sent to the DHCP server to identify the " - "local machine which the DHCP server may use to " - "customize the DHCP lease and options.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:dhcp-send-hostname: @@ -1448,17 +1317,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DHCP_SEND_HOSTNAME, - g_param_spec_boolean (NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, - "Send DHCP hostname", - "If TRUE, a hostname is sent to the DHCP server when " - "acquiring a lease. Some DHCP servers use this " - "hostname to update DNS databases, essentially " - "providing a static hostname for the computer. If " - "the 'dhcp-hostname' property is empty and this " - "property is TRUE, the current persistent hostname " - "of the computer is sent.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:dhcp-hostname: @@ -1468,13 +1331,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DHCP_HOSTNAME, - g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, - "DHCP Hostname", - "If the 'dhcp-send-hostname' property is TRUE, then " - "the specified name will be sent to the DHCP server " - "when acquiring a lease.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:never-default: @@ -1484,13 +1345,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NEVER_DEFAULT, - g_param_spec_boolean (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, - "Never default", - "If TRUE, this connection will never be the default " - "IPv4 connection, meaning it will never be assigned " - "the default route by NetworkManager.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP4Config:may-fail: @@ -1504,18 +1363,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAY_FAIL, - g_param_spec_boolean (NM_SETTING_IP4_CONFIG_MAY_FAIL, - "May Fail", - "If TRUE, allow overall network configuration to " - "proceed even if IPv4 configuration times out. " - "Note that at least one IP configuration must " - "succeed or overall network configuration will still " - "fail. For example, in IPv6-only networks, setting " - "this property to TRUE allows the overall network " - "configuration to succeed if IPv4 configuration " - "fails but IPv6 configuration completes successfully.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP4_CONFIG_MAY_FAIL, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } @@ -1977,4 +1829,3 @@ nm_ip4_route_set_metric (NMIP4Route *route, guint32 metric) route->metric = metric; } - diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index 3f0d006b..6e9a9a22 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_IP4_CONFIG_H @@ -63,6 +60,7 @@ GQuark nm_setting_ip4_config_error_quark (void); #define NM_SETTING_IP4_CONFIG_DNS_SEARCH "dns-search" #define NM_SETTING_IP4_CONFIG_ADDRESSES "addresses" #define NM_SETTING_IP4_CONFIG_ROUTES "routes" +#define NM_SETTING_IP4_CONFIG_ROUTE_METRIC "route-metric" #define NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" #define NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" #define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id" @@ -217,6 +215,9 @@ NM_AVAILABLE_IN_0_9_10 gboolean nm_setting_ip4_config_remove_route_by_value (NMSettingIP4Config *setting, NMIP4Route *route); void nm_setting_ip4_config_clear_routes (NMSettingIP4Config *setting); +NM_AVAILABLE_IN_1_0 +gint64 nm_setting_ip4_config_get_route_metric (NMSettingIP4Config *setting); + gboolean nm_setting_ip4_config_get_ignore_auto_routes (NMSettingIP4Config *setting); gboolean nm_setting_ip4_config_get_ignore_auto_dns (NMSettingIP4Config *setting); const char * nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting); diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index b027ee96..654f0496 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * David Cantrell - * * 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 @@ -19,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include -#include +#include #include "nm-setting-ip6-config.h" #include "nm-param-spec-specialized.h" @@ -78,6 +77,7 @@ typedef struct { GSList *dns_search; /* list of strings */ GSList *addresses; /* array of NMIP6Address */ GSList *routes; /* array of NMIP6Route */ + gint64 route_metric; gboolean ignore_auto_routes; gboolean ignore_auto_dns; gboolean never_default; @@ -94,6 +94,7 @@ enum { PROP_DNS_SEARCH, PROP_ADDRESSES, PROP_ROUTES, + PROP_ROUTE_METRIC, PROP_IGNORE_AUTO_ROUTES, PROP_IGNORE_AUTO_DNS, PROP_NEVER_DEFAULT, @@ -174,7 +175,7 @@ const struct in6_addr * nm_setting_ip6_config_get_dns (NMSettingIP6Config *setting, guint32 i) { NMSettingIP6ConfigPrivate *priv; - + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL); @@ -711,6 +712,26 @@ nm_setting_ip6_config_clear_routes (NMSettingIP6Config *setting) g_object_notify (G_OBJECT (setting), NM_SETTING_IP6_CONFIG_ROUTES); } +/** + * nm_setting_ip6_config_get_route_metric: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:route-metric + * property. + * + * Returns: the route metric that is used for IPv6 routes that don't explicitly + * specify a metric. See #NMSettingIP6Config:route-metric for more details. + * + * Since: 1.0 + **/ +gint64 +nm_setting_ip6_config_get_route_metric (NMSettingIP6Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), -1); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->route_metric; +} + /** * nm_setting_ip6_config_get_ignore_auto_routes: * @setting: the #NMSettingIP6Config @@ -905,7 +926,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object); @@ -930,6 +951,9 @@ set_property (GObject *object, guint prop_id, g_slist_free_full (priv->routes, g_free); priv->routes = nm_utils_ip6_routes_from_gvalue (value); break; + case PROP_ROUTE_METRIC: + priv->route_metric = g_value_get_int64 (value); + break; case PROP_IGNORE_AUTO_ROUTES: priv->ignore_auto_routes = g_value_get_boolean (value); break; @@ -957,7 +981,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object); @@ -977,6 +1001,9 @@ get_property (GObject *object, guint prop_id, case PROP_ROUTES: nm_utils_ip6_routes_to_gvalue (priv->routes, value); break; + case PROP_ROUTE_METRIC: + g_value_set_int64 (value, priv->route_metric); + break; case PROP_IGNORE_AUTO_ROUTES: g_value_set_boolean (value, priv->ignore_auto_routes); break; @@ -1032,24 +1059,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_METHOD, - g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD, - "Method", - "IPv6 configuration method. If 'auto' is specified " - "then the appropriate automatic method (PPP, router " - "advertisement, etc) is used for the device and " - "most other properties can be left unset. To force " - "the use of DHCP only, specify 'dhcp'; this method " - "is only valid for Ethernet-based hardware. If " - "'link-local' is specified, then an IPv6 link-local " - "address will be assigned to the interface. If " - "'manual' is specified, static IP addressing is " - "used and at least one IP address must be given in " - " the 'addresses' property. If 'ignore' is " - "specified, IPv6 configuration is not done. This " - "property must be set. Note: the 'shared' method " - "is not yet supported.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:dhcp-hostname: @@ -1061,12 +1075,10 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DHCP_HOSTNAME, - g_param_spec_string (NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME, - "DHCP Hostname", - "The specified name will be sent to the DHCP server " - "when acquiring a lease.", + g_param_spec_string (NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME, "", "", NULL, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:dns: @@ -1081,20 +1093,10 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DNS, - _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS, - "DNS", - "Array of DNS servers, where each member of the " - "array is a byte array containing the IPv6 address " - "of the DNS server (in network byte order). For " - "the 'auto' method, these DNS servers are " - "appended to those (if any) returned by automatic " - "configuration. DNS servers cannot be used with " - "the 'shared' or 'link-local' methods as there is " - "no usptream network. In all other methods, " - "these DNS servers are used as the only DNS " - "servers for this connection.", - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS, "", "", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:dns-search: @@ -1107,18 +1109,10 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DNS_SEARCH, - _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS_SEARCH, - "DNS search", - "List of DNS search domains. For the 'auto' " - "method, these search domains are appended to " - "those returned by automatic configuration. " - "Search domains cannot be used with the 'shared' " - "or 'link-local' methods as there is no upstream " - "network. In all other methods, these search " - "domains are used as the only search domains for " - "this connection.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS_SEARCH, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:addresses: @@ -1136,25 +1130,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ADDRESSES, - _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ADDRESSES, - "Addresses", - "Array of IPv6 address structures. Each IPv6 " - "address structure is composed of 3 members, the " - "first being a byte array containing the IPv6 " - "address (network byte order), the second a " - "32-bit integer containing the IPv6 address " - "prefix, and the third a byte array containing " - "the IPv6 address (network byte order) of the " - "gateway associated with this address, if any. " - "If no gateway is given, the third element should " - "be given as all zeros. For the 'auto' method, " - "given IP addresses are appended to those returned " - "by automatic configuration. Addresses cannot be " - "used with the 'shared' or 'link-local' methods " - "as the interface is automatically assigned an " - "address with these methods.", - DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ADDRESSES, "", "", + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:routes: @@ -1170,22 +1150,33 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ROUTES, - _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ROUTES, - "Routes", - "Array of IPv6 route structures. Each IPv6 route " - "structure is composed of 4 members; the first " - "being the destination IPv6 network or address " - "(network byte order) as a byte array, the second " - "the destination network or address IPv6 prefix, " - "the third being the next-hop IPv6 address " - "(network byte order) if any, and the fourth " - "being the route metric. For the 'auto' method, " - "given IP routes are appended to those returned " - "by automatic configuration. Routes cannot be " - "used with the 'shared' or 'link-local' methods " - "because there is no upstream network.", - DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ROUTES, "", "", + DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIP6Config:route-metric: + * + * The default metric for routes that don't explicitly specify a metric. + * The default value -1 means that the metric is choosen automatically + * based on the device type. + * The metric applies to dynamic routes, manual (static) routes that + * don't have an explicit metric setting, address prefix routes, and + * the default route. + * As the linux kernel replaces zero (0) by 1024 (user-default), setting + * this property to 0 means effectively setting it to 1024. + * + * Since: 1.0 + **/ + g_object_class_install_property + (object_class, PROP_ROUTE_METRIC, + g_param_spec_int64 (NM_SETTING_IP6_CONFIG_ROUTE_METRIC, "", "", + -1, G_MAXUINT32, -1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:ignore-auto-routes: @@ -1196,14 +1187,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IGNORE_AUTO_ROUTES, - g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, - "Ignore automatic routes", - "When the method is set to 'auto' or 'dhcp' and this " - "property is set to TRUE, automatically configured " - "routes are ignored and only routes specified in the " - "'routes' property, if any, are used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:ignore-auto-dns: @@ -1216,15 +1204,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IGNORE_AUTO_DNS, - g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, - "Ignore DHCPv6/RDNSS DNS", - "When the method is set to 'auto' or 'dhcp' and this " - "property is set to TRUE, automatically configured " - "nameservers and search domains are ignored and only " - "nameservers and search domains specified in the 'dns' " - "and 'dns-search' properties, if any, are used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:never-default: @@ -1235,13 +1219,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NEVER_DEFAULT, - g_param_spec_boolean (NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, - "Never default", - "If TRUE, this connection will never be the default " - "IPv6 connection, meaning it will never be assigned " - "the default IPv6 route by NetworkManager.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:may-fail: @@ -1255,18 +1237,11 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAY_FAIL, - g_param_spec_boolean (NM_SETTING_IP6_CONFIG_MAY_FAIL, - "May Fail", - "If TRUE, allow overall network configuration to " - "proceed even if IPv6 configuration times out. " - "Note that at least one IP configuration must " - "succeed or overall network configuration will still " - "fail. For example, in IPv4-only networks, setting " - "this property to TRUE allows the overall network " - "configuration to succeed if IPv6 configuration " - "fails but IPv4 configuration completes successfully.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_MAY_FAIL, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingIP6Config:ip6-privacy: @@ -1281,20 +1256,13 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) **/ g_object_class_install_property (object_class, PROP_IP6_PRIVACY, - g_param_spec_int (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, - "Configure IPv6 Privacy", - "Configure IPv6 Privacy Extensions for SLAAC, described " - "in RFC4941. If enabled, it makes the kernel generate " - "a temporary IPv6 address in addition to the public one " - "generated from MAC address via modified EUI-64. This " - "enhances privacy, but could cause problems in some " - "applications, on the other hand. The permitted values " - "are: 0: disabled, 1: enabled (prefer public address), " - "2: enabled (prefer temporary addresses).", + g_param_spec_int (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, "", "", NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } /********************************************************************/ diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h index d1f4ca84..0a2f00dd 100644 --- a/libnm-util/nm-setting-ip6-config.h +++ b/libnm-util/nm-setting-ip6-config.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * David Cantrell - * * 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 @@ -19,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. */ #ifndef NM_SETTING_IP6_CONFIG_H @@ -64,6 +61,7 @@ GQuark nm_setting_ip6_config_error_quark (void); #define NM_SETTING_IP6_CONFIG_DNS_SEARCH "dns-search" #define NM_SETTING_IP6_CONFIG_ADDRESSES "addresses" #define NM_SETTING_IP6_CONFIG_ROUTES "routes" +#define NM_SETTING_IP6_CONFIG_ROUTE_METRIC "route-metric" #define NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" #define NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" #define NM_SETTING_IP6_CONFIG_NEVER_DEFAULT "never-default" @@ -186,7 +184,7 @@ void nm_ip6_route_set_dest (NMIP6Route *route, guint32 nm_ip6_route_get_prefix (NMIP6Route *route); void nm_ip6_route_set_prefix (NMIP6Route *route, - guint32 prefix); + guint32 prefix); const struct in6_addr *nm_ip6_route_get_next_hop (NMIP6Route *route); void nm_ip6_route_set_next_hop (NMIP6Route *route, @@ -248,6 +246,9 @@ gboolean nm_setting_ip6_config_remove_route_by_value (NMSettingIP void nm_setting_ip6_config_clear_routes (NMSettingIP6Config *setting); gboolean nm_setting_ip6_config_get_ignore_auto_routes (NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_0 +gint64 nm_setting_ip6_config_get_route_metric (NMSettingIP6Config *setting); + gboolean nm_setting_ip6_config_get_ignore_auto_dns (NMSettingIP6Config *setting); const char * nm_setting_ip6_config_get_dhcp_hostname (NMSettingIP6Config *setting); gboolean nm_setting_ip6_config_get_never_default (NMSettingIP6Config *setting); diff --git a/libnm-util/nm-setting-olpc-mesh.c b/libnm-util/nm-setting-olpc-mesh.c index d344fa04..e4b6dae5 100644 --- a/libnm-util/nm-setting-olpc-mesh.c +++ b/libnm-util/nm-setting-olpc-mesh.c @@ -1,10 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * Sjoerd Simons - * Daniel Drake - * * 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 @@ -20,15 +15,17 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. - * (C) Copyright 2009 One Laptop per Child + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2009 One Laptop per Child */ +#include "config.h" + #include #include #include -#include +#include #include "NetworkManager.h" #include "nm-setting-olpc-mesh.h" @@ -175,7 +172,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingOlpcMeshPrivate *priv = NM_SETTING_OLPC_MESH_GET_PRIVATE (object); @@ -201,7 +198,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingOlpcMesh *setting = NM_SETTING_OLPC_MESH (object); @@ -243,11 +240,11 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SSID, - _nm_param_spec_specialized (NM_SETTING_OLPC_MESH_SSID, - "SSID", - "SSID of the mesh network to join.", + _nm_param_spec_specialized (NM_SETTING_OLPC_MESH_SSID, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingOlpcMesh:channel: @@ -256,11 +253,12 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CHANNEL, - g_param_spec_uint (NM_SETTING_OLPC_MESH_CHANNEL, - "Channel", - "Channel on which the mesh network to join is located.", + g_param_spec_uint (NM_SETTING_OLPC_MESH_CHANNEL, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingOlpcMesh:dhcp-anycast-address: @@ -271,13 +269,8 @@ nm_setting_olpc_mesh_class_init (NMSettingOlpcMeshClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DHCP_ANYCAST_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, - "Anycast DHCP MAC address", - "Anycast DHCP MAC address used when " - "requesting an IP address via DHCP. The " - "specific anycast address used determines " - "which DHCP server class answers the " - "the request.", + _nm_param_spec_specialized (NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-olpc-mesh.h b/libnm-util/nm-setting-olpc-mesh.h index 59c03b48..54b268e2 100644 --- a/libnm-util/nm-setting-olpc-mesh.h +++ b/libnm-util/nm-setting-olpc-mesh.h @@ -1,10 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * Sjoerd Simons - * Daniel Drake - * * 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 @@ -20,9 +15,9 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. - * (C) Copyright 2009 One Laptop per Child + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2009 One Laptop per Child */ #ifndef NM_SETTING_OLPC_MESH_H diff --git a/libnm-util/nm-setting-ppp.c b/libnm-util/nm-setting-ppp.c index 237af9c8..a01d3e10 100644 --- a/libnm-util/nm-setting-ppp.c +++ b/libnm-util/nm-setting-ppp.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,11 +16,13 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ -#include +#include "config.h" + +#include #include "nm-setting-ppp.h" #include "nm-setting-private.h" @@ -417,7 +416,7 @@ nm_setting_ppp_init (NMSettingPPP *setting) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingPPPPrivate *priv = NM_SETTING_PPP_GET_PRIVATE (object); @@ -484,7 +483,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingPPP *setting = NM_SETTING_PPP (object); @@ -572,14 +571,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NOAUTH, - g_param_spec_boolean (NM_SETTING_PPP_NOAUTH, - "NoAuth", - "If TRUE, do not require the other side (usually the " - "PPP server) to authenticate itself to the client. " - "If FALSE, require authentication from the remote " - "side. In almost all cases, this should be TRUE.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_NOAUTH, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:refuse-eap: @@ -588,11 +584,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REFUSE_EAP, - g_param_spec_boolean (NM_SETTING_PPP_REFUSE_EAP, - "Refuse EAP", - "If TRUE, the EAP authentication method will not be used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_EAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:refuse-pap: @@ -601,11 +597,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REFUSE_PAP, - g_param_spec_boolean (NM_SETTING_PPP_REFUSE_PAP, - "Refuse PAP", - "If TRUE, the PAP authentication method will not be used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_PAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:refuse-chap: @@ -614,11 +610,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REFUSE_CHAP, - g_param_spec_boolean (NM_SETTING_PPP_REFUSE_CHAP, - "Refuse CHAP", - "If TRUE, the CHAP authentication method will not be used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_CHAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:refuse-mschap: @@ -627,11 +623,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REFUSE_MSCHAP, - g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAP, - "Refuse MSCHAP", - "If TRUE, the MSCHAP authentication method will not be used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:refuse-mschapv2: @@ -640,11 +636,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REFUSE_MSCHAPV2, - g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAPV2, - "Refuse MSCHAPv2", - "If TRUE, the MSCHAPv2 authentication method will not be used.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REFUSE_MSCHAPV2, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:nobsdcomp: @@ -653,11 +649,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NOBSDCOMP, - g_param_spec_boolean (NM_SETTING_PPP_NOBSDCOMP, - "No BSD compression", - "If TRUE, BSD compression will not be requested.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_boolean (NM_SETTING_PPP_NOBSDCOMP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:nodeflate: @@ -666,11 +663,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NODEFLATE, - g_param_spec_boolean (NM_SETTING_PPP_NODEFLATE, - "No deflate", - "If TRUE, 'deflate' compression will not be requested.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_boolean (NM_SETTING_PPP_NODEFLATE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:no-vj-comp: @@ -679,11 +677,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NO_VJ_COMP, - g_param_spec_boolean (NM_SETTING_PPP_NO_VJ_COMP, - "No VJ compression", - "If TRUE, Van Jacobsen TCP header compression will not be requested.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_boolean (NM_SETTING_PPP_NO_VJ_COMP, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:require-mppe: @@ -695,15 +694,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REQUIRE_MPPE, - g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE, - "Require MPPE", - "If TRUE, MPPE (Microsoft Point-to-Point Encrpytion) " - "will be required for the PPP session. If either " - "64-bit or 128-bit MPPE is not available the session " - "will fail. Note that MPPE is not used on mobile " - "broadband connections.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:require-mppe-128: @@ -714,15 +709,10 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_REQUIRE_MPPE_128, - g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE_128, - "Require MPPE 128", - "If TRUE, 128-bit MPPE (Microsoft Point-to-Point " - "Encrpytion) will be required for the PPP session, " - "and the '" NM_SETTING_PPP_REQUIRE_MPPE "' property " - "must also be set to TRUE. If 128-bit MPPE is not " - "available the session will fail.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_REQUIRE_MPPE_128, "", "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:mppe-stateful: @@ -732,12 +722,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MPPE_STATEFUL, - g_param_spec_boolean (NM_SETTING_PPP_MPPE_STATEFUL, - "MPPE stateful", - "If TRUE, stateful MPPE is used. See pppd documentation " - "for more information on stateful MPPE.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_MPPE_STATEFUL, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:crtscts: @@ -748,14 +737,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CRTSCTS, - g_param_spec_boolean (NM_SETTING_PPP_CRTSCTS, - "CRTSCTS", - "If TRUE, specify that pppd should set the serial " - "port to use hardware flow control with RTS and CTS " - "signals. This value should normally be set to " - "FALSE.", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_PPP_CRTSCTS, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:baud: @@ -766,13 +752,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BAUD, - g_param_spec_uint (NM_SETTING_PPP_BAUD, - "Baud", - "If non-zero, instruct pppd to set the serial port to " - "the specified baudrate. This value should normally be " - "left as 0 to automatically choose the speed.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_PPP_BAUD, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:mru: @@ -783,13 +768,11 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) */ g_object_class_install_property (object_class, PROP_MRU, - g_param_spec_uint (NM_SETTING_PPP_MRU, - "MRU", - "If non-zero, instruct pppd to request that the peer " - "send packets no larger than the specified size. If " - "non-zero, the MRU should be between 128 and 16384.", - 0, 16384, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_PPP_MRU, "", "", + 0, 16384, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:mtu: @@ -799,12 +782,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_SETTING_PPP_MTU, - "MTU", - "If non-zero, instruct pppd to send packets no larger " - "than the specified size.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_PPP_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:lcp-echo-failure: @@ -816,16 +799,12 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_LCP_ECHO_FAILURE, - g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_FAILURE, - "LCP echo failure", - "If non-zero, instruct pppd to presume the connection to " - "the peer has failed if the specified number of LCP " - "echo-requests go unanswered by the peer. The " - "'" NM_SETTING_PPP_LCP_ECHO_INTERVAL "' property must " - "also be set to a non-zero value if this property is " - "used.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_FAILURE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPP:lcp-echo-interval: @@ -837,13 +816,10 @@ nm_setting_ppp_class_init (NMSettingPPPClass *setting_class) **/ g_object_class_install_property (object_class, PROP_LCP_ECHO_INTERVAL, - g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_INTERVAL, - "LCP echo interval", - "If non-zero, instruct pppd to send an LCP echo-request " - "frame to the peer every n seconds (where n is the " - "specified value). Note that some PPP peers will respond " - "to echo requests and some will not, and it is not " - "possible to autodetect this.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_PPP_LCP_ECHO_INTERVAL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-ppp.h b/libnm-util/nm-setting-ppp.h index 17a7181d..5733902b 100644 --- a/libnm-util/nm-setting-ppp.h +++ b/libnm-util/nm-setting-ppp.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_PPP_H diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index fdae691b..deaeb2e8 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,12 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include -#include +#include #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" @@ -210,7 +209,7 @@ nm_setting_pppoe_init (NMSettingPPPOE *setting) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingPPPOEPrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (object); @@ -238,7 +237,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingPPPOE *setting = NM_SETTING_PPPOE (object); @@ -299,16 +298,10 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SERVICE, - g_param_spec_string (NM_SETTING_PPPOE_SERVICE, - "Service", - "If specified, instruct PPPoE to only initiate sessions " - "with access concentrators that provide the specified " - "service. For most providers, this should be left " - "blank. It is only required if there are multiple " - "access concentrators or a specific service is known " - "to be required.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_PPPOE_SERVICE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPPOE:username: @@ -317,11 +310,10 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) **/ g_object_class_install_property (object_class, PROP_USERNAME, - g_param_spec_string (NM_SETTING_PPPOE_USERNAME, - "Username", - "Username used to authenticate with the PPPoE service.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_PPPOE_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPPOE:password: @@ -330,23 +322,23 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PASSWORD, - g_param_spec_string (NM_SETTING_PPPOE_PASSWORD, - "Password", - "Password used to authenticate with the PPPoE service.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_PPPOE_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingPPPOE:password-flags: * * Flags indicating how to handle the #NMSettingPPPOE:password property. **/ - g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_PPPOE_PASSWORD_FLAGS, - "Password Flags", - "Flags indicating how to handle the PPPoE password.", + g_object_class_install_property + (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_PPPOE_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-pppoe.h b/libnm-util/nm-setting-pppoe.h index 9be90ddb..9d04af9e 100644 --- a/libnm-util/nm-setting-pppoe.h +++ b/libnm-util/nm-setting-pppoe.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_PPPOE_H diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h index c3ec9d19..1b271d0c 100644 --- a/libnm-util/nm-setting-private.h +++ b/libnm-util/nm-setting-private.h @@ -15,13 +15,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 Red Hat, Inc. + * Copyright 2011 Red Hat, Inc. */ #ifndef NM_SETTING_PRIVATE_H #define NM_SETTING_PRIVATE_H -#include "nm-setting.h" #include "nm-glib-compat.h" #define NM_SETTING_SECRET_FLAGS_ALL \ @@ -30,6 +29,22 @@ NM_SETTING_SECRET_FLAG_NOT_SAVED | \ NM_SETTING_SECRET_FLAG_NOT_REQUIRED) +/** + * NMSettingVerifyResult: + * @NM_SETTING_VERIFY_SUCCESS: the setting verifies successfully + * @NM_SETTING_VERIFY_ERROR: the setting has a serious misconfiguration + * @NM_SETTING_VERIFY_NORMALIZABLE: the setting is valid but has properties + * that should be normalized + * @NM_SETTING_VERIFY_NORMALIZABLE_ERROR: the setting is invalid but the + * errors can be fixed by nm_connection_normalize(). + */ +typedef enum { + NM_SETTING_VERIFY_SUCCESS = TRUE, + NM_SETTING_VERIFY_ERROR = FALSE, + NM_SETTING_VERIFY_NORMALIZABLE = 2, + NM_SETTING_VERIFY_NORMALIZABLE_ERROR = 3, +} NMSettingVerifyResult; + void _nm_register_setting (const char *name, const GType type, const guint32 priority, @@ -40,10 +55,13 @@ void _nm_register_setting (const char *name, gboolean _nm_setting_is_base_type (NMSetting *setting); gboolean _nm_setting_type_is_base_type (GType type); +guint32 _nm_setting_get_setting_priority (NMSetting *setting); GType _nm_setting_lookup_setting_type (const char *name); GType _nm_setting_lookup_setting_type_by_quark (GQuark error_quark); gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b); +gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value); + typedef enum NMSettingUpdateSecretResult { NM_SETTING_UPDATE_SECRET_ERROR = FALSE, NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED = TRUE, @@ -87,10 +105,18 @@ static void __attribute__((constructor)) register_setting (void) \ NMSetting *nm_setting_find_in_list (GSList *settings_list, const char *setting_name); -/* Private NMSettingIP4Config methods */ -#include "nm-setting-ip4-config.h" -const char *nm_setting_ip4_config_get_address_label (NMSettingIP4Config *setting, guint32 i); -gboolean nm_setting_ip4_config_add_address_with_label (NMSettingIP4Config *setting, NMIP4Address *address, const char *label); +NMSettingVerifyResult _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name, + gboolean allow_missing, + const char *setting_name, + const char *setting_property, + GQuark error_quark, + gint e_invalid_property, + gint e_missing_property, + GSList *all_settings, + GError **error); -#endif /* NM_SETTING_PRIVATE_H */ +NMSettingVerifyResult _nm_setting_verify (NMSetting *setting, + GSList *all_settings, + GError **error); +#endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-util/nm-setting-serial.c b/libnm-util/nm-setting-serial.c index 70152bb3..24f2c898 100644 --- a/libnm-util/nm-setting-serial.c +++ b/libnm-util/nm-setting-serial.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,10 +16,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include "nm-setting-serial.h" @@ -183,7 +182,7 @@ nm_setting_serial_init (NMSettingSerial *setting) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingSerialPrivate *priv = NM_SETTING_SERIAL_GET_PRIVATE (object); @@ -211,7 +210,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingSerial *setting = NM_SETTING_SERIAL (object); @@ -261,14 +260,11 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BAUD, - g_param_spec_uint (NM_SETTING_SERIAL_BAUD, - "Baud", - "Speed to use for communication over the serial port. " - "Note that this value usually has no effect for mobile " - "broadband modems as they generally ignore speed " - "settings and use the highest available speed.", - 0, G_MAXUINT, 57600, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_SERIAL_BAUD, "", "", + 0, G_MAXUINT, 57600, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingSerial:bits: @@ -277,12 +273,11 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BITS, - g_param_spec_uint (NM_SETTING_SERIAL_BITS, - "Bits", - "Byte-width of the serial communication. The 8 in " - "'8n1' for example.", - 5, 8, 8, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_SERIAL_BITS, "", "", + 5, 8, 8, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingSerial:parity: @@ -292,12 +287,11 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PARITY, - g_param_spec_char (NM_SETTING_SERIAL_PARITY, - "Parity", - "Parity setting of the serial port. Either 'E' for even " - "parity, 'o' for odd parity, or 'n' for no parity.", - 'E', 'o', 'n', - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_char (NM_SETTING_SERIAL_PARITY, "", "", + 'E', 'o', 'n', + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingSerial:stopbits: @@ -307,12 +301,11 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) **/ g_object_class_install_property (object_class, PROP_STOPBITS, - g_param_spec_uint (NM_SETTING_SERIAL_STOPBITS, - "Stopbits", - "Number of stop bits for communication on the serial " - "port. Either 1 or 2. The 1 in '8n1' for example.", - 1, 2, 1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_SERIAL_STOPBITS, "", "", + 1, 2, 1, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingSerial:send-delay: @@ -321,10 +314,9 @@ nm_setting_serial_class_init (NMSettingSerialClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SEND_DELAY, - g_param_spec_uint64 (NM_SETTING_SERIAL_SEND_DELAY, - "SendDelay", - "Time to delay between each byte sent to the modem, " - "in microseconds.", - 0, G_MAXUINT64, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint64 (NM_SETTING_SERIAL_SEND_DELAY, "", "", + 0, G_MAXUINT64, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-serial.h b/libnm-util/nm-setting-serial.h index 5a73d103..44d46cf3 100644 --- a/libnm-util/nm-setting-serial.h +++ b/libnm-util/nm-setting-serial.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_SERIAL_H diff --git a/libnm-util/nm-setting-team-port.c b/libnm-util/nm-setting-team-port.c index c0b7748b..6bc71c98 100644 --- a/libnm-util/nm-setting-team-port.c +++ b/libnm-util/nm-setting-team-port.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,13 +14,17 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ +#include "config.h" + #include #include #include #include -#include +#include #include "nm-setting-team-port.h" #include "nm-utils.h" @@ -176,13 +178,9 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CONFIG, - g_param_spec_string (NM_SETTING_TEAM_PORT_CONFIG, - "Config", - "JSON configuration for the team port. " - "The property should contain raw JSON configuration data " - "suitable for teamd, because the value is passed directly to " - "teamd. If not specified, the dafault configuration is used. " - "See man teamd.conf for the format details.", + g_param_spec_string (NM_SETTING_TEAM_PORT_CONFIG, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-team-port.h b/libnm-util/nm-setting-team-port.h index 50b9f7e3..4e802220 100644 --- a/libnm-util/nm-setting-team-port.h +++ b/libnm-util/nm-setting-team-port.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,6 +14,8 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ #ifndef NM_SETTING_TEAM_PORT_H diff --git a/libnm-util/nm-setting-team.c b/libnm-util/nm-setting-team.c index af9da62c..19bc9596 100644 --- a/libnm-util/nm-setting-team.c +++ b/libnm-util/nm-setting-team.c @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,12 +14,16 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ +#include "config.h" + #include #include #include -#include +#include #include "nm-setting-team.h" #include "nm-param-spec-specialized.h" @@ -134,25 +136,13 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting); - if (!priv->interface_name || !strlen(priv->interface_name)) { - g_set_error_literal (error, - NM_SETTING_TEAM_ERROR, - NM_SETTING_TEAM_ERROR_MISSING_PROPERTY, - _("property is missing")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_INTERFACE_NAME); - return FALSE; - } - - if (!nm_utils_iface_valid_name (priv->interface_name)) { - g_set_error_literal (error, - NM_SETTING_TEAM_ERROR, - NM_SETTING_TEAM_ERROR_INVALID_PROPERTY, - _("property is invalid")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_INTERFACE_NAME); - return FALSE; - } - - return TRUE; + return _nm_setting_verify_deprecated_virtual_iface_name ( + priv->interface_name, FALSE, + NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TEAM_INTERFACE_NAME, + NM_SETTING_TEAM_ERROR, + NM_SETTING_TEAM_ERROR_INVALID_PROPERTY, + NM_SETTING_TEAM_ERROR_MISSING_PROPERTY, + all_settings, error); } static const char * @@ -242,11 +232,11 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE_NAME, - g_param_spec_string (NM_SETTING_TEAM_INTERFACE_NAME, - "InterfaceName", - "The name of the virtual in-kernel team network interface", + g_param_spec_string (NM_SETTING_TEAM_INTERFACE_NAME, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingTeam:config: @@ -258,13 +248,9 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CONFIG, - g_param_spec_string (NM_SETTING_TEAM_CONFIG, - "Config", - "JSON configuration for the team network interface. " - "The property should contain raw JSON configuration data " - "suitable for teamd, because the value is passed directly to " - "teamd. If not specified, the default configuration is used. " - "See man teamd.conf for the format details.", + g_param_spec_string (NM_SETTING_TEAM_CONFIG, "", "", NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-team.h b/libnm-util/nm-setting-team.h index 978eed07..d67c8c71 100644 --- a/libnm-util/nm-setting-team.h +++ b/libnm-util/nm-setting-team.h @@ -1,7 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2013 Jiri Pirko - * * 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 @@ -16,6 +14,8 @@ * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. + * + * Copyright 2013 Jiri Pirko */ #ifndef NM_SETTING_TEAM_H diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c index ef91b5f1..43b6a91c 100644 --- a/libnm-util/nm-setting-vlan.c +++ b/libnm-util/nm-setting-vlan.c @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Weiping Pan - * * 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 @@ -18,13 +16,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2014 Red Hat, Inc. + * Copyright 2011 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include #include -#include +#include #include "nm-setting-vlan.h" #include "nm-param-spec-specialized.h" @@ -260,7 +260,8 @@ nm_setting_vlan_add_priority_str (NMSettingVlan *setting, list = get_map (setting, map); item = priority_map_new_from_str (map, str); - g_return_val_if_fail (item != NULL, FALSE); + if (!item) + g_return_val_if_reached (FALSE); /* Duplicates get replaced */ for (iter = list; iter; iter = g_slist_next (iter)) { @@ -537,20 +538,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) s_wired = iter->data; } - /* If interface_name is specified, it must be a valid interface name. We - * don't check that it matches parent and/or id, because we allowing - * renaming vlans to arbitrary names. - */ - if (priv->interface_name && !nm_utils_iface_valid_name (priv->interface_name)) { - g_set_error (error, - NM_SETTING_VLAN_ERROR, - NM_SETTING_VLAN_ERROR_INVALID_PROPERTY, - _("'%s' is not a valid interface name"), - priv->interface_name); - g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_INTERFACE_NAME); - return FALSE; - } - if (priv->parent) { if (nm_utils_is_uuid (priv->parent)) { /* If we have an NMSettingConnection:master with slave-type="vlan", @@ -582,7 +569,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) priv->parent); g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT); return FALSE; - } + } } else { /* If parent is NULL, the parent must be specified via * NMSettingWired:mac-address. @@ -609,7 +596,17 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - return TRUE; + /* If interface_name is specified, it must be a valid interface name. We + * don't check that it matches parent and/or id, because we allow + * renaming vlans to arbitrary names. + */ + return _nm_setting_verify_deprecated_virtual_iface_name ( + priv->interface_name, TRUE, + NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_INTERFACE_NAME, + NM_SETTING_VLAN_ERROR, + NM_SETTING_VLAN_ERROR_INVALID_PROPERTY, + NM_SETTING_VLAN_ERROR_MISSING_PROPERTY, + all_settings, error); } static const char * @@ -758,17 +755,12 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INTERFACE_NAME, - g_param_spec_string (NM_SETTING_VLAN_INTERFACE_NAME, - "InterfaceName", - "If given, specifies the kernel name of the VLAN " - "interface. If not given, a default name will be " - "constructed from the interface described by the " - "parent interface and the 'id' property, ex " - "'eth2.1'. The parent interface may be given by " - "the 'parent' property or by the 'mac-address' " - "property of a 'wired' setting.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_VLAN_INTERFACE_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVlan:parent: @@ -780,15 +772,12 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_string (NM_SETTING_VLAN_PARENT, - "Parent", - "If given, specifies the parent interface name or " - "parent connection UUID from which this VLAN " - "interface should be created. If this property is " - "not specified, the connection must contain a " - "'wired' setting with a 'mac-address' property.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_VLAN_PARENT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVlan:id: @@ -798,12 +787,12 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_ID, - g_param_spec_uint (NM_SETTING_VLAN_ID, - "VLAN ID", - "The VLAN indentifier the interface created by " - "this connection should be assigned.", + g_param_spec_uint (NM_SETTING_VLAN_ID, "", "", 0, 4095, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVlan:flags: @@ -816,16 +805,12 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_FLAGS, - g_param_spec_uint (NM_SETTING_VLAN_FLAGS, - "VLAN flags", - "One or more flags which control the behavior and " - "features of the VLAN interface. Flags include " - "reordering of output packet headers (0x01), use " - "of the GVRP protocol (0x02), and loose binding " - "of the interface to its master device's operating " - "state (0x04).", + g_param_spec_uint (NM_SETTING_VLAN_FLAGS, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVlan:ingress-priority-map: @@ -836,15 +821,11 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_INGRESS_PRIORITY_MAP, - _nm_param_spec_specialized (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, - "VLAN ingress priority mapping", - "For incoming packets, a list of mappings " - "from 802.1p priorities to Linux SKB " - "priorities. The mapping is given in the " - "format 'from:to' where both 'from' and " - "'to' are unsigned integers, ie '7:3'.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVlan:egress-priority-map: @@ -855,13 +836,9 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ g_object_class_install_property (object_class, PROP_EGRESS_PRIORITY_MAP, - _nm_param_spec_specialized (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, - "VLAN egress priority mapping", - "For outgoing packets, a list of mappings " - "from Linux SKB priorities to 802.1p " - "priorities. The mapping is given in the " - "format 'from:to' where both 'from' and " - "'to' are unsigned integers, ie '7:3'.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_VLAN_EGRESS_PRIORITY_MAP, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-vlan.h b/libnm-util/nm-setting-vlan.h index ca77f6fe..3e209480 100644 --- a/libnm-util/nm-setting-vlan.h +++ b/libnm-util/nm-setting-vlan.h @@ -1,8 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Weiping Pan - * * 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 @@ -18,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2014 Red Hat, Inc. + * Copyright 2011 - 2014 Red Hat, Inc. */ #ifndef NM_SETTING_VLAN_H diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 4b479b8f..1feeb588 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -1,8 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -18,15 +15,17 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include #include -#include +#include #include "nm-setting-vpn.h" #include "nm-param-spec-specialized.h" @@ -84,6 +83,11 @@ typedef struct { */ char *user_name; + /* Whether the VPN stays up across link changes, until the user + * explicitly disconnects it. + */ + gboolean persistent; + /* The hash table is created at setting object * init time and should not be replaced. It is * a char * -> char * mapping, and both the key @@ -107,6 +111,7 @@ enum { PROP_0, PROP_SERVICE_TYPE, PROP_USER_NAME, + PROP_PERSISTENT, PROP_DATA, PROP_SECRETS, @@ -157,6 +162,20 @@ nm_setting_vpn_get_user_name (NMSettingVPN *setting) return NM_SETTING_VPN_GET_PRIVATE (setting)->user_name; } +/** + * nm_setting_vpn_get_persistent: + * @setting: the #NMSettingVPN + * + * Returns: the #NMSettingVPN:persistent property of the setting + **/ +gboolean +nm_setting_vpn_get_persistent (NMSettingVPN *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); + + return NM_SETTING_VPN_GET_PRIVATE (setting)->persistent; +} + /** * nm_setting_vpn_get_num_data_items: * @setting: the #NMSettingVPN @@ -479,7 +498,7 @@ update_secret_hash (NMSetting *setting, if (!value || !strlen (value)) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Secret %s value was empty", name); + "Secret %s value was empty", name); return NM_SETTING_UPDATE_SECRET_ERROR; } } @@ -548,29 +567,31 @@ get_secret_flags (NMSetting *setting, char *flags_key; gpointer val; unsigned long tmp; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; flags_key = g_strdup_printf ("%s-flags", secret_name); if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { errno = 0; tmp = strtoul ((const char *) val, NULL, 10); if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { - if (out_flags) - *out_flags = (guint32) tmp; + flags = (NMSettingSecretFlags) tmp; success = TRUE; } else { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "Failed to convert '%s' value '%s' to uint", + _("Failed to convert '%s' value '%s' to uint"), flags_key, (const char *) val); } } else { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_FOUND, - "Secret flags property '%s' not found", flags_key); + _("Secret flags property '%s' not found"), flags_key); } g_free (flags_key); + if (out_flags) + *out_flags = flags; return success; } @@ -659,9 +680,9 @@ compare_property (NMSetting *setting, static gboolean clear_secrets_with_flags (NMSetting *setting, - GParamSpec *pspec, - NMSettingClearSecretsWithFlagsFn func, - gpointer user_data) + GParamSpec *pspec, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); GHashTableIter iter; @@ -731,7 +752,7 @@ copy_hash (gpointer key, gpointer value, gpointer user_data) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (object); GHashTable *new_hash; @@ -745,6 +766,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->user_name); priv->user_name = g_value_dup_string (value); break; + case PROP_PERSISTENT: + priv->persistent = g_value_get_boolean (value); + break; case PROP_DATA: /* Must make a deep copy of the hash table here... */ g_hash_table_remove_all (priv->data); @@ -767,7 +791,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingVPN *setting = NM_SETTING_VPN (object); NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); @@ -779,6 +803,9 @@ get_property (GObject *object, guint prop_id, case PROP_USER_NAME: g_value_set_string (value, nm_setting_vpn_get_user_name (setting)); break; + case PROP_PERSISTENT: + g_value_set_boolean (value, priv->persistent); + break; case PROP_DATA: g_value_set_boxed (value, priv->data); break; @@ -822,14 +849,10 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SERVICE_TYPE, - g_param_spec_string (NM_SETTING_VPN_SERVICE_TYPE, - "Service type", - "D-Bus service name of the VPN plugin that this " - "setting uses to connect to its network. i.e. " - "org.freedesktop.NetworkManager.vpnc for the vpnc " - "plugin.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_VPN_SERVICE_TYPE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVPN:user-name: @@ -843,18 +866,24 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) **/ g_object_class_install_property (object_class, PROP_USER_NAME, - g_param_spec_string (NM_SETTING_VPN_USER_NAME, - "User name", - "If the VPN connection requires a user name for " - "authentication, that name should be provided here. " - "If the connection is available to more than one " - "user, and the VPN requires each user to supply a " - "different name, then leave this property empty. If " - "this property is empty, NetworkManager will " - "automatically supply the username of the user which " - "requested the VPN connection.", + g_param_spec_string (NM_SETTING_VPN_USER_NAME, "", "", NULL, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingVPN:persistent: + * + * If the VPN service supports persistence, and this property is %TRUE, + * the VPN will attempt to stay connected across link changes and outages, + * until explicitly disconnected. + **/ + g_object_class_install_property + (object_class, PROP_PERSISTENT, + g_param_spec_boolean (NM_SETTING_VPN_PERSISTENT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVPN:data: @@ -864,13 +893,10 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DATA, - _nm_param_spec_specialized (NM_SETTING_VPN_DATA, - "Data", - "Dictionary of key/value pairs of VPN plugin " - "specific data. Both keys and values must be " - "strings.", - DBUS_TYPE_G_MAP_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_VPN_DATA, "", "", + DBUS_TYPE_G_MAP_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingVPN:secrets: @@ -880,12 +906,9 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SECRETS, - _nm_param_spec_specialized (NM_SETTING_VPN_SECRETS, - "Secrets", - "Dictionary of key/value pairs of VPN plugin " - "specific secrets like passwords or private keys." - " Both keys and values must be strings.", - DBUS_TYPE_G_MAP_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + _nm_param_spec_specialized (NM_SETTING_VPN_SECRETS, "", "", + DBUS_TYPE_G_MAP_OF_STRING, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index 259384bf..fbc9fe34 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2013 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_VPN_H @@ -57,6 +54,7 @@ GQuark nm_setting_vpn_error_quark (void); #define NM_SETTING_VPN_SERVICE_TYPE "service-type" #define NM_SETTING_VPN_USER_NAME "user-name" +#define NM_SETTING_VPN_PERSISTENT "persistent" #define NM_SETTING_VPN_DATA "data" #define NM_SETTING_VPN_SECRETS "secrets" @@ -88,6 +86,7 @@ GType nm_setting_vpn_get_type (void); NMSetting *nm_setting_vpn_new (void); const char *nm_setting_vpn_get_service_type (NMSettingVPN *setting); const char *nm_setting_vpn_get_user_name (NMSettingVPN *setting); +gboolean nm_setting_vpn_get_persistent (NMSettingVPN *setting); guint32 nm_setting_vpn_get_num_data_items (NMSettingVPN *setting); void nm_setting_vpn_add_data_item (NMSettingVPN *setting, diff --git a/libnm-util/nm-setting-wimax.c b/libnm-util/nm-setting-wimax.c index 8bf16b3d..acb00f5e 100644 --- a/libnm-util/nm-setting-wimax.c +++ b/libnm-util/nm-setting-wimax.c @@ -16,14 +16,16 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2011 - 2013 Red Hat, Inc. - * (C) Copyright 2009 Novell, Inc. + * Copyright 2011 - 2013 Red Hat, Inc. + * Copyright 2009 Novell, Inc. */ +#include "config.h" + #include #include #include -#include +#include #include "nm-setting-wimax.h" #include "nm-param-spec-specialized.h" @@ -179,7 +181,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object); @@ -201,7 +203,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingWimax *setting = NM_SETTING_WIMAX (object); @@ -241,12 +243,10 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NETWORK_NAME, - g_param_spec_string (NM_SETTING_WIMAX_NETWORK_NAME, - "NetworkName", - "Network Service Provider (NSP) name of the WiMAX " - "network this connection should use.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIMAX_NETWORK_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWimax:mac-address: @@ -257,12 +257,8 @@ nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_WIMAX_MAC_ADDRESS, - "MAC Address", - "If specified, this connection will only apply to " - "the WiMAX device whose MAC address matches. " - "This property does not change the MAC address " - "of the device (known as MAC spoofing).", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIMAX_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-wimax.h b/libnm-util/nm-setting-wimax.h index 935960d8..781d717c 100644 --- a/libnm-util/nm-setting-wimax.h +++ b/libnm-util/nm-setting-wimax.h @@ -16,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2009 Novell, Inc. + * Copyright 2009 Novell, Inc. */ #ifndef NM_SETTING_WIMAX_H diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c index a956a52f..8d927921 100644 --- a/libnm-util/nm-setting-wired.c +++ b/libnm-util/nm-setting-wired.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,15 +16,17 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include #include -#include +#include #include "nm-setting-wired.h" #include "nm-param-spec-specialized.h" @@ -877,16 +876,10 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_PORT, - g_param_spec_string (NM_SETTING_WIRED_PORT, - "Port", - "Specific port type to use if multiple the device " - "supports multiple attachment methods. One of " - "'tp' (Twisted Pair), 'aui' (Attachment Unit Interface), " - "'bnc' (Thin Ethernet) or 'mii' (Media Independent " - "Interface. If the device supports only one port " - "type, this setting is ignored.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRED_PORT, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:speed: @@ -896,12 +889,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SPEED, - g_param_spec_uint (NM_SETTING_WIRED_SPEED, - "Speed", - "If non-zero, request that the device use only the " - "specified speed. In Mbit/s, ie 100 == 100Mbit/s.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_WIRED_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:duplex: @@ -911,12 +903,10 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_DUPLEX, - g_param_spec_string (NM_SETTING_WIRED_DUPLEX, - "Duplex", - "If specified, request that the device only use the " - "specified duplex mode. Either 'half' or 'full'.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRED_DUPLEX, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:auto-negotiate: @@ -927,14 +917,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_AUTO_NEGOTIATE, - g_param_spec_boolean (NM_SETTING_WIRED_AUTO_NEGOTIATE, - "AutoNegotiate", - "If TRUE, allow auto-negotiation of port speed and " - "duplex mode. If FALSE, do not allow auto-negotiation," - "in which case the 'speed' and 'duplex' properties " - "should be set.", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_boolean (NM_SETTING_WIRED_AUTO_NEGOTIATE, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:mac-address: @@ -945,14 +932,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS, - "Device MAC Address", - "If specified, this connection will only apply to " - "the Ethernet device whose permanent MAC address matches. " - "This property does not change the MAC address " - "of the device (i.e. MAC spoofing).", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:cloned-mac-address: @@ -962,13 +946,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CLONED_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - "Cloned MAC Address", - "If specified, request that the device use " - "this MAC address instead of its permanent MAC address. " - "This is known as MAC cloning or spoofing.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:mac-address-blacklist: @@ -980,14 +962,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS_BLACKLIST, - _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, - "MAC Address Blacklist", - "If specified, this connection will never apply to " - "the Ethernet device whose permanent MAC address matches " - "an address in the list. Each MAC address is in the " - "standard hex-digits-and-colons notation (00:11:22:33:44:55).", + _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, "", "", DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:mtu: @@ -997,13 +976,12 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_SETTING_WIRED_MTU, - "MTU", - "If non-zero, only transmit packets of the specified " - "size or smaller, breaking larger packets up into " - "multiple Ethernet frames.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_WIRED_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:s390-subchannels: @@ -1018,19 +996,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_S390_SUBCHANNELS, - _nm_param_spec_specialized (NM_SETTING_WIRED_S390_SUBCHANNELS, - "z/VM Subchannels", - "Identifies specific subchannels that this " - "network device uses for communcation with z/VM " - "or s390 host. Like the 'mac-address' property " - "for non-z/VM devices, this property can be used " - "to ensure this connection only applies to the " - "network device that uses these subchannels. The " - "list should contain exactly 3 strings, and each " - "string may only be composed of hexadecimal " - "characters and the period (.) character.", - DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_WIRED_S390_SUBCHANNELS, "", "", + DBUS_TYPE_G_ARRAY_OF_STRING, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:s390-nettype: @@ -1040,13 +1010,11 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_S390_NETTYPE, - g_param_spec_string (NM_SETTING_WIRED_S390_NETTYPE, - "s390 Net Type", - "s390 network device type; one of 'qeth', 'lcs', or " - "'ctc', representing the different types of virtual " - "network devices available on s390 systems.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + g_param_spec_string (NM_SETTING_WIRED_S390_NETTYPE, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWired:s390-options: @@ -1058,13 +1026,9 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class) **/ g_object_class_install_property (object_class, PROP_S390_OPTIONS, - _nm_param_spec_specialized (NM_SETTING_WIRED_S390_OPTIONS, - "s390 Options", - "Dictionary of key/value pairs of s390-specific " - "device options. Both keys and values must be " - "strings. Allowed keys include 'portno', " - "'layer2', 'portname', 'protocol', among others.", - DBUS_TYPE_G_MAP_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE)); + _nm_param_spec_specialized (NM_SETTING_WIRED_S390_OPTIONS, "", "", + DBUS_TYPE_G_MAP_OF_STRING, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h index 9580b0a8..33d6d54d 100644 --- a/libnm-util/nm-setting-wired.h +++ b/libnm-util/nm-setting-wired.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_WIRED_H diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index 40c56181..5e3456ce 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,14 +16,15 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include -#include +#include #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" @@ -1068,7 +1066,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) g_set_error_literal (error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - _("property is invalid")); + _("property is invalid")); g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } @@ -1183,7 +1181,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); @@ -1263,7 +1261,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object); NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting); @@ -1355,15 +1353,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_KEY_MGMT, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "Key management", - "Key management used for the connection. One of " - "'none' (WEP), 'ieee8021x' (Dynamic WEP), 'wpa-none' " - "(WPA-PSK Ad-Hoc), 'wpa-psk' (infrastructure WPA-PSK), " - "or 'wpa-eap' (WPA-Enterprise). This property must " - "be set for any Wi-Fi connection that uses security.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_REQUIRED)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_REQUIRED | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-tx-keyidx: @@ -1375,15 +1369,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_TX_KEYIDX, - g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, - "WEP TX key index", - "When static WEP is used (ie, key-mgmt = 'none') and a " - "non-default WEP key index is used by the AP, put that " - "WEP key index here. Valid values are 0 (default key) " - "through 3. Note that some consumer access points " - "(like the Linksys WRT54G) number the keys 1 - 4.", - 0, 3, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, "", "", + 0, 3, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:auth-alg: @@ -1396,17 +1386,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_AUTH_ALG, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "AuthAlg", - "When WEP is used (ie, key-mgmt = 'none' or " - "'ieee8021x') indicate the 802.11 authentication " - "algorithm required by the AP here. One of 'open' for " - "Open System, 'shared' for Shared Key, or 'leap' for " - "Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = " - "'ieee8021x' and auth-alg = 'leap') the 'leap-username' " - "and 'leap-password' properties must be specified.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:proto: @@ -1417,15 +1400,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_PROTO, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PROTO, - "Proto", - "List of strings specifying the allowed WPA " - "protocol versions to use. Each element may be " - "one 'wpa' (allow WPA) or 'rsn' (allow " - "WPA2/RSN). If not specified, both WPA and RSN " - "connections are allowed.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PROTO, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:pairwise: @@ -1437,16 +1415,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_PAIRWISE, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, - "Pairwise", - "A list of pairwise encryption algorithms which " - "prevents connections to Wi-Fi networks that do " - "not utilize one of the algorithms in the list. " - "For maximum compatibility leave this property " - "empty. Each list element may be one of 'tkip' " - "or 'ccmp'.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:group: @@ -1458,16 +1430,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_GROUP, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_GROUP, - "Group", - "A list of group/broadcast encryption algorithms " - "which prevents connections to Wi-Fi networks " - "that do not utilize one of the algorithms in " - "the list. For maximum compatibility leave this " - "property empty. Each list element may be one " - " of 'wep40', 'wep104', 'tkip', or 'ccmp'.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_GROUP, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:leap-username: @@ -1477,12 +1443,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_LEAP_USERNAME, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, - "LEAP Username", - "The login username for legacy LEAP connections " - "(ie, key-mgmt = 'ieee8021x' and auth-alg = 'leap').", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key0: @@ -1492,13 +1456,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_KEY0, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, - "WEP key0", - "Index 0 WEP key. This is the WEP key used in most " - "networks. See the 'wep-key-type' property for a " - "description of how this key is interpreted.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key1: @@ -1508,13 +1470,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_KEY1, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, - "WEP key1", - "Index 1 WEP key. This WEP index is not used by most " - "networks. See the 'wep-key-type' property for a " - "description of how this key is interpreted.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key2: @@ -1524,13 +1484,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_KEY2, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, - "WEP key2", - "Index 2 WEP key. This WEP index is not used by most " - "networks. See the 'wep-key-type' property for a " - "description of how this key is interpreted.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key3: @@ -1540,13 +1498,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_KEY3, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, - "WEP key3", - "Index 3 WEP key. This WEP index is not used by most " - "networks. See the 'wep-key-type' property for a " - "description of how this key is interpreted.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key-flags: @@ -1555,14 +1511,14 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting * #NMSettingWirelessSecurity:wep-key1, #NMSettingWirelessSecurity:wep-key2, * and #NMSettingWirelessSecurity:wep-key3 properties. **/ - g_object_class_install_property (object_class, PROP_WEP_KEY_FLAGS, - g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, - "WEP Key Flags", - "Flags indicating how to handle the WEP keys.", + g_object_class_install_property + (object_class, PROP_WEP_KEY_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:psk: @@ -1576,18 +1532,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_PSK, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, - "PSK", - "Pre-Shared-Key for WPA networks. If the key is " - "64-characters long, it must contain only hexadecimal " - "characters and is interpreted as a hexadecimal WPA " - "key. Otherwise, the key must be between 8 and 63 " - "ASCII characters (as specified in the 802.11i standard) " - "and is interpreted as a WPA passphrase, and is hashed " - "to derive the actual WPA-PSK used when connecting to " - "the Wi-Fi network.", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:psk-flags: @@ -1595,14 +1544,14 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting * Flags indicating how to handle the #NMSettingWirelessSecurity:psk * property. **/ - g_object_class_install_property (object_class, PROP_PSK_FLAGS, - g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, - "PSK Flags", - "Flags indicating how to handle the WPA PSK key.", + g_object_class_install_property + (object_class, PROP_PSK_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:leap-password: @@ -1612,12 +1561,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_LEAP_PASSWORD, - g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - "LEAP Password", - "The login password for legacy LEAP connections " - "(ie, key-mgmt = 'ieee8021x' and auth-alg = 'leap').", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SECRET)); + g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_SECRET | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:leap-password-flags: @@ -1625,14 +1573,14 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting * Flags indicating how to handle the * #NMSettingWirelessSecurity:leap-password property. **/ - g_object_class_install_property (object_class, PROP_LEAP_PASSWORD_FLAGS, - g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, - "LEAP Password Flags", - "Flags indicating how to handle the LEAP password.", + g_object_class_install_property + (object_class, PROP_LEAP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "", "", NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_NONE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWirelessSecurity:wep-key-type: @@ -1646,18 +1594,11 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting **/ g_object_class_install_property (object_class, PROP_WEP_KEY_TYPE, - g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, - "WEP Key Type", - "Controls the interpretation of WEP keys. Allowed values " - "are 1 (interpret WEP keys as hexadecimal or ASCII keys) " - "or 2 (interpret WEP keys as WEP Passphrases). If set to " - "1 and the keys are hexadecimal, they must be either 10 or " - "26 characters in length. If set to 1 and the keys are " - "ASCII keys, they must be either 5 or 13 characters in " - "length. If set to 2, the passphrase is hashed using " - " the de-facto MD5 method to derive the actual WEP key.", - NM_WEP_KEY_TYPE_UNKNOWN, - NM_WEP_KEY_TYPE_LAST, - NM_WEP_KEY_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, "", "", + NM_WEP_KEY_TYPE_UNKNOWN, + NM_WEP_KEY_TYPE_LAST, + NM_WEP_KEY_TYPE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h index df5d77ab..97a456b0 100644 --- a/libnm-util/nm-setting-wireless-security.h +++ b/libnm-util/nm-setting-wireless-security.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_WIRELESS_SECURITY_H diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index ca53d6f9..99f4c9b1 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,15 +16,17 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include #include -#include +#include #include "NetworkManager.h" #include "nm-setting-wireless.h" @@ -731,7 +730,7 @@ nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting) **/ const char * nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, - guint32 i) + guint32 i) { g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL); @@ -894,7 +893,7 @@ finalize (GObject *object) static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object); @@ -962,7 +961,7 @@ set_property (GObject *object, guint prop_id, static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingWireless *setting = NM_SETTING_WIRELESS (object); @@ -1037,11 +1036,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SSID, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_SSID, - "SSID", - "SSID of the Wi-Fi network. Must be specified.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_SSID, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:mode: @@ -1051,12 +1049,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_string (NM_SETTING_WIRELESS_MODE, - "Mode", - "Wi-Fi network mode; one of 'infrastructure', " - "'adhoc' or 'ap'. If blank, infrastructure is assumed.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRELESS_MODE, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:band: @@ -1070,18 +1066,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BAND, - g_param_spec_string (NM_SETTING_WIRELESS_BAND, - "Band", - "802.11 frequency band of the network. One of 'a' " - "for 5GHz 802.11a or 'bg' for 2.4GHz 802.11. This " - "will lock associations to the Wi-Fi network to the " - "specific band, i.e. if 'a' is specified, the device " - "will not associate with the same network in the " - "2.4GHz band even if the network's settings are " - "compatible. This setting depends on specific driver " - "capability and may not work with all drivers.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRELESS_BAND, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:channel: @@ -1093,15 +1081,11 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CHANNEL, - g_param_spec_uint (NM_SETTING_WIRELESS_CHANNEL, - "Channel", - "Wireless channel to use for the Wi-Fi connection. The " - "device will only join (or create for Ad-Hoc networks) " - "a Wi-Fi network on the specified channel. Because " - "channel numbers overlap between bands, this property " - "also requires the 'band' property to be set.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint (NM_SETTING_WIRELESS_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:bssid: @@ -1113,16 +1097,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_BSSID, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_BSSID, - "BSSID", - "If specified, directs the device to only associate " - "with the given access point. This capability is " - "highly driver dependent and not supported by all " - "devices. Note: this property does not control " - "the BSSID used when creating an Ad-Hoc network " - "and is unlikely to in the future.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_BSSID, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:rate: @@ -1134,15 +1112,12 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_RATE, - g_param_spec_uint (NM_SETTING_WIRELESS_RATE, - "Rate", - "If non-zero, directs the device to only use the " - "specified bitrate for communication with the access " - "point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This " - "property is highly driver dependent and not all devices " - "support setting a static bitrate.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_WIRELESS_RATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:tx-power: @@ -1153,14 +1128,12 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_TX_POWER, - g_param_spec_uint (NM_SETTING_WIRELESS_TX_POWER, - "TX Power", - "If non-zero, directs the device to use the specified " - "transmit power. Units are dBm. This property is highly " - "driver dependent and not all devices support setting a " - "static transmit power.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_WIRELESS_TX_POWER, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:mac-address: @@ -1171,14 +1144,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS, - "Device MAC Address", - "If specified, this connection will only apply to " - "the Wi-Fi device whose permanent MAC address matches. " - "This property does not change the MAC address " - "of the device (i.e. MAC spoofing).", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:cloned-mac-address: @@ -1188,13 +1157,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_CLONED_MAC_ADDRESS, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - "Spoof MAC Address", - "If specified, request that the Wi-Fi device use " - "this MAC address instead of its permanent MAC address. " - "This is known as MAC cloning or spoofing.", - DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE)); + _nm_param_spec_specialized (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, "", "", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:mac-address-blacklist: @@ -1205,15 +1171,11 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MAC_ADDRESS_BLACKLIST, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, - "MAC Address Blacklist", - "A list of permanent MAC addresses of Wi-Fi " - "devices to which this connection should " - "never apply. Each MAC address should be " - "given in the standard hex-digits-and-colons " - "notation (eg '00:11:22:33:44:55').", + _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, "", "", DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:seen-bssids: @@ -1227,18 +1189,11 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SEEN_BSSIDS, - _nm_param_spec_specialized (NM_SETTING_WIRELESS_SEEN_BSSIDS, - "Seen BSSIDS", - "A list of BSSIDs (each BSSID formatted as a MAC " - "address like 00:11:22:33:44:55') that have been " - "detected as part of the Wi-Fi network. " - "NetworkManager internally tracks previously seen " - "BSSIDs. The property is only meant for reading " - "and reflects the BSSID list of NetworkManager. " - "The changes you make to this property will not be " - "preserved.", + _nm_param_spec_specialized (NM_SETTING_WIRELESS_SEEN_BSSIDS, "", "", DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE)); + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:mtu: @@ -1248,13 +1203,12 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_SETTING_WIRELESS_MTU, - "MTU", - "If non-zero, only transmit packets of the specified " - "size or smaller, breaking larger packets up into " - "multiple Ethernet frames.", - 0, G_MAXUINT32, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_param_spec_uint (NM_SETTING_WIRELESS_MTU, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:security: @@ -1270,15 +1224,10 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_SEC, - g_param_spec_string (NM_SETTING_WIRELESS_SEC, - "Security", - "If the wireless connection has any security " - "restrictions, like 802.1x, WEP, or WPA, set this " - "property to '" NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "' " - "and ensure the connection contains a valid " - NM_SETTING_WIRELESS_SECURITY_SETTING_NAME " setting.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_WIRELESS_SEC, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /** * NMSettingWireless:hidden: @@ -1291,15 +1240,8 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class) **/ g_object_class_install_property (object_class, PROP_HIDDEN, - g_param_spec_boolean (NM_SETTING_WIRELESS_HIDDEN, - "Hidden", - "If TRUE, indicates this network is a non-broadcasting " - "network that hides its SSID. In this case various " - "workarounds may take place, such as probe-scanning " - "the SSID for more reliable network discovery. " - "However, these workarounds expose inherent " - "insecurities with hidden SSID networks, and thus " - "hidden SSID networks should be used with caution.", + g_param_spec_boolean (NM_SETTING_WIRELESS_HIDDEN, "", "", FALSE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index 221a921a..18f78cff 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2014 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_WIRELESS_H @@ -155,11 +152,11 @@ guint32 nm_setting_wireless_get_mtu (NMSettingWireless gboolean nm_setting_wireless_get_hidden (NMSettingWireless *setting); gboolean nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting, - const char *bssid); + const char *bssid); guint32 nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting); const char *nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting, - guint32 i); + guint32 i); gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless, NMSettingWirelessSecurity *s_wireless_sec, diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 0e8a06c4..105981bc 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,11 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include +#include #include "nm-setting.h" #include "nm-setting-private.h" @@ -211,6 +211,17 @@ _get_setting_type_priority (GType type) return info->priority; } +guint32 +_nm_setting_get_setting_priority (NMSetting *setting) +{ + NMSettingPrivate *priv; + + g_return_val_if_fail (NM_IS_SETTING (setting), G_MAXUINT32); + priv = NM_SETTING_GET_PRIVATE (setting); + _ensure_setting_info (setting, priv); + return priv->info->priority; +} + gboolean _nm_setting_type_is_base_type (GType type) { @@ -262,8 +273,8 @@ _nm_setting_compare_priority (gconstpointer a, gconstpointer b) { guint32 prio_a, prio_b; - prio_a = _get_setting_type_priority (G_OBJECT_TYPE (a)); - prio_b = _get_setting_type_priority (G_OBJECT_TYPE (b)); + prio_a = _nm_setting_get_setting_priority ((NMSetting *) a); + prio_b = _nm_setting_get_setting_priority ((NMSetting *) b); if (prio_a < prio_b) return -1; @@ -291,7 +302,7 @@ destroy_gvalue (gpointer data) * Converts the #NMSetting into a #GHashTable mapping each setting property * name to a GValue describing that property, suitable for marshalling over * D-Bus or serializing. The mapping is string to GValue. - * + * * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable * describing the setting's properties **/ @@ -306,11 +317,6 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) g_return_val_if_fail (NM_IS_SETTING (setting), NULL); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); - if (!property_specs) { - g_warning ("%s: couldn't find property specs for object of type '%s'", - __func__, g_type_name (G_OBJECT_TYPE (setting))); - return NULL; - } hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, destroy_gvalue); @@ -343,12 +349,6 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) } g_free (property_specs); - /* Don't return empty hashes, except for base types */ - if (g_hash_table_size (hash) < 1 && !_nm_setting_is_base_type (setting)) { - g_hash_table_destroy (hash); - hash = NULL; - } - return hash; } @@ -364,7 +364,7 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) * are strongly typed, thus the GValue type of the hash value must be correct. * See the documentation on each #NMSetting object subclass for the correct * property names and value types. - * + * * Returns: a new #NMSetting object populated with the properties from the * hash table, or %NULL on failure **/ @@ -396,19 +396,16 @@ nm_setting_new_from_hash (GType setting_type, GHashTable *hash) param_spec = g_object_class_find_property (class, prop_name); if (!param_spec) { - /* Oh, we're so nice and only warn, maybe it should be a fatal error? */ - g_warning ("Ignoring invalid property '%s'", prop_name); + /* Assume that any unrecognized property either can be ignored, or + * else has a backward-compatibility equivalent. + */ + g_debug ("Ignoring unrecognized property '%s'", prop_name); continue; } g_value_init (dst_value, G_VALUE_TYPE (src_value)); - if (g_value_transform (src_value, dst_value)) - params[n_params++].name = prop_name; - else { - g_warning ("Ignoring property '%s' with invalid type (%s)", - prop_name, G_VALUE_TYPE_NAME (src_value)); - g_value_unset (dst_value); - } + g_value_copy (src_value, dst_value); + params[n_params++].name = prop_name; } setting = (NMSetting *) g_object_newv (setting_type, n_params, params); @@ -422,6 +419,27 @@ nm_setting_new_from_hash (GType setting_type, GHashTable *hash) return setting; } +gboolean +_nm_setting_get_property (NMSetting *setting, const char *property_name, GValue *value) +{ + GParamSpec *prop_spec; + + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (property_name, FALSE); + g_return_val_if_fail (value, FALSE); + + prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); + + if (!prop_spec) { + g_value_unset (value); + return FALSE; + } + + g_value_init (value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), property_name, value); + return TRUE; +} + static void duplicate_setting (NMSetting *setting, const char *name, @@ -517,20 +535,31 @@ nm_setting_get_name (NMSetting *setting) gboolean nm_setting_verify (NMSetting *setting, GSList *all_settings, GError **error) { - g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); - g_return_val_if_fail (!error || *error == NULL, FALSE); + NMSettingVerifyResult result = _nm_setting_verify (setting, all_settings, error); + + if (result == NM_SETTING_VERIFY_NORMALIZABLE) + g_clear_error (error); + + return result == NM_SETTING_VERIFY_SUCCESS || result == NM_SETTING_VERIFY_NORMALIZABLE; +} + +NMSettingVerifyResult +_nm_setting_verify (NMSetting *setting, GSList *all_settings, GError **error) +{ + g_return_val_if_fail (NM_IS_SETTING (setting), NM_SETTING_VERIFY_ERROR); + g_return_val_if_fail (!error || *error == NULL, NM_SETTING_VERIFY_ERROR); if (NM_SETTING_GET_CLASS (setting)->verify) return NM_SETTING_GET_CLASS (setting)->verify (setting, all_settings, error); - return TRUE; + return NM_SETTING_VERIFY_SUCCESS; } static gboolean compare_property (NMSetting *setting, - NMSetting *other, - const GParamSpec *prop_spec, - NMSettingCompareFlags flags) + NMSetting *other, + const GParamSpec *prop_spec, + NMSettingCompareFlags flags) { GValue value1 = G_VALUE_INIT; GValue value2 = G_VALUE_INIT; @@ -541,8 +570,12 @@ compare_property (NMSetting *setting, NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE; NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE; - nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL); - nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL); + g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE); + + if (!nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL)) + g_return_val_if_reached (FALSE); + if (!nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL)) + g_return_val_if_reached (FALSE); /* If the secret flags aren't the same the settings aren't the same */ if (a_secret_flags != b_secret_flags) @@ -610,7 +643,7 @@ nm_setting_compare (NMSetting *a, /* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */ if ( (flags & NM_SETTING_COMPARE_FLAG_FUZZY) - && (prop_spec->flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))) + && (prop_spec->flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET))) continue; if ((flags & NM_SETTING_COMPARE_FLAG_INFERRABLE) && !(prop_spec->flags & NM_SETTING_PARAM_INFERRABLE)) @@ -647,7 +680,16 @@ should_compare_prop (NMSetting *setting, if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS) return FALSE; - nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL); + if ( NM_IS_SETTING_VPN (setting) + && g_strcmp0 (prop_name, NM_SETTING_VPN_SECRETS) == 0) { + /* FIXME: NMSettingVPN:NM_SETTING_VPN_SECRETS has NM_SETTING_PARAM_SECRET. + * nm_setting_get_secret_flags() quite possibly fails, but it might succeed if the + * setting accidently uses a key "secrets". */ + return FALSE; + } + + if (!nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL)) + g_return_val_if_reached (FALSE); if ( (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS) && (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) @@ -699,6 +741,8 @@ nm_setting_diff (NMSetting *a, guint i; NMSettingDiffResult a_result = NM_SETTING_DIFF_RESULT_IN_A; NMSettingDiffResult b_result = NM_SETTING_DIFF_RESULT_IN_B; + NMSettingDiffResult a_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; + NMSettingDiffResult b_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; gboolean results_created = FALSE; g_return_val_if_fail (results != NULL, FALSE); @@ -708,6 +752,12 @@ nm_setting_diff (NMSetting *a, g_return_val_if_fail (G_OBJECT_TYPE (a) == G_OBJECT_TYPE (b), FALSE); } + if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == + (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) { + /* conflicting flags: default to WITH_DEFAULT (clearing NO_DEFAULT). */ + flags &= ~NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT; + } + /* If the caller is calling this function in a pattern like this to get * complete diffs: * @@ -720,6 +770,8 @@ nm_setting_diff (NMSetting *a, if (invert_results) { a_result = NM_SETTING_DIFF_RESULT_IN_B; b_result = NM_SETTING_DIFF_RESULT_IN_A; + a_result_default = NM_SETTING_DIFF_RESULT_IN_B_DEFAULT; + b_result_default = NM_SETTING_DIFF_RESULT_IN_A_DEFAULT; } if (*results == NULL) { @@ -732,8 +784,7 @@ nm_setting_diff (NMSetting *a, for (i = 0; i < n_property_specs; i++) { GParamSpec *prop_spec = property_specs[i]; - NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN, tmp; - gboolean different = TRUE; + NMSettingDiffResult r = NM_SETTING_DIFF_RESULT_UNKNOWN; /* Handle compare flags */ if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags)) @@ -742,28 +793,58 @@ nm_setting_diff (NMSetting *a, continue; if (b) { + gboolean different; + different = !NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags); if (different) { + gboolean a_is_default, b_is_default; GValue value = G_VALUE_INIT; g_value_init (&value, prop_spec->value_type); g_object_get_property (G_OBJECT (a), prop_spec->name, &value); - if (!g_param_value_defaults (prop_spec, &value)) - r |= a_result; + a_is_default = g_param_value_defaults (prop_spec, &value); g_value_reset (&value); g_object_get_property (G_OBJECT (b), prop_spec->name, &value); - if (!g_param_value_defaults (prop_spec, &value)) - r |= b_result; + b_is_default = g_param_value_defaults (prop_spec, &value); g_value_unset (&value); + if ((flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) == 0) { + if (!a_is_default) + r |= a_result; + if (!b_is_default) + r |= b_result; + } else { + r |= a_result | b_result; + if (a_is_default) + r |= a_result_default; + if (b_is_default) + r |= b_result_default; + } } - } else + } else if ((flags & (NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT)) == 0) r = a_result; /* only in A */ + else { + GValue value = G_VALUE_INIT; - if (different) { - tmp = GPOINTER_TO_UINT (g_hash_table_lookup (*results, prop_spec->name)); - g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (tmp | r)); + g_value_init (&value, prop_spec->value_type); + g_object_get_property (G_OBJECT (a), prop_spec->name, &value); + if (!g_param_value_defaults (prop_spec, &value)) + r |= a_result; + else if (flags & NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT) + r |= a_result | a_result_default; + + g_value_unset (&value); + } + + if (r != NM_SETTING_DIFF_RESULT_UNKNOWN) { + void *p; + + if (g_hash_table_lookup_extended (*results, prop_spec->name, NULL, &p)) { + if ((r & GPOINTER_TO_UINT (p)) != r) + g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r | GPOINTER_TO_UINT (p))); + } else + g_hash_table_insert (*results, g_strdup (prop_spec->name), GUINT_TO_POINTER (r)); } } g_free (property_specs); @@ -788,8 +869,8 @@ nm_setting_diff (NMSetting *a, **/ void nm_setting_enumerate_values (NMSetting *setting, - NMSettingValueIterFn func, - gpointer user_data) + NMSettingValueIterFn func, + gpointer user_data) { GParamSpec **property_specs; guint n_property_specs; @@ -862,15 +943,19 @@ _nm_setting_clear_secrets (NMSetting *setting) static gboolean clear_secrets_with_flags (NMSetting *setting, - GParamSpec *pspec, - NMSettingClearSecretsWithFlagsFn func, - gpointer user_data) + GParamSpec *pspec, + NMSettingClearSecretsWithFlagsFn func, + gpointer user_data) { NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; gboolean changed = FALSE; + g_return_val_if_fail (!NM_IS_SETTING_VPN (setting), FALSE); + /* Clear the secret if the user function says to do so */ - nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL); + if (!nm_setting_get_secret_flags (setting, pspec->name, &flags, NULL)) + g_return_val_if_reached (FALSE); + if (func (setting, pspec->name, flags, user_data) == TRUE) { GValue value = G_VALUE_INIT; @@ -963,7 +1048,6 @@ static int update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) { GParamSpec *prop_spec; - GValue transformed_value = G_VALUE_INIT; prop_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key); if (!prop_spec) { @@ -995,11 +1079,6 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** g_object_set_property (G_OBJECT (setting), prop_spec->name, value); return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; } - if (g_value_transform (value, &transformed_value)) { - g_object_set_property (G_OBJECT (setting), prop_spec->name, &transformed_value); - g_value_unset (&transformed_value); - return NM_SETTING_UPDATE_SECRET_SUCCESS_MODIFIED; - } g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, @@ -1016,7 +1095,7 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** * * Update the setting's secrets, given a hash table of secrets intended for that * setting (deserialized from D-Bus for example). - * + * * Returns: %TRUE if the secrets were successfully updated, %FALSE on failure to * update one or more of the secrets. **/ @@ -1095,8 +1174,11 @@ get_secret_flags (NMSetting *setting, char *flags_prop; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - if (verify_secret) - g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + if (verify_secret && !is_secret_prop (setting, secret_name, error)) { + if (out_flags) + *out_flags = NM_SETTING_SECRET_FLAG_NONE; + return FALSE; + } flags_prop = g_strdup_printf ("%s-flags", secret_name); g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL); @@ -1199,8 +1281,6 @@ nm_setting_to_string (NMSetting *setting) g_return_val_if_fail (NM_IS_SETTING (setting), NULL); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); - if (!property_specs) - return NULL; string = g_string_new (nm_setting_get_name (setting)); g_string_append_c (string, '\n'); @@ -1259,6 +1339,87 @@ nm_setting_get_virtual_iface_name (NMSetting *setting) return NULL; } + +NMSettingVerifyResult +_nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name, + gboolean allow_missing, + const char *setting_name, + const char *setting_property, + GQuark error_quark, + gint e_invalid_property, + gint e_missing_property, + GSList *all_settings, + GError **error) +{ + NMSettingConnection *s_con; + const char *con_name; + + s_con = NM_SETTING_CONNECTION (nm_setting_find_in_list (all_settings, NM_SETTING_CONNECTION_SETTING_NAME)); + con_name = s_con ? nm_setting_connection_get_interface_name (s_con) : NULL; + if (!interface_name && !con_name) { + if (allow_missing) + return NM_SETTING_VERIFY_SUCCESS; + + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return NM_SETTING_VERIFY_ERROR; + } + if (!con_name && !nm_utils_iface_valid_name (interface_name)) { + /* the interface_name is invalid, we cannot normalize it. Only do this if !con_name, + * because if con_name is set, it can overwrite interface_name. */ + g_set_error_literal (error, + error_quark, + e_invalid_property, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", setting_name, setting_property); + return NM_SETTING_VERIFY_ERROR; + } + if (!con_name) { + /* NMSettingConnection has interface not set, it should be normalized to interface_name */ + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + if (!nm_utils_iface_valid_name (con_name)) { + /* NMSettingConnection:interface_name is invalid, we cannot normalize it. */ + g_set_error_literal (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME); + return NM_SETTING_VERIFY_ERROR; + } + if (!interface_name) { + /* Normalize by setting NMSettingConnection:interface_name. */ + g_set_error_literal (error, + error_quark, + e_missing_property, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", setting_name, setting_property); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + if (strcmp (con_name, interface_name) != 0) { + /* con_name and interface_name are different. It can be normalized by setting interface_name + * to con_name. */ + g_set_error_literal (error, + error_quark, + e_invalid_property, + _("property is invalid")); + g_prefix_error (error, "%s.%s: ", setting_name, setting_property); + /* we would like to make this a NORMALIZEABLE_ERROR, but that might + * break older connections. */ + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + return NM_SETTING_VERIFY_SUCCESS; +} + /*****************************************************************************/ static void @@ -1348,13 +1509,8 @@ nm_setting_class_init (NMSettingClass *setting_class) **/ g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_SETTING_NAME, - "Name", - "The setting's name; these names are defined by the " - "specification and cannot be changed after the object " - "has been created. Each setting class has a name, and " - "all objects of that class share the same name.", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SETTING_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } - diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index 51e7de48..28c6975a 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -1,9 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Dan Williams - * Tambet Ingo - * * 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 @@ -19,8 +16,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. - * (C) Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2008 Novell, Inc. */ #ifndef NM_SETTING_H @@ -127,6 +124,20 @@ typedef enum { * @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which * the secret's flags indicate the secret should not be saved to persistent * storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED) + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will also include properties that + * are set to their default value. See also @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT. + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT: if this flag is set, + * nm_setting_diff() and nm_connection_diff() will not include properties that + * are set to their default value. This is the opposite of + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. If both flags are set together, + * @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT wins. If both flags are unset, + * this means to exclude default properties if there is a setting to compare, + * but include all properties, if the setting 'b' is missing. This is the legacy + * behaviour of libnm-util, where nm_setting_diff() behaved differently depending + * on whether the setting 'b' was available. If @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT + * is set, nm_setting_diff() will also set the flags @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT + * and @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, if the values are default values. * * These flags modify the comparison behavior when comparing two settings or * two connections. @@ -138,7 +149,9 @@ typedef enum { NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008, - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010 + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT = 0x00000020, + NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT = 0x00000040, /* 0x80000000 is used for a private flag */ } NMSettingCompareFlags; @@ -173,7 +186,7 @@ typedef struct { GObjectClass parent; /* Virtual functions */ - gboolean (*verify) (NMSetting *setting, + gint (*verify) (NMSetting *setting, GSList *all_settings, GError **error); @@ -270,6 +283,10 @@ gboolean nm_setting_compare (NMSetting *a, * @NM_SETTING_DIFF_RESULT_UNKNOWN: unknown result * @NM_SETTING_DIFF_RESULT_IN_A: the property is present in setting A * @NM_SETTING_DIFF_RESULT_IN_B: the property is present in setting B + * @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT: the property is present in + * setting A but is set to the default value. This flag is only set, + * if you specify @NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT. + * @NM_SETTING_DIFF_RESULT_IN_B_DEFAULT: analog to @NM_SETTING_DIFF_RESULT_IN_A_DEFAULT. * * These values indicate the result of a setting difference operation. **/ @@ -277,6 +294,8 @@ typedef enum { NM_SETTING_DIFF_RESULT_UNKNOWN = 0x00000000, NM_SETTING_DIFF_RESULT_IN_A = 0x00000001, NM_SETTING_DIFF_RESULT_IN_B = 0x00000002, + NM_SETTING_DIFF_RESULT_IN_A_DEFAULT = 0x00000004, + NM_SETTING_DIFF_RESULT_IN_B_DEFAULT = 0x00000004, } NMSettingDiffResult; gboolean nm_setting_diff (NMSetting *a, @@ -318,4 +337,3 @@ const char *nm_setting_get_virtual_iface_name (NMSetting *setting); G_END_DECLS #endif /* NM_SETTING_H */ - diff --git a/libnm-util/nm-utils-enum-types.c b/libnm-util/nm-utils-enum-types.c index 9b3eb4f4..6ef157da 100644 --- a/libnm-util/nm-utils-enum-types.c +++ b/libnm-util/nm-utils-enum-types.c @@ -47,6 +47,7 @@ nm_connection_error_get_type (void) { NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND", "ConnectionSettingNotFound" }, { NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID", "ConnectionTypeInvalid" }, { NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "NM_CONNECTION_ERROR_SETTING_NOT_FOUND", "SettingNotFound" }, + { NM_CONNECTION_ERROR_INVALID_SETTING, "NM_CONNECTION_ERROR_INVALID_SETTING", "InvalidSetting" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -112,6 +113,8 @@ nm_setting_compare_flags_get_type (void) { NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS", "ignore-secrets" }, { NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS", "ignore-agent-owned-secrets" }, { NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, "NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS", "ignore-not-saved-secrets" }, + { NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT, "NM_SETTING_COMPARE_FLAG_DIFF_RESULT_WITH_DEFAULT", "diff-result-with-default" }, + { NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, "NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT", "diff-result-no-default" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -152,6 +155,8 @@ nm_setting_diff_result_get_type (void) { NM_SETTING_DIFF_RESULT_UNKNOWN, "NM_SETTING_DIFF_RESULT_UNKNOWN", "unknown" }, { NM_SETTING_DIFF_RESULT_IN_A, "NM_SETTING_DIFF_RESULT_IN_A", "in-a" }, { NM_SETTING_DIFF_RESULT_IN_B, "NM_SETTING_DIFF_RESULT_IN_B", "in-b" }, + { NM_SETTING_DIFF_RESULT_IN_A_DEFAULT, "NM_SETTING_DIFF_RESULT_IN_A_DEFAULT", "in-a-default" }, + { NM_SETTING_DIFF_RESULT_IN_B_DEFAULT, "NM_SETTING_DIFF_RESULT_IN_B_DEFAULT", "in-b-default" }, { 0, NULL, NULL } }; GType g_define_type_id = diff --git a/libnm-util/nm-utils-enum-types.h b/libnm-util/nm-utils-enum-types.h deleted file mode 100644 index 9b14a5d3..00000000 --- a/libnm-util/nm-utils-enum-types.h +++ /dev/null @@ -1,101 +0,0 @@ - - - -/* Generated by glib-mkenums. Do not edit */ - -#ifndef __NM_UTILS_ENUM_TYPES_H__ -#define __NM_UTILS_ENUM_TYPES_H__ - -#include - -G_BEGIN_DECLS -GType nm_connection_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ()) -GType nm_setting_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_ERROR (nm_setting_error_get_type ()) -GType nm_setting_secret_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_SECRET_FLAGS (nm_setting_secret_flags_get_type ()) -GType nm_setting_compare_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_COMPARE_FLAGS (nm_setting_compare_flags_get_type ()) -GType nm_setting_hash_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_HASH_FLAGS (nm_setting_hash_flags_get_type ()) -GType nm_setting_diff_result_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_DIFF_RESULT (nm_setting_diff_result_get_type ()) -GType nm_setting_802_1x_ck_format_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_802_1X_CK_FORMAT (nm_setting_802_1x_ck_format_get_type ()) -GType nm_setting_802_1x_ck_scheme_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_802_1X_CK_SCHEME (nm_setting_802_1x_ck_scheme_get_type ()) -GType nm_setting_802_1x_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_802_1X_ERROR (nm_setting_802_1x_error_get_type ()) -GType nm_setting_adsl_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_ADSL_ERROR (nm_setting_adsl_error_get_type ()) -GType nm_setting_bluetooth_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_BLUETOOTH_ERROR (nm_setting_bluetooth_error_get_type ()) -GType nm_setting_bond_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_BOND_ERROR (nm_setting_bond_error_get_type ()) -GType nm_setting_team_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_TEAM_ERROR (nm_setting_team_error_get_type ()) -GType nm_setting_team_port_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_TEAM_PORT_ERROR (nm_setting_team_port_error_get_type ()) -GType nm_setting_bridge_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_BRIDGE_ERROR (nm_setting_bridge_error_get_type ()) -GType nm_setting_bridge_port_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_BRIDGE_PORT_ERROR (nm_setting_bridge_port_error_get_type ()) -GType nm_setting_connection_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_CONNECTION_ERROR (nm_setting_connection_error_get_type ()) -GType nm_setting_dcb_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_DCB_ERROR (nm_setting_dcb_error_get_type ()) -GType nm_setting_dcb_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_DCB_FLAGS (nm_setting_dcb_flags_get_type ()) -GType nm_setting_infiniband_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_INFINIBAND_ERROR (nm_setting_infiniband_error_get_type ()) -GType nm_setting_ip4_config_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_IP4_CONFIG_ERROR (nm_setting_ip4_config_error_get_type ()) -GType nm_setting_vlan_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_VLAN_ERROR (nm_setting_vlan_error_get_type ()) -GType nm_vlan_priority_map_get_type (void) G_GNUC_CONST; -#define NM_TYPE_VLAN_PRIORITY_MAP (nm_vlan_priority_map_get_type ()) -GType nm_vlan_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_VLAN_FLAGS (nm_vlan_flags_get_type ()) -GType nm_setting_ip6_config_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_IP6_CONFIG_ERROR (nm_setting_ip6_config_error_get_type ()) -GType nm_setting_ip6_config_privacy_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_IP6_CONFIG_PRIVACY (nm_setting_ip6_config_privacy_get_type ()) -GType nm_setting_ppp_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_PPP_ERROR (nm_setting_ppp_error_get_type ()) -GType nm_setting_pppoe_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_PPPOE_ERROR (nm_setting_pppoe_error_get_type ()) -GType nm_setting_serial_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_SERIAL_ERROR (nm_setting_serial_error_get_type ()) -GType nm_setting_generic_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_GENERIC_ERROR (nm_setting_generic_error_get_type ()) -GType nm_setting_gsm_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_GSM_ERROR (nm_setting_gsm_error_get_type ()) -GType nm_setting_gsm_network_type_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_GSM_NETWORK_TYPE (nm_setting_gsm_network_type_get_type ()) -GType nm_setting_gsm_network_band_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_GSM_NETWORK_BAND (nm_setting_gsm_network_band_get_type ()) -GType nm_setting_cdma_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_CDMA_ERROR (nm_setting_cdma_error_get_type ()) -GType nm_setting_olpc_mesh_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_OLPC_MESH_ERROR (nm_setting_olpc_mesh_error_get_type ()) -GType nm_setting_wimax_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_WIMAX_ERROR (nm_setting_wimax_error_get_type ()) -GType nm_setting_wired_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_WIRED_ERROR (nm_setting_wired_error_get_type ()) -GType nm_setting_wireless_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_WIRELESS_ERROR (nm_setting_wireless_error_get_type ()) -GType nm_setting_wireless_security_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR (nm_setting_wireless_security_error_get_type ()) -GType nm_wep_key_type_get_type (void) G_GNUC_CONST; -#define NM_TYPE_WEP_KEY_TYPE (nm_wep_key_type_get_type ()) -GType nm_setting_vpn_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTING_VPN_ERROR (nm_setting_vpn_error_get_type ()) -GType nm_utils_security_type_get_type (void) G_GNUC_CONST; -#define NM_TYPE_UTILS_SECURITY_TYPE (nm_utils_security_type_get_type ()) -G_END_DECLS - -#endif /* __NM_UTILS_ENUM_TYPES_H__ */ - - - diff --git a/libnm-util/nm-utils-private.h b/libnm-util/nm-utils-private.h index 9d73a939..0e7be21e 100644 --- a/libnm-util/nm-utils-private.h +++ b/libnm-util/nm-utils-private.h @@ -1,10 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * Ray Strode - * Dan Williams - * Tambet Ingo - * +/* * 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 @@ -20,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2008 Red Hat, Inc. + * Copyright 2005 - 2008 Red Hat, Inc. */ #ifndef __NM_UTILS_PRIVATE_H__ @@ -39,32 +34,4 @@ gboolean _nm_utils_gvalue_array_validate (GValueArray *elements, void _nm_value_transforms_register (void); -/***********************************************************/ - -typedef struct NMUtilsPrivateData { - const char * (*nm_setting_ip4_config_get_address_label) (NMSettingIP4Config *setting, - guint32 i); - gboolean (*nm_setting_ip4_config_add_address_with_label) (NMSettingIP4Config *setting, - NMIP4Address *address, - const char *label); -} NMUtilsPrivateData; - -const NMUtilsPrivateData *nm_utils_get_private (void); - -/** - * NM_UTILS_PRIVATE_CALL: - * @call: a call to a private libnm-util function - * - * Used to call private libnm-util functions. Eg, if there was a - * private function called nm_foo_get_bar(), you could call it like: - * - * bar = NM_UTILS_PRIVATE_CALL (nm_foo_get_bar (foo, x, y, z)); - * - * This macro only exists inside the NetworkManager source tree and - * is not part of the public API. - * - * Since: 0.9.10 - */ -#define NM_UTILS_PRIVATE_CALL(call) (nm_utils_get_private ()->call) - #endif diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 0176d9c3..203803f2 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1,11 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * Ray Strode - * Dan Williams - * Tambet Ingo - * +/* * 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 @@ -21,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2013 Red Hat, Inc. + * Copyright 2005 - 2013 Red Hat, Inc. */ #include "config.h" @@ -31,6 +26,10 @@ #include #include #include +#include +#include +#include +#include #include "nm-utils.h" #include "nm-utils-private.h" @@ -38,13 +37,17 @@ #include "nm-dbus-glib-types.h" #include "nm-setting-private.h" #include "crypto.h" +#include "nm-utils-internal.h" + +/* Embed the commit id in the build binary */ +static const char *const __nm_git_sha = STRLEN (NM_GIT_SHA) > 0 ? "NM_GIT_SHA:"NM_GIT_SHA : ""; /** * SECTION:nm-utils * @short_description: Utility functions * @include: nm-utils.h * - * A collection of utility functions for working SSIDs, IP addresses, Wi-Fi + * A collection of utility functions for working with SSIDs, IP addresses, Wi-Fi * access points and devices, among other things. */ @@ -144,7 +147,7 @@ init_lang_to_encodings_hash (void) langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal); while (enc->lang) { g_hash_table_insert (langToEncodings5, (gpointer) enc->lang, - (gpointer) &enc->encodings); + (gpointer) &enc->encodings); enc++; } } @@ -155,7 +158,7 @@ init_lang_to_encodings_hash (void) langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal); while (enc->lang) { g_hash_table_insert (langToEncodings2, (gpointer) enc->lang, - (gpointer) &enc->encodings); + (gpointer) &enc->encodings); enc++; } } @@ -184,8 +187,7 @@ get_encodings_for_lang (const char *lang, init_lang_to_encodings_hash (); tmp_lang = g_strdup (lang); - if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang))) - { + if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang))) { *encoding1 = (char *) encodings->encoding1; *encoding2 = (char *) encodings->encoding2; *encoding3 = (char *) encodings->encoding3; @@ -195,8 +197,7 @@ get_encodings_for_lang (const char *lang, /* Truncate tmp_lang to length of 2 */ if (strlen (tmp_lang) > 2) tmp_lang[2] = '\0'; - if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang))) - { + if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang))) { *encoding1 = (char *) encodings->encoding1; *encoding2 = (char *) encodings->encoding2; *encoding3 = (char *) encodings->encoding3; @@ -209,25 +210,40 @@ get_encodings_for_lang (const char *lang, /* init, deinit for libnm_util */ +static void __attribute__((constructor)) +_check_symbols (void) +{ + GModule *self; + gpointer func; + + self = g_module_open (NULL, 0); + if (g_module_symbol (self, "nm_device_state_get_type", &func)) + g_error ("libnm symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported"); + g_module_close (self); +} + static gboolean initialized = FALSE; /** * nm_utils_init: * @error: location to store error, or %NULL * - * Initializes libnm-util; should be called when starting and program that - * uses libnm-util. Sets up an atexit() handler to ensure de-initialization - * is performed, but calling nm_utils_deinit() to explicitly deinitialize - * libnm-util can also be done. This function can be called more than once. - * + * Initializes libnm-util; should be called when starting any program that + * uses libnm-util. This function can be called more than once. + * * Returns: %TRUE if the initialization was successful, %FALSE on failure. **/ gboolean nm_utils_init (GError **error) { + (void) __nm_git_sha; + if (!initialized) { initialized = TRUE; + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + if (!crypto_init (error)) return FALSE; @@ -239,18 +255,12 @@ nm_utils_init (GError **error) /** * nm_utils_deinit: * - * Frees all resources used internally by libnm-util. This function is called - * from an atexit() handler, set up by nm_utils_init(), but is safe to be called - * more than once. Subsequent calls have no effect until nm_utils_init() is - * called again. + * No-op. Although this function still exists for ABI compatibility reasons, it + * does not have any effect, and does not ever need to be called. **/ void nm_utils_deinit (void) { - if (initialized) { - crypto_deinit (); - initialized = FALSE; - } } /* ssid helpers */ @@ -340,16 +350,16 @@ nm_utils_ssid_to_utf8 (const GByteArray *ssid) gboolean nm_utils_is_empty_ssid (const guint8 * ssid, int len) { - /* Single white space is for Linksys APs */ - if (len == 1 && ssid[0] == ' ') - return TRUE; + /* Single white space is for Linksys APs */ + if (len == 1 && ssid[0] == ' ') + return TRUE; - /* Otherwise, if the entire ssid is 0, we assume it is hidden */ - while (len--) { - if (ssid[len] != '\0') - return FALSE; - } - return TRUE; + /* Otherwise, if the entire ssid is 0, we assume it is hidden */ + while (len--) { + if (ssid[len] != '\0') + return FALSE; + } + return TRUE; } #define ESSID_MAX_SIZE 32 @@ -475,8 +485,8 @@ nm_utils_gvalue_hash_dup (GHashTable *hash) g_return_val_if_fail (hash != NULL, NULL); table = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - value_destroy); + (GDestroyNotify) g_free, + value_destroy); g_hash_table_foreach (hash, value_dup, table); @@ -675,7 +685,7 @@ nm_utils_security_valid (NMUtilsSecurityType type, || ((type == NMU_SEC_LEAP) && !adhoc)) { if (wifi_caps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104)) return TRUE; - else + else return FALSE; } } @@ -894,7 +904,7 @@ nm_utils_wpa_psk_valid (const char *psk) * this serialization is not guaranteed to be stable and the #GArray may be * extended in the future. * - * Returns: (transfer full) (element-type NetworkManager.IP4Address): a newly allocated #GSList of #NMIP4Address objects + * Returns: (transfer full) (element-type NMIP4Address): a newly allocated #GSList of #NMIP4Address objects **/ GSList * nm_utils_ip4_addresses_from_gvalue (const GValue *value) @@ -912,7 +922,7 @@ nm_utils_ip4_addresses_from_gvalue (const GValue *value) g_warning ("Ignoring invalid IP4 address"); continue; } - + addr = nm_ip4_address_new (); nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0)); nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1)); @@ -976,7 +986,7 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) * format of this serialization is not guaranteed to be stable and may be * extended in the future. * - * Returns: (transfer full) (element-type NetworkManager.IP4Route): a newly allocated #GSList of #NMIP4Route objects + * Returns: (transfer full) (element-type NMIP4Route): a newly allocated #GSList of #NMIP4Route objects **/ GSList * nm_utils_ip4_routes_from_gvalue (const GValue *value) @@ -1133,7 +1143,7 @@ nm_utils_ip4_get_default_prefix (guint32 ip) * this serialization is not guaranteed to be stable and the #GValueArray may be * extended in the future. * - * Returns: (transfer full) (element-type NetworkManager.IP6Address): a newly allocated #GSList of #NMIP6Address objects + * Returns: (transfer full) (element-type NMIP6Address): a newly allocated #GSList of #NMIP6Address objects **/ GSList * nm_utils_ip6_addresses_from_gvalue (const GValue *value) @@ -1168,7 +1178,7 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) ba_addr = g_value_get_boxed (tmp); if (ba_addr->len != 16) { g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, ba_addr->len); + __func__, ba_addr->len); continue; } @@ -1176,7 +1186,7 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) prefix = g_value_get_uint (tmp); if (prefix > 128) { g_warning ("%s: ignoring invalid IP6 prefix %d", - __func__, prefix); + __func__, prefix); continue; } @@ -1185,7 +1195,7 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) ba_gw = g_value_get_boxed (tmp); if (ba_gw->len != 16) { g_warning ("%s: ignoring invalid IP6 gateway address of length %d", - __func__, ba_gw->len); + __func__, ba_gw->len); continue; } } @@ -1270,7 +1280,7 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) * into a #GSList of #NMIP6Route objects. The specific format of this serialization * is not guaranteed to be stable and may be extended in the future. * - * Returns: (transfer full) (element-type NetworkManager.IP6Route): a newly allocated #GSList of #NMIP6Route objects + * Returns: (transfer full) (element-type NMIP6Route): a newly allocated #GSList of #NMIP6Route objects **/ GSList * nm_utils_ip6_routes_from_gvalue (const GValue *value) @@ -1298,7 +1308,7 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); if (dest->len != 16) { g_warning ("%s: ignoring invalid IP6 dest address of length %d", - __func__, dest->len); + __func__, dest->len); continue; } @@ -1307,7 +1317,7 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); if (next_hop->len != 16) { g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", - __func__, next_hop->len); + __func__, next_hop->len); continue; } @@ -1334,7 +1344,7 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) * Utility function to convert a #GSList of #NMIP6Route objects into a #GPtrArray of * #GValueArrays of (#GArray of #guchars), #guint32, (#GArray of #guchars), and #guint32 * representing a list of NetworkManager IPv6 routes (which is a tuple of destination, - * prefix, next hop, and metric). The specific format of this serialization is not + * prefix, next hop, and metric). The specific format of this serialization is not * guaranteed to be stable and may be extended in the future. **/ void @@ -1485,9 +1495,11 @@ char * nm_utils_uuid_generate_from_string (const char *s) { GError *error = NULL; - uuid_t *uuid; + uuid_t uuid; char *buf = NULL; + g_return_val_if_fail (s && *s, NULL); + if (!nm_utils_init (&error)) { g_warning ("error initializing crypto: (%d) %s", error ? error->code : 0, @@ -1497,21 +1509,18 @@ nm_utils_uuid_generate_from_string (const char *s) return NULL; } - uuid = g_malloc0 (sizeof (*uuid)); - if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (*uuid), &error)) { + if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid), &error)) { g_warning ("error generating UUID: (%d) %s", error ? error->code : 0, error ? error->message : "unknown"); if (error) g_error_free (error); - goto out; + return NULL; } buf = g_malloc0 (37); - uuid_unparse_lower (*uuid, &buf[0]); + uuid_unparse_lower (uuid, &buf[0]); -out: - g_free (uuid); return buf; } @@ -1721,9 +1730,9 @@ nm_utils_rsa_key_encrypt_aes (const GByteArray *data, * nm_utils_file_is_pkcs12: * @filename: name of the file to test * - * Utility function to find out if the @filename is in PKCS#12 format. + * Utility function to find out if the @filename is in PKCS#12 format. * - * Returns: %TRUE if the file is PKCS#12, %FALSE if it is not + * Returns: %TRUE if the file is PKCS#12, %FALSE if it is not **/ gboolean nm_utils_file_is_pkcs12 (const char *filename) @@ -1731,6 +1740,82 @@ nm_utils_file_is_pkcs12 (const char *filename) return crypto_is_pkcs12_file (filename, NULL); } +/**********************************************************************************************/ + +/** + * nm_utils_file_search_in_paths: + * @progname: the helper program name, like "iptables" + * Must be a non-empty string, without path separator (/). + * @try_first: (allow-none): a custom path to try first before searching. + * It is silently ignored if it is empty or not an absolute path. + * @paths: (allow-none): a %NULL terminated list of search paths. + * Can be empty or %NULL, in which case only @try_first is checked. + * @file_test_flags: the flags passed to g_file_test() when searching + * for @progname. Set it to 0 to skip the g_file_test(). + * @predicate: (scope call): if given, pass the file name to this function + * for additional checks. This check is performed after the check for + * @file_test_flags. You cannot omit both @file_test_flags and @predicate. + * @user_data: (closure): (allow-none): user data for @predicate function. + * @error: on failure, a "not found" error using @error_domain and @error_code + * + * Searches for a @progname file in a list of search @paths. + * + * Returns: (transfer none): the full path to the helper, if found, or %NULL if not found. + * The returned string is not owned by the caller, but later + * invocations of the function might overwrite it. + */ +const char * +nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error) +{ + GString *tmp; + const char *ret; + + g_return_val_if_fail (!error || !*error, NULL); + g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL); + g_return_val_if_fail (file_test_flags || predicate, NULL); + + /* Only consider @try_first if it is a valid, absolute path. This makes + * it simpler to pass in a path from configure checks. */ + if ( try_first + && try_first[0] == '/' + && (file_test_flags == 0 || g_file_test (try_first, file_test_flags)) + && (!predicate || predicate (try_first, user_data))) + return g_intern_string (try_first); + + if (!paths || !*paths) + goto NOT_FOUND; + + tmp = g_string_sized_new (50); + for (; *paths; paths++) { + if (!*paths) + continue; + g_string_append (tmp, *paths); + if (tmp->str[tmp->len - 1] != '/') + g_string_append_c (tmp, '/'); + g_string_append (tmp, progname); + if ( (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags)) + && (!predicate || predicate (tmp->str, user_data))) { + ret = g_intern_string (tmp->str); + g_string_free (tmp, TRUE); + return ret; + } + g_string_set_size (tmp, 0); + } + g_string_free (tmp, TRUE); + +NOT_FOUND: + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname); + return NULL; +} + +/**********************************************************************************************/ + /* Band, channel/frequency stuff for wireless */ struct cf_pair { guint32 chan; @@ -1899,7 +1984,7 @@ nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band) if (channel == pair->chan) return channel; if ((channel < (pair+1)->chan) && (channel > pair->chan)) { - if (direction > 0) + if (direction > 0) return (pair+1)->chan; else return pair->chan; @@ -1942,7 +2027,8 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) /** * nm_utils_hwaddr_len: - * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND * * Returns the length in octets of a hardware address of type @type. * @@ -1963,11 +2049,12 @@ nm_utils_hwaddr_len (int type) * nm_utils_hwaddr_type: * @len: the length of hardware address in bytes * - * Returns the type (either %ARPHRD_ETHER or %ARPHRD_INFINIBAND) of - * the raw address given its length. + * Returns the type (either ARPHRD_ETHER or + * ARPHRD_INFINIBAND) of the raw address given its length. * - * Return value: the type, either %ARPHRD_ETHER or %ARPHRD_INFINIBAND. - * If the length is unexpected, return -1 (unsupported type/length). + * Return value: the type, either ARPHRD_ETHER or + * ARPHRD_INFINIBAND. If the length is unexpected, return -1 + * (unsupported type/length). * * Deprecated: This could not be extended to cover other types, since * there is not a one-to-one mapping between types and lengths. This @@ -1992,7 +2079,8 @@ nm_utils_hwaddr_type (int len) /** * nm_utils_hwaddr_aton: * @asc: the ASCII representation of a hardware address - * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND * @buffer: buffer to store the result into * * Parses @asc and converts it to binary form in @buffer. See @@ -2019,7 +2107,8 @@ nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer) /** * nm_utils_hwaddr_atoba: * @asc: the ASCII representation of a hardware address - * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND * * Parses @asc and converts it to binary form in a #GByteArray. See * nm_utils_hwaddr_aton() if you don't want a #GByteArray. @@ -2051,7 +2140,8 @@ nm_utils_hwaddr_atoba (const char *asc, int type) /** * nm_utils_hwaddr_ntoa: * @addr: a binary hardware address - * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * @type: the type of address; either ARPHRD_ETHER or + * ARPHRD_INFINIBAND * * Converts @addr to textual form. * @@ -2235,8 +2325,7 @@ nm_utils_bin2hexstr (const char *bytes, int len, int final_len) g_return_val_if_fail (final_len < buflen, NULL); result = g_malloc0 (buflen); - for (i = 0; i < len; i++) - { + for (i = 0; i < len; i++) { result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf]; result[2*i+1] = hex_digits[bytes[i] & 0xf]; } @@ -2385,13 +2474,14 @@ static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN]; /** * nm_utils_inet4_ntop: (skip) * @inaddr: the address that should be converted to string. - * @dst: the destination buffer, it must contain at least %INET_ADDRSTRLEN - * or %NM_UTILS_INET_ADDRSTRLEN characters. If set to %NULL, it will return - * a pointer to an internal, static buffer (shared with nm_utils_inet6_ntop()). - * Beware, that the internal buffer will be overwritten with ever new call - * of nm_utils_inet4_ntop() or nm_utils_inet6_ntop() that does not provied it's - * own @dst buffer. Also, using the internal buffer is not thread safe. When - * in doubt, pass your own @dst buffer to avoid these issues. + * @dst: the destination buffer, it must contain at least + * INET_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet6_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * using the internal buffer is not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. * * Wrapper for inet_ntop. * @@ -2410,13 +2500,14 @@ nm_utils_inet4_ntop (in_addr_t inaddr, char *dst) /** * nm_utils_inet6_ntop: (skip) * @in6addr: the address that should be converted to string. - * @dst: the destination buffer, it must contain at least %INET6_ADDRSTRLEN - * or %NM_UTILS_INET_ADDRSTRLEN characters. If set to %NULL, it will return - * a pointer to an internal, static buffer (shared with nm_utils_inet4_ntop()). - * Beware, that the internal buffer will be overwritten with ever new call - * of nm_utils_inet4_ntop() or nm_utils_inet6_ntop() that does not provied it's - * own @dst buffer. Also, using the internal buffer is not thread safe. When - * in doubt, pass your own @dst buffer to avoid these issues. + * @dst: the destination buffer, it must contain at least + * INET6_ADDRSTRLEN or %NM_UTILS_INET_ADDRSTRLEN + * characters. If set to %NULL, it will return a pointer to an internal, static + * buffer (shared with nm_utils_inet4_ntop()). Beware, that the internal + * buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or + * nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also, + * using the internal buffer is not thread safe. When in doubt, pass your own + * @dst buffer to avoid these issues. * * Wrapper for inet_ntop. * @@ -2498,13 +2589,10 @@ nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_typ /***********************************************************/ -/* Unused prototype to make the compiler happy */ -const NMUtilsPrivateData *nm_util_get_private (void); +/* Unused prototypes to make the compiler happy */ +gconstpointer nm_utils_get_private (void); +gconstpointer nm_util_get_private (void); -static const NMUtilsPrivateData data = { - .nm_setting_ip4_config_get_address_label = nm_setting_ip4_config_get_address_label, - .nm_setting_ip4_config_add_address_with_label = nm_setting_ip4_config_add_address_with_label, -}; /** * nm_utils_get_private: @@ -2516,10 +2604,11 @@ static const NMUtilsPrivateData data = { * * Since: 0.9.10 */ -const NMUtilsPrivateData * +gconstpointer nm_utils_get_private (void) { - return &data; + /* We told you not to use it! */ + g_assert_not_reached (); } /** @@ -2531,9 +2620,9 @@ nm_utils_get_private (void) * * Since: 0.9.10 */ -const NMUtilsPrivateData * +gconstpointer nm_util_get_private (void) { - /* Compat function to preserve ABI */ - return nm_utils_get_private (); + /* We told you not to use it! */ + g_assert_not_reached (); } diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index bb8786a1..530fe833 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -1,10 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * Ray Strode - * Dan Williams - * Tambet Ingo - * +/* * 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 @@ -20,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2013 Red Hat, Inc. + * Copyright 2005 - 2013 Red Hat, Inc. */ #ifndef NM_UTILS_H @@ -126,6 +121,16 @@ GByteArray *nm_utils_rsa_key_encrypt_aes (const GByteArray *data, GError **error); gboolean nm_utils_file_is_pkcs12 (const char *filename); +typedef gboolean (*NMUtilsFileSearchInPathsPredicate) (const char *filename, gpointer user_data); + +const char *nm_utils_file_search_in_paths (const char *progname, + const char *try_first, + const char *const *paths, + GFileTest file_test_flags, + NMUtilsFileSearchInPathsPredicate predicate, + gpointer user_data, + GError **error); + guint32 nm_utils_wifi_freq_to_channel (guint32 freq); guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band); guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band); @@ -134,9 +139,8 @@ gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band); /** * NM_UTILS_HWADDR_LEN_MAX: * - * The maximum length of a hardware address of a type known by - * nm_utils_hwaddr_len() or nm_utils_hwaddr_aton(). This can be used - * as the size of the buffer passed to nm_utils_hwaddr_aton(). + * The maximum length of hardware addresses handled by NetworkManager itself, + * nm_utils_hwaddr_len(), and nm_utils_hwaddr_aton(). */ #define NM_UTILS_HWADDR_LEN_MAX 20 /* INFINIBAND_ALEN */ diff --git a/libnm-util/nm-value-transforms.c b/libnm-util/nm-value-transforms.c index f92596dc..00e7e775 100644 --- a/libnm-util/nm-value-transforms.c +++ b/libnm-util/nm-value-transforms.c @@ -1,7 +1,6 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * +/* * 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 @@ -115,7 +114,7 @@ static void _string_array_to_string (const GPtrArray *strings, GValue *dest_value) { GString *printable; - int i; + guint i; printable = g_string_new (NULL); for (i = 0; strings && i < strings->len; i++) { @@ -544,7 +543,7 @@ _nm_value_transforms_register (void) g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, _nm_utils_convert_op_to_string); - g_value_register_transform_func (G_TYPE_STRV, + g_value_register_transform_func (G_TYPE_STRV, DBUS_TYPE_G_LIST_OF_STRING, _nm_utils_convert_strv_to_slist); g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, @@ -554,7 +553,7 @@ _nm_value_transforms_register (void) DBUS_TYPE_G_ARRAY_OF_STRING, _nm_utils_convert_strv_to_ptrarray); g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_string_list_to_string); g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING, G_TYPE_STRING, @@ -563,28 +562,28 @@ _nm_value_transforms_register (void) G_TYPE_STRING, _nm_utils_convert_op_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_uint_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_ip4_addr_route_struct_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_gvalue_hash_to_string); g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_STRING, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_string_hash_to_string); g_value_register_transform_func (DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_STRING, _nm_utils_convert_byte_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_ip6_dns_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_ip6_addr_struct_array_to_string); g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - G_TYPE_STRING, + G_TYPE_STRING, _nm_utils_convert_ip6_route_struct_array_to_string); g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, diff --git a/libnm-util/nm-version.h.in b/libnm-util/nm-version.h.in new file mode 100644 index 00000000..0a33ac29 --- /dev/null +++ b/libnm-util/nm-version.h.in @@ -0,0 +1,123 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_VERSION_H +#define NM_VERSION_H + +/** + * NM_MAJOR_VERSION: + * + * Evaluates to the major version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MAJOR_VERSION (@NM_MAJOR_VERSION@) + +/** + * NM_MINOR_VERSION: + * + * Evaluates to the minor version number of NetworkManager which this source + * is compiled against. + */ +#define NM_MINOR_VERSION (@NM_MINOR_VERSION@) + +/** + * NM_MICRO_VERSION: + * + * Evaluates to the micro version number of NetworkManager which this source + * compiled against. + */ +#define NM_MICRO_VERSION (@NM_MICRO_VERSION@) + +/** + * NM_CHECK_VERSION: + * @major: major version (e.g. 1 for version 1.2.5) + * @minor: minor version (e.g. 2 for version 1.2.5) + * @micro: micro version (e.g. 5 for version 1.2.5) + * + * Returns: %TRUE if the version of the NetworkManager header files + * is the same as or newer than the passed-in version. + */ +#define NM_CHECK_VERSION(major,minor,micro) \ + (NM_MAJOR_VERSION > (major) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION > (minor)) || \ + (NM_MAJOR_VERSION == (major) && NM_MINOR_VERSION == (minor) && NM_MICRO_VERSION >= (micro))) + + +/* Deprecation / Availability macros */ + +#define NM_ENCODE_VERSION(major,minor,micro) ((major) << 16 | (minor) << 8 | (micro)) + +#define NM_VERSION_0_9_8 (NM_ENCODE_VERSION (0, 9, 8)) +#define NM_VERSION_0_9_10 (NM_ENCODE_VERSION (0, 9, 10)) +#define NM_VERSION_1_0 (NM_ENCODE_VERSION (1, 0, 0)) + +#define NM_VERSION_CUR_STABLE NM_VERSION_0_9_10 +#define NM_VERSION_NEXT_STABLE NM_VERSION_1_0 + +#if !defined (NM_VERSION_MIN_REQUIRED) || (NM_VERSION_MIN_REQUIRED == 0) +# undef NM_VERSION_MIN_REQUIRED +# define NM_VERSION_MIN_REQUIRED (NM_VERSION_CUR_STABLE) +#endif + +#if !defined (NM_VERSION_MAX_ALLOWED) || (NM_VERSION_MAX_ALLOWED == 0) +# undef NM_VERSION_MAX_ALLOWED +# define NM_VERSION_MAX_ALLOWED (NM_VERSION_CUR_STABLE) +#endif + +/* sanity checks */ +#if NM_VERSION_MIN_REQUIRED > NM_VERSION_NEXT_STABLE +#error "NM_VERSION_MIN_REQUIRED must be <= NM_VERSION_NEXT_STABLE" +#endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_MIN_REQUIRED +#error "NM_VERSION_MAX_ALLOWED must be >= NM_VERSION_MIN_REQUIRED" +#endif +#if NM_VERSION_MIN_REQUIRED < NM_VERSION_0_9_8 +#error "NM_VERSION_MIN_REQUIRED must be >= NM_VERSION_0_9_8" +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_0_9_10 +# define NM_DEPRECATED_IN_0_9_10 G_DEPRECATED +# define NM_DEPRECATED_IN_0_9_10_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_0_9_10 +# define NM_DEPRECATED_IN_0_9_10_FOR(f) +#endif + +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_0 +# define NM_DEPRECATED_IN_1_0 G_DEPRECATED +# define NM_DEPRECATED_IN_1_0_FOR(f) G_DEPRECATED_FOR(f) +#else +# define NM_DEPRECATED_IN_1_0 +# define NM_DEPRECATED_IN_1_0_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_0_9_10 +# define NM_AVAILABLE_IN_0_9_10 G_UNAVAILABLE(0.9,10) +#else +# define NM_AVAILABLE_IN_0_9_10 +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_0 +# define NM_AVAILABLE_IN_1_0 G_UNAVAILABLE(1,0) +#else +# define NM_AVAILABLE_IN_1_0 +#endif + +#endif /* NM_VERSION_H */ diff --git a/libnm-util/tests/Makefile.am b/libnm-util/tests/Makefile.am index 6d3d225e..690bdbf6 100644 --- a/libnm-util/tests/Makefile.am +++ b/libnm-util/tests/Makefile.am @@ -1,18 +1,16 @@ if ENABLE_TESTS -SUBDIRS=certs - AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-util/tests/certs/\" + -DBUILD_DIR=\"$(abs_builddir)\" \ + -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-core/tests/certs/\" -noinst_PROGRAMS = \ +TESTS = \ test-settings-defaults \ test-crypto \ test-secrets \ @@ -20,6 +18,10 @@ noinst_PROGRAMS = \ test-setting-8021x \ test-setting-dcb +noinst_PROGRAMS = \ + $(TESTS) \ + test-libnm-linking + test_settings_defaults_SOURCES = \ test-settings-defaults.c @@ -52,6 +54,8 @@ test_general_LDADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) +test_general_DEPENDENCIES = test-libnm-linking + test_setting_8021x_SOURCES = \ test-setting-8021x.c @@ -68,66 +72,13 @@ test_setting_dcb_LDADD = \ $(GLIB_LIBS) \ $(DBUS_LIBS) -check-local: test-crypto test-setting-8021x -# Private key and CA certificate in the same file (PEM) - $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test" - -# Private key by itself (PEM) - $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-key-only.pem "test" - -# PKCS#8 private key by itself (PEM) - $(abs_builddir)/test-setting-8021x $(srcdir)/certs/pkcs8-enc-key.pem "1234567890" - -# Private key and CA certificate in the same file (pkcs12) - $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-cert.p12 "test" - -# Normal CA certificate - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.pem - -# Another CA certificate - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_ca_cert.pem - -# Normal CA certificate (DER format) - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.der - -# CA certificate without an ending newline - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/ca-no-ending-newline.pem +test_libnm_linking_SOURCES = \ + test-libnm-linking.c -# Combined user cert and private key - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_key_and_cert.pem - -# Another combined user cert and private key - $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_key_and_cert.pem - -# Private key with 8 bytes of tail padding - $(abs_builddir)/test-crypto --key \ - $(srcdir)/certs/test_key_and_cert.pem \ - "test" \ - $(srcdir)/certs/test-key-only-decrypted.der - -# Private key only (not combined with a cert) - $(abs_builddir)/test-crypto --key \ - $(srcdir)/certs/test-key-only.pem \ - "test" \ - $(srcdir)/certs/test-key-only-decrypted.der - -# Private key with 6 bytes of tail padding - $(abs_builddir)/test-crypto --key $(srcdir)/certs/test2_key_and_cert.pem "12345testing" - -# PKCS#12 file - $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test-cert.p12 "test" - -# Another PKCS#12 file - $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test2-cert.p12 "12345testing" - -# PKCS#8 encrypted private key - $(abs_builddir)/test-crypto --pkcs8 \ - $(srcdir)/certs/pkcs8-enc-key.pem \ - "1234567890" - -# Private key with AES cipher - $(abs_builddir)/test-crypto --key $(srcdir)/certs/test-aes-key.pem "test-aes-password" - -TESTS = test-settings-defaults test-secrets test-general test-setting-dcb +test_libnm_linking_LDADD = \ + $(top_builddir)/libnm/libnm.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) endif diff --git a/libnm-util/tests/Makefile.in b/libnm-util/tests/Makefile.in index de57f25a..9ef02e8c 100644 --- a/libnm-util/tests/Makefile.in +++ b/libnm-util/tests/Makefile.in @@ -78,14 +78,13 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-settings-defaults$(EXEEXT) \ +@ENABLE_TESTS_TRUE@TESTS = test-settings-defaults$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-crypto$(EXEEXT) test-secrets$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-general$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-setting-8021x$(EXEEXT) \ @ENABLE_TESTS_TRUE@ test-setting-dcb$(EXEEXT) -@ENABLE_TESTS_TRUE@TESTS = test-settings-defaults$(EXEEXT) \ -@ENABLE_TESTS_TRUE@ test-secrets$(EXEEXT) test-general$(EXEEXT) \ -@ENABLE_TESTS_TRUE@ test-setting-dcb$(EXEEXT) +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = $(am__EXEEXT_1) \ +@ENABLE_TESTS_TRUE@ test-libnm-linking$(EXEEXT) subdir = libnm-util/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -109,6 +108,11 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +@ENABLE_TESTS_TRUE@am__EXEEXT_1 = test-settings-defaults$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-crypto$(EXEEXT) test-secrets$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-general$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-8021x$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-setting-dcb$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__test_crypto_SOURCES_DIST = test-crypto.c @ENABLE_TESTS_TRUE@am_test_crypto_OBJECTS = test-crypto.$(OBJEXT) @@ -124,7 +128,12 @@ am__v_lt_1 = am__test_general_SOURCES_DIST = test-general.c @ENABLE_TESTS_TRUE@am_test_general_OBJECTS = test-general.$(OBJEXT) test_general_OBJECTS = $(am_test_general_OBJECTS) -@ENABLE_TESTS_TRUE@test_general_DEPENDENCIES = \ +am__test_libnm_linking_SOURCES_DIST = test-libnm-linking.c +@ENABLE_TESTS_TRUE@am_test_libnm_linking_OBJECTS = \ +@ENABLE_TESTS_TRUE@ test-libnm-linking.$(OBJEXT) +test_libnm_linking_OBJECTS = $(am_test_libnm_linking_OBJECTS) +@ENABLE_TESTS_TRUE@test_libnm_linking_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__test_secrets_SOURCES_DIST = test-secrets.c @@ -189,35 +198,21 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(test_crypto_SOURCES) $(test_general_SOURCES) \ - $(test_secrets_SOURCES) $(test_setting_8021x_SOURCES) \ - $(test_setting_dcb_SOURCES) $(test_settings_defaults_SOURCES) + $(test_libnm_linking_SOURCES) $(test_secrets_SOURCES) \ + $(test_setting_8021x_SOURCES) $(test_setting_dcb_SOURCES) \ + $(test_settings_defaults_SOURCES) DIST_SOURCES = $(am__test_crypto_SOURCES_DIST) \ $(am__test_general_SOURCES_DIST) \ + $(am__test_libnm_linking_SOURCES_DIST) \ $(am__test_secrets_SOURCES_DIST) \ $(am__test_setting_8021x_SOURCES_DIST) \ $(am__test_setting_dcb_SOURCES_DIST) \ $(am__test_settings_defaults_SOURCES_DIST) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-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 \ - tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -259,33 +254,7 @@ am__tty_colors = { \ std=''; \ fi; \ } -DIST_SUBDIRS = certs 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@ @@ -295,6 +264,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -418,6 +389,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -437,6 +409,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -463,7 +436,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -542,16 +515,15 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -@ENABLE_TESTS_TRUE@SUBDIRS = certs @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-util/tests/certs/\" +@ENABLE_TESTS_TRUE@ -DBUILD_DIR=\"$(abs_builddir)\" \ +@ENABLE_TESTS_TRUE@ -DTEST_CERT_DIR=\"$(top_srcdir)/libnm-core/tests/certs/\" @ENABLE_TESTS_TRUE@test_settings_defaults_SOURCES = \ @ENABLE_TESTS_TRUE@ test-settings-defaults.c @@ -585,6 +557,7 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) +@ENABLE_TESTS_TRUE@test_general_DEPENDENCIES = test-libnm-linking @ENABLE_TESTS_TRUE@test_setting_8021x_SOURCES = \ @ENABLE_TESTS_TRUE@ test-setting-8021x.c @@ -601,7 +574,16 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) -all: all-recursive +@ENABLE_TESTS_TRUE@test_libnm_linking_SOURCES = \ +@ENABLE_TESTS_TRUE@ test-libnm-linking.c + +@ENABLE_TESTS_TRUE@test_libnm_linking_LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ +@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) + +all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -653,6 +635,10 @@ test-general$(EXEEXT): $(test_general_OBJECTS) $(test_general_DEPENDENCIES) $(EX @rm -f test-general$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_general_OBJECTS) $(test_general_LDADD) $(LIBS) +test-libnm-linking$(EXEEXT): $(test_libnm_linking_OBJECTS) $(test_libnm_linking_DEPENDENCIES) $(EXTRA_test_libnm_linking_DEPENDENCIES) + @rm -f test-libnm-linking$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_libnm_linking_OBJECTS) $(test_libnm_linking_LDADD) $(LIBS) + test-secrets$(EXEEXT): $(test_secrets_OBJECTS) $(test_secrets_DEPENDENCIES) $(EXTRA_test_secrets_DEPENDENCIES) @rm -f test-secrets$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_secrets_OBJECTS) $(test_secrets_LDADD) $(LIBS) @@ -677,6 +663,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-libnm-linking.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-secrets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-8021x.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-setting-dcb.Po@am__quote@ @@ -709,61 +696,14 @@ mostlyclean-libtool: 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. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - 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" - ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive +tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 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; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ @@ -776,7 +716,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-recursive +ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) @@ -789,7 +729,7 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-recursive +cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ @@ -931,47 +871,20 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - 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 -@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local -check: check-recursive + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am 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 +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-recursive +installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ @@ -993,155 +906,94 @@ 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." -clean: clean-recursive +clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am -distclean: distclean-recursive +distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-recursive +dvi: dvi-am dvi-am: -html: html-recursive +html: html-am html-am: -info: info-recursive +info: info-am info-am: install-data-am: -install-dvi: install-dvi-recursive +install-dvi: install-dvi-am install-dvi-am: install-exec-am: -install-html: install-html-recursive +install-html: install-html-am install-html-am: -install-info: install-info-recursive +install-info: install-info-am install-info-am: install-man: -install-pdf: install-pdf-recursive +install-pdf: install-pdf-am install-pdf-am: -install-ps: install-ps-recursive +install-ps: install-ps-am install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-recursive +maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-recursive +mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-recursive +pdf: pdf-am pdf-am: -ps: ps-recursive +ps: ps-am ps-am: uninstall-am: -.MAKE: $(am__recursive_targets) check-am install-am install-strip +.MAKE: check-am install-am install-strip -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-TESTS check-am check-local clean clean-generic \ - clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am 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 \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-crypto test-setting-8021x -# Private key and CA certificate in the same file (PEM) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test" - -# Private key by itself (PEM) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-key-only.pem "test" - -# PKCS#8 private key by itself (PEM) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/pkcs8-enc-key.pem "1234567890" - -# Private key and CA certificate in the same file (pkcs12) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-setting-8021x $(srcdir)/certs/test-cert.p12 "test" - -# Normal CA certificate -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.pem - -# Another CA certificate -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_ca_cert.pem - -# Normal CA certificate (DER format) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_ca_cert.der - -# CA certificate without an ending newline -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/ca-no-ending-newline.pem - -# Combined user cert and private key -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test_key_and_cert.pem - -# Another combined user cert and private key -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --cert $(srcdir)/certs/test2_key_and_cert.pem - -# Private key with 8 bytes of tail padding -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --key \ -@ENABLE_TESTS_TRUE@ $(srcdir)/certs/test_key_and_cert.pem \ -@ENABLE_TESTS_TRUE@ "test" \ -@ENABLE_TESTS_TRUE@ $(srcdir)/certs/test-key-only-decrypted.der - -# Private key only (not combined with a cert) -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --key \ -@ENABLE_TESTS_TRUE@ $(srcdir)/certs/test-key-only.pem \ -@ENABLE_TESTS_TRUE@ "test" \ -@ENABLE_TESTS_TRUE@ $(srcdir)/certs/test-key-only-decrypted.der - -# Private key with 6 bytes of tail padding -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --key $(srcdir)/certs/test2_key_and_cert.pem "12345testing" - -# PKCS#12 file -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test-cert.p12 "test" - -# Another PKCS#12 file -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --p12 $(srcdir)/certs/test2-cert.p12 "12345testing" - -# PKCS#8 encrypted private key -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --pkcs8 \ -@ENABLE_TESTS_TRUE@ $(srcdir)/certs/pkcs8-enc-key.pem \ -@ENABLE_TESTS_TRUE@ "1234567890" - -# Private key with AES cipher -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-crypto --key $(srcdir)/certs/test-aes-key.pem "test-aes-password" - # 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/libnm-util/tests/certs/Makefile.am b/libnm-util/tests/certs/Makefile.am deleted file mode 100644 index 30992517..00000000 --- a/libnm-util/tests/certs/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# test-cert.p12 created with: -# -# openssl pkcs12 -export \ -# -in test_key_and_cert.pem \ -# -inkey test_key_and_cert.pem \ -# -certfile test_ca_cert.pem \ -# -name "test-pkcs12" \ -# -out test-cert.p12 - -EXTRA_DIST = \ - test_ca_cert.pem \ - test_ca_cert.der \ - test_key_and_cert.pem \ - test-cert.p12 \ - test2_ca_cert.pem \ - test2_key_and_cert.pem \ - test2-cert.p12 \ - ca-no-ending-newline.pem \ - test-key-only.pem \ - test-key-only-decrypted.der \ - pkcs8-enc-key.pem \ - pkcs8-noenc-key.pem \ - pkcs8-decrypted.der \ - test-aes-key.pem - diff --git a/libnm-util/tests/certs/Makefile.in b/libnm-util/tests/certs/Makefile.in deleted file mode 100644 index 218cb48d..00000000 --- a/libnm-util/tests/certs/Makefile.in +++ /dev/null @@ -1,597 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 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@ - -# test-cert.p12 created with: -# -# openssl pkcs12 -export \ -# -in test_key_and_cert.pem \ -# -inkey test_key_and_cert.pem \ -# -certfile test_ca_cert.pem \ -# -name "test-pkcs12" \ -# -out test-cert.p12 -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -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 = libnm-util/tests/certs -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -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@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -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@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -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@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -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@ -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_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -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_CXX = @ac_ct_CXX@ -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@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -EXTRA_DIST = \ - test_ca_cert.pem \ - test_ca_cert.der \ - test_key_and_cert.pem \ - test-cert.p12 \ - test2_ca_cert.pem \ - test2_key_and_cert.pem \ - test2-cert.p12 \ - ca-no-ending-newline.pem \ - test-key-only.pem \ - test-key-only-decrypted.der \ - pkcs8-enc-key.pem \ - pkcs8-noenc-key.pem \ - pkcs8-decrypted.der \ - test-aes-key.pem - -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 libnm-util/tests/certs/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu libnm-util/tests/certs/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: - -ctags CTAGS: - -cscope cscopelist: - - -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 -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: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -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: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am 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 \ - tags-am 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/libnm-util/tests/certs/ca-no-ending-newline.pem b/libnm-util/tests/certs/ca-no-ending-newline.pem deleted file mode 100644 index 664e299a..00000000 --- a/libnm-util/tests/certs/ca-no-ending-newline.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD -VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv -bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv -b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH -iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS -r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 -04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r -GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 -3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P -lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ ------END CERTIFICATE----- \ No newline at end of file diff --git a/libnm-util/tests/certs/pkcs8-decrypted.der b/libnm-util/tests/certs/pkcs8-decrypted.der deleted file mode 100644 index 2cbdeb5e..00000000 Binary files a/libnm-util/tests/certs/pkcs8-decrypted.der and /dev/null differ diff --git a/libnm-util/tests/certs/pkcs8-enc-key.pem b/libnm-util/tests/certs/pkcs8-enc-key.pem deleted file mode 100644 index 0d08f2d2..00000000 --- a/libnm-util/tests/certs/pkcs8-enc-key.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIE6TAbBgkqhkiG9w0BBQMwDgQIwiGFT4Jz6RsCAggABIIEyJNMddDYofbhydUp -J3VyrYIjv3LziJ7dkTXE3+mEYRCQrGLgljWBbib2JOLVCFt8melL6Yv1RcoVR7X7 -vrRqyycu0DumI4f5+Bf4wc234JNVhSaLYsw244fFtcnK2Gyn4IaVmWmrNvrwfX/w -SKcVmO30D5C5PCKzv2bou5FmnJLKdDQV1t816cr9T8pTx7MHvBzSZXbh86334BhF -T3zNwo8j2/+Gq2NBWUn+2GTTV8/r26aIwPcFi4QH6I2ghBwFmFHqU3/PoRm6nkmg -CqJj2Dggy+8zE5qg0iId7lrio0OjCH+Qed6NGwIa2lgv/bhuJVP3FOk4gqamJWHi -WMaq9McmS+03q2iokYeSQGbx85x+I90RTFZKhFx4dkerf6oTC/YoL4F++ff0e91v -sOrQsBkgRhrRtFwa9OFCzbsknlixONdd+ITkyX490xz1wcZTDkKtMDRLIPWa2O0b -MEq75jPYThZ5pF1vc5r+rqPafN7SfI+DDmhzJYEQNRoCWA4pH9Gwv0ayKnOgoj4K -TuFhXvcyWzTnVXmcqEFyf3CRrB0Ti+Z61enupC+FCuYV5lGsx9kJaTumTk2UPD02 -9Ap3asDLozdEPSXBG3+oCM2s01/IJlxtR84C97r9rpmWTc9K6DCBScETe9KnIghW -PU7XFogueG5Gwpe+x+IlTDq+qiyUNVX1uMGDcIaCC3VsoWqZrpnGGBhsovwBaXKt -T9fT2nE27Fd6DRWso4fgos6PPx7RVveu17BTMVQeUq9L8GrV4JNrE3a9aoXdbUhc -6gMiyAqxh/HEyciYoXsR9oVNi+VM0y8q3hL5nIcgDrCZr/c9aQ8+fuQBDXRrmrQd -bR2iwNLCBnbmQmM/vM333VhJ4MSOKd3SGw/j41K+Nr3uP5KRZUwV+5yy3ef/hGxU -i9JjCmSUt2bfWRUFlNaf1hCTYaKD0xnVr1SLFU4snIgh2qKawyqVc9EE2f+FcOM5 -0RtwQ3ku6FOk3cy6/xeKpResCHbWDS6nQaIKYyLukV+gm5MJIhOMkj2z4T1eXGUr -Nu/L7Gz+ps7ct0lM8W82n5lzSEa5/l1eNGM0wtQoAwutFEZp7Nx/IBKK87jVttr6 -82UVJeRk7rO2Mpobfw2LbKwga4rsuLrx3UwVDBWdLx7dNIc1rGoAxhsc72+skFgF -Uztwy4Yv1Uiji4T6v+mObPZD/HiIDL0vF02Pz08rNlgB0DgaTKrpql2FutIuQAdf -AciffQIoh9VGERlJoWuunG/UTxg2XRl2m1vCDrgBMInax+PXCv7/5Vh21AQc3fWP -uf4k6JSy46hYni7VTVKn6C/Di9z7oIrGl/jDkDsaenAbToyX9VWr3s7EBwnhTQ/I -OQ9bkWCagHIQlwJbu4M4/VAbiR26NrcR0C3JXBlPlT0qvFFB8gKbJAQEXtwIFS2h -m2fe0k6mQASMwdbJYXZ/wfsg5PPAWsKtny1aMvi0mTPSD5uRhIfEGEuR+AT4UbEW -BkEIE0lgGly4P1SpunKDQQE6m/e7h8Nl4pi8SMSme3YoX5MJwCP/CNkLBDVenAZI -oBrdoVox86SjwnUozVG192lcEAULlk+3ZGt6T9JXLBQl9hpNtyTC6SFh84R+5RoN -AevNl1bDfO+Vci0uJw== ------END ENCRYPTED PRIVATE KEY----- diff --git a/libnm-util/tests/certs/pkcs8-noenc-key.pem b/libnm-util/tests/certs/pkcs8-noenc-key.pem deleted file mode 100644 index f73fb55a..00000000 --- a/libnm-util/tests/certs/pkcs8-noenc-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC80HGgFdlFIL2F -W5rHQ99xOkMrWcZ7an9YurDebAE3M0UwqxM24+5mWbxc8FJ8yYugdMzuI5Nq77IA -DwJpv9ZjMfnKC1VDMj3bmmMdPurfx8pLdLw/jhk3wBaYk6vMvh4z66Yvmb7valGq -Pxh6CRTnekNGI9XA7me4JNBlisl0Qasn9g4pl9PiGJAruEamS4Pk6dSWbfw58bs7 -/Yo5ejyt/Mn1n0Q/r3Gv/lAS0qRvmrW6GE1rMtANMfuGRNlAln21TzNcJzykm+sp -RWptxXEI0NY7u9+RP4M3C1mJxWir7AZDbtinpOZH6vF+92yMzgEYOLK/WZVdSPdW -tROv9xtPAgMBAAECggEBAJAfp+vjYZJjuGaYEuAxjdhW+biYcWn5U7V9484TsSXa -i+DnZOZMO8iCjMaAZuZ7zYmwPlE0dK12w29KBbSEy3eySRIRboa5TgBXq3pCcXRZ -g6/vLlZw+AzXIiha6BODt3g4UwUYnWcQx79lJCDa18sNR1a9ucbn8+Har/wiYT3M -JjTbUT6wR6rKEXchB58ZugYGhOTfugSDQg4U/dwEHPIaJ/wme++JUV5B/tjeGCG3 -F43o2Oos5vjfrDSpUKIYZn+2BdhP434jkwj22wQ2sy0ruU/kQx8nogMTRfP1v4GU -9QmNXj/DB24K388ZxcDmcxBJxrGAJ0MohYFo28DqRBECgYEA6hyKEqe2UbJx/+B6 -8mYgHb+pS2j0M4jPl11q9MMLVxLnDY9xZ85IEyWHQEC0GavPSAois0oiDeGAm32c -j6TFyV3/oPTmZSyV93/agWgnH9Xtc481pbNAb0GMfyotvRRE/+6ti9+Cl7oH9Qmm -ldMk7Hn6sK9t2mUOW8idPjKqlqcCgYEAzne25BryLJoIinbRMZg9KTfxfgUE6EKc -Tk5+9CFQn0/AItQJuKbIUyggYH4psWW5hWq6hFlmMYMR48FKv9ry7pZTB0djaoYD -lN+wSuhzUYWXedkAjvPmekITmf6rbnPfwOZvsr8CGMEUekqJPnPLzsQy+Ea2y/fb -QY4SHe7gExkCgYEAr+1scOJpZvFjK7ckjT3jipd6ADpJsORxo7zG4FImFnQU/6K4 -xRpGHWVJQyaccOIkrW04cGUYPDgmrjJx0ZwwKceijvEaphMgS1JgAHklVY4sl3ea -CAAxPqoSi4lFv94Yj/9rmT4IZD6fNivfbJ20FKUBl37tXX4tkRmr2I64lOcCgYEA -x3eqzrclrmdlxvfBZOuScwbkHP6WXhk0TwbQ6eRhsnfmxP8bITSoJoaGuRJKD2Oa -l0WkSobgDwd0uhecsrvBpTS/pDGY32n3fdWZyNTHzEOHMyWtv23tBcJek5ERaBU0 -X3WBBiw4x1eKBBeMfjR6+xhbsbcHlQiw36V05UxJWMkCgYEAhtcYvrfU4K48IJTU -qp03nvd+dMY3IUTdZNOCh8bswLKyn3aq3MfWF9Vp7kDAI3cfyMpSrAQnmg4nVcn6 -Gf3wakG8bpiSRbJnGN+iLm8JsD+3Vw9KzvKOOQVmpT7xt5Kupx1hWvLHQWvfYgOG -qEtTM8/+LD7W3I7midJNt50CD8A= ------END PRIVATE KEY----- diff --git a/libnm-util/tests/certs/test-aes-key.pem b/libnm-util/tests/certs/test-aes-key.pem deleted file mode 100644 index aab8f463..00000000 --- a/libnm-util/tests/certs/test-aes-key.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,800391B7DD72364B4C2562E0B6AEA000 - -E9dgNCIATOr4CN5c8o6B+8wdqq/I1BLmPmW2qT7YZepoF7E+RUb8ZLjo1VO2XsJw -Ir4EzuH7837zBD9dP5CjlY8cWfR63gZpEWRY5Jub8kzvqiL4UZ0Qr8IHOZxAkKEz -EL1Pn7e+tYt4kA372LPZHWO3vRCgmL1iSJj2/k3avPWAx7NUie4bzGI+00WNv699 -ClKzsJbWB1eiQvYgOr4aVV26oWfa896JkBoGhgZQ6ckqFpsdAos8m46iOSVZrwgq -Y2/d1CvfQod+87c8LRatwAjf+d6YAJJaeMyxjCGuAY6/JyDsorUkM2OlvbTt6WOA -gSPWO8I+Ov6THb4IuPhpIJ30Sl88tc6MlIByW49EWu2G1jPw3L8iqRzZ50Z85dyz -N9yFP91wEwi5F0Zed4iEpg3NVfklEe/VYqCldc5f9fZ84G5V98ZlAdNSqwd/UNBU -iPTflGqVpp1u+J2isOk+Agpj1MCxh2q0RNuvY9KHzOYBScirfbG4DKNbQgS/5Zw7 -3g9YL5Wbo7BczHLiXf/2adu6T8wI1LKRjkeLV9dK1Vw3ZaGy3mB9oFhCgjh9BNHw -wC78CVcUErjtOXdQagiCQn5k5EGeAB97QFROoAFjAmGvq3xCi4EHd9Sk6fcMm7Oi -1fuVR5EXUubF4Llq06lFzQp01s2F73noH49bs3qwdf0n8nrL2XhKB0XCOV/I3K5c -Y3W+YSl361QGjZ/NUcFLIIy+Uro90MmUBNk6af+wGHRJeflpVnK0ATX1PtpNHziz -jiMiIZicjgfVLxl1a5zTl6KUmGWKlZb533adQ0s6q9Qmi5Vk5L5W/GdMjcFtZbM6 -GU7EOkwihMLb3DVsNbm7vb8tUXqe/e5RmXtij8Yb+2a6/M9yaOHa0VjHzdiKHecr -eEYaKQDj7NCWLslNnRRh9GmgXcu2pqBhqRM3HAt3cEaHKKWHTcoWcz11pFwMHNtn -bU9GjGRVc3lCGhVNRiloO0zrKHmcBpDVLw2+ycXXpj/RaBW2fy0xRLKolyla+jEr -zdLzVI61O50ZMycOtPmE7DVZpkokn32hGer1eCOFnsN1lywi4cWLvU0jbQC+CJyw -T9vS8zB3WgOl8rC1AHsfQ4KYajlKleQm89deurQymnt/Qx49SiQA+TpwG9Xvx2TP -3Vc1NwZfM9ZZ1+6xit/rTuS3LhnmhEnGnV5ZyvAdmkCcV2iHjOnLnQWWQn24MHU3 -8Y9D4AdpI5V7Igwr3vH2NZMiw1W2Yc5EJuPAT8nIs5sgOYhXB/QLPJvulvOQhuNC -NPwJ6A505JrVNfHuEaoGUyA+mPeWuLwQo8y8cM6ZdFMG3RrwFNzuYTrc1Z/9GsmA -C0UfHf5dL0r7oWZ1SbpSvsmHYqc8sIypq0ohuLEbpegS/hWP8b2/XDRTjfTiJOrM -4LsUH9PMOJSxDlwS+7e3FdcGfgXfsMgB3aOjQvNpKEolOuv4A5LVFeMrrwtw4Xo1 -EuhstZwyarUTJenDUXzkakhA+8Yw/g2a7RsnANVTkeBuv2PbqFL4zdlsWvcpkz41 -ESxx1siSeU1E9beOII0zSi8vUD0IAevRHaWSlfU2po600IzX1FN97pa4DJV2ycgn ------END RSA PRIVATE KEY----- diff --git a/libnm-util/tests/certs/test-cert.p12 b/libnm-util/tests/certs/test-cert.p12 deleted file mode 100644 index ae4a6830..00000000 Binary files a/libnm-util/tests/certs/test-cert.p12 and /dev/null differ diff --git a/libnm-util/tests/certs/test-key-only-decrypted.der b/libnm-util/tests/certs/test-key-only-decrypted.der deleted file mode 100644 index c8652537..00000000 Binary files a/libnm-util/tests/certs/test-key-only-decrypted.der and /dev/null differ diff --git a/libnm-util/tests/certs/test-key-only.pem b/libnm-util/tests/certs/test-key-only.pem deleted file mode 100644 index 5ef530e9..00000000 --- a/libnm-util/tests/certs/test-key-only.pem +++ /dev/null @@ -1,92 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 - -KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k -r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ -PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj -5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ -amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj -yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR -PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV -xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg -T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab -HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu -Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev -0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB -m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf -rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f -FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S -uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN -vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt -1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh -ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw -l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v -tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm -aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco -0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD -u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj -DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg ------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=test, CN=test/emailAddress=test@test.com - Validity - Not Before: Feb 2 02:22:25 2009 GMT - Not After : Jan 31 02:22:25 2019 GMT - Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: - b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: - d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: - 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: - 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: - 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: - 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: - 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: - 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: - a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: - ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: - cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: - bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: - 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: - 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: - bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: - 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: - 1c:83 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: - 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B - X509v3 Authority Key Identifier: - keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E - DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com - serial:E6:4C:5C:96:26:5E:D6:D0 - - Signature Algorithm: md5WithRSAEncryption - 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: - a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: - e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: - b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: - 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: - ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: - 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: - 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: - e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: - 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: - 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: - 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: - d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: - a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: - 6b:80:38:6e - diff --git a/libnm-util/tests/certs/test2-cert.p12 b/libnm-util/tests/certs/test2-cert.p12 deleted file mode 100644 index 9d5732b0..00000000 Binary files a/libnm-util/tests/certs/test2-cert.p12 and /dev/null differ diff --git a/libnm-util/tests/certs/test2_ca_cert.pem b/libnm-util/tests/certs/test2_ca_cert.pem deleted file mode 100644 index 9a487ca4..00000000 --- a/libnm-util/tests/certs/test2_ca_cert.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEpDCCA4ygAwIBAgIJANDnVhixAO1GMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD -VQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czERMA8GA1UEBxMIV2VzdGZv -cmQxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5n -MRAwDgYDVQQDEwdlYXB0ZXN0MRgwFgYJKoZIhvcNAQkBFglpdEBpdC5jb20wHhcN -MDcxMTA5MTU0ODI1WhcNMTcxMTA2MTU0ODI1WjCBkjELMAkGA1UEBhMCVVMxFjAU -BgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQK -Ew1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMH -ZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAz9zRLSiQyQangDgEliEP8xSpnPJS7GjXzrkZS3sk -gZLuVuwoFeZRq3Hsrq/wGd/vM0KUFNmEaMc+47jnuv0UHQcQ45ZACO7s4/Aflhzj -lkmud/z06hVknIzjXmvS6q2ttCviHsXnfokl+wAxuUhsd+le0xjP9H1jXny4YBuS -jP+yGUz7PL4w1sFFghKIPrlB7m4GkFbQRqvH7FSJg86GWopPwJvNvIzhOZiO1a1D -CAAL4Ru3jxtNFxqWT87C/qUEe/2Qb7jtNyqFcKfwZyZh4u1bo0c8bjErlUZERbWz -zM3hTFypuw+i2v+0h3A8/Xb0hTjcHkUoJgfSdbsOLC5TOwIDAQABo4H6MIH3MB0G -A1UdDgQWBBR+UOaH4e8nrEuMcEXJl7UN5r/wDTCBxwYDVR0jBIG/MIG8gBR+UOaH -4e8nrEuMcEXJl7UN5r/wDaGBmKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgT -DU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQg -SGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVz -dDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tggkA0OdWGLEA7UYwDAYDVR0TBAUw -AwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAmE2jqUymfxN2Vv7bPafoK/EpZwGPxu+z -phRFsgUgWVzidc/GtOxN81LduJ+ow8MEbQIabo4JV/MdKzuPuhAHToAQdeb0LIWa -p59vTIZiVhUt0cMAbQwKcTnfmDnXw9wytvtKgeAXJq0Jd6F+uNXTiR1btlYLZqmF -oSu54cHQlXpUT9z0BnQ8eXd7m0TwfzGQkTHQI7xBa87lZDAkJaTlhv7fR5vPmJYY -0LiXii71ce+4hxdlp7hQfwQ2sb8FPY3RlVboTRD0CvGaWypWhdSZnS790dBXgZOs -NCge6NGuHzW5LtiZE9ppuv8qJysVcIFdAqt8dkx58ksOqFcARCerXw== ------END CERTIFICATE----- diff --git a/libnm-util/tests/certs/test2_key_and_cert.pem b/libnm-util/tests/certs/test2_key_and_cert.pem deleted file mode 100644 index a668596e..00000000 --- a/libnm-util/tests/certs/test2_key_and_cert.pem +++ /dev/null @@ -1,119 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,5FA2D6D6242C26D0 - -dyNdbh115sczbUEhiaGYJ6fazyvJss5thPFEmkP6aftYlvXY6vPtc++xFCCktiSd -qFVEyi6oDyV4iGPmX7pCJ0e+pSI6uFNXKFtxh5/+/wXZcOEMCvfu7w2IrvYF2LHY -qJDljcISSRxeINuYO7TETD5fLLRKj2X9vwwkwVN02b2N5jsrm6Bt//WbatqSB3ln -FHyQhVKkvdl9Hr1XNmEfgGfZSxxDoPu1DjhtZ5ja2LZj64C2CXdI0oq2wcAVvQNn -rZeeg9sinQJkz9rwsNaWqlYw4X+YD2JRSwZuvwkWRydYMwgb1XS/jCxtuFF8NXWP -RBAOAZZUy7onzohsJHVVa05wCKQ4klo+PEfI3vn7BeuHyciCc0eFqGRvz8eFDybH -ZdPbU/3vGp+mOB7gd27TptttTCQQy9uM5CIyovNSYsAIw1Z583Ea4q8eXgzkgD6D -isCqkGXMfPbNXU3myQGDnQwWRi2CqX+rXM8PJUhdewLAlmHRz/aYSuql2BRixJKx -eASzmFBYdAjrvafda5D+xTyJwXEwdq/HlqMK9cY28ZbNrzA2Kor2X23EKC1+VG8k -B67OsfUhW27j4u6aV5JdLf87OtF3mHFRR+Lzs7i7LYvJ8ACE+jiIi7PboZjK5Oiv -JqTK0BwDaeNYjkd6jiJh8It/ReMbLk65J3eldOklN0VMPYiqcQnHvSPC2DD1YAy+ -Rv/JVj6TvzvgEAj+hgH6MAAF6u3ARj6+10DlvhUubkOC5RztLKReu8B+427TuuDb -T03gFpHD6X9IqSiq/QfYFyHFojCVSrv6wDZOcHc1s71kpJ8R14YIVe+DrrZN/0D4 -M631jdNg3JARMZXcXTHrghGIdPmOtrsRyTTRZuGoVup/DW9MRzOzCTMSNCX8T+eq -13HMSNQEO9lMwy0sYeO5c7sjHY4K1ubZuVE1mvXq4JLz3YxXJIvgp8TUvqDnAsK+ -Fv63bDoTg5Tq63XvnaKc7Lawneyg5ZAMzPN3nM0/1EZcn/2ICI5c4Yepc5t63EI5 -KytuXx86Mcx234enj3uMeuM22POQ1SnKOef6dFzK/CE8J8eUEY/aDhX4eBl/s3nd -U4+aaFKYz3HTazePayt2SC6rP/KKMmS14q59bOQA1DiWxCvmA2ypRyP87fV5DstH -I53RD5xp1P38iaO8U/divD0W2dkv748s9DQqYrHPtWALT9esxNU07CgB8Zt070si -7pzjQ8FDCZ8ygDmwWGNSBz1nA90Cpd6gAFDrep7HAtDE4qgNfokycpaJZkXBei/U -tC4tWYRbqDEsEbeBHvQRJzzqWzk9e/P4fQoelM3aryKzKLG5z7KvywVifKMLECQ+ -tIpzoRp06nuTA/O+iLFdkCy3JEWszfvvOwTwtIIV6+3s8TU0k9MmzEe3rGL+QqT/ -Tf+9/dN5LK+LWyc99BfmCOrBuFtQmHyEXkfe6EuFYEwj0B2ZfnLCon6cdRujjK7H -IJslC1B/cBVqG3KCrbBzjeygKfJ5Ijo72oXZJOCFTLeJefZKGGWJCp9nG9h9Wrcf -fEN/mj3wBvTa90/PYFj9NuaBtrvMF8Rn9XDeYPq2JGL8YkNdPuO8A+2Yko8wcvST ------END RSA PRIVATE KEY----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 2 (0x2) - Signature Algorithm: md5WithRSAEncryption - Issuer: C=US, ST=Massachusetts, L=Westford, O=Red Hat, Inc., OU=Engineering, CN=eaptest/emailAddress=it@it.com - Validity - Not Before: Nov 9 15:50:14 2007 GMT - Not After : Nov 6 15:50:14 2017 GMT - Subject: C=US, ST=Massachusetts, O=Red Hat, Inc., OU=Engineering, CN=client/emailAddress=it@it.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:b0:8f:4f:1c:93:d4:43:e7:87:b7:22:33:55:a8: - 35:a1:c4:01:b0:f1:ed:26:23:96:ab:65:c2:c2:54: - db:79:22:03:ad:3f:6f:22:e3:63:3f:f4:21:6d:fa: - 88:c8:8f:1a:ce:55:49:7c:98:33:6a:67:8a:8d:d9: - 34:b0:c3:42:f4:72:a4:45:43:05:72:5d:0c:d3:42: - f8:9c:66:3b:b8:f8:77:ea:f6:b6:94:d7:cc:5d:62: - 34:2a:14:48:0a:bc:65:94:f5:7a:63:98:6c:88:4c: - 25:d8:95:f1:40:3d:00:d2:fb:43:28:fa:02:fb:2c: - 80:b3:e1:33:e7:8c:ce:8a:a0:1b:3d:04:4d:bc:a1: - b6:a2:42:8b:8e:f3:5b:4a:72:34:7d:8d:ba:d8:46: - 22:35:da:5c:f8:dd:fc:6d:9e:59:22:b7:6b:e7:78: - 56:54:9f:4c:d1:e2:4a:23:a3:bc:04:ea:46:6b:70: - 8a:fb:fe:8a:73:ca:36:d5:f3:e9:17:e3:22:d5:b3: - 70:05:e7:f7:37:b7:21:b5:90:53:27:27:ea:36:9b: - 00:ff:35:b0:66:3d:dc:a9:2f:95:d2:21:18:98:4f: - 28:07:09:70:20:a8:b1:82:aa:a5:df:ae:0f:e3:36: - be:68:8c:9e:80:d3:33:d0:f5:84:17:d9:0f:eb:9d: - af:0b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: - 71:AB:BB:91:B7:04:DE:43:35:36:07:8A:35:CA:BE:5C:3E:EB:B1:09 - X509v3 Authority Key Identifier: - keyid:7E:50:E6:87:E1:EF:27:AC:4B:8C:70:45:C9:97:B5:0D:E6:BF:F0:0D - DirName:/C=US/ST=Massachusetts/L=Westford/O=Red Hat, Inc./OU=Engineering/CN=eaptest/emailAddress=it@it.com - serial:D0:E7:56:18:B1:00:ED:46 - - Signature Algorithm: md5WithRSAEncryption - ce:43:6d:f7:f8:4a:66:fd:8a:2c:41:a6:e0:03:0e:60:30:d4: - 41:01:ba:46:ba:81:97:64:68:83:25:9c:e1:2c:03:8b:2d:ca: - 85:cf:bc:fa:ca:22:c4:59:28:23:8f:ff:50:94:60:1c:90:dd: - 75:f4:d4:ea:8c:fa:61:61:08:35:4a:8f:aa:a7:e9:3d:76:e9: - 08:28:55:01:c4:03:42:c7:ad:58:bb:ee:94:f7:09:b3:9a:9b: - 8b:d0:25:95:18:a6:22:d5:2c:fc:b7:bb:91:0c:7c:03:7f:9b: - 85:de:b0:e4:95:a8:73:94:27:0a:11:4e:e3:67:ae:2b:cc:e7: - 51:29:10:23:57:5c:3e:e7:ea:47:e0:f0:8f:5b:a2:9f:26:cf: - 7f:b5:7c:44:b1:7b:83:67:3c:41:ae:c6:66:64:e0:d2:ef:57: - a4:5c:1b:94:11:ce:28:e5:91:51:ef:e1:98:b7:3b:9a:cc:f7: - b9:85:76:eb:a8:2b:15:4a:cc:1a:a3:42:fa:be:1c:ce:b8:eb: - ee:12:d7:2f:e4:a8:cf:eb:2a:8f:78:e8:91:88:fa:c2:98:75: - 6a:4c:92:3f:2e:0d:e1:20:39:36:c6:2c:be:67:30:c3:f3:c3: - 65:81:ac:e3:3c:19:6a:21:ee:ea:f5:22:66:74:b2:07:53:7c: - 9a:0c:24:a6 ------BEGIN CERTIFICATE----- -MIIEtDCCA5ygAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCVVMx -FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAPBgNVBAcTCFdlc3Rmb3JkMRYwFAYD -VQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEQMA4GA1UE -AxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJaXRAaXQuY29tMB4XDTA3MTEwOTE1 -NTAxNFoXDTE3MTEwNjE1NTAxNFowfjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1h -c3NhY2h1c2V0dHMxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xFDASBgNVBAsTC0Vu -Z2luZWVyaW5nMQ8wDQYDVQQDEwZjbGllbnQxGDAWBgkqhkiG9w0BCQEWCWl0QGl0 -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCPTxyT1EPnh7ci -M1WoNaHEAbDx7SYjlqtlwsJU23kiA60/byLjYz/0IW36iMiPGs5VSXyYM2pnio3Z -NLDDQvRypEVDBXJdDNNC+JxmO7j4d+r2tpTXzF1iNCoUSAq8ZZT1emOYbIhMJdiV -8UA9ANL7Qyj6AvssgLPhM+eMzoqgGz0ETbyhtqJCi47zW0pyNH2NuthGIjXaXPjd -/G2eWSK3a+d4VlSfTNHiSiOjvATqRmtwivv+inPKNtXz6RfjItWzcAXn9ze3IbWQ -Uycn6jabAP81sGY93KkvldIhGJhPKAcJcCCosYKqpd+uD+M2vmiMnoDTM9D1hBfZ -D+udrwsCAwEAAaOCASYwggEiMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w -ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRxq7uRtwTeQzU2 -B4o1yr5cPuuxCTCBxwYDVR0jBIG/MIG8gBR+UOaH4e8nrEuMcEXJl7UN5r/wDaGB -mKSBlTCBkjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxETAP -BgNVBAcTCFdlc3Rmb3JkMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMRQwEgYDVQQL -EwtFbmdpbmVlcmluZzEQMA4GA1UEAxMHZWFwdGVzdDEYMBYGCSqGSIb3DQEJARYJ -aXRAaXQuY29tggkA0OdWGLEA7UYwDQYJKoZIhvcNAQEEBQADggEBAM5Dbff4Smb9 -iixBpuADDmAw1EEBuka6gZdkaIMlnOEsA4styoXPvPrKIsRZKCOP/1CUYByQ3XX0 -1OqM+mFhCDVKj6qn6T126QgoVQHEA0LHrVi77pT3CbOam4vQJZUYpiLVLPy3u5EM -fAN/m4XesOSVqHOUJwoRTuNnrivM51EpECNXXD7n6kfg8I9bop8mz3+1fESxe4Nn -PEGuxmZk4NLvV6RcG5QRzijlkVHv4Zi3O5rM97mFduuoKxVKzBqjQvq+HM646+4S -1y/kqM/rKo946JGI+sKYdWpMkj8uDeEgOTbGLL5nMMPzw2WBrOM8GWoh7ur1ImZ0 -sgdTfJoMJKY= ------END CERTIFICATE----- diff --git a/libnm-util/tests/certs/test_ca_cert.der b/libnm-util/tests/certs/test_ca_cert.der deleted file mode 100644 index e844f65b..00000000 Binary files a/libnm-util/tests/certs/test_ca_cert.der and /dev/null differ diff --git a/libnm-util/tests/certs/test_ca_cert.pem b/libnm-util/tests/certs/test_ca_cert.pem deleted file mode 100644 index faa3fc29..00000000 --- a/libnm-util/tests/certs/test_ca_cert.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEhjCCA26gAwIBAgIJAOZMXJYmXtbQMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD -VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw -FQYDVQQKEw5NeSBDb21wYW55IEx0ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxME -dGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAyMDIwMjIx -NTJaFw0xOTAxMzEwMjIxNTJaMIGIMQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVy -a3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0 -ZDENMAsGA1UECxMEdGVzdDENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3DQEJARYN -dGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANZz -iHfFR6Gqdz5Gq1elSaf7J2tznfialPyMkRoqngSItrM3JWlkfBu3ZIpGSYG8+Z8H -JjaKh/zkCCH73HcjADCocm/XtgxlOlccDtBvfDqifb2dBikcmcfh0tX0o4JU9L+z -WP7sVcUkJG7C5811lA5pAsLVooJxrZnrta6XstGvFgTSxI2Y4Jowf0syM5b/AHIQ -+htsVhSyj1DWM9day3QsEMZl55SCxCLTB6ZIJLF6NmTYwdnzWWTQf4k7kcptZJU8 -Fqv60b/ATvvUf7S+ZMGLopFIIlmc1Kkn7VTseIKy4ycYuDpyimQy3Yw4flC00vhl -hTijH+5dlVOUFrRh0bsCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUUjMuImZ5guVBLo07 -suXM+r6ZM44wgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6ZM46hgY6k -gYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcT -B05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQLEwR0ZXN0 -MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA -5kxcliZe1tAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAZsWzGp9D -10NWf8ts3A9mhcEb8oDgKNpCOZF9gqr2usZygJjY9MX2n0n81T8XaWDk1wZLlcDW -hzIalCY8rpE57Dj3MEmdCmYr3BrAy6GVlc/MO7ffTHxogl9ouScSYo8ETTtNMKCg -zwkDnXjGzmb1e59DIXMVHBBbTmJXJbM8XP9A2azJkVUyE2fSdWksXMP0XklGbW2p -DksJ+8G1IWkyRhnINV5GZLLNAT5gBA6sUv/iqQKwk8r2dsweMPtLoLWZPAaZErYh -sthGy00Q0GJkmkJpQl8QIlPq5vylNcMUhvc8tmzwk+rDVUj3jTJWqFwMtnHAaNyC -FXl9ynWpe5J28w== ------END CERTIFICATE----- diff --git a/libnm-util/tests/certs/test_key_and_cert.pem b/libnm-util/tests/certs/test_key_and_cert.pem deleted file mode 100644 index c00495d0..00000000 --- a/libnm-util/tests/certs/test_key_and_cert.pem +++ /dev/null @@ -1,119 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,B29FCA6ECB7C0C48 - -KuRV4sEVQkY0r0E+E81Se2qpm54HeboUMIJcMVqAt/HIeYwpjEzmXHUywXgayA5k -r5Uvru95vymFz80q/rl6i4Mt3ckEQ3/VHmBI4pPj/JeRbiDhqTyLqpB5zMgbuti+ -PsEemlbiaCMZFdJk8rJBWADTkirGbXs5ciLwTJyrJXhkBVTqoHtphSWMELxcrnQj -5bAXZ+rnApWA7LR3yCY1UE0Nj39Yu8lkzDJtbsSXPJVO//OQiGuQRcY6roAUzeS/ -amLdIYqoZm3OF83Ro88XZCIDCG6XjgKoqojtekClVIytB6mHWk+IHhI7DgU/pDBj -yOskzVRMja9ECnqaVX+bmlmJGZBgcd7+XiebCXNY9IAx/ZQDMbDJDoJusvH6npJR -PBgag8QBSzwpFyEP/1LrlyVyggZcGuXDWfUiM2rt2UvLm8QYeT5WGfUI+QwW6JRV -xEz2QwRiPsmj0uK2fXLKHbY0Pv79IMLqgesCAUbndWsi94kjAhpJGa/WfKVb8Dpg -T+mVa2OT0pgewPWJ3h5f47ag27WDJthsIUHAvNZ03uM23DIqDh6o03/B3/4r1Uab -HzsLWhUOzbLihO08qcPk/JqtDVCv579mpgvy7bL2ZsZUzefnmg+ah+1bhLguryZu -Zrt1hTu5WTz27UbYwWNtkxWnWcM9sSF9y+KVwumYhIUGTvg3Jds/jmp/Z5ad8tev -0RQuWmqnXVD51Y92tOXobJH7JwGbQ4GeRNG/UX7DS9Lvb6rPgmmxvGbXMcjEMapB -m5DLjCD7Lz4++sfzhCic3/nL8e8fjoYZmCbL/SpYjGjTrfoNaGYaT0De8MxCSjPf -rNT+ldWFD0oAOTmT0uqOFkeIx3vxczSQUyRfzGOLqtb9mAXk8lvdb8Myb5atfe8f -FNBL5ocz6Szv2AmKmjZE5P6NKSllyryCYl+H2QU0e3OyY8S9aG2aG8fqeVKaA01S -uOOjsK6IKMpkit+VFDP7RWvS8p1FTwTVRdbMZzASW8+D98OHsTlOENtQuuFyvNaN -vPHrbHltTkwDlYVab9UpFr/ZRW3cNJrmcl0hyeCJxk5u8B9UwW6yZmd24hxda2xt -1QjnxfWlX0i5KTmfWFyPmRYt1WH9rdVaH6wqRbGNbMRT7Lez0E/2+LXjFiiEe0Vh -ZuryhyhUXpHY8yyHxFY92XT504Z3wPUaJ1tQxGhdziZ7HcqFT8f4oTNJdBNtzqNw -l63gSTaKUkSB14CBOyR84cqpgSMwZvWZb3RQFYY4GSALWwhnn6PWeRhjWAXPms2v -tRmfEyDUCyPxDarezvS9kUir3XbvnCkoJOrK/lw4a8ygGBCBqRKOdI0SRUf1Nnjm -aZBrKrXHv5vP66fyC7cGMTq35+iiHbE//rRDGPrf9vpmw3ki3FlDMyAXOC5yWDco -0n+cNDyHJDdIW3+3nfZvSgPPMwmTdfNO90X3YczSmMTGjnIuhQMf7FMFmMZOSrqD -u234vYCjIIlph3aVpbzjOqKg3d4nuP9oouyAgRAr+vShgHRmq0jvsAiGH3Q6RqEj -DvkM1NgoloMy5RhKF4hIeaQM/UlgoXrcEx0RGCJHykQcQmVa5cf5EwjrO7b+w2Lg ------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=test, CN=test/emailAddress=test@test.com - Validity - Not Before: Feb 2 02:22:25 2009 GMT - Not After : Jan 31 02:22:25 2019 GMT - Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=test-client, CN=test-client/emailAddress=test-client@test.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (2048 bit) - Modulus (2048 bit): - 00:ce:d2:e9:fb:f4:a4:ce:66:87:cc:8b:2d:d2:c3: - b8:fa:be:ea:53:08:95:9e:27:4a:04:78:31:a1:36: - d2:e5:42:f5:76:f7:24:71:b8:d3:10:fd:b7:57:86: - 68:29:02:1b:e9:93:2b:af:c0:7e:3d:58:16:34:10: - 25:85:7e:28:2d:42:fc:34:7f:d6:4f:0a:e7:b6:b9: - 40:51:c8:e5:89:60:cd:73:51:63:67:e1:59:36:31: - 5e:d0:87:4b:5d:97:8a:42:22:d3:42:f2:83:62:79: - 84:45:5b:d8:20:97:e2:d1:34:23:5e:ec:bf:8a:41: - 7c:ad:80:50:f3:9b:1c:51:5d:e4:29:1c:c1:c6:7c: - a1:00:70:0f:f6:79:77:03:22:f5:4b:ab:76:ca:20: - ab:e1:4e:53:6c:86:68:e9:d6:0f:6e:95:4b:b5:b5: - cf:d3:6c:d4:73:db:c0:3d:1d:20:20:72:ab:3e:25: - bb:3f:cd:5f:2d:77:fd:d7:0b:a8:eb:0c:73:c0:3f: - 74:27:17:56:cf:31:9a:a9:ed:c1:39:27:c7:aa:e9: - 77:48:f4:6d:56:89:35:5c:79:5b:f6:2f:8c:9f:93: - bc:13:1c:d0:74:5f:30:1b:15:43:71:8e:ff:1a:df: - 65:65:69:c2:8a:5a:ab:04:4a:80:de:20:29:8d:48: - 1c:83 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: - 34:E9:5C:D8:FC:C7:AF:F7:5D:F4:13:D3:82:1A:CD:52:0F:4A:BB:0B - X509v3 Authority Key Identifier: - keyid:52:33:2E:22:66:79:82:E5:41:2E:8D:3B:B2:E5:CC:FA:BE:99:33:8E - DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=test/CN=test/emailAddress=test@test.com - serial:E6:4C:5C:96:26:5E:D6:D0 - - Signature Algorithm: md5WithRSAEncryption - 88:c4:dd:c5:4a:a6:8e:1f:36:62:80:31:6b:2b:85:34:0d:6c: - a7:dc:e1:5a:3c:dd:74:57:db:59:be:8b:f2:79:40:2d:bd:9b: - e1:ab:0e:03:75:20:75:2f:ea:97:f9:d4:7e:15:75:c2:82:f5: - b1:37:e4:8b:24:d4:ef:02:3b:19:6a:56:bb:9f:c3:a5:b4:c4: - 39:a0:64:96:5b:c3:a8:19:74:ec:0b:cf:33:df:f3:12:f3:e2: - ab:1d:7d:de:21:64:cd:b1:a0:6f:7a:77:84:d4:62:8a:50:e6: - 76:5d:af:3a:ef:1a:87:0e:1a:38:c4:f9:0d:2f:14:e0:20:32: - 4c:2e:70:d2:71:82:d5:e5:c9:13:2c:4e:b4:c8:63:65:1d:48: - e8:c3:56:6d:88:84:57:65:13:1e:42:48:b4:03:25:71:4e:12: - 9d:1a:88:65:d5:71:21:3b:0e:be:37:1c:f0:88:6b:45:0c:0e: - 6c:e5:60:cb:86:bf:bf:40:30:c4:cf:94:f8:1c:60:d4:1b:df: - 88:02:7a:45:7e:d1:c6:f3:07:b9:b1:8f:2a:55:2f:be:77:9f: - d1:46:64:05:b7:67:c5:b2:ac:8c:42:8f:6a:51:a4:0d:2b:16: - a4:d6:39:a5:f8:25:ed:68:25:13:b5:19:ac:6c:e9:ec:ee:03: - 6b:80:38:6e ------BEGIN CERTIFICATE----- -MIIErjCCA5agAwIBAgIBATANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCVVMx -EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO -TXkgQ29tcGFueSBMdGQxDTALBgNVBAsTBHRlc3QxDTALBgNVBAMTBHRlc3QxHDAa -BgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMjAyMDIyMjI1WhcNMTkw -MTMxMDIyMjI1WjCBizELMAkGA1UEBhMCVVMxEjAQBgNVBAgTCUJlcmtzaGlyZTEX -MBUGA1UEChMOTXkgQ29tcGFueSBMdGQxFDASBgNVBAsTC3Rlc3QtY2xpZW50MRQw -EgYDVQQDEwt0ZXN0LWNsaWVudDEjMCEGCSqGSIb3DQEJARYUdGVzdC1jbGllbnRA -dGVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDO0un79KTO -ZofMiy3Sw7j6vupTCJWeJ0oEeDGhNtLlQvV29yRxuNMQ/bdXhmgpAhvpkyuvwH49 -WBY0ECWFfigtQvw0f9ZPCue2uUBRyOWJYM1zUWNn4Vk2MV7Qh0tdl4pCItNC8oNi -eYRFW9ggl+LRNCNe7L+KQXytgFDzmxxRXeQpHMHGfKEAcA/2eXcDIvVLq3bKIKvh -TlNshmjp1g9ulUu1tc/TbNRz28A9HSAgcqs+Jbs/zV8td/3XC6jrDHPAP3QnF1bP -MZqp7cE5J8eq6XdI9G1WiTVceVv2L4yfk7wTHNB0XzAbFUNxjv8a32VlacKKWqsE -SoDeICmNSByDAgMBAAGjggEcMIIBGDAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf -Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNOlc2PzH -r/dd9BPTghrNUg9Kuwswgb0GA1UdIwSBtTCBsoAUUjMuImZ5guVBLo07suXM+r6Z -M46hgY6kgYswgYgxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO -BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQ0wCwYDVQQL -EwR0ZXN0MQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qu -Y29tggkA5kxcliZe1tAwDQYJKoZIhvcNAQEEBQADggEBAIjE3cVKpo4fNmKAMWsr -hTQNbKfc4Vo83XRX21m+i/J5QC29m+GrDgN1IHUv6pf51H4VdcKC9bE35Isk1O8C -OxlqVrufw6W0xDmgZJZbw6gZdOwLzzPf8xLz4qsdfd4hZM2xoG96d4TUYopQ5nZd -rzrvGocOGjjE+Q0vFOAgMkwucNJxgtXlyRMsTrTIY2UdSOjDVm2IhFdlEx5CSLQD -JXFOEp0aiGXVcSE7Dr43HPCIa0UMDmzlYMuGv79AMMTPlPgcYNQb34gCekV+0cbz -B7mxjypVL753n9FGZAW3Z8WyrIxCj2pRpA0rFqTWOaX4Je1oJRO1Gaxs6ezuA2uA -OG4= ------END CERTIFICATE----- diff --git a/libnm-util/tests/test-crypto.c b/libnm-util/tests/test-crypto.c index c11b6392..4bf2b3be 100644 --- a/libnm-util/tests/test-crypto.c +++ b/libnm-util/tests/test-crypto.c @@ -18,9 +18,11 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2011 Red Hat, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -92,18 +94,21 @@ out: #endif static void -test_load_cert (const char *path, const char *desc) +test_cert (gconstpointer test_data) { + char *path; GByteArray *array; NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN; GError *error = NULL; + path = g_build_filename (TEST_CERT_DIR, (const char *) test_data, NULL); + array = crypto_load_and_verify_certificate (path, &format, &error); - ASSERT (array != NULL, desc, + ASSERT (array != NULL, "cert", "couldn't read certificate file '%s': %d %s", path, error->code, error->message); - ASSERT (format == NM_CRYPTO_FILE_FORMAT_X509, desc, + ASSERT (format == NM_CRYPTO_FILE_FORMAT_X509, "cert", "%s: unexpected certificate format (expected %d, got %d)", path, NM_CRYPTO_FILE_FORMAT_X509, format); @@ -275,7 +280,7 @@ is_cipher_aes (const char *path) } g_free (contents); - return is_aes; + return is_aes; } static void @@ -330,55 +335,132 @@ test_encrypt_private_key (const char *path, g_byte_array_free (array, TRUE); } -int main (int argc, char **argv) +static void +test_key (gconstpointer test_data) +{ + char **parts, *path, *password, *decrypted_path; + int len; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + len = g_strv_length (parts); + ASSERT (len == 2 || len == 3, "test-crypto", + "wrong number of arguments (, , [])"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + decrypted_path = parts[2] ? g_build_filename (TEST_CERT_DIR, parts[2], NULL) : NULL; + + test_is_pkcs12 (path, TRUE, "not-pkcs12"); + test_load_private_key (path, password, decrypted_path, FALSE, "private-key"); + test_load_private_key (path, "blahblahblah", NULL, TRUE, "private-key-bad-password"); + test_load_private_key (path, NULL, NULL, TRUE, "private-key-no-password"); + test_encrypt_private_key (path, password, "private-key-rencrypt"); + + g_free (path); + g_free (decrypted_path); + g_strfreev (parts); +} + +static void +test_pkcs12 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + ASSERT (g_strv_length (parts) == 2, "test-crypto", + "wrong number of arguments (, )"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, FALSE, "is-pkcs12"); + test_load_pkcs12 (path, password, FALSE, "pkcs12-private-key"); + test_load_pkcs12 (path, "blahblahblah", TRUE, "pkcs12-private-key-bad-password"); + test_load_pkcs12_no_password (path, "pkcs12-private-key-no-password"); + + g_free (path); + g_strfreev (parts); +} + +static void +test_pkcs8 (gconstpointer test_data) +{ + char **parts, *path, *password; + + parts = g_strsplit ((const char *) test_data, ", ", -1); + ASSERT (g_strv_length (parts) == 2, "test-crypto", + "wrong number of arguments (, )"); + + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; + + test_is_pkcs12 (path, TRUE, "not-pkcs12"); + test_load_pkcs8 (path, password, FALSE, "pkcs8-private-key"); + /* Until gnutls and NSS grow support for all the ciphers that openssl + * can use with PKCS#8, we can't actually verify the password. So we + * expect a bad password to work for the time being. + */ + test_load_pkcs8 (path, "blahblahblah", FALSE, "pkcs8-private-key-bad-password"); + + g_free (path); + g_strfreev (parts); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) { GError *error = NULL; - char *progname; - ASSERT (argc > 2, "test-crypto", - "wrong number of arguments (expected at least an operation and an object)"); + nmtst_init (&argc, &argv, TRUE); if (!crypto_init (&error)) FAIL ("crypto-init", "failed to initialize crypto: %s", error->message); - if (!strcmp (argv[1], "--cert")) - test_load_cert (argv[2], "cert"); - else if (!strcmp (argv[1], "--key")) { - const char *decrypted_path = (argc == 5) ? argv[4] : NULL; - - ASSERT (argc == 4 || argc == 5, "test-crypto", - "wrong number of arguments (--key [])"); - - test_is_pkcs12 (argv[2], TRUE, "not-pkcs12"); - test_load_private_key (argv[2], argv[3], decrypted_path, FALSE, "private-key"); - test_load_private_key (argv[2], "blahblahblah", NULL, TRUE, "private-key-bad-password"); - test_load_private_key (argv[2], NULL, NULL, TRUE, "private-key-no-password"); - test_encrypt_private_key (argv[2], argv[3], "private-key-rencrypt"); - } else if (!strcmp (argv[1], "--p12")) { - test_is_pkcs12 (argv[2], FALSE, "is-pkcs12"); - test_load_pkcs12 (argv[2], argv[3], FALSE, "pkcs12-private-key"); - test_load_pkcs12 (argv[2], "blahblahblah", TRUE, "pkcs12-private-key-bad-password"); - test_load_pkcs12_no_password (argv[2], "pkcs12-private-key-no-password"); - } else if (!strcmp (argv[1], "--pkcs8")) { - ASSERT (argc == 4, "test-crypto", - "wrong number of arguments (--pkcs8 )"); - - test_is_pkcs12 (argv[2], TRUE, "not-pkcs12"); - test_load_pkcs8 (argv[2], argv[3], FALSE, "pkcs8-private-key"); - /* Until gnutls and NSS grow support for all the ciphers that openssl - * can use with PKCS#8, we can't actually verify the password. So we - * expect a bad password to work for the time being. - */ - test_load_pkcs8 (argv[2], "blahblahblah", FALSE, "pkcs8-private-key-bad-password"); - } else { - ASSERT (argc > 2, "test-crypto", "unknown test type (not --cert, --key, or --p12)"); - } - - crypto_deinit (); - - progname = g_path_get_basename (argv[0]); - fprintf (stdout, "%s: SUCCESS\n", progname); - g_free (progname); - return 0; + g_test_add_data_func ("/libnm/crypto/cert/pem", + "test_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-2", + "test2_ca_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/der", + "test_ca_cert.der", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-no-ending-newline", + "ca-no-ending-newline.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined", + "test_key_and_cert.pem", + test_cert); + g_test_add_data_func ("/libnm/crypto/cert/pem-combined-2", + "test2_key_and_cert.pem", + test_cert); + + g_test_add_data_func ("/libnm/crypto/key/padding-6", + "test_key_and_cert.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/key-only", + "test-key-only.pem, test, test-key-only-decrypted.der", + test_key); + g_test_add_data_func ("/libnm/crypto/key/padding-8", + "test2_key_and_cert.pem, 12345testing", + test_key); + g_test_add_data_func ("/libnm/crypto/key/aes", + "test-aes-key.pem, test-aes-password", + test_key); + + g_test_add_data_func ("/libnm/crypto/PKCS#12/1", + "test-cert.p12, test", + test_pkcs12); + g_test_add_data_func ("/libnm/crypto/PKCS#12/2", + "test2-cert.p12, 12345testing", + test_pkcs12); + + g_test_add_data_func ("/libnm/crypto/PKCS#8", + "pkcs8-enc-key.pem, 1234567890", + test_pkcs8); + + return g_test_run (); } diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 97625605..f748fcf5 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -15,15 +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) 2008 - 2011 Red Hat, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. * */ +#include "config.h" + #include #include #include #include #include +#include +#include #include @@ -41,7 +45,6 @@ #include "nm-setting-vlan.h" #include "nm-setting-bond.h" #include "nm-utils.h" -#include "nm-utils-private.h" #include "nm-dbus-glib-types.h" #include "nm-test-utils.h" @@ -307,156 +310,6 @@ test_setting_vpn_modify_during_foreach (void) g_object_unref (s_vpn); } -static void -test_setting_ip4_config_labels (void) -{ - NMSettingIP4Config *s_ip4; - NMIP4Address *addr; - const char *label; - GPtrArray *addrs; - GSList *labels; - GError *error = NULL; - - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NULL); - - /* addr 1 */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, 0x01010101); - nm_ip4_address_set_prefix (addr, 24); - - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)); - g_assert_cmpstr (label, ==, NULL); - - /* addr 2 */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, 0x02020202); - nm_ip4_address_set_prefix (addr, 24); - - NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, "eth0:1")); - nm_ip4_address_unref (addr); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1)); - g_assert_cmpstr (label, ==, "eth0:1"); - - /* addr 3 */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, 0x03030303); - nm_ip4_address_set_prefix (addr, 24); - - NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, NULL)); - nm_ip4_address_unref (addr); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 2)); - g_assert_cmpstr (label, ==, NULL); - - /* Remove addr 1 and re-verify remaining addresses */ - nm_setting_ip4_config_remove_address (s_ip4, 0); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - - addr = nm_setting_ip4_config_get_address (s_ip4, 0); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)); - g_assert_cmpstr (label, ==, "eth0:1"); - - addr = nm_setting_ip4_config_get_address (s_ip4, 1); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1)); - g_assert_cmpstr (label, ==, NULL); - - - /* Test explicit property assignment */ - g_object_get (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_ADDRESSES, &addrs, - "address-labels", &labels, - NULL); - - nm_setting_ip4_config_clear_addresses (s_ip4); - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 0); - - /* Setting addrs but not labels will result in empty labels */ - g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_ADDRESSES, addrs, - NULL); - g_boxed_free (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, addrs); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 2); - - addr = nm_setting_ip4_config_get_address (s_ip4, 0); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)); - g_assert_cmpstr (label, ==, NULL); - - addr = nm_setting_ip4_config_get_address (s_ip4, 1); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1)); - g_assert_cmpstr (label, ==, NULL); - - /* Setting labels now will leave addresses untouched */ - g_object_set (G_OBJECT (s_ip4), - "address-labels", labels, - NULL); - g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, labels); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 2); - - addr = nm_setting_ip4_config_get_address (s_ip4, 0); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x02020202); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)); - g_assert_cmpstr (label, ==, "eth0:1"); - - addr = nm_setting_ip4_config_get_address (s_ip4, 1); - g_assert_cmpint (nm_ip4_address_get_address (addr), ==, 0x03030303); - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 1)); - g_assert_cmpstr (label, ==, NULL); - - /* Setting labels to a value that's too short or too long will result in - * the setting not verifying. - */ - labels = g_slist_append (NULL, "eth0:2"); - g_object_set (G_OBJECT (s_ip4), - "address-labels", labels, - NULL); - - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_error (error, NM_SETTING_IP4_CONFIG_ERROR, NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY); - g_assert (g_str_has_prefix (error->message, "ipv4.address-labels:")); - g_clear_error (&error); - - labels = g_slist_append (labels, "eth0:3"); - g_object_set (G_OBJECT (s_ip4), - "address-labels", labels, - NULL); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_no_error (error); - - labels = g_slist_append (labels, "eth0:4"); - g_object_set (G_OBJECT (s_ip4), - "address-labels", labels, - NULL); - nm_setting_verify (NM_SETTING (s_ip4), NULL, &error); - g_assert_error (error, NM_SETTING_IP4_CONFIG_ERROR, NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY); - g_assert (g_str_has_prefix (error->message, "ipv4.address-labels:")); - g_clear_error (&error); - - - g_object_unref (s_ip4); -} - #define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) #define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS)) @@ -893,7 +746,7 @@ new_connection_hash (char **out_uuid, } static void -test_connection_replace_settings () +test_connection_replace_settings (void) { NMConnection *connection; GHashTable *new_settings; @@ -932,7 +785,7 @@ test_connection_replace_settings () } static void -test_connection_replace_settings_from_connection () +test_connection_replace_settings_from_connection (void) { NMConnection *connection, *replacement; GError *error = NULL; @@ -994,7 +847,7 @@ test_connection_replace_settings_from_connection () } static void -test_connection_new_from_hash () +test_connection_new_from_hash (void) { NMConnection *connection; GHashTable *new_settings; @@ -1416,8 +1269,8 @@ test_connection_diff_a_only (void) { NM_SETTING_IP4_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A }, - { "address-labels", NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_IP4_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A }, @@ -1980,9 +1833,9 @@ test_ip4_netmask_to_prefix (void) { int i, j; - GRand *rand = g_rand_new (); + GRand *r = g_rand_new (); - g_rand_set_seed (rand, 1); + g_rand_set_seed (r, 1); for (i = 2; i<=32; i++) { guint32 netmask = nm_utils_ip4_prefix_to_netmask (i); @@ -1991,11 +1844,11 @@ test_ip4_netmask_to_prefix (void) g_assert_cmpint (i, ==, nm_utils_ip4_netmask_to_prefix (netmask)); for (j = 0; j < 2*i; j++) { - guint32 r = g_rand_int (rand); + guint32 n = g_rand_int (r); guint32 netmask_holey; guint32 prefix_holey; - netmask_holey = (netmask & r) | netmask_lowest_bit; + netmask_holey = (netmask & n) | netmask_lowest_bit; if (netmask_holey == netmask) continue; @@ -2008,7 +1861,7 @@ test_ip4_netmask_to_prefix (void) } } - g_rand_free (rand); + g_rand_free (r); } #define ASSERT_CHANGED(statement) \ @@ -2153,7 +2006,7 @@ test_setting_ip4_changed_signal (void) ASSERT_CHANGED (nm_setting_ip4_config_add_address (s_ip4, addr)); ASSERT_CHANGED (nm_setting_ip4_config_remove_address (s_ip4, 0)); - g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*addr != NULL && label != NULL*"); + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*elt != NULL*"); ASSERT_UNCHANGED (nm_setting_ip4_config_remove_address (s_ip4, 1)); g_test_assert_expected_messages (); @@ -2484,6 +2337,201 @@ test_setting_old_uuid (void) g_assert (success == TRUE); } +/* + * nm_connection_verify() modifies the connection by setting + * the interface-name property to the virtual_iface_name of + * the type specific settings. + * + * It would be preferable of verify() not to touch the connection, + * but as it is now, stick with it and test it. + **/ +static void +test_connection_verify_sets_interface_name (void) +{ + NMConnection *con; + NMSettingConnection *s_con; + NMSettingBond *s_bond; + GError *error = NULL; + gboolean success; + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_ID, "test1", + NM_SETTING_CONNECTION_UUID, "22001632-bbb4-4616-b277-363dce3dfb5b", + NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + s_bond = (NMSettingBond *) nm_setting_bond_new (); + g_object_set (G_OBJECT (s_bond), + NM_SETTING_BOND_INTERFACE_NAME, "bond-x", + NULL); + + con = nm_connection_new (); + nm_connection_add_setting (con, NM_SETTING (s_con)); + nm_connection_add_setting (con, NM_SETTING (s_bond)); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, NULL); + + /* for backward compatiblity, normalizes the interface name */ + success = nm_connection_verify (con, &error); + g_assert (success && !error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, "bond-x"); + + g_object_unref (con); +} + +/* + * Test normalization of interface-name + **/ +static void +test_connection_normalize_virtual_iface_name (void) +{ + NMConnection *con; + NMSettingConnection *s_con; + NMSettingVlan *s_vlan; + NMSetting *setting; + GError *error = NULL; + gboolean success; + const char *IFACE_NAME = "iface"; + const char *IFACE_VIRT = "iface-X"; + gboolean modified = FALSE; + + con = nm_connection_new (); + + setting = nm_setting_ip4_config_new (); + g_object_set (setting, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + nm_connection_add_setting (con, setting); + + setting = nm_setting_ip6_config_new (); + g_object_set (setting, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + nm_connection_add_setting (con, setting); + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_ID, "test1", + NM_SETTING_CONNECTION_UUID, "22001632-bbb4-4616-b277-363dce3dfb5b", + NM_SETTING_CONNECTION_TYPE, NM_SETTING_VLAN_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, IFACE_NAME, + NULL); + s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); + g_object_set (G_OBJECT (s_vlan), + NM_SETTING_VLAN_INTERFACE_NAME, IFACE_VIRT, + NM_SETTING_VLAN_PARENT, "eth0", + NULL); + + nm_connection_add_setting (con, NM_SETTING (s_con)); + nm_connection_add_setting (con, NM_SETTING (s_vlan)); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_VIRT); + + /* for backward compatiblity, normalizes the interface name */ + success = nm_connection_verify (con, &error); + g_assert (success && !error); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_VIRT); + + success = nm_connection_normalize (con, NULL, &modified, &error); + g_assert (success && !error); + g_assert (modified); + + g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME); + g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, IFACE_NAME); + + success = nm_connection_verify (con, &error); + g_assert (success && !error); + + g_object_unref (con); +} + +static void +_test_libnm_linking_setup_child_process (gpointer user_data) +{ + int val; + struct rlimit limit; + + /* the child process is supposed to crash. We don't want it + * to write a core dump. */ + + val = getrlimit (RLIMIT_CORE, &limit); + if (val == 0) { + limit.rlim_cur = 0; + val = setrlimit (RLIMIT_CORE, &limit); + if (val == 0) + return; + } + /* on error, do not crash or fail assertion. Instead just exit */ + exit (1); +} + +static void +test_libnm_linking (void) +{ + char *argv[] = { "./test-libnm-linking", NULL }; + char *out, *err; + int status; + GError *error = NULL; + + g_spawn_sync (BUILD_DIR, argv, NULL, 0 /*G_SPAWN_DEFAULT*/, + _test_libnm_linking_setup_child_process, NULL, + &out, &err, &status, &error); + g_assert_no_error (error); + + g_assert (WIFSIGNALED (status)); + + g_assert (strstr (err, "Mixing libnm") != NULL); + g_free (out); + g_free (err); +} + +/******************************************************************************/ + +static void +_test_uuid (const char *expected_uuid, const char *str) +{ + gs_free char *uuid_test = NULL; + + g_assert (str); + + uuid_test = nm_utils_uuid_generate_from_string (str); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed: text=%s, uuid=%s, expected=%s", + str, uuid_test, expected_uuid); + } +} + +static void +test_nm_utils_uuid_generate_from_string (void) +{ + gs_free char *uuid_test = NULL; + + _test_uuid ("0cc175b9-c0f1-b6a8-31c3-99e269772661", "a"); + _test_uuid ("098f6bcd-4621-d373-cade-4e832627b4f6", "test"); + _test_uuid ("59c0547b-7fe2-1c15-2cce-e328e8bf6742", "/etc/NetworkManager/system-connections/em1"); + + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*nm_utils_uuid_generate_from_string*: *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (""); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); + + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, "*nm_utils_uuid_generate_from_string*: *s && *s*"); + uuid_test = nm_utils_uuid_generate_from_string (NULL); + g_assert (uuid_test == NULL); + g_test_assert_expected_messages (); +} + +/******************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -2496,7 +2544,6 @@ int main (int argc, char **argv) test_setting_vpn_items (); test_setting_vpn_update_secrets (); test_setting_vpn_modify_during_foreach (); - test_setting_ip4_config_labels (); test_setting_ip6_config_old_address_array (); test_setting_gsm_apn_spaces (); test_setting_gsm_apn_bad_chars (); @@ -2521,6 +2568,8 @@ int main (int argc, char **argv) test_connection_replace_settings (); test_connection_replace_settings_from_connection (); test_connection_new_from_hash (); + test_connection_verify_sets_interface_name (); + test_connection_normalize_virtual_iface_name (); test_setting_connection_permissions_helpers (); test_setting_connection_permissions_property (); @@ -2558,6 +2607,10 @@ int main (int argc, char **argv) test_setting_wireless_security_changed_signal (); test_setting_802_1x_changed_signal (); + test_libnm_linking (); + + test_nm_utils_uuid_generate_from_string (); + base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); g_free (base); diff --git a/libnm-util/tests/test-libnm-linking.c b/libnm-util/tests/test-libnm-linking.c new file mode 100644 index 00000000..9738d44d --- /dev/null +++ b/libnm-util/tests/test-libnm-linking.c @@ -0,0 +1,48 @@ +/* -*- 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 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +extern GType nm_state_get_type (void); + +int +main (int argc, char **argv) +{ + /* If we reach main(), then the test has failed. */ + g_printerr ("libnm/libnm-util constructor failed to detect symbol mixing\n"); + + /* This is just to ensure that both libnm.so and libnm-util.so get pulled + * in; libnm-util doesn't have "nm_state_get_type" and libnm doesn't have + * "nm_utils_slist_free". (We intentionally choose different symbols than the + * ones that the libraries check for.) + */ + nm_state_get_type (); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + nm_utils_slist_free (NULL, g_free); + G_GNUC_END_IGNORE_DEPRECATIONS; + + g_assert_not_reached (); +} diff --git a/libnm-util/tests/test-secrets.c b/libnm-util/tests/test-secrets.c index 73fc9224..fb0ad4c7 100644 --- a/libnm-util/tests/test-secrets.c +++ b/libnm-util/tests/test-secrets.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) 2008 - 2011 Red Hat, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. * */ +#include "config.h" + #include #include @@ -679,7 +681,7 @@ test_update_secrets_whole_connection_empty_base_setting (void) connection = wifi_connection_new (); secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - g_assert_cmpint (g_hash_table_size (secrets), ==, 1); + g_assert_cmpint (g_hash_table_size (secrets), ==, 3); g_assert (g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SETTING_NAME)); success = nm_connection_update_secrets (connection, diff --git a/libnm-util/tests/test-setting-8021x.c b/libnm-util/tests/test-setting-8021x.c index 62889c61..4b37d92b 100644 --- a/libnm-util/tests/test-setting-8021x.c +++ b/libnm-util/tests/test-setting-8021x.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) 2008 - 2011 Red Hat, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. * */ +#include "config.h" + #include #include @@ -404,40 +406,57 @@ test_clear_phase2_private_key (const char *path, const char *password) g_object_unref (s_8021x); } -int main (int argc, char **argv) +static void +do_8021x_test (gconstpointer test_data) { - GError *error = NULL; - char *base; - - if (argc < 3) - FAIL ("init", "need at least two arguments: "); + char **parts, *path, *password; -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + parts = g_strsplit ((const char *) test_data, ", ", -1); + g_assert_cmpint (g_strv_length (parts), ==, 2); - if (!nm_utils_init (&error)) - FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + path = g_build_filename (TEST_CERT_DIR, parts[0], NULL); + password = parts[1]; /* Test phase1 and phase2 path scheme */ - test_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_PATH); - test_phase2_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_PATH); + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_PATH); /* Test phase1 and phase2 blob scheme */ - test_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_BLOB); - test_phase2_private_key_import (argv[1], argv[2], NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); + test_phase2_private_key_import (path, password, NM_SETTING_802_1X_CK_SCHEME_BLOB); /* Test that using a wrong password does not change existing data */ - test_wrong_password_keeps_data (argv[1], argv[2]); - test_wrong_phase2_password_keeps_data (argv[1], argv[2]); + test_wrong_password_keeps_data (path, password); + test_wrong_phase2_password_keeps_data (path, password); /* Test clearing the private key */ - test_clear_private_key (argv[1], argv[2]); - test_clear_phase2_private_key (argv[1], argv[2]); + test_clear_private_key (path, password); + test_clear_phase2_private_key (path, password); - base = g_path_get_basename (argv[0]); - fprintf (stdout, "%s: SUCCESS\n", base); - g_free (base); - return 0; + g_free (path); + g_strfreev (parts); +} + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_data_func ("/libnm-utils/setting-8021x/key-and-cert", + "test_key_and_cert.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm-utils/setting-8021x/key-only", + "test-key-only.pem, test", + do_8021x_test); + g_test_add_data_func ("/libnm-utils/setting-8021x/pkcs8-enc-key", + "pkcs8-enc-key.pem, 1234567890", + do_8021x_test); + g_test_add_data_func ("/libnm-utils/setting-8021x/pkcs12", + "test-cert.p12, test", + do_8021x_test); + + return g_test_run (); } diff --git a/libnm-util/tests/test-setting-dcb.c b/libnm-util/tests/test-setting-dcb.c index de07f2c2..1c7d78b8 100644 --- a/libnm-util/tests/test-setting-dcb.c +++ b/libnm-util/tests/test-setting-dcb.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) 2013 Red Hat, Inc. + * Copyright 2013 Red Hat, Inc. * */ +#include "config.h" + #include #include #include diff --git a/libnm-util/tests/test-settings-defaults.c b/libnm-util/tests/test-settings-defaults.c index 15412fed..7441e1ff 100644 --- a/libnm-util/tests/test-settings-defaults.c +++ b/libnm-util/tests/test-settings-defaults.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) 2008 - 2011 Red Hat, Inc. + * Copyright 2008 - 2011 Red Hat, Inc. * */ +#include "config.h" + #include #include diff --git a/libnm/Makefile.am b/libnm/Makefile.am new file mode 100644 index 00000000..e8915b42 --- /dev/null +++ b/libnm/Makefile.am @@ -0,0 +1,224 @@ +include $(GLIB_MAKEFILE) + +SUBDIRS = . tests + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/introspection \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/libnm \ + -I$(top_builddir)/libnm \ + -DG_LOG_DOMAIN=\""libnm"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DNMRUNDIR=\"$(nmrundir)\" + +include $(top_srcdir)/libnm-core/Makefile.libnm-core + +# libnm + +lib_LTLIBRARIES = libnm.la + +libnmincludedir = $(includedir)/libnm + +libnminclude_hfiles = \ + NetworkManager.h \ + nm-access-point.h \ + nm-active-connection.h \ + nm-client.h \ + nm-device-adsl.h \ + nm-device-bond.h \ + nm-device-bridge.h \ + nm-device-bt.h \ + nm-device-ethernet.h \ + nm-device-generic.h \ + nm-device-infiniband.h \ + nm-device-modem.h \ + nm-device-olpc-mesh.h \ + nm-device-team.h \ + nm-device-vlan.h \ + nm-device-wifi.h \ + nm-device-wimax.h \ + nm-device.h \ + nm-dhcp-config.h \ + nm-enum-types.h \ + nm-ip-config.h \ + nm-object.h \ + nm-remote-connection.h \ + nm-types.h \ + nm-vpn-connection.h \ + nm-vpn-editor-plugin.h \ + nm-wimax-nsp.h + +libnminclude_nointrospect_hfiles = \ + nm-secret-agent-old.h \ + nm-vpn-plugin-old.h + +libnminclude_HEADERS = \ + $(libnminclude_hfiles) \ + $(libnminclude_nointrospect_hfiles) + +libnm_la_private_headers = \ + nm-dbus-helpers.h \ + nm-device-private.h \ + nm-dhcp4-config.h \ + nm-dhcp6-config.h \ + nm-ip4-config.h \ + nm-ip6-config.h \ + nm-manager.h \ + nm-object-cache.h \ + nm-object-private.h \ + nm-remote-connection-private.h \ + nm-remote-settings.h + +libnm_la_csources = \ + nm-access-point.c \ + nm-active-connection.c \ + nm-client.c \ + nm-dbus-helpers.c \ + nm-device-adsl.c \ + nm-device-bond.c \ + nm-device-bridge.c \ + nm-device-bt.c \ + nm-device-ethernet.c \ + nm-device-generic.c \ + nm-device-infiniband.c \ + nm-device-modem.c \ + nm-device-olpc-mesh.c \ + nm-device-team.c \ + nm-device-vlan.c \ + nm-device-wifi.c \ + nm-device-wimax.c \ + nm-device.c \ + nm-dhcp-config.c \ + nm-dhcp4-config.c \ + nm-dhcp6-config.c \ + nm-enum-types.c \ + nm-ip-config.c \ + nm-ip4-config.c \ + nm-ip6-config.c \ + nm-manager.c \ + nm-object-cache.c \ + nm-object.c \ + nm-remote-connection.c \ + nm-remote-settings.c \ + nm-secret-agent-old.c \ + nm-vpn-connection.c \ + nm-vpn-plugin-old.c \ + nm-vpn-editor-plugin.c \ + nm-wimax-nsp.c + +libnm_la_SOURCES = \ + $(libnm_la_csources) \ + $(libnm_la_private_headers) + +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c +nm_enum_types_sources = $(libnminclude_HEADERS) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include \n' +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM + +libnm_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + $(top_builddir)/introspection/libnmdbus.la \ + $(GLIB_LIBS) \ + $(UUID_LIBS) \ + $(GUDEV_LIBS) + +SYMBOL_VIS_FILE=$(srcdir)/libnm.ver + +libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ + -version-info "0:0:0" + +### + +BUILT_SOURCES = $(GLIB_GENERATED) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libnm.pc + +DISTCLEANFILES = libnm.pc + +EXTRA_DIST = libnm.pc.in libnm.ver + +CLEANFILES = $(BUILT_SOURCES) + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = +INTROSPECTION_COMPILER_ARGS = \ + --includedir=$(top_srcdir)/libnm-core \ + --includedir=$(top_builddir)/libnm-core \ + --includedir=$(top_srcdir)/libnm \ + --includedir=$(top_builddir)/libnm + +if HAVE_INTROSPECTION +introspection_sources = \ + $(libnm_core_headers) \ + $(libnminclude_hfiles) \ + $(libnm_core_sources) \ + $(libnm_la_csources) + +NM-1.0.gir: libnm.la +NM_1_0_gir_INCLUDES = Gio-2.0 +NM_1_0_gir_PACKAGES = gio-2.0 gudev-1.0 +NM_1_0_gir_EXPORT_PACKAGES = libnm +NM_1_0_gir_CFLAGS = $(AM_CPPFLAGS) +NM_1_0_gir_LIBS = libnm.la +NM_1_0_gir_FILES = $(introspection_sources) +NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm +INTROSPECTION_GIRS += NM-1.0.gir + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) +endif + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm.so $(SYMBOL_VIS_FILE) + +if BUILD_SETTING_DOCS + +noinst_DATA = \ + nm-property-docs.xml \ + nm-setting-docs-overrides.xml \ + nm-setting-docs.xml \ + nm-keyfile-docs.xml \ + nm-ifcfg-rh-docs.xml + +docs_sources = $(filter-out %/nm-core-enum-types.c,$(libnm_core_sources)) + +nm-setting-docs-overrides.xml: generate-plugin-docs.pl $(docs_sources) + $(srcdir)/generate-plugin-docs.pl dbus $(top_srcdir)/libnm-core $@ + +nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1.0.typelib libnm.la + export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ + export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ + $(srcdir)/generate-setting-docs.py \ + --gir $(builddir)/NM-1.0.gir \ + --output $@ + +nm-setting-docs.xml: generate-setting-docs.py $(docs_sources) nm-setting-docs-overrides.xml | NM-1.0.gir NM-1.0.typelib libnm.la + export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ + export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ + $(srcdir)/generate-setting-docs.py \ + --gir $(builddir)/NM-1.0.gir \ + --overrides $(builddir)/nm-setting-docs-overrides.xml \ + --output $@ + +nm-keyfile-docs.xml: generate-plugin-docs.pl $(docs_sources) + $(srcdir)/generate-plugin-docs.pl keyfile $(top_srcdir)/libnm-core $@ +nm-ifcfg-rh-docs.xml: generate-plugin-docs.pl $(docs_sources) + $(srcdir)/generate-plugin-docs.pl ifcfg-rh $(top_srcdir)/libnm-core $@ + +CLEANFILES += $(noinst_DATA) +EXTRA_DIST += $(noinst_DATA) + +endif + +EXTRA_DIST += generate-setting-docs.py generate-plugin-docs.pl diff --git a/libnm/Makefile.in b/libnm/Makefile.in new file mode 100644 index 00000000..6e1fad47 --- /dev/null +++ b/libnm/Makefile.in @@ -0,0 +1,1349 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ + +# In order for this to work correctly from both libnm-core/ and libnm/, +# we have to specify full pathnames. (We can't just use $(addprefix) from +# libnm/, because that's incompatible with the Makefile.introspection rules.) + + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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@ +DIST_COMMON = $(top_srcdir)/libnm-core/Makefile.libnm-core \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/libnm.pc.in $(top_srcdir)/build-aux/depcomp \ + $(libnminclude_HEADERS) +@HAVE_INTROSPECTION_TRUE@am__append_1 = NM-1.0.gir +@HAVE_INTROSPECTION_TRUE@am__append_2 = $(gir_DATA) $(typelib_DATA) +@BUILD_SETTING_DOCS_TRUE@am__append_3 = $(noinst_DATA) +@BUILD_SETTING_DOCS_TRUE@am__append_4 = $(noinst_DATA) +subdir = libnm +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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 = libnm.pc +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__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" \ + "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" \ + "$(DESTDIR)$(libnmincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libnm_la_DEPENDENCIES = $(top_builddir)/libnm-core/libnm-core.la \ + $(top_builddir)/introspection/libnmdbus.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = nm-access-point.lo nm-active-connection.lo \ + nm-client.lo nm-dbus-helpers.lo nm-device-adsl.lo \ + nm-device-bond.lo nm-device-bridge.lo nm-device-bt.lo \ + nm-device-ethernet.lo nm-device-generic.lo \ + nm-device-infiniband.lo nm-device-modem.lo \ + nm-device-olpc-mesh.lo nm-device-team.lo nm-device-vlan.lo \ + nm-device-wifi.lo nm-device-wimax.lo nm-device.lo \ + nm-dhcp-config.lo nm-dhcp4-config.lo nm-dhcp6-config.lo \ + nm-enum-types.lo nm-ip-config.lo nm-ip4-config.lo \ + nm-ip6-config.lo nm-manager.lo nm-object-cache.lo nm-object.lo \ + nm-remote-connection.lo nm-remote-settings.lo \ + nm-secret-agent-old.lo nm-vpn-connection.lo \ + nm-vpn-plugin-old.lo nm-vpn-editor-plugin.lo nm-wimax-nsp.lo +am__objects_2 = +am_libnm_la_OBJECTS = $(am__objects_1) $(am__objects_2) +libnm_la_OBJECTS = $(am_libnm_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libnm_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libnm_la_SOURCES) +DIST_SOURCES = $(libnm_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-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 \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(gir_DATA) $(noinst_DATA) $(pkgconfig_DATA) $(typelib_DATA) +HEADERS = $(libnminclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +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@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +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@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +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@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +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@ +PERL = @PERL@ +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_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +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_CXX = @ac_ct_CXX@ +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@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +SUBDIRS = . tests +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/introspection \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/libnm \ + -I$(top_builddir)/libnm \ + -DG_LOG_DOMAIN=\""libnm"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DNMRUNDIR=\"$(nmrundir)\" + +core = $(top_srcdir)/libnm-core +core_build = $(top_builddir)/libnm-core +libnm_core_headers = \ + $(core_build)/nm-core-enum-types.h \ + $(core_build)/nm-version.h \ + $(core)/nm-connection.h \ + $(core)/nm-core-types.h \ + $(core)/nm-dbus-interface.h \ + $(core)/nm-errors.h \ + $(core)/nm-setting-8021x.h \ + $(core)/nm-setting-adsl.h \ + $(core)/nm-setting-bluetooth.h \ + $(core)/nm-setting-bond.h \ + $(core)/nm-setting-bridge-port.h \ + $(core)/nm-setting-bridge.h \ + $(core)/nm-setting-cdma.h \ + $(core)/nm-setting-connection.h \ + $(core)/nm-setting-dcb.h \ + $(core)/nm-setting-generic.h \ + $(core)/nm-setting-gsm.h \ + $(core)/nm-setting-infiniband.h \ + $(core)/nm-setting-ip-config.h \ + $(core)/nm-setting-ip4-config.h \ + $(core)/nm-setting-ip6-config.h \ + $(core)/nm-setting-olpc-mesh.h \ + $(core)/nm-setting-ppp.h \ + $(core)/nm-setting-pppoe.h \ + $(core)/nm-setting-serial.h \ + $(core)/nm-setting-team-port.h \ + $(core)/nm-setting-team.h \ + $(core)/nm-setting-vlan.h \ + $(core)/nm-setting-vpn.h \ + $(core)/nm-setting-wimax.h \ + $(core)/nm-setting-wired.h \ + $(core)/nm-setting-wireless-security.h \ + $(core)/nm-setting-wireless.h \ + $(core)/nm-setting.h \ + $(core)/nm-simple-connection.h \ + $(core)/nm-utils.h \ + $(core)/nm-vpn-dbus-interface.h + +libnm_core_private_headers = \ + $(core)/crypto.h \ + $(core)/nm-connection-private.h \ + $(core)/nm-core-internal.h \ + $(core)/nm-property-compare.h \ + $(core)/nm-setting-private.h \ + $(core)/nm-utils-private.h + +libnm_core_sources = \ + $(core_build)/nm-core-enum-types.c \ + $(core)/crypto.c \ + $(core)/nm-connection.c \ + $(core)/nm-errors.c \ + $(core)/nm-property-compare.c \ + $(core)/nm-setting-8021x.c \ + $(core)/nm-setting-adsl.c \ + $(core)/nm-setting-bluetooth.c \ + $(core)/nm-setting-bond.c \ + $(core)/nm-setting-bridge-port.c \ + $(core)/nm-setting-bridge.c \ + $(core)/nm-setting-cdma.c \ + $(core)/nm-setting-connection.c \ + $(core)/nm-setting-dcb.c \ + $(core)/nm-setting-generic.c \ + $(core)/nm-setting-gsm.c \ + $(core)/nm-setting-infiniband.c \ + $(core)/nm-setting-ip-config.c \ + $(core)/nm-setting-ip4-config.c \ + $(core)/nm-setting-ip6-config.c \ + $(core)/nm-setting-olpc-mesh.c \ + $(core)/nm-setting-ppp.c \ + $(core)/nm-setting-pppoe.c \ + $(core)/nm-setting-serial.c \ + $(core)/nm-setting-team-port.c \ + $(core)/nm-setting-team.c \ + $(core)/nm-setting-vlan.c \ + $(core)/nm-setting-vpn.c \ + $(core)/nm-setting-wimax.c \ + $(core)/nm-setting-wired.c \ + $(core)/nm-setting-wireless-security.c \ + $(core)/nm-setting-wireless.c \ + $(core)/nm-setting.c \ + $(core)/nm-simple-connection.c \ + $(core)/nm-utils.c + + +# libnm +lib_LTLIBRARIES = libnm.la +libnmincludedir = $(includedir)/libnm +libnminclude_hfiles = \ + NetworkManager.h \ + nm-access-point.h \ + nm-active-connection.h \ + nm-client.h \ + nm-device-adsl.h \ + nm-device-bond.h \ + nm-device-bridge.h \ + nm-device-bt.h \ + nm-device-ethernet.h \ + nm-device-generic.h \ + nm-device-infiniband.h \ + nm-device-modem.h \ + nm-device-olpc-mesh.h \ + nm-device-team.h \ + nm-device-vlan.h \ + nm-device-wifi.h \ + nm-device-wimax.h \ + nm-device.h \ + nm-dhcp-config.h \ + nm-enum-types.h \ + nm-ip-config.h \ + nm-object.h \ + nm-remote-connection.h \ + nm-types.h \ + nm-vpn-connection.h \ + nm-vpn-editor-plugin.h \ + nm-wimax-nsp.h + +libnminclude_nointrospect_hfiles = \ + nm-secret-agent-old.h \ + nm-vpn-plugin-old.h + +libnminclude_HEADERS = \ + $(libnminclude_hfiles) \ + $(libnminclude_nointrospect_hfiles) + +libnm_la_private_headers = \ + nm-dbus-helpers.h \ + nm-device-private.h \ + nm-dhcp4-config.h \ + nm-dhcp6-config.h \ + nm-ip4-config.h \ + nm-ip6-config.h \ + nm-manager.h \ + nm-object-cache.h \ + nm-object-private.h \ + nm-remote-connection-private.h \ + nm-remote-settings.h + +libnm_la_csources = \ + nm-access-point.c \ + nm-active-connection.c \ + nm-client.c \ + nm-dbus-helpers.c \ + nm-device-adsl.c \ + nm-device-bond.c \ + nm-device-bridge.c \ + nm-device-bt.c \ + nm-device-ethernet.c \ + nm-device-generic.c \ + nm-device-infiniband.c \ + nm-device-modem.c \ + nm-device-olpc-mesh.c \ + nm-device-team.c \ + nm-device-vlan.c \ + nm-device-wifi.c \ + nm-device-wimax.c \ + nm-device.c \ + nm-dhcp-config.c \ + nm-dhcp4-config.c \ + nm-dhcp6-config.c \ + nm-enum-types.c \ + nm-ip-config.c \ + nm-ip4-config.c \ + nm-ip6-config.c \ + nm-manager.c \ + nm-object-cache.c \ + nm-object.c \ + nm-remote-connection.c \ + nm-remote-settings.c \ + nm-secret-agent-old.c \ + nm-vpn-connection.c \ + nm-vpn-plugin-old.c \ + nm-vpn-editor-plugin.c \ + nm-wimax-nsp.c + +libnm_la_SOURCES = \ + $(libnm_la_csources) \ + $(libnm_la_private_headers) + +GLIB_GENERATED = nm-enum-types.h nm-enum-types.c +nm_enum_types_sources = $(libnminclude_HEADERS) +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include \n' +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +libnm_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + $(top_builddir)/introspection/libnmdbus.la \ + $(GLIB_LIBS) \ + $(UUID_LIBS) \ + $(GUDEV_LIBS) + +SYMBOL_VIS_FILE = $(srcdir)/libnm.ver +libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ + -version-info "0:0:0" + + +### +BUILT_SOURCES = $(GLIB_GENERATED) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libnm.pc +DISTCLEANFILES = libnm.pc +EXTRA_DIST = libnm.pc.in libnm.ver $(am__append_4) \ + generate-setting-docs.py generate-plugin-docs.pl +CLEANFILES = $(BUILT_SOURCES) $(am__append_2) $(am__append_3) +INTROSPECTION_GIRS = $(am__append_1) +INTROSPECTION_COMPILER_ARGS = \ + --includedir=$(top_srcdir)/libnm-core \ + --includedir=$(top_builddir)/libnm-core \ + --includedir=$(top_srcdir)/libnm \ + --includedir=$(top_builddir)/libnm + +@HAVE_INTROSPECTION_TRUE@introspection_sources = \ +@HAVE_INTROSPECTION_TRUE@ $(libnm_core_headers) \ +@HAVE_INTROSPECTION_TRUE@ $(libnminclude_hfiles) \ +@HAVE_INTROSPECTION_TRUE@ $(libnm_core_sources) \ +@HAVE_INTROSPECTION_TRUE@ $(libnm_la_csources) + +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_INCLUDES = Gio-2.0 +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_PACKAGES = gio-2.0 gudev-1.0 +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_EXPORT_PACKAGES = libnm +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_CFLAGS = $(AM_CPPFLAGS) +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_LIBS = libnm.la +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_FILES = $(introspection_sources) +@HAVE_INTROSPECTION_TRUE@NM_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm +@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0 +@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS) +@HAVE_INTROSPECTION_TRUE@typelibdir = $(libdir)/girepository-1.0 +@HAVE_INTROSPECTION_TRUE@typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) +@BUILD_SETTING_DOCS_TRUE@noinst_DATA = \ +@BUILD_SETTING_DOCS_TRUE@ nm-property-docs.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-setting-docs-overrides.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-setting-docs.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-keyfile-docs.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-ifcfg-rh-docs.xml + +@BUILD_SETTING_DOCS_TRUE@docs_sources = $(filter-out %/nm-core-enum-types.c,$(libnm_core_sources)) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/libnm-core/Makefile.libnm-core $(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 libnm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libnm/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_srcdir)/libnm-core/Makefile.libnm-core: + +$(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): +libnm.pc: $(top_builddir)/config.status $(srcdir)/libnm.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libnm.la: $(libnm_la_OBJECTS) $(libnm_la_DEPENDENCIES) $(EXTRA_libnm_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_la_LINK) -rpath $(libdir) $(libnm_la_OBJECTS) $(libnm_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-access-point.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-active-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dbus-helpers.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-adsl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bond.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bridge.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ethernet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-generic.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-infiniband.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-modem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-olpc-mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vlan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-wifi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-wimax.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp4-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp6-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ip-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ip4-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ip6-config.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-object-cache.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-object.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-remote-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-remote-settings.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-secret-agent-old.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-editor-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-vpn-plugin-old.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wimax-nsp.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-girDATA: $(gir_DATA) + @$(NORMAL_INSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(girdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(girdir)" || exit 1; \ + fi; \ + 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)$(girdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \ + done + +uninstall-girDATA: + @$(NORMAL_UNINSTALL) + @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(girdir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + 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)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-typelibDATA: $(typelib_DATA) + @$(NORMAL_INSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(typelibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(typelibdir)" || exit 1; \ + fi; \ + 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)$(typelibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibdir)" || exit $$?; \ + done + +uninstall-typelibDATA: + @$(NORMAL_UNINSTALL) + @list='$(typelib_DATA)'; test -n "$(typelibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(typelibdir)'; $(am__uninstall_files_from_dir) +install-libnmincludeHEADERS: $(libnminclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libnminclude_HEADERS)'; test -n "$(libnmincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libnmincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libnmincludedir)" || exit 1; \ + fi; \ + 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_HEADER) $$files '$(DESTDIR)$(libnmincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libnmincludedir)" || exit $$?; \ + done + +uninstall-libnmincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libnminclude_HEADERS)'; test -n "$(libnmincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libnmincludedir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + 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" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + 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; \ + $(am__define_uniq_tagged_files); \ + 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-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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 \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + 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 + $(MAKE) $(AM_MAKEFLAGS) check-local +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libnmincludedir)"; 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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-girDATA install-libnmincludeHEADERS \ + install-pkgconfigDATA install-typelibDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +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-girDATA uninstall-libLTLIBRARIES \ + uninstall-libnmincludeHEADERS uninstall-pkgconfigDATA \ + uninstall-typelibDATA + +.MAKE: $(am__recursive_targets) all check check-am install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am check-local clean clean-generic clean-libLTLIBRARIES \ + clean-libtool cscopelist-am ctags ctags-am 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-girDATA \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-libnmincludeHEADERS install-man \ + install-pdf install-pdf-am install-pkgconfigDATA install-ps \ + install-ps-am install-strip install-typelibDATA 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-am uninstall uninstall-am uninstall-girDATA \ + uninstall-libLTLIBRARIES uninstall-libnmincludeHEADERS \ + uninstall-pkgconfigDATA uninstall-typelibDATA + +include $(GLIB_MAKEFILE) + +-include $(INTROSPECTION_MAKEFILE) + +@HAVE_INTROSPECTION_TRUE@NM-1.0.gir: libnm.la + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm.so $(SYMBOL_VIS_FILE) + +@BUILD_SETTING_DOCS_TRUE@nm-setting-docs-overrides.xml: generate-plugin-docs.pl $(docs_sources) +@BUILD_SETTING_DOCS_TRUE@ $(srcdir)/generate-plugin-docs.pl dbus $(top_srcdir)/libnm-core $@ + +@BUILD_SETTING_DOCS_TRUE@nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1.0.typelib libnm.la +@BUILD_SETTING_DOCS_TRUE@ export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ +@BUILD_SETTING_DOCS_TRUE@ export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ +@BUILD_SETTING_DOCS_TRUE@ $(srcdir)/generate-setting-docs.py \ +@BUILD_SETTING_DOCS_TRUE@ --gir $(builddir)/NM-1.0.gir \ +@BUILD_SETTING_DOCS_TRUE@ --output $@ + +@BUILD_SETTING_DOCS_TRUE@nm-setting-docs.xml: generate-setting-docs.py $(docs_sources) nm-setting-docs-overrides.xml | NM-1.0.gir NM-1.0.typelib libnm.la +@BUILD_SETTING_DOCS_TRUE@ export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ +@BUILD_SETTING_DOCS_TRUE@ export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ +@BUILD_SETTING_DOCS_TRUE@ $(srcdir)/generate-setting-docs.py \ +@BUILD_SETTING_DOCS_TRUE@ --gir $(builddir)/NM-1.0.gir \ +@BUILD_SETTING_DOCS_TRUE@ --overrides $(builddir)/nm-setting-docs-overrides.xml \ +@BUILD_SETTING_DOCS_TRUE@ --output $@ + +@BUILD_SETTING_DOCS_TRUE@nm-keyfile-docs.xml: generate-plugin-docs.pl $(docs_sources) +@BUILD_SETTING_DOCS_TRUE@ $(srcdir)/generate-plugin-docs.pl keyfile $(top_srcdir)/libnm-core $@ +@BUILD_SETTING_DOCS_TRUE@nm-ifcfg-rh-docs.xml: generate-plugin-docs.pl $(docs_sources) +@BUILD_SETTING_DOCS_TRUE@ $(srcdir)/generate-plugin-docs.pl ifcfg-rh $(top_srcdir)/libnm-core $@ + +# 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/libnm/NetworkManager.h b/libnm/NetworkManager.h new file mode 100644 index 00000000..251a0422 --- /dev/null +++ b/libnm/NetworkManager.h @@ -0,0 +1,89 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_H__ +#define __NETWORKMANAGER_H__ + +#define __NETWORKMANAGER_H_INSIDE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __NETWORKMANAGER_H_INSIDE__ + +#endif /* __NETWORKMANAGER_H__ */ diff --git a/libnm/generate-plugin-docs.pl b/libnm/generate-plugin-docs.pl new file mode 100755 index 00000000..35cfdfc6 --- /dev/null +++ b/libnm/generate-plugin-docs.pl @@ -0,0 +1,198 @@ +#!/usr/bin/env perl +# vim: ft=perl ts=2 sts=2 sw=2 et ai +# -*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + +# +# 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 2014 Red Hat, Inc. +# + +# +# The script parses nm-setting-*.c files and extracts documentation related +# to setting plugins. The documentation is in a simple format of lines +# "keyword: value". The documentation is enclosed between tags +# ------ and ---end--- +# Recognized keywords are: +# "property: " - property name +# "variable: " - name of the variable used by the plugin +# "format: " - format of the value in 'keyfile' plugin +# "default: " - default value when variable is not used +# "values: " - allowed values (e.g. for enumerations) +# "example: " - example(s) +# "description: " - description text +# Value is an arbitrary string that can span over multiple lines. +# +# ifcfg-rh specifics: +# - mark NM extension variables with (+), e.g. variable: UUID(+) +# + +use strict; +use warnings; +use v5.10; +#YAML:XS is based on libyaml C library and it is a good and fast YAML implementation. +#However it may not be present everywhere. So use YAML instead. +#use YAML::XS qw(Load); +use YAML qw(Load); + +# global variables +my @keywords = ("property", "variable", "format", "values", "default", "example", "description"); +my @source_files; +my @data; +my $fo; + +(scalar @ARGV == 3) or die "Usage: $0 \n"; +my ($plugin, $srcdir, $output) = @ARGV; +my $start_tag = "---$plugin---\\s*\$"; +my $end_tag = '---end---'; + +# get source files to scan for documentation comments (nm-setting-.c) +my $file = "$srcdir/Makefile.libnm-core"; +open my $fh, '<', $file or die "Can't open $file: $!"; +while (my $line = <$fh>) { + chomp $line; + my @strings = $line =~ /\/(nm-setting-[^.]*\.c)(?:\s|$)/g; + push @source_files, @strings +} +close $fh; + +# open output file +open $fo, '>', $output or die "Can't open $output: $!"; + +# write XML header +write_header(); + +# write generated documenation for each setting +foreach my $c_file (@source_files) { + my $path = "$srcdir/$c_file"; + my $setting_name = get_setting_name($path); + write_item(""); + scan_doc_comments($path, $start_tag, $end_tag); + write_item(""); +} + +# write XML footer +write_footer(); + +# close output file +close $fo; + + +### --- subroutines --- ### + +# get setting name from NM_SETTING_*_SETTING_NAME constant in C header file +sub get_setting_name { + my $path = $_[0]; + $path =~ s/c$/h/; # use header file to find out setting name + open my $fh, '<', $path or die "Can't open $path: $!"; + while (my $line = <$fh>) { + if ($line =~ /NM_SETTING_.+SETTING_NAME\s+\"(\S+)\"/) { + return $1; + } + } +} + +# scan source setting file for documentation tags and write them to XML +sub scan_doc_comments { + my($setting_file, $start, $end) = @_; + open my $fi, '<', $setting_file or die "Can't open $setting_file: $!"; + while (<$fi>) { + if (/$start/ .. /$end/) { + next if /$start/; + if (/$end/) { + process_data(); + } else { + push @data, $_; + } + next; + } + # ignore text not inside marks + } + close $fi; +} + +# process plugin property documentation comments (as a YAML document) +sub process_data { + return if not @data; + my $kwd_pat = join("|", @keywords); + my $yaml_literal_seq = "|\n"; + + foreach (@data) { + # make a proper YAML document from @data + $_ =~ s/^\s*\**\s+|\s+$//; # remove leading spaces and *, and traling spaces + # Properly indent the text so that it is a valid YAML, and insert | (for literal text) + if ($_ =~ /^($kwd_pat):\s+/) { + # add | after "keyword:" that allows using literal text (YAML won't break on special character) + # http://learnxinyminutes.com/docs/yaml/ and http://www.yaml.org/spec/1.2/spec.html#id2795688 + $_ =~ s/(^($kwd_pat):)/$1 $yaml_literal_seq/; + } else { + $_ = " " . $_; # indent the text + } + } + my $str = join ("", @data); + my $yaml_data = Load($str); + + # now write a line into the XML + my $name = $yaml_data->{property} // ""; + my $var = $yaml_data->{variable} // $name; # fallback to "property: " + my $format = $yaml_data->{format} // ""; + my $values = $yaml_data->{values} // ""; + my $def = $yaml_data->{default} // ""; + my $exam = $yaml_data->{example} // ""; + my $desc = $yaml_data->{description} // ""; + + chomp($name, $var, $format, $values, $def, $exam, $desc); + escape_xml_chars($name, $var, $format, $values, $def, $exam, $desc); + my $foo = sprintf("", + $name, $var, $format, $values, $def, $exam, $desc); + write_item($foo); + @data = (); +} + +# - XML handling - +sub write_header { + (my $header = + qq{ + + + + }) =~ s/^ {7}//mg; + print {$fo} $header; +} + +sub write_footer { + my $footer = ""; + print {$fo} $footer; +} + +sub write_item { + my $str = join("", @_); + print {$fo} $str, "\n"; +} + +sub escape_xml_chars { + # http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined%5Fentities%5Fin%5FXML + foreach my $val (@_) { + $val =~ s/&/&/sg; + $val =~ s//>/sg; + $val =~ s/"/"/sg; + $val =~ s/'/'/sg; + } +} + diff --git a/libnm/generate-setting-docs.py b/libnm/generate-setting-docs.py new file mode 100755 index 00000000..e1e35a86 --- /dev/null +++ b/libnm/generate-setting-docs.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +# 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. +# +# Copyright 2009 - 2014 Red Hat, Inc. + +from __future__ import print_function + +from gi.repository import NM, GObject +import argparse, datetime, re, sys +import xml.etree.ElementTree as ET + +dbus_type_name_map = { + 'b': 'boolean', + 's': 'string', + 'i': 'int32', + 'u': 'uint32', + 't': 'uint64', + 'x': 'int64', + 'y': 'byte', + 'as': 'array of string', + 'au': 'array of uint32', + 'ay': 'byte array', + 'a{ss}': 'dict of string to string', + 'a{sv}': 'vardict', + 'aau': 'array of array of uint32', + 'aay': 'array of byte array', + 'a(ayuay)': 'array of legacy IPv6 address struct', + 'a(ayuayu)': 'array of legacy IPv6 route struct', +} + +ns_map = { + 'c': 'http://www.gtk.org/introspection/c/1.0', + 'gi': 'http://www.gtk.org/introspection/core/1.0', + 'glib': 'http://www.gtk.org/introspection/glib/1.0' +} +identifier_key = '{%s}identifier' % ns_map['c'] +nick_key = '{%s}nick' % ns_map['glib'] +symbol_prefix_key = '{%s}symbol-prefix' % ns_map['c'] + +constants = { + 'TRUE': 'TRUE', + 'FALSE': 'FALSE', + 'G_MAXUINT32': 'G_MAXUINT32', + 'NULL': 'NULL' } +setting_names = {} + +def init_constants(girxml, settings): + for const in girxml.findall('./gi:namespace/gi:constant', ns_map): + cname = const.attrib['{%s}type' % ns_map['c']] + cvalue = const.attrib['value'] + if const.find('./gi:type[@name="utf8"]', ns_map) is not None: + cvalue = '"%s"' % cvalue + constants[cname] = cvalue + + for enum in girxml.findall('./gi:namespace/gi:enumeration', ns_map): + for enumval in enum.findall('./gi:member', ns_map): + cname = enumval.attrib[identifier_key] + cvalue = '%s (%s)' % (cname, enumval.attrib['value']) + constants[cname] = cvalue + + for enum in girxml.findall('./gi:namespace/gi:bitfield', ns_map): + for enumval in enum.findall('./gi:member', ns_map): + cname = enumval.attrib[identifier_key] + cvalue = '%s (0x%x)' % (cname, int(enumval.attrib['value'])) + constants[cname] = cvalue + + for setting in settings: + setting_type_name = 'NM' + setting.attrib['name']; + setting_name_symbol = 'NM_' + setting.attrib[symbol_prefix_key].upper() + '_SETTING_NAME' + if constants.has_key(setting_name_symbol): + setting_name = constants[setting_name_symbol] + setting_names[setting_type_name] = setting_name + +def get_prop_type(setting, pspec, propxml): + dbus_type = setting.get_dbus_property_type(pspec.name).dup_string() + prop_type = dbus_type_name_map[dbus_type] + + if GObject.type_is_a(pspec.value_type, GObject.TYPE_ENUM) or GObject.type_is_a(pspec.value_type, GObject.TYPE_FLAGS): + prop_type = "%s (%s)" % (pspec.value_type.name, prop_type) + + return prop_type + +def get_docs(setting, pspec, propxml): + doc_xml = propxml.find('gi:doc', ns_map) + if doc_xml is None: + return None + + doc = doc_xml.text + if 'deprecated' in propxml.attrib: + doc = doc + ' Deprecated: ' + propxml.attrib['deprecated'] + + doc = re.sub(r'\n\s*', r' ', doc) + + # Expand constants + doc = re.sub(r'%([^%]\w*)', lambda match: constants[match.group(1)], doc) + + # #NMSettingWired:mac-address -> "mac-address" + doc = re.sub(r'#[A-Za-z0-9_]*:([A-Za-z0-9_-]*)', r'"\1"', doc) + + # #NMSettingWired setting -> "802-3-ethernet" setting + doc = re.sub(r'#([A-Z]\w*) setting', lambda match: setting_names[match.group(1)] + ' setting', doc) + + # remaining gtk-doc cleanup + doc = doc.replace('%%', '%') + doc = doc.replace('', '') + doc = re.sub(r' Element-.ype:.*', '', doc) + doc = re.sub(r'#([A-Z]\w*)', r'\1', doc) + + # Remove sentences that refer to functions + doc = re.sub(r'\.\s+[^.]*\w\(\)[^.]*\.', r'.', doc) + + return doc + +def get_default_value(setting, pspec, propxml): + default_value = setting.get_property(pspec.name.replace('-', '_')) + if default_value is None: + return default_value + + value_type = get_prop_type(setting, pspec, propxml) + if value_type == 'string' and default_value != '' and pspec.name != 'name': + default_value = '"%s"' % default_value + elif value_type == 'gchar' and default_value != '': + default_value = "'%s'" % default_value + elif value_type == 'boolean': + default_value = str(default_value).upper() + elif value_type == 'byte array': + default_value = '[]' + elif str(default_value).startswith('<'): + default_value = None + + return default_value + +def escape(val): + return str(val).replace('"', '"') + +def usage(): + print("Usage: %s --gir FILE --output FILE" % sys.argv[0]) + exit() + +parser = argparse.ArgumentParser() +parser.add_argument('-g', '--gir', metavar='FILE', help='NM-1.0.gir file') +parser.add_argument('-x', '--overrides', metavar='FILE', help='documentation overrides file') +parser.add_argument('-o', '--output', metavar='FILE', help='output file') + +args = parser.parse_args() +if args.gir is None or args.output is None: + usage() + +girxml = ET.parse(args.gir).getroot() +outfile = open(args.output, mode='w') + +basexml = girxml.find('./gi:namespace/gi:class[@name="Setting"]', ns_map) +settings = girxml.findall('./gi:namespace/gi:class[@parent="Setting"]', ns_map) +# Hack. Need a better way to do this +ipxml = girxml.find('./gi:namespace/gi:class[@name="SettingIPConfig"]', ns_map) +settings.extend(girxml.findall('./gi:namespace/gi:class[@parent="SettingIPConfig"]', ns_map)) +settings = sorted(settings, key=lambda setting: setting.attrib['{%s}symbol-prefix' % ns_map['c']]) + +init_constants(girxml, settings) + +if args.overrides is not None: + overrides = ET.parse(args.overrides).getroot() + +outfile.write(""" + +]> + +""") + +for settingxml in settings: + if settingxml.attrib.has_key('abstract'): + continue + + new_func = NM.__getattr__(settingxml.attrib['name']) + setting = new_func() + + outfile.write(" \n" % setting.props.name) + + setting_properties = { prop.name: prop for prop in GObject.list_properties(setting) } + if args.overrides is None: + setting_overrides = {} + else: + setting_overrides = { override.attrib['name']: override for override in overrides.findall('./setting[@name="%s"]/property' % setting.props.name) } + + properties = sorted(set.union(set(setting_properties.keys()), set(setting_overrides.keys()))) + + for prop in properties: + value_type = None + value_desc = None + default_value = None + + if prop in setting_properties: + pspec = setting_properties[prop] + propxml = settingxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + if propxml is None: + propxml = basexml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + if propxml is None: + propxml = ipxml.find('./gi:property[@name="%s"]' % pspec.name, ns_map) + + value_type = get_prop_type(setting, pspec, propxml) + value_desc = get_docs(setting, pspec, propxml) + default_value = get_default_value(setting, pspec, propxml) + + if prop in setting_overrides: + override = setting_overrides[prop] + if override.attrib['format'] != '': + value_type = override.attrib['format'] + if override.attrib['description'] != '': + value_desc = override.attrib['description'] + + if default_value is not None: + outfile.write(" \n" % + (prop, value_type, escape(default_value), escape(value_desc))) + else: + outfile.write(" \n" % + (prop, value_type, escape(value_desc))) + + outfile.write(" \n") + +outfile.write("\n") +outfile.close() diff --git a/libnm/libnm.pc.in b/libnm/libnm.pc.in new file mode 100644 index 00000000..6392799a --- /dev/null +++ b/libnm/libnm.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libnm +Description: Convenience library for clients of NetworkManager +Version: @VERSION@ +Requires: gio-2.0 dbus-glib-1 +Cflags: -I${includedir}/libnm +Libs: -L${libdir} -lnm + + diff --git a/libnm/libnm.ver b/libnm/libnm.ver new file mode 100644 index 00000000..82bcdb9f --- /dev/null +++ b/libnm/libnm.ver @@ -0,0 +1,846 @@ +libnm_1_0_0 { +global: + nm_802_11_ap_flags_get_type; + nm_802_11_ap_security_flags_get_type; + nm_802_11_mode_get_type; + nm_access_point_connection_valid; + nm_access_point_filter_connections; + nm_access_point_get_bssid; + nm_access_point_get_flags; + nm_access_point_get_frequency; + nm_access_point_get_max_bitrate; + nm_access_point_get_mode; + nm_access_point_get_rsn_flags; + nm_access_point_get_ssid; + nm_access_point_get_strength; + nm_access_point_get_type; + nm_access_point_get_wpa_flags; + nm_active_connection_get_connection; + nm_active_connection_get_connection_type; + nm_active_connection_get_default6; + nm_active_connection_get_default; + nm_active_connection_get_devices; + nm_active_connection_get_dhcp4_config; + nm_active_connection_get_dhcp6_config; + nm_active_connection_get_id; + nm_active_connection_get_ip4_config; + nm_active_connection_get_ip6_config; + nm_active_connection_get_master; + nm_active_connection_get_specific_object_path; + nm_active_connection_get_state; + nm_active_connection_get_type; + nm_active_connection_get_uuid; + nm_active_connection_get_vpn; + nm_active_connection_state_get_type; + nm_agent_manager_error_get_type; + nm_agent_manager_error_quark; + nm_bluetooth_capabilities_get_type; + nm_client_activate_connection_async; + nm_client_activate_connection_finish; + nm_client_add_and_activate_connection_async; + nm_client_add_and_activate_connection_finish; + nm_client_add_connection_async; + nm_client_add_connection_finish; + nm_client_check_connectivity; + nm_client_check_connectivity_async; + nm_client_check_connectivity_finish; + nm_client_deactivate_connection; + nm_client_deactivate_connection_async; + nm_client_deactivate_connection_finish; + nm_client_error_get_type; + nm_client_error_quark; + nm_client_get_activating_connection; + nm_client_get_active_connections; + nm_client_get_connection_by_id; + nm_client_get_connection_by_path; + nm_client_get_connection_by_uuid; + nm_client_get_connections; + nm_client_get_connectivity; + nm_client_get_device_by_iface; + nm_client_get_device_by_path; + nm_client_get_devices; + nm_client_get_logging; + nm_client_get_nm_running; + nm_client_get_permission_result; + nm_client_get_primary_connection; + nm_client_get_startup; + nm_client_get_state; + nm_client_get_type; + nm_client_get_version; + nm_client_load_connections; + nm_client_load_connections_async; + nm_client_load_connections_finish; + nm_client_networking_get_enabled; + nm_client_networking_set_enabled; + nm_client_new; + nm_client_new_async; + nm_client_new_finish; + nm_client_permission_get_type; + nm_client_permission_result_get_type; + nm_client_reload_connections; + nm_client_reload_connections_async; + nm_client_reload_connections_finish; + nm_client_save_hostname; + nm_client_save_hostname_async; + nm_client_save_hostname_finish; + nm_client_set_logging; + nm_client_wimax_get_enabled; + nm_client_wimax_hardware_get_enabled; + nm_client_wimax_set_enabled; + nm_client_wireless_get_enabled; + nm_client_wireless_hardware_get_enabled; + nm_client_wireless_set_enabled; + nm_client_wwan_get_enabled; + nm_client_wwan_hardware_get_enabled; + nm_client_wwan_set_enabled; + nm_connection_add_setting; + nm_connection_clear_secrets; + nm_connection_clear_secrets_with_flags; + nm_connection_clear_settings; + nm_connection_compare; + nm_connection_diff; + nm_connection_dump; + nm_connection_error_get_type; + nm_connection_error_quark; + nm_connection_for_each_setting_value; + nm_connection_get_connection_type; + nm_connection_get_id; + nm_connection_get_interface_name; + nm_connection_get_path; + nm_connection_get_setting; + nm_connection_get_setting_802_1x; + nm_connection_get_setting_adsl; + nm_connection_get_setting_bluetooth; + nm_connection_get_setting_bond; + nm_connection_get_setting_bridge; + nm_connection_get_setting_bridge_port; + nm_connection_get_setting_by_name; + nm_connection_get_setting_cdma; + nm_connection_get_setting_connection; + nm_connection_get_setting_dcb; + nm_connection_get_setting_generic; + nm_connection_get_setting_gsm; + nm_connection_get_setting_infiniband; + nm_connection_get_setting_ip4_config; + nm_connection_get_setting_ip6_config; + nm_connection_get_setting_olpc_mesh; + nm_connection_get_setting_ppp; + nm_connection_get_setting_pppoe; + nm_connection_get_setting_serial; + nm_connection_get_setting_team; + nm_connection_get_setting_team_port; + nm_connection_get_setting_vlan; + nm_connection_get_setting_vpn; + nm_connection_get_setting_wimax; + nm_connection_get_setting_wired; + nm_connection_get_setting_wireless; + nm_connection_get_setting_wireless_security; + nm_connection_get_type; + nm_connection_get_uuid; + nm_connection_get_virtual_device_description; + nm_connection_is_type; + nm_connection_is_virtual; + nm_connection_need_secrets; + nm_connection_normalize; + nm_connection_remove_setting; + nm_connection_replace_settings; + nm_connection_replace_settings_from_connection; + nm_connection_serialization_flags_get_type; + nm_connection_set_path; + nm_connection_to_dbus; + nm_connection_update_secrets; + nm_connection_verify; + nm_connectivity_state_get_type; + nm_crypto_error_get_type; + nm_crypto_error_quark; + nm_device_adsl_get_carrier; + nm_device_adsl_get_type; + nm_device_bond_get_carrier; + nm_device_bond_get_hw_address; + nm_device_bond_get_slaves; + nm_device_bond_get_type; + nm_device_bridge_get_carrier; + nm_device_bridge_get_hw_address; + nm_device_bridge_get_slaves; + nm_device_bridge_get_type; + nm_device_bt_get_capabilities; + nm_device_bt_get_hw_address; + nm_device_bt_get_name; + nm_device_bt_get_type; + nm_device_capabilities_get_type; + nm_device_connection_compatible; + nm_device_connection_valid; + nm_device_delete; + nm_device_delete_async; + nm_device_delete_finish; + nm_device_disambiguate_names; + nm_device_disconnect; + nm_device_disconnect_async; + nm_device_disconnect_finish; + nm_device_error_get_type; + nm_device_error_quark; + nm_device_ethernet_get_carrier; + nm_device_ethernet_get_hw_address; + nm_device_ethernet_get_permanent_hw_address; + nm_device_ethernet_get_speed; + nm_device_ethernet_get_type; + nm_device_filter_connections; + nm_device_generic_get_hw_address; + nm_device_generic_get_type; + nm_device_get_active_connection; + nm_device_get_autoconnect; + nm_device_get_available_connections; + nm_device_get_capabilities; + nm_device_get_description; + nm_device_get_device_type; + nm_device_get_dhcp4_config; + nm_device_get_dhcp6_config; + nm_device_get_driver; + nm_device_get_driver_version; + nm_device_get_firmware_missing; + nm_device_get_firmware_version; + nm_device_get_hw_address; + nm_device_get_iface; + nm_device_get_ip4_config; + nm_device_get_ip6_config; + nm_device_get_ip_iface; + nm_device_get_managed; + nm_device_get_mtu; + nm_device_get_physical_port_id; + nm_device_get_product; + nm_device_get_setting_type; + nm_device_get_state; + nm_device_get_state_reason; + nm_device_get_type; + nm_device_get_type_description; + nm_device_get_udi; + nm_device_get_vendor; + nm_device_infiniband_get_carrier; + nm_device_infiniband_get_hw_address; + nm_device_infiniband_get_type; + nm_device_is_software; + nm_device_modem_capabilities_get_type; + nm_device_modem_get_current_capabilities; + nm_device_modem_get_modem_capabilities; + nm_device_modem_get_type; + nm_device_olpc_mesh_get_active_channel; + nm_device_olpc_mesh_get_companion; + nm_device_olpc_mesh_get_hw_address; + nm_device_olpc_mesh_get_type; + nm_device_set_autoconnect; + nm_device_state_get_type; + nm_device_state_reason_get_type; + nm_device_team_get_carrier; + nm_device_team_get_hw_address; + nm_device_team_get_slaves; + nm_device_team_get_type; + nm_device_type_get_type; + nm_device_vlan_get_carrier; + nm_device_vlan_get_hw_address; + nm_device_vlan_get_parent; + nm_device_vlan_get_type; + nm_device_vlan_get_vlan_id; + nm_device_wifi_capabilities_get_type; + nm_device_wifi_get_access_point_by_path; + nm_device_wifi_get_access_points; + nm_device_wifi_get_active_access_point; + nm_device_wifi_get_bitrate; + nm_device_wifi_get_capabilities; + nm_device_wifi_get_hw_address; + nm_device_wifi_get_mode; + nm_device_wifi_get_permanent_hw_address; + nm_device_wifi_get_type; + nm_device_wifi_request_scan; + nm_device_wifi_request_scan_async; + nm_device_wifi_request_scan_finish; + nm_device_wimax_get_active_nsp; + nm_device_wimax_get_bsid; + nm_device_wimax_get_center_frequency; + nm_device_wimax_get_cinr; + nm_device_wimax_get_hw_address; + nm_device_wimax_get_nsp_by_path; + nm_device_wimax_get_nsps; + nm_device_wimax_get_rssi; + nm_device_wimax_get_tx_power; + nm_device_wimax_get_type; + nm_dhcp_config_get_family; + nm_dhcp_config_get_one_option; + nm_dhcp_config_get_options; + nm_dhcp_config_get_type; + nm_ip_address_equal; + nm_ip_address_get_address; + nm_ip_address_get_address_binary; + nm_ip_address_get_attribute; + nm_ip_address_get_attribute_names; + nm_ip_address_get_family; + nm_ip_address_get_prefix; + nm_ip_address_get_type; + nm_ip_address_new; + nm_ip_address_new_binary; + nm_ip_address_ref; + nm_ip_address_set_address; + nm_ip_address_set_address_binary; + nm_ip_address_set_attribute; + nm_ip_address_set_prefix; + nm_ip_address_unref; + nm_ip_config_get_addresses; + nm_ip_config_get_domains; + nm_ip_config_get_family; + nm_ip_config_get_gateway; + nm_ip_config_get_nameservers; + nm_ip_config_get_routes; + nm_ip_config_get_searches; + nm_ip_config_get_type; + nm_ip_config_get_wins_servers; + nm_ip_route_equal; + nm_ip_route_get_attribute; + nm_ip_route_get_attribute_names; + nm_ip_route_get_dest; + nm_ip_route_get_dest_binary; + nm_ip_route_get_family; + nm_ip_route_get_metric; + nm_ip_route_get_next_hop; + nm_ip_route_get_next_hop_binary; + nm_ip_route_get_prefix; + nm_ip_route_get_type; + nm_ip_route_new; + nm_ip_route_new_binary; + nm_ip_route_ref; + nm_ip_route_set_attribute; + nm_ip_route_set_dest; + nm_ip_route_set_dest_binary; + nm_ip_route_set_metric; + nm_ip_route_set_next_hop; + nm_ip_route_set_next_hop_binary; + nm_ip_route_set_prefix; + nm_ip_route_unref; + nm_manager_error_get_type; + nm_manager_error_quark; + nm_object_get_path; + nm_object_get_type; + nm_remote_connection_commit_changes; + nm_remote_connection_commit_changes_async; + nm_remote_connection_commit_changes_finish; + nm_remote_connection_delete; + nm_remote_connection_delete_async; + nm_remote_connection_delete_finish; + nm_remote_connection_get_secrets; + nm_remote_connection_get_secrets_async; + nm_remote_connection_get_secrets_finish; + nm_remote_connection_get_type; + nm_remote_connection_get_unsaved; + nm_remote_connection_get_visible; + nm_remote_connection_save; + nm_remote_connection_save_async; + nm_remote_connection_save_finish; + nm_secret_agent_capabilities_get_type; + nm_secret_agent_error_get_type; + nm_secret_agent_error_quark; + nm_secret_agent_get_secrets_flags_get_type; + nm_secret_agent_old_delete_secrets; + nm_secret_agent_old_get_registered; + nm_secret_agent_old_get_secrets; + nm_secret_agent_old_get_type; + nm_secret_agent_old_register; + nm_secret_agent_old_register_async; + nm_secret_agent_old_register_finish; + nm_secret_agent_old_save_secrets; + nm_secret_agent_old_unregister; + nm_secret_agent_old_unregister_async; + nm_secret_agent_old_unregister_finish; + nm_setting_802_1x_add_altsubject_match; + nm_setting_802_1x_add_eap_method; + nm_setting_802_1x_add_phase2_altsubject_match; + nm_setting_802_1x_ck_format_get_type; + nm_setting_802_1x_ck_scheme_get_type; + nm_setting_802_1x_clear_altsubject_matches; + nm_setting_802_1x_clear_eap_methods; + nm_setting_802_1x_clear_phase2_altsubject_matches; + nm_setting_802_1x_get_altsubject_match; + nm_setting_802_1x_get_anonymous_identity; + nm_setting_802_1x_get_ca_cert_blob; + nm_setting_802_1x_get_ca_cert_path; + nm_setting_802_1x_get_ca_cert_scheme; + nm_setting_802_1x_get_ca_path; + nm_setting_802_1x_get_client_cert_blob; + nm_setting_802_1x_get_client_cert_path; + nm_setting_802_1x_get_client_cert_scheme; + nm_setting_802_1x_get_eap_method; + nm_setting_802_1x_get_identity; + nm_setting_802_1x_get_num_altsubject_matches; + nm_setting_802_1x_get_num_eap_methods; + nm_setting_802_1x_get_num_phase2_altsubject_matches; + nm_setting_802_1x_get_pac_file; + nm_setting_802_1x_get_password; + nm_setting_802_1x_get_password_flags; + nm_setting_802_1x_get_password_raw; + nm_setting_802_1x_get_password_raw_flags; + nm_setting_802_1x_get_phase1_fast_provisioning; + nm_setting_802_1x_get_phase1_peaplabel; + nm_setting_802_1x_get_phase1_peapver; + nm_setting_802_1x_get_phase2_altsubject_match; + nm_setting_802_1x_get_phase2_auth; + nm_setting_802_1x_get_phase2_autheap; + nm_setting_802_1x_get_phase2_ca_cert_blob; + nm_setting_802_1x_get_phase2_ca_cert_path; + nm_setting_802_1x_get_phase2_ca_cert_scheme; + nm_setting_802_1x_get_phase2_ca_path; + nm_setting_802_1x_get_phase2_client_cert_blob; + nm_setting_802_1x_get_phase2_client_cert_path; + nm_setting_802_1x_get_phase2_client_cert_scheme; + nm_setting_802_1x_get_phase2_private_key_blob; + nm_setting_802_1x_get_phase2_private_key_format; + nm_setting_802_1x_get_phase2_private_key_password; + nm_setting_802_1x_get_phase2_private_key_password_flags; + nm_setting_802_1x_get_phase2_private_key_path; + nm_setting_802_1x_get_phase2_private_key_scheme; + nm_setting_802_1x_get_phase2_subject_match; + nm_setting_802_1x_get_pin; + nm_setting_802_1x_get_pin_flags; + nm_setting_802_1x_get_private_key_blob; + nm_setting_802_1x_get_private_key_format; + nm_setting_802_1x_get_private_key_password; + nm_setting_802_1x_get_private_key_password_flags; + nm_setting_802_1x_get_private_key_path; + nm_setting_802_1x_get_private_key_scheme; + nm_setting_802_1x_get_subject_match; + nm_setting_802_1x_get_system_ca_certs; + nm_setting_802_1x_get_type; + nm_setting_802_1x_new; + nm_setting_802_1x_remove_altsubject_match; + nm_setting_802_1x_remove_altsubject_match_by_value; + nm_setting_802_1x_remove_eap_method; + nm_setting_802_1x_remove_eap_method_by_value; + nm_setting_802_1x_remove_phase2_altsubject_match; + nm_setting_802_1x_remove_phase2_altsubject_match_by_value; + nm_setting_802_1x_set_ca_cert; + nm_setting_802_1x_set_client_cert; + nm_setting_802_1x_set_phase2_ca_cert; + nm_setting_802_1x_set_phase2_client_cert; + nm_setting_802_1x_set_phase2_private_key; + nm_setting_802_1x_set_private_key; + nm_setting_adsl_get_encapsulation; + nm_setting_adsl_get_password; + nm_setting_adsl_get_password_flags; + nm_setting_adsl_get_protocol; + nm_setting_adsl_get_type; + nm_setting_adsl_get_username; + nm_setting_adsl_get_vci; + nm_setting_adsl_get_vpi; + nm_setting_adsl_new; + nm_setting_bluetooth_get_bdaddr; + nm_setting_bluetooth_get_connection_type; + nm_setting_bluetooth_get_type; + nm_setting_bluetooth_new; + nm_setting_bond_add_option; + nm_setting_bond_get_num_options; + nm_setting_bond_get_option; + nm_setting_bond_get_option_by_name; + nm_setting_bond_get_option_default; + nm_setting_bond_get_type; + nm_setting_bond_get_valid_options; + nm_setting_bond_new; + nm_setting_bond_remove_option; + nm_setting_bond_validate_option; + nm_setting_bridge_get_ageing_time; + nm_setting_bridge_get_forward_delay; + nm_setting_bridge_get_hello_time; + nm_setting_bridge_get_mac_address; + nm_setting_bridge_get_max_age; + nm_setting_bridge_get_priority; + nm_setting_bridge_get_stp; + nm_setting_bridge_get_type; + nm_setting_bridge_new; + nm_setting_bridge_port_get_hairpin_mode; + nm_setting_bridge_port_get_path_cost; + nm_setting_bridge_port_get_priority; + nm_setting_bridge_port_get_type; + nm_setting_bridge_port_new; + nm_setting_cdma_get_number; + nm_setting_cdma_get_password; + nm_setting_cdma_get_password_flags; + nm_setting_cdma_get_type; + nm_setting_cdma_get_username; + nm_setting_cdma_new; + nm_setting_compare; + nm_setting_compare_flags_get_type; + nm_setting_connection_add_permission; + nm_setting_connection_add_secondary; + nm_setting_connection_get_autoconnect; + nm_setting_connection_get_autoconnect_priority; + nm_setting_connection_get_connection_type; + nm_setting_connection_get_gateway_ping_timeout; + nm_setting_connection_get_id; + nm_setting_connection_get_interface_name; + nm_setting_connection_get_master; + nm_setting_connection_get_num_permissions; + nm_setting_connection_get_num_secondaries; + nm_setting_connection_get_permission; + nm_setting_connection_get_read_only; + nm_setting_connection_get_secondary; + nm_setting_connection_get_slave_type; + nm_setting_connection_get_timestamp; + nm_setting_connection_get_type; + nm_setting_connection_get_uuid; + nm_setting_connection_get_zone; + nm_setting_connection_is_slave_type; + nm_setting_connection_new; + nm_setting_connection_permissions_user_allowed; + nm_setting_connection_remove_permission; + nm_setting_connection_remove_permission_by_value; + nm_setting_connection_remove_secondary; + nm_setting_connection_remove_secondary_by_value; + nm_setting_dcb_flags_get_type; + nm_setting_dcb_get_app_fcoe_flags; + nm_setting_dcb_get_app_fcoe_mode; + nm_setting_dcb_get_app_fcoe_priority; + nm_setting_dcb_get_app_fip_flags; + nm_setting_dcb_get_app_fip_priority; + nm_setting_dcb_get_app_iscsi_flags; + nm_setting_dcb_get_app_iscsi_priority; + nm_setting_dcb_get_priority_bandwidth; + nm_setting_dcb_get_priority_flow_control; + nm_setting_dcb_get_priority_flow_control_flags; + nm_setting_dcb_get_priority_group_bandwidth; + nm_setting_dcb_get_priority_group_flags; + nm_setting_dcb_get_priority_group_id; + nm_setting_dcb_get_priority_strict_bandwidth; + nm_setting_dcb_get_priority_traffic_class; + nm_setting_dcb_get_type; + nm_setting_dcb_new; + nm_setting_dcb_set_priority_bandwidth; + nm_setting_dcb_set_priority_flow_control; + nm_setting_dcb_set_priority_group_bandwidth; + nm_setting_dcb_set_priority_group_id; + nm_setting_dcb_set_priority_strict_bandwidth; + nm_setting_dcb_set_priority_traffic_class; + nm_setting_diff; + nm_setting_diff_result_get_type; + nm_setting_duplicate; + nm_setting_enumerate_values; + nm_setting_generic_get_type; + nm_setting_generic_new; + nm_setting_get_dbus_property_type; + nm_setting_get_name; + nm_setting_get_secret_flags; + nm_setting_get_type; + nm_setting_gsm_get_apn; + nm_setting_gsm_get_home_only; + nm_setting_gsm_get_network_id; + nm_setting_gsm_get_number; + nm_setting_gsm_get_password; + nm_setting_gsm_get_password_flags; + nm_setting_gsm_get_pin; + nm_setting_gsm_get_pin_flags; + nm_setting_gsm_get_type; + nm_setting_gsm_get_username; + nm_setting_gsm_new; + nm_setting_infiniband_get_mac_address; + nm_setting_infiniband_get_mtu; + nm_setting_infiniband_get_p_key; + nm_setting_infiniband_get_parent; + nm_setting_infiniband_get_transport_mode; + nm_setting_infiniband_get_type; + nm_setting_infiniband_get_virtual_interface_name; + nm_setting_infiniband_new; + nm_setting_ip4_config_get_dhcp_client_id; + nm_setting_ip4_config_get_type; + nm_setting_ip4_config_new; + nm_setting_ip6_config_get_ip6_privacy; + nm_setting_ip6_config_get_type; + nm_setting_ip6_config_new; + nm_setting_ip6_config_privacy_get_type; + nm_setting_ip_config_add_address; + nm_setting_ip_config_add_dns; + nm_setting_ip_config_add_dns_search; + nm_setting_ip_config_add_route; + nm_setting_ip_config_clear_addresses; + nm_setting_ip_config_clear_dns; + nm_setting_ip_config_clear_dns_searches; + nm_setting_ip_config_clear_routes; + nm_setting_ip_config_get_address; + nm_setting_ip_config_get_dhcp_hostname; + nm_setting_ip_config_get_dhcp_send_hostname; + nm_setting_ip_config_get_dns; + nm_setting_ip_config_get_dns_search; + nm_setting_ip_config_get_gateway; + nm_setting_ip_config_get_ignore_auto_dns; + nm_setting_ip_config_get_ignore_auto_routes; + nm_setting_ip_config_get_may_fail; + nm_setting_ip_config_get_method; + nm_setting_ip_config_get_never_default; + nm_setting_ip_config_get_num_addresses; + nm_setting_ip_config_get_num_dns; + nm_setting_ip_config_get_num_dns_searches; + nm_setting_ip_config_get_num_routes; + nm_setting_ip_config_get_route; + nm_setting_ip_config_get_route_metric; + nm_setting_ip_config_get_type; + nm_setting_ip_config_remove_address; + nm_setting_ip_config_remove_address_by_value; + nm_setting_ip_config_remove_dns; + nm_setting_ip_config_remove_dns_by_value; + nm_setting_ip_config_remove_dns_search; + nm_setting_ip_config_remove_dns_search_by_value; + nm_setting_ip_config_remove_route; + nm_setting_ip_config_remove_route_by_value; + nm_setting_lookup_type; + nm_setting_olpc_mesh_get_channel; + nm_setting_olpc_mesh_get_dhcp_anycast_address; + nm_setting_olpc_mesh_get_ssid; + nm_setting_olpc_mesh_get_type; + nm_setting_olpc_mesh_new; + nm_setting_ppp_get_baud; + nm_setting_ppp_get_crtscts; + nm_setting_ppp_get_lcp_echo_failure; + nm_setting_ppp_get_lcp_echo_interval; + nm_setting_ppp_get_mppe_stateful; + nm_setting_ppp_get_mru; + nm_setting_ppp_get_mtu; + nm_setting_ppp_get_no_vj_comp; + nm_setting_ppp_get_noauth; + nm_setting_ppp_get_nobsdcomp; + nm_setting_ppp_get_nodeflate; + nm_setting_ppp_get_refuse_chap; + nm_setting_ppp_get_refuse_eap; + nm_setting_ppp_get_refuse_mschap; + nm_setting_ppp_get_refuse_mschapv2; + nm_setting_ppp_get_refuse_pap; + nm_setting_ppp_get_require_mppe; + nm_setting_ppp_get_require_mppe_128; + nm_setting_ppp_get_type; + nm_setting_ppp_new; + nm_setting_pppoe_get_password; + nm_setting_pppoe_get_password_flags; + nm_setting_pppoe_get_service; + nm_setting_pppoe_get_type; + nm_setting_pppoe_get_username; + nm_setting_pppoe_new; + nm_setting_secret_flags_get_type; + nm_setting_serial_get_baud; + nm_setting_serial_get_bits; + nm_setting_serial_get_parity; + nm_setting_serial_get_send_delay; + nm_setting_serial_get_stopbits; + nm_setting_serial_get_type; + nm_setting_serial_new; + nm_setting_serial_parity_get_type; + nm_setting_set_secret_flags; + nm_setting_team_get_config; + nm_setting_team_get_type; + nm_setting_team_new; + nm_setting_team_port_get_config; + nm_setting_team_port_get_type; + nm_setting_team_port_new; + nm_setting_to_string; + nm_setting_verify; + nm_setting_vlan_add_priority; + nm_setting_vlan_add_priority_str; + nm_setting_vlan_clear_priorities; + nm_setting_vlan_get_flags; + nm_setting_vlan_get_id; + nm_setting_vlan_get_num_priorities; + nm_setting_vlan_get_parent; + nm_setting_vlan_get_priority; + nm_setting_vlan_get_type; + nm_setting_vlan_new; + nm_setting_vlan_remove_priority; + nm_setting_vlan_remove_priority_by_value; + nm_setting_vlan_remove_priority_str_by_value; + nm_setting_vpn_add_data_item; + nm_setting_vpn_add_secret; + nm_setting_vpn_foreach_data_item; + nm_setting_vpn_foreach_secret; + nm_setting_vpn_get_data_item; + nm_setting_vpn_get_num_data_items; + nm_setting_vpn_get_num_secrets; + nm_setting_vpn_get_secret; + nm_setting_vpn_get_service_type; + nm_setting_vpn_get_type; + nm_setting_vpn_get_user_name; + nm_setting_vpn_new; + nm_setting_vpn_remove_data_item; + nm_setting_vpn_remove_secret; + nm_setting_wimax_get_mac_address; + nm_setting_wimax_get_network_name; + nm_setting_wimax_get_type; + nm_setting_wimax_new; + nm_setting_wired_add_mac_blacklist_item; + nm_setting_wired_add_s390_option; + nm_setting_wired_clear_mac_blacklist_items; + nm_setting_wired_get_auto_negotiate; + nm_setting_wired_get_cloned_mac_address; + nm_setting_wired_get_duplex; + nm_setting_wired_get_mac_address; + nm_setting_wired_get_mac_address_blacklist; + nm_setting_wired_get_mac_blacklist_item; + nm_setting_wired_get_mtu; + nm_setting_wired_get_num_mac_blacklist_items; + nm_setting_wired_get_num_s390_options; + nm_setting_wired_get_port; + nm_setting_wired_get_s390_nettype; + nm_setting_wired_get_s390_option; + nm_setting_wired_get_s390_option_by_key; + nm_setting_wired_get_s390_subchannels; + nm_setting_wired_get_speed; + nm_setting_wired_get_type; + nm_setting_wired_get_valid_s390_options; + nm_setting_wired_new; + nm_setting_wired_remove_mac_blacklist_item; + nm_setting_wired_remove_mac_blacklist_item_by_value; + nm_setting_wired_remove_s390_option; + nm_setting_wireless_add_mac_blacklist_item; + nm_setting_wireless_add_seen_bssid; + nm_setting_wireless_ap_security_compatible; + nm_setting_wireless_clear_mac_blacklist_items; + nm_setting_wireless_get_band; + nm_setting_wireless_get_bssid; + nm_setting_wireless_get_channel; + nm_setting_wireless_get_cloned_mac_address; + nm_setting_wireless_get_hidden; + nm_setting_wireless_get_mac_address; + nm_setting_wireless_get_mac_address_blacklist; + nm_setting_wireless_get_mac_blacklist_item; + nm_setting_wireless_get_mode; + nm_setting_wireless_get_mtu; + nm_setting_wireless_get_num_mac_blacklist_items; + nm_setting_wireless_get_num_seen_bssids; + nm_setting_wireless_get_rate; + nm_setting_wireless_get_seen_bssid; + nm_setting_wireless_get_ssid; + nm_setting_wireless_get_tx_power; + nm_setting_wireless_get_type; + nm_setting_wireless_new; + nm_setting_wireless_remove_mac_blacklist_item; + nm_setting_wireless_remove_mac_blacklist_item_by_value; + nm_setting_wireless_security_add_group; + nm_setting_wireless_security_add_pairwise; + nm_setting_wireless_security_add_proto; + nm_setting_wireless_security_clear_groups; + nm_setting_wireless_security_clear_pairwise; + nm_setting_wireless_security_clear_protos; + nm_setting_wireless_security_get_auth_alg; + nm_setting_wireless_security_get_group; + nm_setting_wireless_security_get_key_mgmt; + nm_setting_wireless_security_get_leap_password; + nm_setting_wireless_security_get_leap_password_flags; + nm_setting_wireless_security_get_leap_username; + nm_setting_wireless_security_get_num_groups; + nm_setting_wireless_security_get_num_pairwise; + nm_setting_wireless_security_get_num_protos; + nm_setting_wireless_security_get_pairwise; + nm_setting_wireless_security_get_proto; + nm_setting_wireless_security_get_psk; + nm_setting_wireless_security_get_psk_flags; + nm_setting_wireless_security_get_type; + nm_setting_wireless_security_get_wep_key; + nm_setting_wireless_security_get_wep_key_flags; + nm_setting_wireless_security_get_wep_key_type; + nm_setting_wireless_security_get_wep_tx_keyidx; + nm_setting_wireless_security_new; + nm_setting_wireless_security_remove_group; + nm_setting_wireless_security_remove_group_by_value; + nm_setting_wireless_security_remove_pairwise; + nm_setting_wireless_security_remove_pairwise_by_value; + nm_setting_wireless_security_remove_proto; + nm_setting_wireless_security_remove_proto_by_value; + nm_setting_wireless_security_set_wep_key; + nm_settings_error_get_type; + nm_settings_error_quark; + nm_simple_connection_get_type; + nm_simple_connection_new; + nm_simple_connection_new_clone; + nm_simple_connection_new_from_dbus; + nm_state_get_type; + nm_utils_ap_mode_security_valid; + nm_utils_bin2hexstr; + nm_utils_check_virtual_device_compatibility; + nm_utils_escape_ssid; + nm_utils_file_is_certificate; + nm_utils_file_is_pkcs12; + nm_utils_file_is_private_key; + nm_utils_file_search_in_paths; + nm_utils_hexstr2bin; + nm_utils_hwaddr_atoba; + nm_utils_hwaddr_aton; + nm_utils_hwaddr_canonical; + nm_utils_hwaddr_len; + nm_utils_hwaddr_matches; + nm_utils_hwaddr_ntoa; + nm_utils_hwaddr_valid; + nm_utils_iface_valid_name; + nm_utils_inet4_ntop; + nm_utils_inet6_ntop; + nm_utils_ip4_addresses_from_variant; + nm_utils_ip4_addresses_to_variant; + nm_utils_ip4_dns_from_variant; + nm_utils_ip4_dns_to_variant; + nm_utils_ip4_get_default_prefix; + nm_utils_ip4_netmask_to_prefix; + nm_utils_ip4_prefix_to_netmask; + nm_utils_ip4_routes_from_variant; + nm_utils_ip4_routes_to_variant; + nm_utils_ip6_addresses_from_variant; + nm_utils_ip6_addresses_to_variant; + nm_utils_ip6_dns_from_variant; + nm_utils_ip6_dns_to_variant; + nm_utils_ip6_routes_from_variant; + nm_utils_ip6_routes_to_variant; + nm_utils_ipaddr_valid; + nm_utils_is_empty_ssid; + nm_utils_is_uuid; + nm_utils_same_ssid; + nm_utils_security_type_get_type; + nm_utils_security_valid; + nm_utils_ssid_to_utf8; + nm_utils_uuid_generate; + nm_utils_wep_key_valid; + nm_utils_wifi_channel_to_freq; + nm_utils_wifi_find_next_channel; + nm_utils_wifi_freq_to_channel; + nm_utils_wifi_is_channel_valid; + nm_utils_wifi_strength_bars; + nm_utils_wpa_psk_valid; + nm_vlan_flags_get_type; + nm_vlan_priority_map_get_type; + nm_vpn_connection_get_banner; + nm_vpn_connection_get_type; + nm_vpn_connection_get_vpn_state; + nm_vpn_connection_state_get_type; + nm_vpn_connection_state_reason_get_type; + nm_vpn_editor_get_type; + nm_vpn_editor_get_widget; + nm_vpn_editor_plugin_capability_get_type; + nm_vpn_editor_plugin_export; + nm_vpn_editor_plugin_get_capabilities; + nm_vpn_editor_plugin_get_editor; + nm_vpn_editor_plugin_get_suggested_filename; + nm_vpn_editor_plugin_get_type; + nm_vpn_editor_plugin_import; + nm_vpn_editor_update_connection; + nm_vpn_plugin_error_get_type; + nm_vpn_plugin_error_quark; + nm_vpn_plugin_failure_get_type; + nm_vpn_plugin_old_disconnect; + nm_vpn_plugin_old_failure; + nm_vpn_plugin_old_get_connection; + nm_vpn_plugin_old_get_secret_flags; + nm_vpn_plugin_old_get_state; + nm_vpn_plugin_old_get_type; + nm_vpn_plugin_old_read_vpn_details; + nm_vpn_plugin_old_secrets_required; + nm_vpn_plugin_old_set_ip4_config; + nm_vpn_plugin_old_set_login_banner; + nm_vpn_plugin_old_set_state; + nm_vpn_service_state_get_type; + nm_wep_key_type_get_type; + nm_wimax_nsp_connection_valid; + nm_wimax_nsp_filter_connections; + nm_wimax_nsp_get_name; + nm_wimax_nsp_get_network_type; + nm_wimax_nsp_get_signal_quality; + nm_wimax_nsp_get_type; + nm_wimax_nsp_network_type_get_type; +local: + *; +}; diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c new file mode 100644 index 00000000..e20cd997 --- /dev/null +++ b/libnm/nm-access-point.c @@ -0,0 +1,598 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-glib-compat.h" + +#include +#include +#include +#include +#include + +#include "nm-access-point.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) + +#define NM_ACCESS_POINT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACCESS_POINT, NMAccessPointPrivate)) + +typedef struct { + NM80211ApFlags flags; + NM80211ApSecurityFlags wpa_flags; + NM80211ApSecurityFlags rsn_flags; + GBytes *ssid; + guint32 frequency; + char *bssid; + NM80211Mode mode; + guint32 max_bitrate; + guint8 strength; +} NMAccessPointPrivate; + +enum { + PROP_0, + PROP_FLAGS, + PROP_WPA_FLAGS, + PROP_RSN_FLAGS, + PROP_SSID, + PROP_FREQUENCY, + PROP_HW_ADDRESS, + PROP_MODE, + PROP_MAX_BITRATE, + PROP_STRENGTH, + PROP_BSSID, + + LAST_PROP +}; + +/** + * nm_access_point_get_flags: + * @ap: a #NMAccessPoint + * + * Gets the flags of the access point. + * + * Returns: the flags + **/ +NM80211ApFlags +nm_access_point_get_flags (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_FLAGS_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->flags; +} + +/** + * nm_access_point_get_wpa_flags: + * @ap: a #NMAccessPoint + * + * Gets the WPA (version 1) flags of the access point. + * + * Returns: the WPA flags + **/ +NM80211ApSecurityFlags +nm_access_point_get_wpa_flags (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_SEC_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->wpa_flags; +} + +/** + * nm_access_point_get_rsn_flags: + * @ap: a #NMAccessPoint + * + * Gets the RSN (Robust Secure Network, ie WPA version 2) flags of the access + * point. + * + * Returns: the RSN flags + **/ +NM80211ApSecurityFlags +nm_access_point_get_rsn_flags (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_SEC_NONE); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->rsn_flags; +} + +/** + * nm_access_point_get_ssid: + * @ap: a #NMAccessPoint + * + * Gets the SSID of the access point. + * + * Returns: (transfer none): the #GBytes containing the SSID, or %NULL if the + * SSID is unknown. + **/ +GBytes * +nm_access_point_get_ssid (NMAccessPoint *ap) +{ + NMAccessPointPrivate *priv; + + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL); + + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->ssid || g_bytes_get_size (priv->ssid) == 0) + return NULL; + + return priv->ssid; +} + +/** + * nm_access_point_get_frequency: + * @ap: a #NMAccessPoint + * + * Gets the frequency of the access point. + * + * Returns: the frequency + **/ +guint32 +nm_access_point_get_frequency (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->frequency; +} + +/** + * nm_access_point_get_bssid: + * @ap: a #NMAccessPoint + * + * Gets the Basic Service Set ID (BSSID) of the Wi-Fi access point. + * + * Returns: the BSSID of the access point. This is an internal string and must + * not be modified or freed. + **/ +const char * +nm_access_point_get_bssid (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->bssid; +} + +/** + * nm_access_point_get_mode: + * @ap: a #NMAccessPoint + * + * Gets the mode of the access point. + * + * Returns: the mode + **/ +NM80211Mode +nm_access_point_get_mode (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->mode; +} + +/** + * nm_access_point_get_max_bitrate: + * @ap: a #NMAccessPoint + * + * Gets the maximum bit rate of the access point in kbit/s. + * + * Returns: the maximum bit rate (kbit/s) + **/ +guint32 +nm_access_point_get_max_bitrate (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->max_bitrate; +} + +/** + * nm_access_point_get_strength: + * @ap: a #NMAccessPoint + * + * Gets the current signal strength of the access point. + * + * Returns: the signal strength + **/ +guint8 +nm_access_point_get_strength (NMAccessPoint *ap) +{ + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); + + return NM_ACCESS_POINT_GET_PRIVATE (ap)->strength; +} + +/** + * nm_access_point_connection_valid: + * @ap: an #NMAccessPoint to validate @connection against + * @connection: an #NMConnection to validate against @ap + * + * Validates a given connection against a given Wi-Fi access point to ensure that + * the connection may be activated with that AP. The connection must match the + * @ap's SSID, (if given) BSSID, and other attributes like security settings, + * channel, band, etc. + * + * Returns: %TRUE if the connection may be activated with this Wi-Fi AP, + * %FALSE if it cannot be. + **/ +gboolean +nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection) +{ + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char *ctype, *ap_bssid; + GBytes *setting_ssid; + GBytes *ap_ssid; + const char *setting_bssid; + const char *setting_mode; + NM80211Mode ap_mode; + const char *setting_band; + guint32 ap_freq, setting_chan, ap_chan; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + ctype = nm_setting_connection_get_connection_type (s_con); + if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0) + return FALSE; + + s_wifi = nm_connection_get_setting_wireless (connection); + if (!s_wifi) + return FALSE; + + /* SSID checks */ + ap_ssid = nm_access_point_get_ssid (ap); + g_warn_if_fail (ap_ssid != NULL); + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (!setting_ssid || !ap_ssid) + return FALSE; + if (!g_bytes_equal (ap_ssid, setting_ssid)) + return FALSE; + + /* BSSID checks */ + ap_bssid = nm_access_point_get_bssid (ap); + g_warn_if_fail (ap_bssid); + setting_bssid = nm_setting_wireless_get_bssid (s_wifi); + if (setting_bssid && ap_bssid) { + if (!nm_utils_hwaddr_matches (ap_bssid, -1, setting_bssid, -1)) + return FALSE; + } + + /* Mode */ + ap_mode = nm_access_point_get_mode (ap); + g_warn_if_fail (ap_mode != NM_802_11_MODE_UNKNOWN); + setting_mode = nm_setting_wireless_get_mode (s_wifi); + if (setting_mode && ap_mode) { + if (!strcmp (setting_mode, "infrastructure") && (ap_mode != NM_802_11_MODE_INFRA)) + return FALSE; + if (!strcmp (setting_mode, "adhoc") && (ap_mode != NM_802_11_MODE_ADHOC)) + return FALSE; + /* Hotspot never matches against APs as it's a device-specific mode. */ + if (!strcmp (setting_mode, "ap")) + return FALSE; + } + + /* Band and Channel/Frequency */ + ap_freq = nm_access_point_get_frequency (ap); + if (ap_freq) { + setting_band = nm_setting_wireless_get_band (s_wifi); + if (g_strcmp0 (setting_band, "a") == 0) { + if (ap_freq < 4915 || ap_freq > 5825) + return FALSE; + } else if (g_strcmp0 (setting_band, "bg") == 0) { + if (ap_freq < 2412 || ap_freq > 2484) + return FALSE; + } + + setting_chan = nm_setting_wireless_get_channel (s_wifi); + if (setting_chan) { + ap_chan = nm_utils_wifi_freq_to_channel (ap_freq); + if (setting_chan != ap_chan) + return FALSE; + } + } + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (!nm_setting_wireless_ap_security_compatible (s_wifi, + s_wsec, + nm_access_point_get_flags (ap), + nm_access_point_get_wpa_flags (ap), + nm_access_point_get_rsn_flags (ap), + ap_mode)) + return FALSE; + + return TRUE; +} + +/** + * nm_access_point_filter_connections: + * @ap: an #NMAccessPoint to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to + * filter + * + * Filters a given array of connections for a given #NMAccessPoint object and + * returns connections which may be activated with the access point. Any + * returned connections will match the @ap's SSID and (if given) BSSID and + * other attributes like security settings, channel, etc. + * + * To obtain the list of connections that are compatible with this access point, + * use nm_client_get_connections() and then filter the returned list for a given + * #NMDevice using nm_device_filter_connections() and finally filter that list + * with this function. + * + * Returns: (transfer container) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @ap. The array should + * be freed with g_ptr_array_unref() when it is no longer required. + **/ +GPtrArray * +nm_access_point_filter_connections (NMAccessPoint *ap, const GPtrArray *connections) +{ + GPtrArray *filtered; + int i; + + filtered = g_ptr_array_new_with_free_func (g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + if (nm_access_point_connection_valid (ap, candidate)) + g_ptr_array_add (filtered, g_object_ref (candidate)); + } + + return filtered; +} + +/************************************************************/ + +static void +nm_access_point_init (NMAccessPoint *ap) +{ +} + +static void +finalize (GObject *object) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); + + if (priv->ssid) + g_bytes_unref (priv->ssid); + + g_free (priv->bssid); + + G_OBJECT_CLASS (nm_access_point_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMAccessPoint *ap = NM_ACCESS_POINT (object); + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_flags (value, nm_access_point_get_flags (ap)); + break; + case PROP_WPA_FLAGS: + g_value_set_flags (value, nm_access_point_get_wpa_flags (ap)); + break; + case PROP_RSN_FLAGS: + g_value_set_flags (value, nm_access_point_get_rsn_flags (ap)); + break; + case PROP_SSID: + g_value_set_boxed (value, nm_access_point_get_ssid (ap)); + break; + case PROP_FREQUENCY: + g_value_set_uint (value, nm_access_point_get_frequency (ap)); + break; + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_access_point_get_bssid (ap)); + break; + case PROP_BSSID: + g_value_set_string (value, nm_access_point_get_bssid (ap)); + break; + case PROP_MODE: + g_value_set_enum (value, nm_access_point_get_mode (ap)); + break; + case PROP_MAX_BITRATE: + g_value_set_uint (value, nm_access_point_get_max_bitrate (ap)); + break; + case PROP_STRENGTH: + g_value_set_uchar (value, nm_access_point_get_strength (ap)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +init_dbus (NMObject *object) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_ACCESS_POINT_FLAGS, &priv->flags }, + { NM_ACCESS_POINT_WPA_FLAGS, &priv->wpa_flags }, + { NM_ACCESS_POINT_RSN_FLAGS, &priv->rsn_flags }, + { NM_ACCESS_POINT_SSID, &priv->ssid }, + { NM_ACCESS_POINT_FREQUENCY, &priv->frequency }, + /* The D-Bus property is HwAddress, but the GObject property is "bssid" */ + { NM_ACCESS_POINT_HW_ADDRESS, &priv->bssid }, + { NM_ACCESS_POINT_MODE, &priv->mode }, + { NM_ACCESS_POINT_MAX_BITRATE, &priv->max_bitrate }, + { NM_ACCESS_POINT_STRENGTH, &priv->strength }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_access_point_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_ACCESS_POINT, + property_info); +} + + +static void +nm_access_point_class_init (NMAccessPointClass *ap_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ap_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ap_class); + + g_type_class_add_private (ap_class, sizeof (NMAccessPointPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_ACCESS_POINT); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMAccessPoint:flags: + * + * The flags of the access point. + **/ + g_object_class_install_property + (object_class, PROP_FLAGS, + g_param_spec_flags (NM_ACCESS_POINT_FLAGS, "", "", + NM_TYPE_802_11_AP_FLAGS, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:wpa-flags: + * + * The WPA flags of the access point. + **/ + g_object_class_install_property + (object_class, PROP_WPA_FLAGS, + g_param_spec_flags (NM_ACCESS_POINT_WPA_FLAGS, "", "", + NM_TYPE_802_11_AP_SECURITY_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:rsn-flags: + * + * The RSN flags of the access point. + **/ + g_object_class_install_property + (object_class, PROP_RSN_FLAGS, + g_param_spec_flags (NM_ACCESS_POINT_RSN_FLAGS, "", "", + NM_TYPE_802_11_AP_SECURITY_FLAGS, + NM_802_11_AP_SEC_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:ssid: + * + * The SSID of the access point, or %NULL if it is not known. + **/ + g_object_class_install_property + (object_class, PROP_SSID, + g_param_spec_boxed (NM_ACCESS_POINT_SSID, "", "", + G_TYPE_BYTES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:frequency: + * + * The frequency of the access point. + **/ + g_object_class_install_property + (object_class, PROP_FREQUENCY, + g_param_spec_uint (NM_ACCESS_POINT_FREQUENCY, "", "", + 0, 10000, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:bssid: + * + * The BSSID of the access point. + **/ + g_object_class_install_property + (object_class, PROP_BSSID, + g_param_spec_string (NM_ACCESS_POINT_BSSID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:hw-address: + * + * Alias for #NMAccessPoint:bssid. + * + * Deprecated: 1.0: use #NMAccessPoint:bssid. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:mode: + * + * The mode of the access point; either "infrastructure" (a central + * coordinator of the wireless network allowing clients to connect) or + * "ad-hoc" (a network with no central controller). + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_enum (NM_ACCESS_POINT_MODE, "", "", + NM_TYPE_802_11_MODE, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:max-bitrate: + * + * The maximum bit rate of the access point in kbit/s. + **/ + g_object_class_install_property + (object_class, PROP_MAX_BITRATE, + g_param_spec_uint (NM_ACCESS_POINT_MAX_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMAccessPoint:strength: + * + * The current signal strength of the access point. + **/ + g_object_class_install_property + (object_class, PROP_STRENGTH, + g_param_spec_uchar (NM_ACCESS_POINT_STRENGTH, "", "", + 0, G_MAXUINT8, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-access-point.h b/libnm/nm-access-point.h new file mode 100644 index 00000000..6991c19a --- /dev/null +++ b/libnm/nm-access-point.h @@ -0,0 +1,85 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_ACCESS_POINT_H__ +#define __NM_ACCESS_POINT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_ACCESS_POINT (nm_access_point_get_type ()) +#define NM_ACCESS_POINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACCESS_POINT, NMAccessPoint)) +#define NM_ACCESS_POINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ACCESS_POINT, NMAccessPointClass)) +#define NM_IS_ACCESS_POINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ACCESS_POINT)) +#define NM_IS_ACCESS_POINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ACCESS_POINT)) +#define NM_ACCESS_POINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACCESS_POINT, NMAccessPointClass)) + +#define NM_ACCESS_POINT_FLAGS "flags" +#define NM_ACCESS_POINT_WPA_FLAGS "wpa-flags" +#define NM_ACCESS_POINT_RSN_FLAGS "rsn-flags" +#define NM_ACCESS_POINT_SSID "ssid" +#define NM_ACCESS_POINT_BSSID "bssid" +#define NM_ACCESS_POINT_FREQUENCY "frequency" +#define NM_ACCESS_POINT_MODE "mode" +#define NM_ACCESS_POINT_MAX_BITRATE "max-bitrate" +#define NM_ACCESS_POINT_STRENGTH "strength" + +/* DEPRECATED */ +#define NM_ACCESS_POINT_HW_ADDRESS "hw-address" + + +struct _NMAccessPoint { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMAccessPointClass; + +GType nm_access_point_get_type (void); + +NM80211ApFlags nm_access_point_get_flags (NMAccessPoint *ap); +NM80211ApSecurityFlags nm_access_point_get_wpa_flags (NMAccessPoint *ap); +NM80211ApSecurityFlags nm_access_point_get_rsn_flags (NMAccessPoint *ap); +GBytes * nm_access_point_get_ssid (NMAccessPoint *ap); +const char * nm_access_point_get_bssid (NMAccessPoint *ap); +guint32 nm_access_point_get_frequency (NMAccessPoint *ap); +NM80211Mode nm_access_point_get_mode (NMAccessPoint *ap); +guint32 nm_access_point_get_max_bitrate (NMAccessPoint *ap); +guint8 nm_access_point_get_strength (NMAccessPoint *ap); + +GPtrArray * nm_access_point_filter_connections (NMAccessPoint *ap, + const GPtrArray *connections); + +gboolean nm_access_point_connection_valid (NMAccessPoint *ap, + NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_ACCESS_POINT_H__ */ diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c new file mode 100644 index 00000000..31f51328 --- /dev/null +++ b/libnm/nm-active-connection.c @@ -0,0 +1,714 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include + +#include "nm-dbus-interface.h" +#include "nm-active-connection.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" +#include "nm-device.h" +#include "nm-device-private.h" +#include "nm-connection.h" +#include "nm-vpn-connection.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-remote-connection.h" + +static GType _nm_active_connection_decide_type (GVariant *value); + +G_DEFINE_TYPE_WITH_CODE (NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT, + _nm_object_register_type_func (g_define_type_id, + _nm_active_connection_decide_type, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + "Vpn"); + ) + +#define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate)) + +typedef struct { + NMRemoteConnection *connection; + char *id; + char *uuid; + char *type; + char *specific_object_path; + GPtrArray *devices; + NMActiveConnectionState state; + gboolean is_default; + NMIPConfig *ip4_config; + NMDhcpConfig *dhcp4_config; + gboolean is_default6; + NMIPConfig *ip6_config; + NMDhcpConfig *dhcp6_config; + gboolean is_vpn; + NMDevice *master; +} NMActiveConnectionPrivate; + +enum { + PROP_0, + PROP_CONNECTION, + PROP_ID, + PROP_UUID, + PROP_TYPE, + PROP_SPECIFIC_OBJECT_PATH, + PROP_DEVICES, + PROP_STATE, + PROP_DEFAULT, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_DEFAULT6, + PROP_IP6_CONFIG, + PROP_DHCP6_CONFIG, + PROP_VPN, + PROP_MASTER, + + LAST_PROP +}; + +static GType +_nm_active_connection_decide_type (GVariant *value) +{ + /* @value is the value of the o.fd.NM.ActiveConnection property "VPN" */ + if (g_variant_get_boolean (value)) + return NM_TYPE_VPN_CONNECTION; + else + return NM_TYPE_ACTIVE_CONNECTION; +} + +/** + * nm_active_connection_get_connection: + * @connection: a #NMActiveConnection + * + * Gets the #NMRemoteConnection associated with @connection. + * + * Returns: (transfer none): the #NMRemoteConnection which this + * #NMActiveConnection is an active instance of. + **/ +NMRemoteConnection * +nm_active_connection_get_connection (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->connection; +} + +/** + * nm_active_connection_get_id: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's ID. + * + * Returns: the ID of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_id (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->id; +} + +/** + * nm_active_connection_get_uuid: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's UUID. + * + * Returns: the UUID of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_uuid (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->uuid; +} + +/** + * nm_active_connection_get_connection_type: + * @connection: a #NMActiveConnection + * + * Gets the #NMConnection's type. + * + * Returns: the type of the #NMConnection that backs the #NMActiveConnection. + * This is the internal string used by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_connection_type (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->type; +} + +/** + * nm_active_connection_get_specific_object_path: + * @connection: a #NMActiveConnection + * + * Gets the path of the "specific object" used at activation. + * + * Currently there is no single method that will allow you to automatically turn + * this into an appropriate #NMObject; you need to know what kind of object it + * is based on other information. (Eg, if @connection corresponds to a Wi-Fi + * connection, then the specific object will be an #NMAccessPoint, and you can + * resolve it with nm_device_wifi_get_access_point_by_path().) + * + * Returns: the specific object's D-Bus path. This is the internal string used + * by the connection, and must not be modified. + **/ +const char * +nm_active_connection_get_specific_object_path (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->specific_object_path; +} + +/** + * nm_active_connection_get_devices: + * @connection: a #NMActiveConnection + * + * Gets the #NMDevices used for the active connections. + * + * Returns: (element-type NMDevice): the #GPtrArray containing #NMDevices. + * This is the internal copy used by the connection, and must not be modified. + **/ +const GPtrArray * +nm_active_connection_get_devices (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->devices; +} + +/** + * nm_active_connection_get_state: + * @connection: a #NMActiveConnection + * + * Gets the active connection's state. + * + * Returns: the state + **/ +NMActiveConnectionState +nm_active_connection_get_state (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NM_ACTIVE_CONNECTION_STATE_UNKNOWN); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->state; +} + +/** + * nm_active_connection_get_default: + * @connection: a #NMActiveConnection + * + * Whether the active connection is the default IPv4 one (that is, is used for + * the default IPv4 route and DNS information). + * + * Returns: %TRUE if the active connection is the default IPv4 connection + **/ +gboolean +nm_active_connection_get_default (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_default; +} + +/** + * nm_active_connection_get_ip4_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv4 #NMIPConfig associated with the #NMActiveConnection. + * + * Returns: (transfer none): the IPv4 #NMIPConfig, or %NULL if the connection is + * not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + **/ +NMIPConfig * +nm_active_connection_get_ip4_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip4_config; +} + +/** + * nm_active_connection_get_dhcp4_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv4 #NMDhcpConfig (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the IPv4 #NMDhcpConfig, or %NULL if the connection + * does not use DHCP, or is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + **/ +NMDhcpConfig * +nm_active_connection_get_dhcp4_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp4_config; +} + +/** + * nm_active_connection_get_default6: + * @connection: a #NMActiveConnection + * + * Whether the active connection is the default IPv6 one (that is, is used for + * the default IPv6 route and DNS information). + * + * Returns: %TRUE if the active connection is the default IPv6 connection + **/ +gboolean +nm_active_connection_get_default6 (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_default6; +} + +/** + * nm_active_connection_get_ip6_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv6 #NMIPConfig associated with the #NMActiveConnection. + * + * Returns: (transfer none): the IPv6 #NMIPConfig, or %NULL if the connection is + * not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED state. + **/ +NMIPConfig * +nm_active_connection_get_ip6_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip6_config; +} + +/** + * nm_active_connection_get_dhcp6_config: + * @connection: an #NMActiveConnection + * + * Gets the current IPv6 #NMDhcpConfig (if any) associated with the + * #NMActiveConnection. + * + * Returns: (transfer none): the IPv6 #NMDhcpConfig, or %NULL if the connection + * does not use DHCPv6, or is not in the %NM_ACTIVE_CONNECTION_STATE_ACTIVATED + * state. + **/ +NMDhcpConfig * +nm_active_connection_get_dhcp6_config (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp6_config; +} + +/** + * nm_active_connection_get_vpn: + * @connection: a #NMActiveConnection + * + * Whether the active connection is a VPN connection. + * + * Returns: %TRUE if the active connection is a VPN connection + **/ +gboolean +nm_active_connection_get_vpn (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->is_vpn; +} + +/** + * nm_active_connection_get_master: + * @connection: a #NMActiveConnection + * + * Gets the master #NMDevice of the connection. + * + * Returns: (transfer none): the master #NMDevice of the #NMActiveConnection. + **/ +NMDevice * +nm_active_connection_get_master (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->master; +} + +static void +nm_active_connection_init (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + + priv->devices = g_ptr_array_new (); +} + +static void +dispose (GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + g_clear_pointer (&priv->devices, g_ptr_array_unref); + + g_clear_object (&priv->connection); + g_clear_object (&priv->master); + g_clear_object (&priv->ip4_config); + g_clear_object (&priv->dhcp4_config); + g_clear_object (&priv->ip6_config); + g_clear_object (&priv->dhcp6_config); + + G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + g_free (priv->id); + g_free (priv->uuid); + g_free (priv->type); + g_free (priv->specific_object_path); + + G_OBJECT_CLASS (nm_active_connection_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMActiveConnection *self = NM_ACTIVE_CONNECTION (object); + + switch (prop_id) { + case PROP_CONNECTION: + g_value_set_object (value, nm_active_connection_get_connection (self)); + break; + case PROP_ID: + g_value_set_string (value, nm_active_connection_get_id (self)); + break; + case PROP_UUID: + g_value_set_string (value, nm_active_connection_get_uuid (self)); + break; + case PROP_TYPE: + g_value_set_string (value, nm_active_connection_get_connection_type (self)); + break; + case PROP_SPECIFIC_OBJECT_PATH: + g_value_set_string (value, nm_active_connection_get_specific_object_path (self)); + break; + case PROP_DEVICES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_active_connection_get_devices (self))); + break; + case PROP_STATE: + g_value_set_enum (value, nm_active_connection_get_state (self)); + break; + case PROP_DEFAULT: + g_value_set_boolean (value, nm_active_connection_get_default (self)); + break; + case PROP_IP4_CONFIG: + g_value_set_object (value, nm_active_connection_get_ip4_config (self)); + break; + case PROP_DHCP4_CONFIG: + g_value_set_object (value, nm_active_connection_get_dhcp4_config (self)); + break; + case PROP_DEFAULT6: + g_value_set_boolean (value, nm_active_connection_get_default6 (self)); + break; + case PROP_IP6_CONFIG: + g_value_set_object (value, nm_active_connection_get_ip6_config (self)); + break; + case PROP_DHCP6_CONFIG: + g_value_set_object (value, nm_active_connection_get_dhcp6_config (self)); + break; + case PROP_VPN: + g_value_set_boolean (value, nm_active_connection_get_vpn (self)); + break; + case PROP_MASTER: + g_value_set_object (value, nm_active_connection_get_master (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +demarshal_specific_object_path (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + char **param = (char **) field; + + /* We have to demarshal this manually, because the D-Bus property name + * ("SpecificObject"), doesn't match the object property name + * ("specific-object-path"). (The name "specific-object" is reserved for + * future use as an NMObject-valued property.) + */ + if (!g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) + return FALSE; + + g_free (*param); + *param = g_variant_dup_string (value, NULL); + return TRUE; +} + +static void +init_dbus (NMObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_ACTIVE_CONNECTION_CONNECTION, &priv->connection, NULL, NM_TYPE_REMOTE_CONNECTION }, + { NM_ACTIVE_CONNECTION_ID, &priv->id }, + { NM_ACTIVE_CONNECTION_UUID, &priv->uuid }, + { NM_ACTIVE_CONNECTION_TYPE, &priv->type }, + { "specific-object", &priv->specific_object_path, demarshal_specific_object_path }, + { NM_ACTIVE_CONNECTION_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE }, + { NM_ACTIVE_CONNECTION_STATE, &priv->state }, + { NM_ACTIVE_CONNECTION_DEFAULT, &priv->is_default }, + { NM_ACTIVE_CONNECTION_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG }, + { NM_ACTIVE_CONNECTION_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG }, + { NM_ACTIVE_CONNECTION_DEFAULT6, &priv->is_default6 }, + { NM_ACTIVE_CONNECTION_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG }, + { NM_ACTIVE_CONNECTION_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG }, + { NM_ACTIVE_CONNECTION_VPN, &priv->is_vpn }, + { NM_ACTIVE_CONNECTION_MASTER, &priv->master, NULL, NM_TYPE_DEVICE }, + + { NULL }, + }; + + NM_OBJECT_CLASS (nm_active_connection_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + property_info); +} + + +static void +nm_active_connection_class_init (NMActiveConnectionClass *ap_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ap_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ap_class); + + g_type_class_add_private (ap_class, sizeof (NMActiveConnectionPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_ACTIVE_CONNECTION); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMActiveConnection:connection: + * + * The connection that this is an active instance of. + **/ + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_object (NM_ACTIVE_CONNECTION_CONNECTION, "", "", + NM_TYPE_REMOTE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:id: + * + * The active connection's ID + **/ + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_string (NM_ACTIVE_CONNECTION_ID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:uuid: + * + * The active connection's UUID + **/ + g_object_class_install_property + (object_class, PROP_UUID, + g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:type: + * + * The active connection's type + **/ + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:specific-object-path: + * + * The path to the "specific object" of the active connection; see + * nm_active_connection_get_specific_object_path() for more details. + **/ + g_object_class_install_property + (object_class, PROP_SPECIFIC_OBJECT_PATH, + g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:devices: + * + * The devices of the active connection. + * + * Element-type: NMDevice + **/ + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:state: + * + * The state of the active connection. + **/ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_ACTIVE_CONNECTION_STATE, "", "", + NM_TYPE_ACTIVE_CONNECTION_STATE, + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:default: + * + * Whether the active connection is the default IPv4 one. + **/ + g_object_class_install_property + (object_class, PROP_DEFAULT, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:ip4-config: + * + * The IPv4 #NMIPConfig of the connection. + **/ + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_IP4_CONFIG, "", "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:dhcp4-config: + * + * The IPv4 #NMDhcpConfig of the connection. + **/ + g_object_class_install_property + (object_class, PROP_DHCP4_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, "", "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:default6: + * + * Whether the active connection is the default IPv6 one. + **/ + g_object_class_install_property + (object_class, PROP_DEFAULT6, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:ip6-config: + * + * The IPv6 #NMIPConfig of the connection. + **/ + g_object_class_install_property + (object_class, PROP_IP6_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_IP6_CONFIG, "", "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:dhcp6-config: + * + * The IPv6 #NMDhcpConfig of the connection. + **/ + g_object_class_install_property + (object_class, PROP_DHCP6_CONFIG, + g_param_spec_object (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, "", "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:vpn: + * + * Whether the active connection is a VPN connection. + **/ + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMActiveConnection:master: + * + * The master device if one exists. + **/ + g_object_class_install_property + (object_class, PROP_MASTER, + g_param_spec_object (NM_ACTIVE_CONNECTION_MASTER, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-active-connection.h b/libnm/nm-active-connection.h new file mode 100644 index 00000000..4bc84148 --- /dev/null +++ b/libnm/nm-active-connection.h @@ -0,0 +1,87 @@ +/* -*- 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. + * + * Copyright 2007 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_ACTIVE_CONNECTION_H__ +#define __NM_ACTIVE_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ()) +#define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) +#define NM_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) +#define NM_IS_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_IS_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_ACTIVE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) + +#define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_ID "id" +#define NM_ACTIVE_CONNECTION_UUID "uuid" +#define NM_ACTIVE_CONNECTION_TYPE "type" +#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH "specific-object-path" +#define NM_ACTIVE_CONNECTION_DEVICES "devices" +#define NM_ACTIVE_CONNECTION_STATE "state" +#define NM_ACTIVE_CONNECTION_DEFAULT "default" +#define NM_ACTIVE_CONNECTION_IP4_CONFIG "ip4-config" +#define NM_ACTIVE_CONNECTION_DHCP4_CONFIG "dhcp4-config" +#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6" +#define NM_ACTIVE_CONNECTION_IP6_CONFIG "ip6-config" +#define NM_ACTIVE_CONNECTION_DHCP6_CONFIG "dhcp6-config" +#define NM_ACTIVE_CONNECTION_VPN "vpn" +#define NM_ACTIVE_CONNECTION_MASTER "master" + +struct _NMActiveConnection { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /*< private >*/ + gpointer padding[8]; +} NMActiveConnectionClass; + +GType nm_active_connection_get_type (void); + +NMRemoteConnection *nm_active_connection_get_connection (NMActiveConnection *connection); +const char *nm_active_connection_get_id (NMActiveConnection *connection); +const char *nm_active_connection_get_uuid (NMActiveConnection *connection); +const char *nm_active_connection_get_connection_type (NMActiveConnection *connection); +const char *nm_active_connection_get_specific_object_path (NMActiveConnection *connection); +const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection); +NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *connection); +NMDevice *nm_active_connection_get_master (NMActiveConnection *connection); +gboolean nm_active_connection_get_default (NMActiveConnection *connection); +NMIPConfig *nm_active_connection_get_ip4_config (NMActiveConnection *connection); +NMDhcpConfig *nm_active_connection_get_dhcp4_config (NMActiveConnection *connection); +gboolean nm_active_connection_get_default6 (NMActiveConnection *connection); +NMIPConfig *nm_active_connection_get_ip6_config (NMActiveConnection *connection); +NMDhcpConfig *nm_active_connection_get_dhcp6_config (NMActiveConnection *connection); +gboolean nm_active_connection_get_vpn (NMActiveConnection *connection); + +G_END_DECLS + +#endif /* __NM_ACTIVE_CONNECTION_H__ */ diff --git a/libnm/nm-client.c b/libnm/nm-client.c new file mode 100644 index 00000000..ef73e329 --- /dev/null +++ b/libnm/nm-client.c @@ -0,0 +1,2238 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-client.h" +#include "nm-manager.h" +#include "nm-remote-settings.h" +#include "nm-device-ethernet.h" +#include "nm-device-wifi.h" +#include "nm-device-private.h" +#include "nm-core-internal.h" +#include "nm-active-connection.h" +#include "nm-vpn-connection.h" +#include "nm-remote-connection.h" +#include "nm-object-cache.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" + +void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); + +static void nm_client_initable_iface_init (GInitableIface *iface); +static void nm_client_async_initable_iface_init (GAsyncInitableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_client_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_client_async_initable_iface_init); + ) + +#define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate)) + +typedef struct { + NMManager *manager; + NMRemoteSettings *settings; +} NMClientPrivate; + +enum { + PROP_0, + PROP_VERSION, + PROP_STATE, + PROP_STARTUP, + PROP_NM_RUNNING, + PROP_NETWORKING_ENABLED, + PROP_WIRELESS_ENABLED, + PROP_WIRELESS_HARDWARE_ENABLED, + PROP_WWAN_ENABLED, + PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, + PROP_ACTIVE_CONNECTIONS, + PROP_CONNECTIVITY, + PROP_PRIMARY_CONNECTION, + PROP_ACTIVATING_CONNECTION, + PROP_DEVICES, + PROP_CONNECTIONS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + + LAST_PROP +}; + +enum { + DEVICE_ADDED, + DEVICE_REMOVED, + PERMISSION_CHANGED, + CONNECTION_ADDED, + CONNECTION_REMOVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/**********************************************************************/ + +/** + * nm_client_error_quark: + * + * Registers an error quark for #NMClient if necessary. + * + * Returns: the error quark used for #NMClient errors. + **/ +GQuark +nm_client_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-client-error-quark"); + return quark; +} + +/**********************************************************************/ + +static void +nm_client_init (NMClient *client) +{ +} + +static gboolean +_nm_client_check_nm_running (NMClient *client, GError **error) +{ + if (nm_client_get_nm_running (client)) + return TRUE; + else { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); + return FALSE; + } +} + +/** + * nm_client_get_version: + * @client: a #NMClient + * + * Gets NetworkManager version. + * + * Returns: string with the version (or %NULL if NetworkManager is not running) + **/ +const char * +nm_client_get_version (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_version (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_state: + * @client: a #NMClient + * + * Gets the current daemon state. + * + * Returns: the current %NMState + **/ +NMState +nm_client_get_state (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + + return nm_manager_get_state (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_startup: + * @client: a #NMClient + * + * Tests whether the daemon is still in the process of activating + * connections at startup. + * + * Returns: whether the daemon is still starting up + **/ +gboolean +nm_client_get_startup (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + + return nm_manager_get_startup (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_nm_running: + * @client: a #NMClient + * + * Determines whether the daemon is running. + * + * Returns: %TRUE if the daemon is running + **/ +gboolean +nm_client_get_nm_running (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_get_nm_running (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_networking_get_enabled: + * @client: a #NMClient + * + * Whether networking is enabled or disabled. + * + * Returns: %TRUE if networking is enabled, %FALSE if networking is disabled + **/ +gboolean +nm_client_networking_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_networking_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_networking_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to set networking enabled, %FALSE to set networking disabled + * @error: (allow-none): return location for a #GError, or %NULL + * + * Enables or disables networking. When networking is disabled, all controlled + * interfaces are disconnected and deactivated. When networking is enabled, + * all controlled interfaces are available for activation. + * + * Returns: %TRUE on success, %FALSE otherwise + **/ +gboolean +nm_client_networking_set_enabled (NMClient *client, gboolean enable, GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + + return nm_manager_networking_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, + enable, error); +} + +/** + * nm_client_wireless_get_enabled: + * @client: a #NMClient + * + * Determines whether the wireless is enabled. + * + * Returns: %TRUE if wireless is enabled + **/ +gboolean +nm_client_wireless_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wireless_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_wireless_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable wireless + * + * Enables or disables wireless devices. + **/ +void +nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) +{ + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, NULL)) + return; + + nm_manager_wireless_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled); +} + +/** + * nm_client_wireless_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the wireless hardware is enabled. + * + * Returns: %TRUE if the wireless hardware is enabled + **/ +gboolean +nm_client_wireless_hardware_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wireless_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_wwan_get_enabled: + * @client: a #NMClient + * + * Determines whether WWAN is enabled. + * + * Returns: %TRUE if WWAN is enabled + **/ +gboolean +nm_client_wwan_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wwan_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_wwan_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WWAN + * + * Enables or disables WWAN devices. + **/ +void +nm_client_wwan_set_enabled (NMClient *client, gboolean enabled) +{ + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, NULL)) + return; + + nm_manager_wwan_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled); +} + +/** + * nm_client_wwan_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WWAN hardware is enabled. + * + * Returns: %TRUE if the WWAN hardware is enabled + **/ +gboolean +nm_client_wwan_hardware_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wwan_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_wimax_get_enabled: + * @client: a #NMClient + * + * Determines whether WiMAX is enabled. + * + * Returns: %TRUE if WiMAX is enabled + **/ +gboolean +nm_client_wimax_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wimax_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_wimax_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WiMAX + * + * Enables or disables WiMAX devices. + **/ +void +nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) +{ + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, NULL)) + return; + + nm_manager_wimax_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled); +} + +/** + * nm_client_wimax_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WiMAX hardware is enabled. + * + * Returns: %TRUE if the WiMAX hardware is enabled + **/ +gboolean +nm_client_wimax_hardware_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_manager_wimax_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_logging: + * @client: a #NMClient + * @level: (allow-none): return location for logging level string + * @domains: (allow-none): return location for log domains string. The string is + * a list of domains separated by "," + * @error: (allow-none): return location for a #GError, or %NULL + * + * Gets NetworkManager current logging level and domains. + * + * Returns: %TRUE on success, %FALSE otherwise + **/ +gboolean +nm_client_get_logging (NMClient *client, char **level, char **domains, GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (level == NULL || *level == NULL, FALSE); + g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + + return nm_manager_get_logging (NM_CLIENT_GET_PRIVATE (client)->manager, + level, domains, error); +} + +/** + * nm_client_set_logging: + * @client: a #NMClient + * @level: (allow-none): logging level to set (%NULL or an empty string for no change) + * @domains: (allow-none): logging domains to set. The string should be a list of log + * domains separated by ",". (%NULL or an empty string for no change) + * @error: (allow-none): return location for a #GError, or %NULL + * + * Sets NetworkManager logging level and/or domains. + * + * Returns: %TRUE on success, %FALSE otherwise + **/ +gboolean +nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + + return nm_manager_set_logging (NM_CLIENT_GET_PRIVATE (client)->manager, + level, domains, error); +} + +/** + * nm_client_get_permission_result: + * @client: a #NMClient + * @permission: the permission for which to return the result, one of #NMClientPermission + * + * Requests the result of a specific permission, which indicates whether the + * client can or cannot perform the action the permission represents + * + * Returns: the permission's result, one of #NMClientPermissionResult + **/ +NMClientPermissionResult +nm_client_get_permission_result (NMClient *client, NMClientPermission permission) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN); + + return nm_manager_get_permission_result (NM_CLIENT_GET_PRIVATE (client)->manager, permission); +} + +/** + * nm_client_get_connectivity: + * @client: an #NMClient + * + * Gets the current network connectivity state. Contrast + * nm_client_check_connectivity() and + * nm_client_check_connectivity_async(), which re-check the + * connectivity state first before returning any information. + * + * Returns: the current connectivity state + */ +NMConnectivityState +nm_client_get_connectivity (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN); + + return nm_manager_get_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_check_connectivity: + * @client: an #NMClient + * @cancellable: a #GCancellable + * @error: return location for a #GError + * + * Updates the network connectivity state and returns the (new) + * current state. Contrast nm_client_get_connectivity(), which returns + * the most recent known state without re-checking. + * + * This is a blocking call; use nm_client_check_connectivity_async() + * if you do not want to block. + * + * Returns: the (new) current connectivity state + */ +NMConnectivityState +nm_client_check_connectivity (NMClient *client, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN); + + if (!_nm_client_check_nm_running (client, error)) + return NM_CONNECTIVITY_UNKNOWN; + + return nm_manager_check_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager, + cancellable, error); +} + +static void +check_connectivity_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMConnectivityState connectivity; + GError *error = NULL; + + connectivity = nm_manager_check_connectivity_finish (NM_MANAGER (object), + result, &error); + if (!error) + g_simple_async_result_set_op_res_gssize (simple, connectivity); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_check_connectivity_async: + * @client: an #NMClient + * @cancellable: a #GCancellable + * @callback: callback to call with the result + * @user_data: data for @callback. + * + * Asynchronously updates the network connectivity state and invokes + * @callback when complete. Contrast nm_client_get_connectivity(), + * which (immediately) returns the most recent known state without + * re-checking, and nm_client_check_connectivity(), which blocks. + */ +void +nm_client_check_connectivity_async (NMClient *client, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_check_connectivity_async); + nm_manager_check_connectivity_async (NM_CLIENT_GET_PRIVATE (client)->manager, + cancellable, check_connectivity_cb, simple); +} + +/** + * nm_client_check_connectivity_finish: + * @client: an #NMClient + * @result: the #GAsyncResult + * @error: return location for a #GError + * + * Retrieves the result of an nm_client_check_connectivity_async() + * call. + * + * Returns: the (new) current connectivity state + */ +NMConnectivityState +nm_client_check_connectivity_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NM_CONNECTIVITY_UNKNOWN); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return NM_CONNECTIVITY_UNKNOWN; + return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple); +} + + +/** + * nm_client_save_hostname: + * @client: the %NMClient + * @hostname: (allow-none): the new persistent hostname to set, or %NULL to + * clear any existing persistent hostname + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ +gboolean +nm_client_save_hostname (NMClient *client, + const char *hostname, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return nm_remote_settings_save_hostname (NM_CLIENT_GET_PRIVATE (client)->settings, + hostname, cancellable, error); +} + +static void +save_hostname_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nm_remote_settings_save_hostname_finish (NM_REMOTE_SETTINGS (object), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_save_hostname_async: + * @client: the %NMClient + * @hostname: (allow-none): the new persistent hostname to set, or %NULL to + * clear any existing persistent hostname + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + **/ +void +nm_client_save_hostname_async (NMClient *client, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_save_hostname_async); + nm_remote_settings_save_hostname_async (NM_CLIENT_GET_PRIVATE (client)->settings, + hostname, + cancellable, save_hostname_cb, simple); +} + +/** + * nm_client_save_hostname_finish: + * @client: the %NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for #GError + * + * Gets the result of an nm_client_save_hostname_async() call. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ +gboolean +nm_client_save_hostname_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/****************************************************************/ +/* Devices */ +/****************************************************************/ + +/** + * nm_client_get_devices: + * @client: a #NMClient + * + * Gets all the known network devices. Use nm_device_get_type() or the + * NM_IS_DEVICE_XXXX functions to determine what kind of + * device member of the returned array is, and then you may use device-specific + * methods such as nm_device_ethernet_get_hw_address(). + * + * Returns: (transfer none) (element-type NMDevice): a #GPtrArray + * containing all the #NMDevices. The returned array is owned by the + * #NMClient object and should not be modified. + **/ +const GPtrArray * +nm_client_get_devices (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_devices (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_device_by_path: + * @client: a #NMClient + * @object_path: the object path to search for + * + * Gets a #NMDevice from a #NMClient. + * + * Returns: (transfer none): the #NMDevice for the given @object_path or %NULL if none is found. + **/ +NMDevice * +nm_client_get_device_by_path (NMClient *client, const char *object_path) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (object_path, NULL); + + return nm_manager_get_device_by_path (NM_CLIENT_GET_PRIVATE (client)->manager, object_path); +} + +/** + * nm_client_get_device_by_iface: + * @client: a #NMClient + * @iface: the interface name to search for + * + * Gets a #NMDevice from a #NMClient. + * + * Returns: (transfer none): the #NMDevice for the given @iface or %NULL if none is found. + **/ +NMDevice * +nm_client_get_device_by_iface (NMClient *client, const char *iface) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (iface, NULL); + + return nm_manager_get_device_by_iface (NM_CLIENT_GET_PRIVATE (client)->manager, iface); +} + +/****************************************************************/ +/* Active Connections */ +/****************************************************************/ + +/** + * nm_client_get_active_connections: + * @client: a #NMClient + * + * Gets the active connections. + * + * Returns: (transfer none) (element-type NMActiveConnection): a #GPtrArray + * containing all the active #NMActiveConnections. + * The returned array is owned by the client and should not be modified. + **/ +const GPtrArray * +nm_client_get_active_connections (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_active_connections (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_primary_connection: + * @client: an #NMClient + * + * Gets the #NMActiveConnection corresponding to the primary active + * network device. + * + * In particular, when there is no VPN active, or the VPN does not + * have the default route, this returns the active connection that has + * the default route. If there is a VPN active with the default route, + * then this function returns the active connection that contains the + * route to the VPN endpoint. + * + * If there is no default route, or the default route is over a + * non-NetworkManager-recognized device, this will return %NULL. + * + * Returns: (transfer none): the appropriate #NMActiveConnection, if + * any + */ +NMActiveConnection * +nm_client_get_primary_connection (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_primary_connection (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +/** + * nm_client_get_activating_connection: + * @client: an #NMClient + * + * Gets the #NMActiveConnection corresponding to a + * currently-activating connection that is expected to become the new + * #NMClient:primary-connection upon successful activation. + * + * Returns: (transfer none): the appropriate #NMActiveConnection, if + * any. + */ +NMActiveConnection * +nm_client_get_activating_connection (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_manager_get_activating_connection (NM_CLIENT_GET_PRIVATE (client)->manager); +} + +static void +activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_manager_activate_connection_finish (NM_MANAGER (object), result, &error); + if (ac) + g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_activate_connection_async: + * @client: a #NMClient + * @connection: (allow-none): an #NMConnection + * @device: (allow-none): the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Asynchronously starts a connection to a particular network using the + * configuration settings from @connection and the network device @device. + * Certain connection types also take a "specific object" which is the object + * path of a connection- specific object, like an #NMAccessPoint for Wi-Fi + * connections, or an #NMWimaxNsp for WiMAX connections, to which you wish to + * connect. If the specific object is not given, NetworkManager can, in some + * cases, automatically determine which network to connect to given the settings + * in @connection. + * + * If @connection is not given for a device-based activation, NetworkManager + * picks the best available connection for the device and activates it. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + **/ +void +nm_client_activate_connection_async (NMClient *client, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + if (device) + g_return_if_fail (NM_IS_DEVICE (device)); + if (connection) + g_return_if_fail (NM_IS_CONNECTION (connection)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_activate_connection_async); + nm_manager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager, + connection, device, specific_object, + cancellable, activate_cb, simple); +} + +/** + * nm_client_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_activate_connection_async(). + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +add_activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_manager_add_and_activate_connection_finish (NM_MANAGER (object), result, &error); + if (ac) + g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_add_and_activate_connection_async: + * @client: a #NMClient + * @partial: (allow-none): an #NMConnection to add; the connection may be + * partially filled (or even %NULL) and will be completed by NetworkManager + * using the given @device and @specific_object before being added + * @device: the #NMDevice + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of %NULL should be used + * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can + * get using nm_object_get_path(), and which will be used to complete the + * details of the newly added connection. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Adds a new connection using the given details (if any) as a template, + * automatically filling in missing settings with the capabilities of the given + * device and specific object. The new connection is then asynchronously + * activated as with nm_client_activate_connection_async(). Cannot be used for + * VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object (in particular, #NMActiveConnection:state) to + * track the activation to its completion. + **/ +void +nm_client_add_and_activate_connection_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_DEVICE (device)); + if (partial) + g_return_if_fail (NM_IS_CONNECTION (partial)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_add_and_activate_connection_async); + nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager, + partial, device, specific_object, + cancellable, add_activate_cb, simple); +} + +/** + * nm_client_add_and_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_and_activate_connection_async(). + * + * You can call nm_active_connection_get_connection() on the returned + * #NMActiveConnection to find the path of the created #NMConnection. + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_add_and_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +/** + * nm_client_deactivate_connection: + * @client: a #NMClient + * @active: the #NMActiveConnection to deactivate + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deactivates an active #NMActiveConnection. + * + * Returns: success or failure + **/ +gboolean +nm_client_deactivate_connection (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); + + if (!_nm_client_check_nm_running (client, NULL)) + return TRUE; + + return nm_manager_deactivate_connection (NM_CLIENT_GET_PRIVATE (client)->manager, + active, cancellable, error); +} + +static void +deactivated_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nm_manager_deactivate_connection_finish (NM_MANAGER (object), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_deactivate_connection_async: + * @client: a #NMClient + * @active: the #NMActiveConnection to deactivate + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the deactivation has completed + * @user_data: caller-specific data passed to @callback + * + * Asynchronously deactivates an active #NMActiveConnection. + **/ +void +nm_client_deactivate_connection_async (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_deactivate_connection_async); + + if (!_nm_client_check_nm_running (client, NULL)) { + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + nm_manager_deactivate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager, + active, + cancellable, deactivated_cb, simple); +} + +/** + * nm_client_deactivate_connection_finish: + * @client: a #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_deactivate_connection_async(). + * + * Returns: success or failure + **/ +gboolean +nm_client_deactivate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/****************************************************************/ +/* Connections */ +/****************************************************************/ + +/** + * nm_client_get_connections: + * @client: the %NMClient + * + * Returns: (transfer none) (element-type NMRemoteConnection): an array + * containing all connections provided by the remote settings service. The + * returned array is owned by the #NMClient object and should not be modified. + **/ +const GPtrArray * +nm_client_get_connections (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + + return nm_remote_settings_get_connections (NM_CLIENT_GET_PRIVATE (client)->settings); +} + +/** + * nm_client_get_connection_by_id: + * @client: the %NMClient + * @id: the id of the remote connection + * + * Returns the first matching %NMRemoteConnection matching a given @id. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if no + * matching object was found. + **/ +NMRemoteConnection * +nm_client_get_connection_by_id (NMClient *client, const char *id) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (id != NULL, NULL); + + return nm_remote_settings_get_connection_by_id (NM_CLIENT_GET_PRIVATE (client)->settings, id); +} + +/** + * nm_client_get_connection_by_path: + * @client: the %NMClient + * @path: the D-Bus object path of the remote connection + * + * Returns the %NMRemoteConnection representing the connection at @path. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if the object was + * not known + **/ +NMRemoteConnection * +nm_client_get_connection_by_path (NMClient *client, const char *path) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (path != NULL, NULL); + + return nm_remote_settings_get_connection_by_path (NM_CLIENT_GET_PRIVATE (client)->settings, path); +} + +/** + * nm_client_get_connection_by_uuid: + * @client: the %NMClient + * @uuid: the UUID of the remote connection + * + * Returns the %NMRemoteConnection identified by @uuid. + * + * Returns: (transfer none): the remote connection object on success, or %NULL if the object was + * not known + **/ +NMRemoteConnection * +nm_client_get_connection_by_uuid (NMClient *client, const char *uuid) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (uuid != NULL, NULL); + + return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid); +} + +static void +add_connection_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMRemoteConnection *conn; + GError *error = NULL; + + conn = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (object), result, &error); + if (conn) + g_simple_async_result_set_op_res_gpointer (simple, conn, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_add_connection_async: + * @client: the %NMClient + * @connection: the connection to add. Note that this object's settings will be + * added, not the object itself + * @save_to_disk: whether to immediately save the connection to disk + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the add operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service add the given settings to a new + * connection. If @save_to_disk is %TRUE, the connection is immediately written + * to disk; otherwise it is initially only stored in memory, but may be saved + * later by calling the connection's nm_remote_connection_commit_changes() + * method. + * + * @connection is untouched by this function and only serves as a template of + * the settings to add. The #NMRemoteConnection object that represents what + * NetworkManager actually added is returned to @callback when the addition + * operation is complete. + * + * Note that the #NMRemoteConnection returned in @callback may not contain + * identical settings to @connection as NetworkManager may perform automatic + * completion and/or normalization of connection properties. + **/ +void +nm_client_add_connection_async (NMClient *client, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_deactivate_connection_async); + nm_remote_settings_add_connection_async (NM_CLIENT_GET_PRIVATE (client)->settings, + connection, save_to_disk, + cancellable, add_connection_cb, simple); +} + +/** + * nm_client_add_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_connection_async(). + * + * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMRemoteConnection * +nm_client_add_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +/** + * nm_client_load_connections: + * @client: the %NMClient + * @filenames: %NULL-terminated array of filenames to load + * @failures: (out) (transfer full): on return, a %NULL-terminated array of + * filenames that failed to load + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the remote settings service load or reload the given files, + * adding or updating the connections described within. + * + * The changes to the indicated files will not yet be reflected in + * @client's connections array when the function returns. + * + * If all of the indicated files were successfully loaded, the + * function will return %TRUE, and @failures will be set to %NULL. If + * NetworkManager tried to load the files, but some (or all) failed, + * then @failures will be set to a %NULL-terminated array of the + * filenames that failed to load. + * + * Returns: %TRUE if NetworkManager at least tried to load @filenames, + * %FALSE if an error occurred (eg, permission denied). + **/ +gboolean +nm_client_load_connections (NMClient *client, + char **filenames, + char ***failures, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (filenames != NULL, FALSE); + + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + + return nm_remote_settings_load_connections (NM_CLIENT_GET_PRIVATE (client)->settings, + filenames, failures, + cancellable, error); +} + +static void +load_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + char **failures = NULL; + + if (nm_remote_settings_load_connections_finish (NM_REMOTE_SETTINGS (object), + &failures, result, &error)) + g_simple_async_result_set_op_res_gpointer (simple, failures, (GDestroyNotify) g_strfreev); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_load_connections_async: + * @client: the %NMClient + * @filenames: %NULL-terminated array of filenames to load + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service asynchronously load or reload the + * given files, adding or updating the connections described within. + * + * See nm_client_load_connections() for more details. + **/ +void +nm_client_load_connections_async (NMClient *client, + char **filenames, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (filenames != NULL); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_load_connections_async); + nm_remote_settings_load_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings, + filenames, + cancellable, load_connections_cb, simple); +} + +/** + * nm_client_load_connections_finish: + * @client: the %NMClient + * @failures: (out) (transfer full): on return, a %NULL-terminated array of + * filenames that failed to load + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of an nm_client_load_connections_async() call. + + * See nm_client_load_connections() for more details. + * + * Returns: %TRUE if NetworkManager at least tried to load @filenames, + * %FALSE if an error occurred (eg, permission denied). + **/ +gboolean +nm_client_load_connections_finish (NMClient *client, + char ***failures, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else { + if (failures) + *failures = g_strdupv (g_simple_async_result_get_op_res_gpointer (simple)); + return TRUE; + } +} + +/** + * nm_client_reload_connections: + * @client: the #NMClient + * @cancellable: a #GCancellable, or %NULL + * @error: return location for #GError + * + * Requests that the remote settings service reload all connection + * files from disk, adding, updating, and removing connections until + * the in-memory state matches the on-disk state. + * + * Return value: %TRUE on success, %FALSE on failure + **/ +gboolean +nm_client_reload_connections (NMClient *client, + GCancellable *cancellable, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + if (!_nm_client_check_nm_running (client, error)) + return FALSE; + + return nm_remote_settings_reload_connections (NM_CLIENT_GET_PRIVATE (client)->settings, + cancellable, error); +} + +static void +reload_connections_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nm_remote_settings_reload_connections_finish (NM_REMOTE_SETTINGS (object), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_reload_connections_async: + * @client: the #NMClient + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the reload operation completes + * @user_data: (closure): caller-specific data passed to @callback + * + * Requests that the remote settings service begin reloading all connection + * files from disk, adding, updating, and removing connections until the + * in-memory state matches the on-disk state. + **/ +void +nm_client_reload_connections_async (NMClient *client, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + + if (!_nm_client_check_nm_running (client, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error); + return; + } + + simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_reload_connections_async); + nm_remote_settings_reload_connections_async (NM_CLIENT_GET_PRIVATE (client)->settings, + cancellable, reload_connections_cb, simple); +} + +/** + * nm_client_reload_connections_finish: + * @client: the #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for #GError + * + * Gets the result of an nm_client_reload_connections_async() call. + * + * Return value: %TRUE on success, %FALSE on failure + **/ +gboolean +nm_client_reload_connections_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/****************************************************************/ + +/** + * nm_client_new: + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Creates a new #NMClient. + * + * Note that this will do blocking D-Bus calls to initialize the + * client. You can use nm_client_new_async() if you want to avoid + * that. + * + * Returns: a new #NMClient or NULL on an error + **/ +NMClient * +nm_client_new (GCancellable *cancellable, + GError **error) +{ + return g_initable_new (NM_TYPE_CLIENT, cancellable, error, + NULL); +} + +static void +client_inited (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (!g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error)) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gpointer (simple, source, g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_client_new_async: + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the client is created + * @user_data: data for @callback + * + * Creates a new #NMClient and begins asynchronously initializing it. + * @callback will be called when it is done; use + * nm_client_new_finish() to get the result. Note that on an error, + * the callback can be invoked with two first parameters as NULL. + **/ +void +nm_client_new_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async); + + g_async_initable_new_async (NM_TYPE_CLIENT, G_PRIORITY_DEFAULT, + cancellable, client_inited, simple, + NULL); +} + +/** + * nm_client_new_finish: + * @result: a #GAsyncResult + * @error: location for a #GError, or %NULL + * + * Gets the result of an nm_client_new_async() call. + * + * Returns: a new #NMClient, or %NULL on error + **/ +NMClient * +nm_client_new_finish (GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, nm_client_new_async), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +subobject_notify (GObject *object, + GParamSpec *pspec, + gpointer client) +{ + if (!g_str_has_suffix (pspec->name, "-internal")) + g_object_notify (client, pspec->name); +} + +static void +manager_device_added (NMManager *manager, + NMDevice *device, + gpointer client) +{ + g_signal_emit (client, signals[DEVICE_ADDED], 0, device); +} +static void +manager_device_removed (NMManager *manager, + NMDevice *device, + gpointer client) +{ + g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); +} + +static void +manager_permission_changed (NMManager *manager, + NMClientPermission permission, + NMClientPermissionResult result, + gpointer client) +{ + g_signal_emit (client, signals[PERMISSION_CHANGED], 0, permission, result); +} + +static void +settings_connection_added (NMRemoteSettings *manager, + NMRemoteConnection *connection, + gpointer client) +{ + g_signal_emit (client, signals[CONNECTION_ADDED], 0, connection); +} +static void +settings_connection_removed (NMRemoteSettings *manager, + NMRemoteConnection *connection, + gpointer client) +{ + g_signal_emit (client, signals[CONNECTION_REMOVED], 0, connection); +} + +static void +constructed (GObject *object) +{ + NMClient *client = NM_CLIENT (object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + + priv->manager = g_object_new (NM_TYPE_MANAGER, + NM_OBJECT_PATH, NM_DBUS_PATH, + NULL); + g_signal_connect (priv->manager, "notify", + G_CALLBACK (subobject_notify), client); + g_signal_connect (priv->manager, "device-added", + G_CALLBACK (manager_device_added), client); + g_signal_connect (priv->manager, "device-removed", + G_CALLBACK (manager_device_removed), client); + g_signal_connect (priv->manager, "permission-changed", + G_CALLBACK (manager_permission_changed), client); + + priv->settings = g_object_new (NM_TYPE_REMOTE_SETTINGS, + NM_OBJECT_PATH, NM_DBUS_PATH_SETTINGS, + NULL); + g_signal_connect (priv->settings, "notify", + G_CALLBACK (subobject_notify), client); + g_signal_connect (priv->settings, "connection-added", + G_CALLBACK (settings_connection_added), client); + g_signal_connect (priv->settings, "connection-removed", + G_CALLBACK (settings_connection_removed), client); + + G_OBJECT_CLASS (nm_client_parent_class)->constructed (object); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMClient *client = NM_CLIENT (initable); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + + if (!g_initable_init (G_INITABLE (priv->manager), cancellable, error)) + return FALSE; + if (!g_initable_init (G_INITABLE (priv->settings), cancellable, error)) + return FALSE; + + return TRUE; +} + +typedef struct { + NMClient *client; + GCancellable *cancellable; + GSimpleAsyncResult *result; + gboolean manager_inited; + gboolean settings_inited; +} NMClientInitData; + +static void +init_async_complete (NMClientInitData *init_data) +{ + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); + g_slice_free (NMClientInitData, init_data); +} + +static void +init_async_inited_manager (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMClientInitData *init_data = user_data; + GError *error = NULL; + + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) + g_simple_async_result_take_error (init_data->result, error); + + init_data->manager_inited = TRUE; + if (init_data->settings_inited) + init_async_complete (init_data); +} + +static void +init_async_inited_settings (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMClientInitData *init_data = user_data; + GError *error = NULL; + + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) + g_simple_async_result_take_error (init_data->result, error); + + init_data->settings_inited = TRUE; + if (init_data->manager_inited) + init_async_complete (init_data); +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (initable); + NMClientInitData *init_data; + + init_data = g_slice_new0 (NMClientInitData); + init_data->client = NM_CLIENT (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + + g_async_initable_init_async (G_ASYNC_INITABLE (priv->manager), + G_PRIORITY_DEFAULT, init_data->cancellable, + init_async_inited_manager, init_data); + g_async_initable_init_async (G_ASYNC_INITABLE (priv->settings), + G_PRIORITY_DEFAULT, init_data->cancellable, + init_async_inited_settings, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +static void +dispose (GObject *object) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + + if (priv->manager) { + g_signal_handlers_disconnect_by_data (priv->manager, object); + g_clear_object (&priv->manager); + } + if (priv->settings) { + g_signal_handlers_disconnect_by_data (priv->settings, object); + g_clear_object (&priv->settings); + } + + G_OBJECT_CLASS (nm_client_parent_class)->dispose (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_NETWORKING_ENABLED: + case PROP_WIRELESS_ENABLED: + case PROP_WWAN_ENABLED: + case PROP_WIMAX_ENABLED: + g_object_set_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager), + pspec->name, 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) +{ + switch (prop_id) { + case PROP_VERSION: + case PROP_STATE: + case PROP_STARTUP: + case PROP_NM_RUNNING: + case PROP_NETWORKING_ENABLED: + case PROP_WIRELESS_ENABLED: + case PROP_WIRELESS_HARDWARE_ENABLED: + case PROP_WWAN_ENABLED: + case PROP_WWAN_HARDWARE_ENABLED: + case PROP_WIMAX_ENABLED: + case PROP_WIMAX_HARDWARE_ENABLED: + case PROP_ACTIVE_CONNECTIONS: + case PROP_CONNECTIVITY: + case PROP_PRIMARY_CONNECTION: + case PROP_ACTIVATING_CONNECTION: + case PROP_DEVICES: + g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager), + pspec->name, value); + break; + case PROP_CONNECTIONS: + case PROP_HOSTNAME: + case PROP_CAN_MODIFY: + g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->settings), + pspec->name, value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_client_class_init (NMClientClass *client_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (client_class); + + g_type_class_add_private (client_class, sizeof (NMClientPrivate)); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + + /* properties */ + + /** + * NMClient:version: + * + * The NetworkManager version. + **/ + g_object_class_install_property + (object_class, PROP_VERSION, + g_param_spec_string (NM_CLIENT_VERSION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:state: + * + * The current daemon state. + **/ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_CLIENT_STATE, "", "", + NM_TYPE_STATE, + NM_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:startup: + * + * Whether the daemon is still starting up. + **/ + g_object_class_install_property + (object_class, PROP_STARTUP, + g_param_spec_boolean (NM_CLIENT_STARTUP, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:nm-running: + * + * Whether the daemon is running. + **/ + g_object_class_install_property + (object_class, PROP_NM_RUNNING, + g_param_spec_boolean (NM_CLIENT_NM_RUNNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:networking-enabled: + * + * Whether networking is enabled. + **/ + g_object_class_install_property + (object_class, PROP_NETWORKING_ENABLED, + g_param_spec_boolean (NM_CLIENT_NETWORKING_ENABLED, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wireless-enabled: + * + * Whether wireless is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIRELESS_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wireless-hardware-enabled: + * + * Whether the wireless hardware is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIRELESS_HARDWARE_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, "", "", + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wwan-enabled: + * + * Whether WWAN functionality is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WWAN_ENABLED, + g_param_spec_boolean (NM_CLIENT_WWAN_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wwan-hardware-enabled: + * + * Whether the WWAN hardware is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WWAN_HARDWARE_ENABLED, + g_param_spec_boolean (NM_CLIENT_WWAN_HARDWARE_ENABLED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wimax-enabled: + * + * Whether WiMAX functionality is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:wimax-hardware-enabled: + * + * Whether the WiMAX hardware is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:active-connections: + * + * The active connections. + * + * Element-type: NMActiveConnection + **/ + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTIONS, + g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:connectivity: + * + * The network connectivity state. + */ + g_object_class_install_property + (object_class, PROP_CONNECTIVITY, + g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "", + NM_TYPE_CONNECTIVITY_STATE, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:primary-connection: + * + * The #NMActiveConnection of the device with the default route; + * see nm_client_get_primary_connection() for more details. + **/ + g_object_class_install_property + (object_class, PROP_PRIMARY_CONNECTION, + g_param_spec_object (NM_CLIENT_PRIMARY_CONNECTION, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:activating-connection: + * + * The #NMActiveConnection of the activating connection that is + * likely to become the new #NMClient:primary-connection. + **/ + g_object_class_install_property + (object_class, PROP_ACTIVATING_CONNECTION, + g_param_spec_object (NM_CLIENT_ACTIVATING_CONNECTION, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:devices: + * + * List of known network devices. + * + * Element-type: NMDevice + **/ + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_CLIENT_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:connections: + * + * The list of configured connections that are available to the user. (Note + * that this differs from the underlying D-Bus property, which may also + * contain the object paths of connections that the user does not have + * permission to read the details of.) + * + * Element-type: NMRemoteConnection + */ + g_object_class_install_property + (object_class, PROP_CONNECTIONS, + g_param_spec_boxed (NM_CLIENT_CONNECTIONS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:hostname: + * + * The machine hostname stored in persistent configuration. This can be + * modified by calling nm_client_save_hostname(). + */ + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_CLIENT_HOSTNAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMClient:can-modify: + * + * If %TRUE, adding and modifying connections is supported. + */ + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_CLIENT_CAN_MODIFY, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + + /** + * NMClient::device-added: + * @client: the client that received the signal + * @device: (type NMDevice): the new device + * + * Notifies that a #NMDevice is added. + **/ + signals[DEVICE_ADDED] = + g_signal_new (NM_CLIENT_DEVICE_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + /** + * NMClient::device-removed: + * @client: the client that received the signal + * @device: (type NMDevice): the removed device + * + * Notifies that a #NMDevice is removed. + **/ + signals[DEVICE_REMOVED] = + g_signal_new (NM_CLIENT_DEVICE_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, device_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + /** + * NMClient::permission-changed: + * @client: the client that received the signal + * @permission: a permission from #NMClientPermission + * @result: the permission's result, one of #NMClientPermissionResult + * + * Notifies that a permission has changed + **/ + signals[PERMISSION_CHANGED] = + g_signal_new (NM_CLIENT_PERMISSION_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + /** + * NMClient::connection-added: + * @client: the settings object that received the signal + * @connection: the new connection + * + * Notifies that a #NMConnection has been added. + **/ + signals[CONNECTION_ADDED] = + g_signal_new (NM_CLIENT_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, connection_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_REMOTE_CONNECTION); + + /** + * NMClient::connection-removed: + * @client: the settings object that received the signal + * @connection: the removed connection + * + * Notifies that a #NMConnection has been removed. + **/ + signals[CONNECTION_REMOVED] = + g_signal_new (NM_CLIENT_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMClientClass, connection_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_REMOTE_CONNECTION); +} + +static void +nm_client_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} + +static void +nm_client_async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = init_async; + iface->init_finish = init_finish; +} diff --git a/libnm/nm-client.h b/libnm/nm-client.h new file mode 100644 index 00000000..619ad858 --- /dev/null +++ b/libnm/nm-client.h @@ -0,0 +1,341 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_CLIENT_H__ +#define __NM_CLIENT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_CLIENT (nm_client_get_type ()) +#define NM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CLIENT, NMClient)) +#define NM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CLIENT, NMClientClass)) +#define NM_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CLIENT)) +#define NM_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CLIENT)) +#define NM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CLIENT, NMClientClass)) + +#define NM_CLIENT_VERSION "version" +#define NM_CLIENT_STATE "state" +#define NM_CLIENT_STARTUP "startup" +#define NM_CLIENT_NM_RUNNING "nm-running" +#define NM_CLIENT_NETWORKING_ENABLED "networking-enabled" +#define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled" +#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" +#define NM_CLIENT_WWAN_ENABLED "wwan-enabled" +#define NM_CLIENT_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_CLIENT_WIMAX_ENABLED "wimax-enabled" +#define NM_CLIENT_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" +#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" +#define NM_CLIENT_CONNECTIVITY "connectivity" +#define NM_CLIENT_PRIMARY_CONNECTION "primary-connection" +#define NM_CLIENT_ACTIVATING_CONNECTION "activating-connection" +#define NM_CLIENT_DEVICES "devices" +#define NM_CLIENT_CONNECTIONS "connections" +#define NM_CLIENT_HOSTNAME "hostname" +#define NM_CLIENT_CAN_MODIFY "can-modify" + +#define NM_CLIENT_DEVICE_ADDED "device-added" +#define NM_CLIENT_DEVICE_REMOVED "device-removed" +#define NM_CLIENT_PERMISSION_CHANGED "permission-changed" +#define NM_CLIENT_CONNECTION_ADDED "connection-added" +#define NM_CLIENT_CONNECTION_REMOVED "connection-removed" + +/** + * NMClientPermission: + * @NM_CLIENT_PERMISSION_NONE: unknown or no permission + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: controls whether networking + * can be globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: controls whether Wi-Fi can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: controls whether WWAN (3G) can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: controls whether WiMAX can be + * globally enabled or disabled + * @NM_CLIENT_PERMISSION_SLEEP_WAKE: controls whether the client can ask + * NetworkManager to sleep and wake + * @NM_CLIENT_PERMISSION_NETWORK_CONTROL: controls whether networking connections + * can be started, stopped, and changed + * @NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: controls whether a password + * protected Wi-Fi hotspot can be created + * @NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: controls whether an open Wi-Fi hotspot + * can be created + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: controls whether connections + * that are available to all users can be modified + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: controls whether connections + * owned by the current user can be modified + * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: controls whether the + * persistent hostname can be changed + * @NM_CLIENT_PERMISSION_LAST: a reserved boundary value + * + * #NMClientPermission values indicate various permissions that NetworkManager + * clients can obtain to perform certain tasks on behalf of the current user. + **/ +typedef enum { + NM_CLIENT_PERMISSION_NONE = 0, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 4, + NM_CLIENT_PERMISSION_SLEEP_WAKE = 5, + NM_CLIENT_PERMISSION_NETWORK_CONTROL = 6, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 7, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 8, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 9, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN = 10, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME = 11, + + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME +} NMClientPermission; + +/** + * NMClientPermissionResult: + * @NM_CLIENT_PERMISSION_RESULT_UNKNOWN: unknown or no authorization + * @NM_CLIENT_PERMISSION_RESULT_YES: the permission is available + * @NM_CLIENT_PERMISSION_RESULT_AUTH: authorization is necessary before the + * permission is available + * @NM_CLIENT_PERMISSION_RESULT_NO: permission to perform the operation is + * denied by system policy + * + * #NMClientPermissionResult values indicate what authorizations and permissions + * the user requires to obtain a given #NMClientPermission + **/ +typedef enum { + NM_CLIENT_PERMISSION_RESULT_UNKNOWN = 0, + NM_CLIENT_PERMISSION_RESULT_YES, + NM_CLIENT_PERMISSION_RESULT_AUTH, + NM_CLIENT_PERMISSION_RESULT_NO +} NMClientPermissionResult; + +/** + * NMClientError: + * @NM_CLIENT_ERROR_FAILED: unknown or unclassified error + * @NM_CLIENT_ERROR_MANAGER_NOT_RUNNING: an operation that requires NetworkManager + * failed because NetworkManager is not running + * @NM_CLIENT_ERROR_OBJECT_CREATION_FAILED: NetworkManager claimed that an + * operation succeeded, but the object that was allegedly created (eg, + * #NMRemoteConnection, #NMActiveConnection) was apparently destroyed before + * #NMClient could create a representation of it. + * + * Describes errors that may result from operations involving a #NMClient. + * + * D-Bus operations may also return errors from other domains, including + * #NMManagerError, #NMSettingsError, #NMAgentManagerError, and #NMConnectionError. + **/ +typedef enum { + NM_CLIENT_ERROR_FAILED = 0, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, +} NMClientError; + +#define NM_CLIENT_ERROR nm_client_error_quark () +GQuark nm_client_error_quark (void); + +struct _NMClient { + GObject parent; +}; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*device_added) (NMClient *client, NMDevice *device); + void (*device_removed) (NMClient *client, NMDevice *device); + void (*permission_changed) (NMClient *client, + NMClientPermission permission, + NMClientPermissionResult result); + void (*connection_added) (NMClient *client, NMRemoteConnection *connection); + void (*connection_removed) (NMClient *client, NMRemoteConnection *connection); + + /*< private >*/ + gpointer padding[8]; +} NMClientClass; + +GType nm_client_get_type (void); + +NMClient *nm_client_new (GCancellable *cancellable, + GError **error); + +void nm_client_new_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMClient *nm_client_new_finish (GAsyncResult *result, + GError **error); + +const char *nm_client_get_version (NMClient *client); +NMState nm_client_get_state (NMClient *client); +gboolean nm_client_get_startup (NMClient *client); +gboolean nm_client_get_nm_running (NMClient *client); + +gboolean nm_client_networking_get_enabled (NMClient *client); +gboolean nm_client_networking_set_enabled (NMClient *client, + gboolean enabled, + GError **error); + +gboolean nm_client_wireless_get_enabled (NMClient *client); +void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled); +gboolean nm_client_wireless_hardware_get_enabled (NMClient *client); + +gboolean nm_client_wwan_get_enabled (NMClient *client); +void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled); +gboolean nm_client_wwan_hardware_get_enabled (NMClient *client); + +gboolean nm_client_wimax_get_enabled (NMClient *client); +void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled); +gboolean nm_client_wimax_hardware_get_enabled (NMClient *client); + +gboolean nm_client_get_logging (NMClient *client, + char **level, + char **domains, + GError **error); +gboolean nm_client_set_logging (NMClient *client, + const char *level, + const char *domains, + GError **error); + +NMClientPermissionResult nm_client_get_permission_result (NMClient *client, + NMClientPermission permission); + +NMConnectivityState nm_client_get_connectivity (NMClient *client); + +NMConnectivityState nm_client_check_connectivity (NMClient *client, + GCancellable *cancellable, + GError **error); +void nm_client_check_connectivity_async (NMClient *client, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMConnectivityState nm_client_check_connectivity_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +gboolean nm_client_save_hostname (NMClient *client, + const char *hostname, + GCancellable *cancellable, + GError **error); +void nm_client_save_hostname_async (NMClient *client, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_save_hostname_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +/* Devices */ + +const GPtrArray *nm_client_get_devices (NMClient *client); +NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); +NMDevice *nm_client_get_device_by_iface (NMClient *client, const char *iface); + +/* Active Connections */ + +const GPtrArray *nm_client_get_active_connections (NMClient *client); + +NMActiveConnection *nm_client_get_primary_connection (NMClient *client); +NMActiveConnection *nm_client_get_activating_connection (NMClient *client); + +void nm_client_activate_connection_async (NMClient *client, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +void nm_client_add_and_activate_connection_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_add_and_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +gboolean nm_client_deactivate_connection (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error); +void nm_client_deactivate_connection_async (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_deactivate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +/* Connections */ + +const GPtrArray *nm_client_get_connections (NMClient *client); + +NMRemoteConnection *nm_client_get_connection_by_id (NMClient *client, const char *id); +NMRemoteConnection *nm_client_get_connection_by_path (NMClient *client, const char *path); +NMRemoteConnection *nm_client_get_connection_by_uuid (NMClient *client, const char *uuid); + +void nm_client_add_connection_async (NMClient *client, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMRemoteConnection *nm_client_add_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +gboolean nm_client_load_connections (NMClient *client, + char **filenames, + char ***failures, + GCancellable *cancellable, + GError **error); +void nm_client_load_connections_async (NMClient *client, + char **filenames, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_load_connections_finish (NMClient *client, + char ***failures, + GAsyncResult *result, + GError **error); + +gboolean nm_client_reload_connections (NMClient *client, + GCancellable *cancellable, + GError **error); +void nm_client_reload_connections_async (NMClient *client, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_client_reload_connections_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __NM_CLIENT_H__ */ diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c new file mode 100644 index 00000000..7a99e70d --- /dev/null +++ b/libnm/nm-dbus-helpers.c @@ -0,0 +1,405 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include "nm-dbus-helpers.h" +#include "nm-dbus-interface.h" + +static GBusType nm_bus = G_BUS_TYPE_SYSTEM; + +GBusType +_nm_dbus_bus_type (void) +{ + static gsize init_value = 0; + + if (g_once_init_enter (&init_value)) { + if (g_getenv ("LIBNM_USE_SESSION_BUS")) + nm_bus = G_BUS_TYPE_SESSION; + + g_once_init_leave (&init_value, 1); + } + + return nm_bus; +} + +static struct { + GMutex mutex; + GWeakRef weak_ref; +} private_connection; + +static void +_private_dbus_connection_closed_cb (GDBusConnection *connection, + gboolean remote_peer_vanished, + GError *error, + gpointer user_data) +{ + GDBusConnection *p; + + g_mutex_lock (&private_connection.mutex); + p = g_weak_ref_get (&private_connection.weak_ref); + if (connection == p) { + g_signal_handlers_disconnect_by_func (G_OBJECT (connection), G_CALLBACK (_private_dbus_connection_closed_cb), NULL); + g_weak_ref_set (&private_connection.weak_ref, NULL); + } + if (p) + g_object_unref (p); + g_mutex_unlock (&private_connection.mutex); +} + +static GDBusConnection * +_private_dbus_connection_internalize (GDBusConnection *connection) +{ + GDBusConnection *p; + + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_return_val_if_fail (!g_dbus_connection_is_closed (connection), NULL); + + g_mutex_lock (&private_connection.mutex); + p = g_weak_ref_get (&private_connection.weak_ref); + if (p) { + g_object_unref (connection); + connection = p; + } else { + g_weak_ref_set (&private_connection.weak_ref, connection); + g_signal_connect (connection, "closed", G_CALLBACK (_private_dbus_connection_closed_cb), NULL); + } + g_mutex_unlock (&private_connection.mutex); + return connection; +} + +GDBusConnection * +_nm_dbus_new_connection (GCancellable *cancellable, GError **error) +{ + GDBusConnection *connection = NULL; + + /* If running as root try the private bus first */ + if (0 == geteuid ()) { + GError *local = NULL; + GDBusConnection *p; + + p = g_weak_ref_get (&private_connection.weak_ref); + if (p) + return p; + + connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, cancellable, &local); + if (connection) + return _private_dbus_connection_internalize (connection); + + if (g_error_matches (local, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_propagate_error (error, local); + return NULL; + } + g_error_free (local); + } + + return g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error); +} + +static void +new_connection_async_got_system (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GDBusConnection *connection; + GError *error = NULL; + + connection = g_bus_get_finish (result, &error); + if (connection) + g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); + else + g_simple_async_result_take_error (simple, error); + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +new_connection_async_got_private (GObject *source, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GDBusConnection *connection; + GError *error = NULL; + + connection = g_dbus_connection_new_for_address_finish (result, &error); + if (connection) { + connection = _private_dbus_connection_internalize (connection); + g_simple_async_result_set_op_res_gpointer (simple, connection, g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); + return; + } + + g_clear_error (&error); + g_bus_get (_nm_dbus_bus_type (), + g_object_get_data (G_OBJECT (simple), "cancellable"), + new_connection_async_got_system, simple); +} + +static void +_nm_dbus_new_connection_async_do (GSimpleAsyncResult *simple, GCancellable *cancellable) +{ + g_dbus_connection_new_for_address ("unix:path=" NMRUNDIR "/private", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, + cancellable, + new_connection_async_got_private, simple); +} + +static gboolean +_nm_dbus_new_connection_async_get_private (gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GDBusConnection *p; + + p = g_weak_ref_get (&private_connection.weak_ref); + if (!p) { + /* The connection is gone. Create a new one async... */ + _nm_dbus_new_connection_async_do (simple, + g_object_get_data (G_OBJECT (simple), "cancellable")); + } else { + g_simple_async_result_set_op_res_gpointer (simple, p, g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); + } + + return G_SOURCE_REMOVE; +} + +void +_nm_dbus_new_connection_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new (NULL, callback, user_data, _nm_dbus_new_connection_async); + + /* If running as root try the private bus first */ + if (0 == geteuid ()) { + GDBusConnection *p; + + if (cancellable) { + g_object_set_data_full (G_OBJECT (simple), "cancellable", + g_object_ref (cancellable), g_object_unref); + } + p = g_weak_ref_get (&private_connection.weak_ref); + if (p) { + g_object_unref (p); + g_idle_add (_nm_dbus_new_connection_async_get_private, simple); + } else + _nm_dbus_new_connection_async_do (simple, cancellable); + } else { + g_bus_get (_nm_dbus_bus_type (), + cancellable, + new_connection_async_got_system, simple); + } +} + +GDBusConnection * +_nm_dbus_new_connection_finish (GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +gboolean +_nm_dbus_is_connection_private (GDBusConnection *connection) +{ + return g_dbus_connection_get_unique_name (connection) == NULL; +} + +static GHashTable *proxy_types; + +#undef _nm_dbus_register_proxy_type +void +_nm_dbus_register_proxy_type (const char *interface, + GType proxy_type) +{ + if (!proxy_types) + proxy_types = g_hash_table_new (g_str_hash, g_str_equal); + + g_assert (g_hash_table_lookup (proxy_types, interface) == NULL); + g_hash_table_insert (proxy_types, (char *) interface, GSIZE_TO_POINTER (proxy_type)); +} + +/* We don't (currently) use GDBus's property-handling code */ +#define NM_DBUS_PROXY_FLAGS (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | \ + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START) + +GDBusProxy * +_nm_dbus_new_proxy_for_connection (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GError **error) +{ + GType proxy_type; + const char *name; + + proxy_type = GPOINTER_TO_SIZE (g_hash_table_lookup (proxy_types, interface)); + if (!proxy_type) + proxy_type = G_TYPE_DBUS_PROXY; + + if (_nm_dbus_is_connection_private (connection)) + name = NULL; + else + name = NM_DBUS_SERVICE; + + return g_initable_new (proxy_type, cancellable, error, + "g-connection", connection, + "g-flags", NM_DBUS_PROXY_FLAGS, + "g-name", name, + "g-object-path", path, + "g-interface-name", interface, + NULL); +} + +void +_nm_dbus_new_proxy_for_connection_async (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GType proxy_type; + const char *name; + + proxy_type = GPOINTER_TO_SIZE (g_hash_table_lookup (proxy_types, interface)); + if (!proxy_type) + proxy_type = G_TYPE_DBUS_PROXY; + + if (_nm_dbus_is_connection_private (connection)) + name = NULL; + else + name = NM_DBUS_SERVICE; + + g_async_initable_new_async (proxy_type, G_PRIORITY_DEFAULT, + cancellable, callback, user_data, + "g-connection", connection, + "g-flags", NM_DBUS_PROXY_FLAGS, + "g-name", name, + "g-object-path", path, + "g-interface-name", interface, + NULL); +} + +GDBusProxy * +_nm_dbus_new_proxy_for_connection_finish (GAsyncResult *result, + GError **error) +{ + GObject *source, *proxy; + + source = g_async_result_get_source_object (result); + proxy = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, error); + g_object_unref (source); + + return G_DBUS_PROXY (proxy); +} + +/* Binds the properties on a generated server-side GDBus object to the + * corresponding properties on the public object. + */ +void +_nm_dbus_bind_properties (gpointer object, gpointer skeleton) +{ + GParamSpec **properties; + guint n_properties; + int i; + + properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (skeleton), &n_properties); + for (i = 0; i < n_properties; i++) { + if (g_str_has_prefix (properties[i]->name, "g-")) + continue; + + g_object_bind_property (object, properties[i]->name, + skeleton, properties[i]->name, + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + } +} + +static char * +signal_name_from_method_name (const char *method_name) +{ + GString *signal_name; + const char *p; + + signal_name = g_string_new ("handle"); + for (p = method_name; *p; p++) { + if (g_ascii_isupper (*p)) + g_string_append_c (signal_name, '-'); + g_string_append_c (signal_name, g_ascii_tolower (*p)); + } + + return g_string_free (signal_name, FALSE); +} + +static void +_nm_dbus_method_meta_marshal (GClosure *closure, GValue *return_value, + guint n_param_values, const GValue *param_values, + gpointer invocation_hint, gpointer marshal_data) +{ + closure->marshal (closure, return_value, n_param_values, + param_values, invocation_hint, + ((GCClosure *)closure)->callback); + + g_value_set_boolean (return_value, TRUE); +} + +/* Takes (method_name, handler_func) pairs and connects the handlers to the + * signals on skeleton, with object as the user_data, but swapped so it comes + * first in the argument list, and handling the return value automatically. + */ +void +_nm_dbus_bind_methods (gpointer object, gpointer skeleton, ...) +{ + va_list ap; + const char *method_name; + char *signal_name; + GCallback handler; + GClosure *closure; + + va_start (ap, skeleton); + while ( (method_name = va_arg (ap, const char *)) + && (handler = va_arg (ap, GCallback))) { + signal_name = signal_name_from_method_name (method_name); + closure = g_cclosure_new_swap (handler, object, NULL); + g_closure_set_meta_marshal (closure, NULL, _nm_dbus_method_meta_marshal); + g_signal_connect_closure (skeleton, signal_name, closure, FALSE); + g_free (signal_name); + } + va_end (ap); +} diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h new file mode 100644 index 00000000..ca779d3a --- /dev/null +++ b/libnm/nm-dbus-helpers.h @@ -0,0 +1,78 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_HELPERS_PRIVATE_H__ +#define __NM_DBUS_HELPERS_PRIVATE_H__ + +#include + +/* Copied from dbus/dbus-shared.h */ +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" + + +GBusType _nm_dbus_bus_type (void); + +GDBusConnection *_nm_dbus_new_connection (GCancellable *cancellable, + GError **error); + +void _nm_dbus_new_connection_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDBusConnection *_nm_dbus_new_connection_finish (GAsyncResult *result, + GError **error); + +gboolean _nm_dbus_is_connection_private (GDBusConnection *connection); + +void _nm_dbus_register_proxy_type (const char *interface, + GType proxy_type); +/* Guarantee that @interface is a static string */ +#define _nm_dbus_register_proxy_type(interface, proxy_type) \ + _nm_dbus_register_proxy_type (interface "", proxy_type) \ + +GDBusProxy *_nm_dbus_new_proxy_for_connection (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GError **error); + +void _nm_dbus_new_proxy_for_connection_async (GDBusConnection *connection, + const char *path, + const char *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GDBusProxy *_nm_dbus_new_proxy_for_connection_finish (GAsyncResult *result, + GError **error); + +void _nm_dbus_bind_properties (gpointer object, + gpointer skeleton); + +void _nm_dbus_bind_methods (gpointer object, + gpointer skeleton, + ...) G_GNUC_NULL_TERMINATED; + +#endif /* __NM_DBUS_HELPERS_PRIVATE_H__ */ diff --git a/libnm/nm-device-adsl.c b/libnm/nm-device-adsl.c new file mode 100644 index 00000000..99771548 --- /dev/null +++ b/libnm/nm-device-adsl.c @@ -0,0 +1,159 @@ +/* -*- 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. + * + * author: Pantelis Koukousoulas + * Copyright 2009 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-device-adsl.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +#include "nm-setting-adsl.h" +#include "nm-setting-connection.h" + +#include +#include + +G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) + +#define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate)) + +typedef struct { + gboolean carrier; + +} NMDeviceAdslPrivate; + +enum { + PROP_0, + PROP_CARRIER, + LAST_PROP +}; + +/** + * nm_device_adsl_get_carrier: + * @device: a #NMDeviceAdsl + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_adsl_get_carrier (NMDeviceAdsl *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ADSL (device), FALSE); + + return NM_DEVICE_ADSL_GET_PRIVATE (device)->carrier; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_adsl_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_ADSL_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an ADSL connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_ADSL; +} + +/******************************************************************/ + +static void +nm_device_adsl_init (NMDeviceAdsl *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_ADSL); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_ADSL_CARRIER, &priv->carrier }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_adsl_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_ADSL, + property_info); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceAdsl *device = NM_DEVICE_ADSL (object); + + switch (prop_id) { + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_adsl_get_carrier (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (adsl_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (adsl_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (adsl_class); + + g_type_class_add_private (object_class, sizeof (NMDeviceAdslPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_ADSL); + + /* virtual methods */ + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /* properties */ + /** + * NMDeviceAdsl:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_ADSL_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-adsl.h b/libnm/nm-device-adsl.h new file mode 100644 index 00000000..d0174514 --- /dev/null +++ b/libnm/nm-device-adsl.h @@ -0,0 +1,58 @@ +/* -*- 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. + * + * Copyright 2011 Pantelis Koukousoulas + */ + +#ifndef __NM_DEVICE_ADSL_H__ +#define __NM_DEVICE_ADSL_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_ADSL (nm_device_adsl_get_type ()) +#define NM_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdsl)) +#define NM_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) +#define NM_IS_DEVICE_ADSL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_ADSL)) +#define NM_IS_DEVICE_ADSL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ADSL)) +#define NM_DEVICE_ADSL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ADSL, NMDeviceAdslClass)) + +#define NM_DEVICE_ADSL_CARRIER "carrier" + +struct _NMDeviceAdsl { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceAdslClass; + +GType nm_device_adsl_get_type (void); + +gboolean nm_device_adsl_get_carrier (NMDeviceAdsl *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_ADSL_H__ */ diff --git a/libnm/nm-device-bond.c b/libnm/nm-device-bond.c new file mode 100644 index 00000000..6bb67323 --- /dev/null +++ b/libnm/nm-device-bond.c @@ -0,0 +1,271 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-bond.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" + +G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) + +#define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) + +typedef struct { + char *hw_address; + gboolean carrier; + GPtrArray *slaves; +} NMDeviceBondPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_SLAVES, + + LAST_PROP +}; + +/** + * nm_device_bond_get_hw_address: + * @device: a #NMDeviceBond + * + * Gets the hardware (MAC) address of the #NMDeviceBond + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_bond_get_hw_address (NMDeviceBond *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BOND (device), NULL); + + return NM_DEVICE_BOND_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_bond_get_carrier: + * @device: a #NMDeviceBond + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_bond_get_carrier (NMDeviceBond *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BOND (device), FALSE); + + return NM_DEVICE_BOND_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_bond_get_slaves: + * @device: a #NMDeviceBond + * + * Gets the devices currently slaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_bond_get_slaves (NMDeviceBond *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BOND (device), FALSE); + + return NM_DEVICE_BOND_GET_PRIVATE (device)->slaves; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a bond connection.")); + return FALSE; + } + + /* FIXME: check slaves? */ + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BOND; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bond_get_hw_address (NM_DEVICE_BOND (device)); +} + +/***********************************************************/ + +static void +nm_device_bond_init (NMDeviceBond *device) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (device); + + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_BOND); + + priv->slaves = g_ptr_array_new (); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_BOND_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_BOND_CARRIER, &priv->carrier }, + { NM_DEVICE_BOND_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_bond_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_BOND, + property_info); +} + +static void +dispose (GObject *object) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object); + + g_clear_pointer (&priv->slaves, g_ptr_array_unref); + + G_OBJECT_CLASS (nm_device_bond_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_bond_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceBond *device = NM_DEVICE_BOND (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_bond_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_bond_get_carrier (device)); + break; + case PROP_SLAVES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_bond_get_slaves (device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_bond_class_init (NMDeviceBondClass *bond_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (bond_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bond_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (bond_class); + + g_type_class_add_private (bond_class, sizeof (NMDeviceBondPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BOND); + + /* virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceBond:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBond:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_BOND_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBond:slaves: + * + * The devices slaved to the bond device. + * + * Element-type: NMDevice + **/ + g_object_class_install_property + (object_class, PROP_SLAVES, + g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-bond.h b/libnm/nm-device-bond.h new file mode 100644 index 00000000..b7a0b113 --- /dev/null +++ b/libnm/nm-device-bond.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_BOND_H__ +#define __NM_DEVICE_BOND_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BOND (nm_device_bond_get_type ()) +#define NM_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBond)) +#define NM_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) +#define NM_IS_DEVICE_BOND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BOND)) +#define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) +#define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) + +#define NM_DEVICE_BOND_HW_ADDRESS "hw-address" +#define NM_DEVICE_BOND_CARRIER "carrier" +#define NM_DEVICE_BOND_SLAVES "slaves" + +struct _NMDeviceBond { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceBondClass; + +GType nm_device_bond_get_type (void); + +const char *nm_device_bond_get_hw_address (NMDeviceBond *device); +gboolean nm_device_bond_get_carrier (NMDeviceBond *device); +const GPtrArray *nm_device_bond_get_slaves (NMDeviceBond *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BOND_H__ */ diff --git a/libnm/nm-device-bridge.c b/libnm/nm-device-bridge.c new file mode 100644 index 00000000..ce28f2c2 --- /dev/null +++ b/libnm/nm-device-bridge.c @@ -0,0 +1,271 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-bridge.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" + +G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) + +#define NM_DEVICE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgePrivate)) + +typedef struct { + char *hw_address; + gboolean carrier; + GPtrArray *slaves; +} NMDeviceBridgePrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_SLAVES, + + LAST_PROP +}; + +/** + * nm_device_bridge_get_hw_address: + * @device: a #NMDeviceBridge + * + * Gets the hardware (MAC) address of the #NMDeviceBridge + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_bridge_get_hw_address (NMDeviceBridge *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BRIDGE (device), NULL); + + return NM_DEVICE_BRIDGE_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_bridge_get_carrier: + * @device: a #NMDeviceBridge + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_bridge_get_carrier (NMDeviceBridge *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BRIDGE (device), FALSE); + + return NM_DEVICE_BRIDGE_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_bridge_get_slaves: + * @device: a #NMDeviceBridge + * + * Gets the devices currently slaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_bridge_get_slaves (NMDeviceBridge *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BRIDGE (device), FALSE); + + return NM_DEVICE_BRIDGE_GET_PRIVATE (device)->slaves; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a bridge connection.")); + return FALSE; + } + + /* FIXME: check ports? */ + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BRIDGE; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bridge_get_hw_address (NM_DEVICE_BRIDGE (device)); +} + +/***********************************************************/ + +static void +nm_device_bridge_init (NMDeviceBridge *device) +{ + NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (device); + + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_BRIDGE); + + priv->slaves = g_ptr_array_new (); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_BRIDGE_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_BRIDGE_CARRIER, &priv->carrier }, + { NM_DEVICE_BRIDGE_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_bridge_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_BRIDGE, + property_info); +} + +static void +dispose (GObject *object) +{ + NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); + + g_clear_pointer (&priv->slaves, g_ptr_array_unref); + + G_OBJECT_CLASS (nm_device_bridge_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_bridge_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceBridge *device = NM_DEVICE_BRIDGE (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_bridge_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_bridge_get_carrier (device)); + break; + case PROP_SLAVES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_bridge_get_slaves (device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (bridge_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bridge_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (bridge_class); + + g_type_class_add_private (bridge_class, sizeof (NMDeviceBridgePrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BRIDGE); + + /* virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceBridge:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_BRIDGE_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBridge:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_BRIDGE_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBridge:slaves: + * + * The devices slaved to the bridge device. + * + * Element-type: NMDevice + **/ + g_object_class_install_property + (object_class, PROP_SLAVES, + g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-bridge.h b/libnm/nm-device-bridge.h new file mode 100644 index 00000000..42a0b3a5 --- /dev/null +++ b/libnm/nm-device-bridge.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_BRIDGE_H__ +#define __NM_DEVICE_BRIDGE_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BRIDGE (nm_device_bridge_get_type ()) +#define NM_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridge)) +#define NM_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) +#define NM_IS_DEVICE_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BRIDGE)) +#define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BRIDGE)) +#define NM_DEVICE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) + +#define NM_DEVICE_BRIDGE_HW_ADDRESS "hw-address" +#define NM_DEVICE_BRIDGE_CARRIER "carrier" +#define NM_DEVICE_BRIDGE_SLAVES "slaves" + +struct _NMDeviceBridge { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceBridgeClass; + +GType nm_device_bridge_get_type (void); + +const char *nm_device_bridge_get_hw_address (NMDeviceBridge *device); +gboolean nm_device_bridge_get_carrier (NMDeviceBridge *device); +const GPtrArray *nm_device_bridge_get_slaves (NMDeviceBridge *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BRIDGE_H__ */ diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c new file mode 100644 index 00000000..77526464 --- /dev/null +++ b/libnm/nm-device-bt.c @@ -0,0 +1,305 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-bt.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-enum-types.h" + +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)) + +typedef struct { + char *hw_address; + char *name; + guint32 bt_capabilities; +} NMDeviceBtPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_NAME, + PROP_BT_CAPABILITIES, + + LAST_PROP +}; + +/** + * nm_device_bt_get_hw_address: + * @device: a #NMDeviceBt + * + * Gets the hardware (MAC) address of the #NMDeviceBt + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_bt_get_hw_address (NMDeviceBt *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BT (device), NULL); + + return NM_DEVICE_BT_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_bt_get_name: + * @device: a #NMDeviceBt + * + * Gets the name of the #NMDeviceBt. + * + * Returns: the name of the device + **/ +const char * +nm_device_bt_get_name (NMDeviceBt *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BT (device), NULL); + + return NM_DEVICE_BT_GET_PRIVATE (device)->name; +} + +/** + * nm_device_bt_get_capabilities: + * @device: a #NMDeviceBt + * + * Returns the Bluetooth device's usable capabilities. + * + * Returns: a combination of #NMBluetoothCapabilities + **/ +NMBluetoothCapabilities +nm_device_bt_get_capabilities (NMDeviceBt *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_BT (device), NM_BT_CAPABILITY_NONE); + + return NM_DEVICE_BT_GET_PRIVATE (device)->bt_capabilities; +} + +static NMBluetoothCapabilities +get_connection_bt_type (NMConnection *connection) +{ + NMSettingBluetooth *s_bt; + const char *bt_type; + + s_bt = nm_connection_get_setting_bluetooth (connection); + if (!s_bt) + return NM_BT_CAPABILITY_NONE; + + bt_type = nm_setting_bluetooth_get_connection_type (s_bt); + g_assert (bt_type); + + if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)) + return NM_BT_CAPABILITY_DUN; + else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)) + return NM_BT_CAPABILITY_NAP; + + return NM_BT_CAPABILITY_NONE; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingBluetooth *s_bt; + const char *hw_addr, *setting_addr; + NMBluetoothCapabilities dev_caps; + NMBluetoothCapabilities bt_type; + + if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a Bluetooth connection.")); + return FALSE; + } + + /* Check BT address */ + hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); + if (hw_addr) { + if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + _("Invalid device Bluetooth address.")); + return FALSE; + } + s_bt = nm_connection_get_setting_bluetooth (connection); + setting_addr = nm_setting_bluetooth_get_bdaddr (s_bt); + if (setting_addr && !nm_utils_hwaddr_matches (setting_addr, -1, hw_addr, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The Bluetooth addresses of the device and the connection didn't match.")); + return FALSE; + } + } + + dev_caps = nm_device_bt_get_capabilities (NM_DEVICE_BT (device)); + bt_type = get_connection_bt_type (connection); + if (!(bt_type & dev_caps)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking Bluetooth capabilities required by the connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_BLUETOOTH; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); +} + +/************************************************************/ + +static void +nm_device_bt_init (NMDeviceBt *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_BT); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_BT_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_BT_NAME, &priv->name }, + { NM_DEVICE_BT_CAPABILITIES, &priv->bt_capabilities }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_bt_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_free (priv->name); + + G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceBt *device = NM_DEVICE_BT (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_bt_get_hw_address (device)); + break; + case PROP_NAME: + g_value_set_string (value, nm_device_bt_get_name (device)); + break; + case PROP_BT_CAPABILITIES: + g_value_set_flags (value, nm_device_bt_get_capabilities (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_bt_class_init (NMDeviceBtClass *bt_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (bt_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bt_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (bt_class); + + g_type_class_add_private (bt_class, sizeof (NMDeviceBtPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceBt:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_BT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBt:name: + * + * The name of the bluetooth device. + **/ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_DEVICE_BT_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceBt:bt-capabilities: + * + * The device's bluetooth capabilities, a combination of #NMBluetoothCapabilities. + **/ + g_object_class_install_property + (object_class, PROP_BT_CAPABILITIES, + g_param_spec_flags (NM_DEVICE_BT_CAPABILITIES, "", "", + NM_TYPE_BLUETOOTH_CAPABILITIES, + NM_BT_CAPABILITY_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + +} diff --git a/libnm/nm-device-bt.h b/libnm/nm-device-bt.h new file mode 100644 index 00000000..e066cbcd --- /dev/null +++ b/libnm/nm-device-bt.h @@ -0,0 +1,65 @@ +/* -*- 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. + * + * Copyright 2008 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_DEVICE_BT_H__ +#define __NM_DEVICE_BT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_BT (nm_device_bt_get_type ()) +#define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BT, NMDeviceBt)) +#define NM_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) +#define NM_IS_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BT)) +#define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT)) +#define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) + +#define NM_DEVICE_BT_HW_ADDRESS "hw-address" +#define NM_DEVICE_BT_NAME "name" +#define NM_DEVICE_BT_CAPABILITIES "bt-capabilities" + +struct _NMDeviceBt { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceBtClass; + +GType nm_device_bt_get_type (void); + +const char *nm_device_bt_get_hw_address (NMDeviceBt *device); + +const char *nm_device_bt_get_name (NMDeviceBt *device); + +NMBluetoothCapabilities nm_device_bt_get_capabilities (NMDeviceBt *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_BT_H__ */ diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c new file mode 100644 index 00000000..be2cb4dc --- /dev/null +++ b/libnm/nm-device-ethernet.c @@ -0,0 +1,317 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include +#include + +#include "nm-device-ethernet.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) + +#define NM_DEVICE_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate)) + +typedef struct { + char *hw_address; + char *perm_hw_address; + guint32 speed; + gboolean carrier; +} NMDeviceEthernetPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_PERM_HW_ADDRESS, + PROP_SPEED, + PROP_CARRIER, + + LAST_PROP +}; + +/** + * nm_device_ethernet_get_hw_address: + * @device: a #NMDeviceEthernet + * + * Gets the active hardware (MAC) address of the #NMDeviceEthernet + * + * Returns: the active hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_ethernet_get_hw_address (NMDeviceEthernet *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL); + + return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_ethernet_get_permanent_hw_address: + * @device: a #NMDeviceEthernet + * + * Gets the permanent hardware (MAC) address of the #NMDeviceEthernet + * + * Returns: the permanent hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL); + + return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->perm_hw_address; +} + +/** + * nm_device_ethernet_get_speed: + * @device: a #NMDeviceEthernet + * + * Gets the speed of the #NMDeviceEthernet. + * + * Returns: the speed of the device + **/ +guint32 +nm_device_ethernet_get_speed (NMDeviceEthernet *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), 0); + + return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->speed; +} + +/** + * nm_device_ethernet_get_carrier: + * @device: a #NMDeviceEthernet + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_ethernet_get_carrier (NMDeviceEthernet *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), FALSE); + + return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->carrier; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingWired *s_wired; + gboolean is_pppoe = FALSE; + + if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) + is_pppoe = TRUE; + else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an Ethernet or PPPoE connection.")); + return FALSE; + } + + s_wired = nm_connection_get_setting_wired (connection); + /* Wired setting optional for PPPoE */ + if (s_wired) { + const char *perm_addr, *setting_addr; + + /* FIXME: filter using s390 subchannels when they are exported over the bus */ + + /* Check MAC address */ + perm_addr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device)); + if (perm_addr) { + if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + setting_addr = nm_setting_wired_get_mac_address (s_wired); + if (setting_addr && !nm_utils_hwaddr_matches (setting_addr, -1, perm_addr, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIRED; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)); +} + +/***********************************************************/ + +static void +nm_device_ethernet_init (NMDeviceEthernet *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_ETHERNET); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_ETHERNET_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, &priv->perm_hw_address }, + { NM_DEVICE_ETHERNET_SPEED, &priv->speed }, + { NM_DEVICE_ETHERNET_CARRIER, &priv->carrier }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_ethernet_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_WIRED, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_free (priv->perm_hw_address); + + G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceEthernet *device = NM_DEVICE_ETHERNET (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_ethernet_get_hw_address (device)); + break; + case PROP_PERM_HW_ADDRESS: + g_value_set_string (value, nm_device_ethernet_get_permanent_hw_address (device)); + break; + case PROP_SPEED: + g_value_set_uint (value, nm_device_ethernet_get_speed (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_ethernet_get_carrier (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (eth_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (eth_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class); + + g_type_class_add_private (eth_class, sizeof (NMDeviceEthernetPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIRED); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceEthernet:hw-address: + * + * The active hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceEthernet:perm-hw-address: + * + * The permanent hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_PERM_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceEthernet:speed: + * + * The speed of the device. + **/ + g_object_class_install_property + (object_class, PROP_SPEED, + g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceEthernet:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_ETHERNET_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + +} diff --git a/libnm/nm-device-ethernet.h b/libnm/nm-device-ethernet.h new file mode 100644 index 00000000..09286e73 --- /dev/null +++ b/libnm/nm-device-ethernet.h @@ -0,0 +1,65 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_ETHERNET_H__ +#define __NM_DEVICE_ETHERNET_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_ETHERNET (nm_device_ethernet_get_type ()) +#define NM_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernet)) +#define NM_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) +#define NM_IS_DEVICE_ETHERNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_ETHERNET)) +#define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) +#define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) + +#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address" +#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" +#define NM_DEVICE_ETHERNET_SPEED "speed" +#define NM_DEVICE_ETHERNET_CARRIER "carrier" + +struct _NMDeviceEthernet { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceEthernetClass; + +GType nm_device_ethernet_get_type (void); + +const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device); +const char * nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device); +guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *device); +gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_ETHERNET_H__ */ diff --git a/libnm/nm-device-generic.c b/libnm/nm-device-generic.c new file mode 100644 index 00000000..3ed0fa7e --- /dev/null +++ b/libnm/nm-device-generic.c @@ -0,0 +1,214 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-device-generic.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-setting-generic.h" +#include "nm-setting-connection.h" + +G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENERIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericPrivate)) + +typedef struct { + char *hw_address; + char *type_description; +} NMDeviceGenericPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_TYPE_DESCRIPTION, + + LAST_PROP +}; + +/** + * nm_device_generic_get_hw_address: + * @device: a #NMDeviceGeneric + * + * Gets the hardware address of the #NMDeviceGeneric + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_generic_get_hw_address (NMDeviceGeneric *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_GENERIC (device), NULL); + + return NM_DEVICE_GENERIC_GET_PRIVATE (device)->hw_address; +} + +/***********************************************************/ + +static const char * +get_type_description (NMDevice *device) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (device); + + return priv->type_description; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_generic_get_hw_address (NM_DEVICE_GENERIC (device)); +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + const char *iface_name; + + if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_GENERIC_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a generic connection.")); + return FALSE; + } + + iface_name = nm_connection_get_interface_name (connection); + if (!iface_name) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection did not specify an interface name.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_GENERIC; +} + +/***********************************************************/ + +static void +nm_device_generic_init (NMDeviceGeneric *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_GENERIC); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_GENERIC_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_GENERIC_TYPE_DESCRIPTION, &priv->type_description }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_generic_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_GENERIC, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_free (priv->type_description); + + G_OBJECT_CLASS (nm_device_generic_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, priv->hw_address); + break; + case PROP_TYPE_DESCRIPTION: + g_value_set_string (value, priv->type_description); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_generic_class_init (NMDeviceGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDeviceGenericPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_GENERIC); + + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->get_type_description = get_type_description; + device_class->get_hw_address = get_hw_address; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceGeneric:hw-address: + * + * The hardware address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceGeneric:type-description: + * + * A description of the specific type of device this is, or %NULL + * if not known. + **/ + g_object_class_install_property + (object_class, PROP_TYPE_DESCRIPTION, + g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-generic.h b/libnm/nm-device-generic.h new file mode 100644 index 00000000..457a8840 --- /dev/null +++ b/libnm/nm-device-generic.h @@ -0,0 +1,59 @@ +/* -*- 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. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_GENERIC_H__ +#define __NM_DEVICE_GENERIC_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_GENERIC (nm_device_generic_get_type ()) +#define NM_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGeneric)) +#define NM_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) +#define NM_IS_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GENERIC)) +#define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) +#define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) + +#define NM_DEVICE_GENERIC_HW_ADDRESS "hw-address" +#define NM_DEVICE_GENERIC_TYPE_DESCRIPTION "type-description" + +struct _NMDeviceGeneric { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceGenericClass; + +GType nm_device_generic_get_type (void); + +const char *nm_device_generic_get_hw_address (NMDeviceGeneric *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_GENERIC_H__ */ diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c new file mode 100644 index 00000000..bce8a87a --- /dev/null +++ b/libnm/nm-device-infiniband.c @@ -0,0 +1,236 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-infiniband.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) + +#define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate)) + +typedef struct { + char *hw_address; + gboolean carrier; +} NMDeviceInfinibandPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + + LAST_PROP +}; + +/** + * nm_device_infiniband_get_hw_address: + * @device: a #NMDeviceInfiniband + * + * Gets the hardware (MAC) address of the #NMDeviceInfiniband + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_infiniband_get_hw_address (NMDeviceInfiniband *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), NULL); + + return NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_infiniband_get_carrier: + * @device: a #NMDeviceInfiniband + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_infiniband_get_carrier (NMDeviceInfiniband *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), FALSE); + + return NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->carrier; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingInfiniband *s_infiniband; + const char *hwaddr, *setting_hwaddr; + + if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an InfiniBand connection.")); + return FALSE; + } + + hwaddr = nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid (hwaddr, INFINIBAND_ALEN)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + + s_infiniband = nm_connection_get_setting_infiniband (connection); + setting_hwaddr = nm_setting_infiniband_get_mac_address (s_infiniband); + if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_INFINIBAND; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); +} + +/***********************************************************/ + +static void +nm_device_infiniband_init (NMDeviceInfiniband *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_INFINIBAND); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_INFINIBAND_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_INFINIBAND_CARRIER, &priv->carrier }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_infiniband_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_infiniband_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceInfiniband *device = NM_DEVICE_INFINIBAND (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_infiniband_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_infiniband_get_carrier (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ib_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ib_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (ib_class); + + g_type_class_add_private (ib_class, sizeof (NMDeviceInfinibandPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_INFINIBAND); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceInfiniband:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_INFINIBAND_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceInfiniband:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_INFINIBAND_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + +} diff --git a/libnm/nm-device-infiniband.h b/libnm/nm-device-infiniband.h new file mode 100644 index 00000000..c1f9be07 --- /dev/null +++ b/libnm/nm-device-infiniband.h @@ -0,0 +1,60 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_INFINIBAND_H__ +#define __NM_DEVICE_INFINIBAND_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_INFINIBAND (nm_device_infiniband_get_type ()) +#define NM_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfiniband)) +#define NM_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) +#define NM_IS_DEVICE_INFINIBAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_IS_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_INFINIBAND)) +#define NM_DEVICE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) + +#define NM_DEVICE_INFINIBAND_HW_ADDRESS "hw-address" +#define NM_DEVICE_INFINIBAND_CARRIER "carrier" + +struct _NMDeviceInfiniband { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceInfinibandClass; + +GType nm_device_infiniband_get_type (void); + +const char * nm_device_infiniband_get_hw_address (NMDeviceInfiniband *device); +gboolean nm_device_infiniband_get_carrier (NMDeviceInfiniband *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_INFINIBAND_H__ */ diff --git a/libnm/nm-device-modem.c b/libnm/nm-device-modem.c new file mode 100644 index 00000000..dcbb447a --- /dev/null +++ b/libnm/nm-device-modem.c @@ -0,0 +1,254 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-modem.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-enum-types.h" + +G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) + +#define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MODEM, NMDeviceModemPrivate)) + +typedef struct { + NMDeviceModemCapabilities caps; + NMDeviceModemCapabilities current_caps; +} NMDeviceModemPrivate; + +enum { + PROP_0, + PROP_MODEM_CAPS, + PROP_CURRENT_CAPS, + LAST_PROP +}; + +/** + * nm_device_modem_get_modem_capabilities: + * @self: a #NMDeviceModem + * + * Returns a bitfield of the generic access technology families the modem + * supports. Not all capabilities are available concurrently however; some + * may require a firmware reload or reinitialization. + * + * Returns: the generic access technology families the modem supports + **/ +NMDeviceModemCapabilities +nm_device_modem_get_modem_capabilities (NMDeviceModem *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE); + + return NM_DEVICE_MODEM_GET_PRIVATE (self)->caps; +} + +/** + * nm_device_modem_get_current_capabilities: + * @self: a #NMDeviceModem + * + * Returns a bitfield of the generic access technology families the modem + * supports without a firmware reload or reinitialization. This value + * represents the network types the modem can immediately connect to. + * + * Returns: the generic access technology families the modem supports without + * a firmware reload or other reinitialization + **/ +NMDeviceModemCapabilities +nm_device_modem_get_current_capabilities (NMDeviceModem *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE); + + return NM_DEVICE_MODEM_GET_PRIVATE (self)->current_caps; +} + +static const char * +get_type_description (NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) + return "gsm"; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return "cdma"; + else + return NULL; +} + +#define MODEM_CAPS_3GPP(caps) (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | \ + NM_DEVICE_MODEM_CAPABILITY_LTE)) + +#define MODEM_CAPS_3GPP2(caps) (caps & (NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingGsm *s_gsm; + NMSettingCdma *s_cdma; + NMDeviceModemCapabilities current_caps; + + if (!NM_DEVICE_CLASS (nm_device_modem_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if ( !nm_connection_is_type (connection, NM_SETTING_GSM_SETTING_NAME) + && !nm_connection_is_type (connection, NM_SETTING_CDMA_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a modem connection.")); + return FALSE; + } + + s_gsm = nm_connection_get_setting_gsm (connection); + s_cdma = nm_connection_get_setting_cdma (connection); + if (!s_cdma && !s_gsm) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not a valid modem connection.")); + return FALSE; + } + + current_caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + if (!(s_gsm && MODEM_CAPS_3GPP (current_caps)) && !(s_cdma && MODEM_CAPS_3GPP2 (current_caps))) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking capabilities required by the connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + NMDeviceModemCapabilities caps; + + caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + if (caps & (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE)) + return NM_TYPE_SETTING_GSM; + else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) + return NM_TYPE_SETTING_CDMA; + else + return G_TYPE_INVALID; +} + +/*******************************************************************/ + +static void +nm_device_modem_init (NMDeviceModem *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_MODEM); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_MODEM_MODEM_CAPABILITIES, &priv->caps }, + { NM_DEVICE_MODEM_CURRENT_CAPABILITIES, &priv->current_caps }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_modem_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_MODEM, + property_info); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (object); + + switch (prop_id) { + case PROP_MODEM_CAPS: + g_value_set_flags (value, nm_device_modem_get_modem_capabilities (self)); + break; + case PROP_CURRENT_CAPS: + g_value_set_flags (value, nm_device_modem_get_current_capabilities (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_modem_class_init (NMDeviceModemClass *modem_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (modem_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (modem_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (modem_class); + + g_type_class_add_private (modem_class, sizeof (NMDeviceModemPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_MODEM); + + /* virtual methods */ + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->get_type_description = get_type_description; + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceModem:modem-capabilities: + * + * The generic family of access technologies the modem supports. Not all + * capabilities are available at the same time however; some modems require + * a firmware reload or other reinitialization to switch between eg + * CDMA/EVDO and GSM/UMTS. + **/ + g_object_class_install_property + (object_class, PROP_MODEM_CAPS, + g_param_spec_flags (NM_DEVICE_MODEM_MODEM_CAPABILITIES, "", "", + NM_TYPE_DEVICE_MODEM_CAPABILITIES, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceModem:current-capabilities: + * + * The generic family of access technologies the modem currently supports + * without a firmware reload or reinitialization. + **/ + g_object_class_install_property + (object_class, PROP_CURRENT_CAPS, + g_param_spec_flags (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", + NM_TYPE_DEVICE_MODEM_CAPABILITIES, + NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-modem.h b/libnm/nm-device-modem.h new file mode 100644 index 00000000..38a4ddbb --- /dev/null +++ b/libnm/nm-device-modem.h @@ -0,0 +1,61 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_DEVICE_MODEM_H__ +#define __NM_DEVICE_MODEM_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_MODEM (nm_device_modem_get_type ()) +#define NM_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModem)) +#define NM_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) +#define NM_IS_DEVICE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MODEM)) +#define NM_IS_DEVICE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_MODEM)) +#define NM_DEVICE_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass)) + +#define NM_DEVICE_MODEM_MODEM_CAPABILITIES "modem-capabilities" +#define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities" + +struct _NMDeviceModem { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceModemClass; + +GType nm_device_modem_get_type (void); + +NMDeviceModemCapabilities nm_device_modem_get_modem_capabilities (NMDeviceModem *self); +NMDeviceModemCapabilities nm_device_modem_get_current_capabilities (NMDeviceModem *self); + +G_END_DECLS + +#endif /* __NM_DEVICE_MODEM_H__ */ diff --git a/libnm/nm-device-olpc-mesh.c b/libnm/nm-device-olpc-mesh.c new file mode 100644 index 00000000..108e5339 --- /dev/null +++ b/libnm/nm-device-olpc-mesh.c @@ -0,0 +1,261 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include + +#include "nm-device-olpc-mesh.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-device-wifi.h" + +G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) + +#define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) + +typedef struct { + char *hw_address; + NMDeviceWifi *companion; + guint32 active_channel; +} NMDeviceOlpcMeshPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_COMPANION, + PROP_ACTIVE_CHANNEL, + + LAST_PROP +}; + +/** + * nm_device_olpc_mesh_get_hw_address: + * @device: a #NMDeviceOlpcMesh + * + * Gets the hardware (MAC) address of the #NMDeviceOlpcMesh + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_olpc_mesh_get_hw_address (NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_OLPC_MESH (device), NULL); + + return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_olpc_mesh_get_companion: + * @device: a #NMDeviceOlpcMesh + * + * Gets the companion device of the #NMDeviceOlpcMesh. + * + * Returns: (transfer none): the companion of the device of %NULL + **/ +NMDeviceWifi * +nm_device_olpc_mesh_get_companion (NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_OLPC_MESH (device), NULL); + + return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->companion; +} + +/** + * nm_device_olpc_mesh_get_active_channel: + * @device: a #NMDeviceOlpcMesh + * + * Returns the active channel of the #NMDeviceOlpcMesh device. + * + * Returns: active channel of the device + **/ +guint32 +nm_device_olpc_mesh_get_active_channel (NMDeviceOlpcMesh *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_OLPC_MESH (device), 0); + + return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->active_channel; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_olpc_mesh_get_hw_address (NM_DEVICE_OLPC_MESH (device)); +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_OLPC_MESH_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not an OLPC Mesh connection.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_OLPC_MESH; +} + +/**************************************************************/ + +static void +nm_device_olpc_mesh_init (NMDeviceOlpcMesh *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_OLPC_MESH); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_OLPC_MESH_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_OLPC_MESH_COMPANION, &priv->companion, NULL, NM_TYPE_DEVICE_WIFI }, + { NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, &priv->active_channel }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, + property_info); +} + +static void +dispose (GObject *object) +{ + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); + + g_clear_object (&priv->companion); + + G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceOlpcMesh *device = NM_DEVICE_OLPC_MESH (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_olpc_mesh_get_hw_address (device)); + break; + case PROP_COMPANION: + g_value_set_object (value, nm_device_olpc_mesh_get_companion (device)); + break; + case PROP_ACTIVE_CHANNEL: + g_value_set_uint (value, nm_device_olpc_mesh_get_active_channel (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (olpc_mesh_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (olpc_mesh_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (olpc_mesh_class); + + g_type_class_add_private (olpc_mesh_class, sizeof (NMDeviceOlpcMeshPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH); + + /* virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceOlpcMesh:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_OLPC_MESH_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceOlpcMesh:companion: + * + * The companion device. + **/ + g_object_class_install_property + (object_class, PROP_COMPANION, + g_param_spec_object (NM_DEVICE_OLPC_MESH_COMPANION, "", "", + NM_TYPE_DEVICE_WIFI, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceOlpcMesh:active-channel: + * + * The device's active channel. + **/ + g_object_class_install_property + (object_class, PROP_ACTIVE_CHANNEL, + g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + +} diff --git a/libnm/nm-device-olpc-mesh.h b/libnm/nm-device-olpc-mesh.h new file mode 100644 index 00000000..b5899445 --- /dev/null +++ b/libnm/nm-device-olpc-mesh.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_OLPC_MESH_H__ +#define __NM_DEVICE_OLPC_MESH_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_OLPC_MESH (nm_device_olpc_mesh_get_type ()) +#define NM_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMesh)) +#define NM_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) +#define NM_IS_DEVICE_OLPC_MESH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OLPC_MESH)) +#define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) + +#define NM_DEVICE_OLPC_MESH_HW_ADDRESS "hw-address" +#define NM_DEVICE_OLPC_MESH_COMPANION "companion" +#define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel" + +struct _NMDeviceOlpcMesh { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceOlpcMeshClass; + +GType nm_device_olpc_mesh_get_type (void); + +const char *nm_device_olpc_mesh_get_hw_address (NMDeviceOlpcMesh *device); +NMDeviceWifi *nm_device_olpc_mesh_get_companion (NMDeviceOlpcMesh *device); +guint32 nm_device_olpc_mesh_get_active_channel (NMDeviceOlpcMesh *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_OLPC_MESH_H__ */ diff --git a/libnm/nm-device-private.h b/libnm/nm-device-private.h new file mode 100644 index 00000000..66fc6b6b --- /dev/null +++ b/libnm/nm-device-private.h @@ -0,0 +1,26 @@ +/* -*- 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. + * + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_PRIVATE_H__ +#define __NM_DEVICE_PRIVATE_H__ + +void _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype); + +#endif /* __NM_DEVICE_PRIVATE_H__ */ diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c new file mode 100644 index 00000000..cff1d718 --- /dev/null +++ b/libnm/nm-device-team.c @@ -0,0 +1,271 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-team.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" + +G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) + +#define NM_DEVICE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TEAM, NMDeviceTeamPrivate)) + +typedef struct { + char *hw_address; + gboolean carrier; + GPtrArray *slaves; +} NMDeviceTeamPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_SLAVES, + + LAST_PROP +}; + +/** + * nm_device_team_get_hw_address: + * @device: a #NMDeviceTeam + * + * Gets the hardware (MAC) address of the #NMDeviceTeam + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_team_get_hw_address (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), NULL); + + return NM_DEVICE_TEAM_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_team_get_carrier: + * @device: a #NMDeviceTeam + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_team_get_carrier (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), FALSE); + + return NM_DEVICE_TEAM_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_team_get_slaves: + * @device: a #NMDeviceTeam + * + * Gets the devices currently enslaved to @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing + * #NMDevices that are slaves of @device. This is the internal + * copy used by the device, and must not be modified. + **/ +const GPtrArray * +nm_device_team_get_slaves (NMDeviceTeam *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), FALSE); + + return NM_DEVICE_TEAM_GET_PRIVATE (device)->slaves; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_team_get_hw_address (NM_DEVICE_TEAM (device)); +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not a team connection.")); + return FALSE; + } + + /* FIXME: check slaves? */ + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_TEAM; +} + +/***********************************************************/ + +static void +nm_device_team_init (NMDeviceTeam *device) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_TEAM); + + priv->slaves = g_ptr_array_new (); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_TEAM_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_TEAM_CARRIER, &priv->carrier }, + { NM_DEVICE_TEAM_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_team_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_TEAM, + property_info); +} + +static void +dispose (GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + g_clear_pointer (&priv->slaves, g_ptr_array_unref); + + G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); + + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_device_team_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceTeam *device = NM_DEVICE_TEAM (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_team_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_team_get_carrier (device)); + break; + case PROP_SLAVES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_team_get_slaves (device))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_team_class_init (NMDeviceTeamClass *team_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (team_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (team_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (team_class); + + g_type_class_add_private (team_class, sizeof (NMDeviceTeamPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_TEAM); + + /* virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceTeam:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_TEAM_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTeam:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_TEAM_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceTeam:slaves: + * + * The devices enslaved to the team device. + * + * Element-type: NMDevice + **/ + g_object_class_install_property + (object_class, PROP_SLAVES, + g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-team.h b/libnm/nm-device-team.h new file mode 100644 index 00000000..a7185795 --- /dev/null +++ b/libnm/nm-device-team.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2013 Jiri Pirko + */ + +#ifndef __NM_DEVICE_TEAM_H__ +#define __NM_DEVICE_TEAM_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) +#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) +#define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TEAM)) +#define NM_IS_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_TEAM)) +#define NM_DEVICE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) + +#define NM_DEVICE_TEAM_HW_ADDRESS "hw-address" +#define NM_DEVICE_TEAM_CARRIER "carrier" +#define NM_DEVICE_TEAM_SLAVES "slaves" + +struct _NMDeviceTeam { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceTeamClass; + +GType nm_device_team_get_type (void); + +const char *nm_device_team_get_hw_address (NMDeviceTeam *device); +gboolean nm_device_team_get_carrier (NMDeviceTeam *device); +const GPtrArray *nm_device_team_get_slaves (NMDeviceTeam *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_TEAM_H__ */ diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c new file mode 100644 index 00000000..fb6e3bd7 --- /dev/null +++ b/libnm/nm-device-vlan.c @@ -0,0 +1,305 @@ +/* -*- 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. + * + * Copyright 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include +#include + +#include "nm-device-vlan.h" +#include "nm-device-private.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate)) + +typedef struct { + char *hw_address; + gboolean carrier; + NMDevice *parent; + guint vlan_id; +} NMDeviceVlanPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_CARRIER, + PROP_PARENT, + PROP_VLAN_ID, + + LAST_PROP +}; + +/** + * nm_device_vlan_get_hw_address: + * @device: a #NMDeviceVlan + * + * Gets the hardware (MAC) address of the #NMDeviceVlan + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_vlan_get_hw_address (NMDeviceVlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), NULL); + + return NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_vlan_get_carrier: + * @device: a #NMDeviceVlan + * + * Whether the device has carrier. + * + * Returns: %TRUE if the device has carrier + **/ +gboolean +nm_device_vlan_get_carrier (NMDeviceVlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE); + + return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier; +} + +/** + * nm_device_vlan_get_parent: + * @device: a #NMDeviceVlan + * + * Returns: (transfer none): the device's parent device + **/ +NMDevice * +nm_device_vlan_get_parent (NMDeviceVlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE); + + return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent; +} + +/** + * nm_device_vlan_get_vlan_id: + * @device: a #NMDeviceVlan + * + * Returns: the device's VLAN ID + **/ +guint +nm_device_vlan_get_vlan_id (NMDeviceVlan *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE); + + return NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVlan *s_vlan; + NMSettingWired *s_wired; + const char *setting_hwaddr; + + if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VLAN connection.")); + return FALSE; + } + + s_vlan = nm_connection_get_setting_vlan (connection); + if (nm_setting_vlan_get_id (s_vlan) != nm_device_vlan_get_vlan_id (NM_DEVICE_VLAN (device))) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VLAN identifiers of the device and the connection didn't match.")); + return FALSE; + } + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) + setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); + else + setting_hwaddr = NULL; + if (setting_hwaddr) { + if (!nm_utils_hwaddr_matches (setting_hwaddr, -1, + NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The hardware address of the device and the connection didn't match.")); + } + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_VLAN; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device)); +} + +/***********************************************************/ + +static void +nm_device_vlan_init (NMDeviceVlan *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_VLAN); +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_VLAN_CARRIER, &priv->carrier }, + { NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE }, + { NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_vlan_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_VLAN, + property_info); +} + +static void +finalize (GObject *object) +{ + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_clear_object (&priv->parent); + + G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceVlan *device = NM_DEVICE_VLAN (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_vlan_get_hw_address (device)); + break; + case PROP_CARRIER: + g_value_set_boolean (value, nm_device_vlan_get_carrier (device)); + break; + case PROP_PARENT: + g_value_set_object (value, nm_device_vlan_get_parent (device)); + break; + case PROP_VLAN_ID: + g_value_set_uint (value, nm_device_vlan_get_vlan_id (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (vlan_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vlan_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (vlan_class); + + g_type_class_add_private (vlan_class, sizeof (NMDeviceVlanPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_VLAN); + + /* virtual methods */ + object_class->finalize = finalize; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + /* properties */ + + /** + * NMDeviceVlan:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVlan:carrier: + * + * Whether the device has carrier. + **/ + g_object_class_install_property + (object_class, PROP_CARRIER, + g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVlan:parent: + * + * The devices's parent device. + **/ + g_object_class_install_property + (object_class, PROP_PARENT, + g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceVlan:vlan-id: + * + * The device's VLAN ID. + **/ + g_object_class_install_property + (object_class, PROP_VLAN_ID, + g_param_spec_uint (NM_DEVICE_VLAN_VLAN_ID, "", "", + 0, 4095, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-device-vlan.h b/libnm/nm-device-vlan.h new file mode 100644 index 00000000..6ab24202 --- /dev/null +++ b/libnm/nm-device-vlan.h @@ -0,0 +1,64 @@ +/* -*- 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. + * + * Copyright 2012 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_VLAN_H__ +#define __NM_DEVICE_VLAN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VLAN (nm_device_vlan_get_type ()) +#define NM_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlan)) +#define NM_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) +#define NM_IS_DEVICE_VLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VLAN)) +#define NM_IS_DEVICE_VLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VLAN)) +#define NM_DEVICE_VLAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VLAN, NMDeviceVlanClass)) + +#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address" +#define NM_DEVICE_VLAN_CARRIER "carrier" +#define NM_DEVICE_VLAN_PARENT "parent" +#define NM_DEVICE_VLAN_VLAN_ID "vlan-id" + +struct _NMDeviceVlan { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDeviceVlanClass; + +GType nm_device_vlan_get_type (void); + +const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device); +gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device); +NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device); +guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VLAN_H__ */ diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c new file mode 100644 index 00000000..4a19f2e5 --- /dev/null +++ b/libnm/nm-device-wifi.c @@ -0,0 +1,837 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include +#include + +#include "nm-device-wifi.h" +#include "nm-access-point.h" +#include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" +#include "nm-core-internal.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-device-wifi.h" + +G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIFI, NMDeviceWifiPrivate)) + +void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); +static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data); + +typedef struct { + NMDeviceWifi *device; + GSimpleAsyncResult *simple; +} RequestScanInfo; + +typedef struct { + NMDBusDeviceWifi *proxy; + + char *hw_address; + char *perm_hw_address; + NM80211Mode mode; + guint32 rate; + NMAccessPoint *active_ap; + NMDeviceWifiCapabilities wireless_caps; + GPtrArray *aps; + + RequestScanInfo *scan_info; +} NMDeviceWifiPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_PERM_HW_ADDRESS, + PROP_MODE, + PROP_BITRATE, + PROP_ACTIVE_ACCESS_POINT, + PROP_WIRELESS_CAPABILITIES, + PROP_ACCESS_POINTS, + + LAST_PROP +}; + +enum { + ACCESS_POINT_ADDED, + ACCESS_POINT_REMOVED, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * nm_device_wifi_get_hw_address: + * @device: a #NMDeviceWifi + * + * Gets the actual hardware (MAC) address of the #NMDeviceWifi + * + * Returns: the actual hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_wifi_get_hw_address (NMDeviceWifi *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->hw_address; +} + +/** + * nm_device_wifi_get_permanent_hw_address: + * @device: a #NMDeviceWifi + * + * Gets the permanent hardware (MAC) address of the #NMDeviceWifi + * + * Returns: the permanent hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->perm_hw_address; +} + +/** + * nm_device_wifi_get_mode: + * @device: a #NMDeviceWifi + * + * Gets the #NMDeviceWifi mode. + * + * Returns: the mode + **/ +NM80211Mode +nm_device_wifi_get_mode (NMDeviceWifi *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0); + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->mode; +} + +/** + * nm_device_wifi_get_bitrate: + * @device: a #NMDeviceWifi + * + * Gets the bit rate of the #NMDeviceWifi in kbit/s. + * + * Returns: the bit rate (kbit/s) + **/ +guint32 +nm_device_wifi_get_bitrate (NMDeviceWifi *device) +{ + NMDeviceState state; + + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0); + + state = nm_device_get_state (NM_DEVICE (device)); + switch (state) { + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_IP_CHECK: + case NM_DEVICE_STATE_SECONDARIES: + case NM_DEVICE_STATE_ACTIVATED: + case NM_DEVICE_STATE_DEACTIVATING: + break; + default: + return 0; + } + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->rate; +} + +/** + * nm_device_wifi_get_capabilities: + * @device: a #NMDeviceWifi + * + * Gets the Wi-Fi capabilities of the #NMDeviceWifi. + * + * Returns: the capabilities + **/ +NMDeviceWifiCapabilities +nm_device_wifi_get_capabilities (NMDeviceWifi *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0); + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->wireless_caps; +} + +/** + * nm_device_wifi_get_active_access_point: + * @device: a #NMDeviceWifi + * + * Gets the active #NMAccessPoint. + * + * Returns: (transfer none): the access point or %NULL if none is active + **/ +NMAccessPoint * +nm_device_wifi_get_active_access_point (NMDeviceWifi *device) +{ + NMDeviceState state; + + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + + state = nm_device_get_state (NM_DEVICE (device)); + switch (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: + case NM_DEVICE_STATE_ACTIVATED: + case NM_DEVICE_STATE_DEACTIVATING: + break; + default: + return NULL; + break; + } + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->active_ap; +} + +/** + * nm_device_wifi_get_access_points: + * @device: a #NMDeviceWifi + * + * Gets all the scanned access points of the #NMDeviceWifi. + * + * Returns: (element-type NMAccessPoint): a #GPtrArray containing all the + * scanned #NMAccessPoints. + * The returned array is owned by the client and should not be modified. + **/ +const GPtrArray * +nm_device_wifi_get_access_points (NMDeviceWifi *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + + return NM_DEVICE_WIFI_GET_PRIVATE (device)->aps; +} + +/** + * nm_device_wifi_get_access_point_by_path: + * @device: a #NMDeviceWifi + * @path: the object path of the access point + * + * Gets a #NMAccessPoint by path. + * + * Returns: (transfer none): the access point or %NULL if none is found. + **/ +NMAccessPoint * +nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device, + const char *path) +{ + const GPtrArray *aps; + int i; + NMAccessPoint *ap = NULL; + + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); + g_return_val_if_fail (path != NULL, NULL); + + aps = nm_device_wifi_get_access_points (device); + if (!aps) + return NULL; + + for (i = 0; i < aps->len; i++) { + NMAccessPoint *candidate = g_ptr_array_index (aps, i); + if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), path)) { + ap = candidate; + break; + } + } + + return ap; +} + +/** + * nm_device_wifi_request_scan: + * @device: a #NMDeviceWifi + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Request NM to scan for access points on @device. Note that the function + * returns immediately after requesting the scan, and it may take some time + * after that for the scan to complete. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + **/ +gboolean +nm_device_wifi_request_scan (NMDeviceWifi *device, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), FALSE); + + ret = nmdbus_device_wifi_call_request_scan_sync (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy, + g_variant_new_array (G_VARIANT_TYPE ("{sv}"), + NULL, 0), + cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +request_scan_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + RequestScanInfo *info = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device); + GError *error = NULL; + + priv->scan_info = NULL; + + if (nmdbus_device_wifi_call_request_scan_finish (NMDBUS_DEVICE_WIFI (source), + result, &error)) + g_simple_async_result_set_op_res_gboolean (info->simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (info->simple, error); + } + + g_simple_async_result_complete (info->simple); + g_object_unref (info->simple); + g_slice_free (RequestScanInfo, info); +} + +/** + * nm_device_wifi_request_scan_async: + * @device: a #NMDeviceWifi + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the scan has been requested + * @user_data: caller-specific data passed to @callback + * + * Request NM to scan for access points on @device. Note that @callback will be + * called immediately after requesting the scan, and it may take some time after + * that for the scan to complete. + **/ +void +nm_device_wifi_request_scan_async (NMDeviceWifi *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + RequestScanInfo *info; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_DEVICE_WIFI (device)); + + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_wifi_request_scan_async); + + /* If a scan is in progress, just return */ + if (priv->scan_info) { + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + info = g_slice_new0 (RequestScanInfo); + info->device = device; + info->simple = simple; + + priv->scan_info = info; + nmdbus_device_wifi_call_request_scan (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy, + g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0), + cancellable, request_scan_cb, info); +} + +/** + * nm_device_wifi_request_scan_finish: + * @device: a #NMDeviceWifi + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_wifi_request_scan_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + **/ +gboolean +nm_device_wifi_request_scan_finish (NMDeviceWifi *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_wifi_request_scan_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +static void +clean_up_aps (NMDeviceWifi *self, gboolean in_dispose) +{ + NMDeviceWifiPrivate *priv; + GPtrArray *aps; + int i; + + g_return_if_fail (NM_IS_DEVICE_WIFI (self)); + + priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + if (priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + } + + aps = priv->aps; + + if (in_dispose) + priv->aps = NULL; + else { + priv->aps = g_ptr_array_new (); + + for (i = 0; i < aps->len; i++) { + NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i)); + + g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap); + } + } + + g_ptr_array_unref (aps); +} + +/** + * _nm_device_wifi_set_wireless_enabled: + * @device: a #NMDeviceWifi + * @enabled: %TRUE to enable the device + * + * Enables or disables the wireless device. + **/ +void +_nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, + gboolean enabled) +{ + g_return_if_fail (NM_IS_DEVICE_WIFI (device)); + + if (!enabled) + clean_up_aps (device, FALSE); +} + +#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \ + NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \ + NM_WIFI_DEVICE_CAP_WPA | \ + NM_WIFI_DEVICE_CAP_RSN) + +#define RSN_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN) + +static gboolean +has_proto (NMSettingWirelessSecurity *s_wsec, const char *proto) +{ + int i; + + for (i = 0; i < nm_setting_wireless_security_get_num_protos (s_wsec); i++) { + if (g_strcmp0 (proto, nm_setting_wireless_security_get_proto (s_wsec, i)) == 0) + return TRUE; + } + return FALSE; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const char *hwaddr, *setting_hwaddr; + NMDeviceWifiCapabilities wifi_caps; + const char *key_mgmt; + + if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a Wi-Fi connection.")); + return FALSE; + } + + /* Check MAC address */ + hwaddr = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + s_wifi = nm_connection_get_setting_wireless (connection); + setting_hwaddr = nm_setting_wireless_get_mac_address (s_wifi); + if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + + /* Check device capabilities; we assume all devices can do WEP at least */ + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (s_wsec) { + /* Connection has security, verify it against the device's capabilities */ + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + if ( !g_strcmp0 (key_mgmt, "wpa-none") + || !g_strcmp0 (key_mgmt, "wpa-psk") + || !g_strcmp0 (key_mgmt, "wpa-eap")) { + + wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device)); + + /* Is device only WEP capable? */ + if (!(wifi_caps & WPA_CAPS)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking WPA capabilities required by the connection.")); + return FALSE; + } + + /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */ + if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The device is lacking WPA2/RSN capabilities required by the connection.")); + return FALSE; + } + } + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIRELESS; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)); +} + +/**************************************************************/ + +static void +nm_device_wifi_init (NMDeviceWifi *device) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_WIFI); + + g_signal_connect (device, + "notify::" NM_DEVICE_STATE, + G_CALLBACK (state_changed_cb), + NULL); + + priv->aps = g_ptr_array_new (); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_wifi_get_hw_address (self)); + break; + case PROP_PERM_HW_ADDRESS: + g_value_set_string (value, nm_device_wifi_get_permanent_hw_address (self)); + break; + case PROP_MODE: + g_value_set_enum (value, nm_device_wifi_get_mode (self)); + break; + case PROP_BITRATE: + g_value_set_uint (value, nm_device_wifi_get_bitrate (self)); + break; + case PROP_ACTIVE_ACCESS_POINT: + g_value_set_object (value, nm_device_wifi_get_active_access_point (self)); + break; + case PROP_WIRELESS_CAPABILITIES: + g_value_set_flags (value, nm_device_wifi_get_capabilities (self)); + break; + case PROP_ACCESS_POINTS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_wifi_get_access_points (self))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + switch (nm_device_get_state (device)) { + case NM_DEVICE_STATE_UNKNOWN: + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_FAILED: + /* Just clear active AP; don't clear the AP list unless wireless is disabled completely */ + if (priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + } + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT); + priv->rate = 0; + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_BITRATE); + break; + default: + break; + } +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_WIFI_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, &priv->perm_hw_address }, + { NM_DEVICE_WIFI_MODE, &priv->mode }, + { NM_DEVICE_WIFI_BITRATE, &priv->rate }, + { NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, &priv->active_ap, NULL, NM_TYPE_ACCESS_POINT }, + { NM_DEVICE_WIFI_CAPABILITIES, &priv->wireless_caps }, + { NM_DEVICE_WIFI_ACCESS_POINTS, &priv->aps, NULL, NM_TYPE_ACCESS_POINT, "access-point" }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_wifi_parent_class)->init_dbus (object); + + priv->proxy = NMDBUS_DEVICE_WIFI (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE_WIRELESS)); + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + property_info); +} + +static void +access_point_removed (NMDeviceWifi *self, NMAccessPoint *ap) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + if (ap == priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT); + + priv->rate = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE); + } +} + +static void +dispose (GObject *object) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); + + if (priv->aps) + clean_up_aps (NM_DEVICE_WIFI (object), TRUE); + + G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); + + g_free (priv->hw_address); + g_free (priv->perm_hw_address); + + G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); +} + +static void +nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wifi_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wifi_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class); + + g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIRELESS); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE_WIRELESS, + NMDBUS_TYPE_DEVICE_WIFI_PROXY); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + wifi_class->access_point_removed = access_point_removed; + + /* properties */ + + /** + * NMDeviceWifi:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:perm-hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_PERM_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:mode: + * + * The mode of the device. + **/ + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_enum (NM_DEVICE_WIFI_MODE, "", "", + NM_TYPE_802_11_MODE, + NM_802_11_MODE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:bitrate: + * + * The bit rate of the device in kbit/s. + **/ + g_object_class_install_property + (object_class, PROP_BITRATE, + g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:active-access-point: + * + * The active #NMAccessPoint of the device. + **/ + g_object_class_install_property + (object_class, PROP_ACTIVE_ACCESS_POINT, + g_param_spec_object (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", + NM_TYPE_ACCESS_POINT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:wireless-capabilities: + * + * The wireless capabilities of the device. + **/ + g_object_class_install_property + (object_class, PROP_WIRELESS_CAPABILITIES, + g_param_spec_flags (NM_DEVICE_WIFI_CAPABILITIES, "", "", + NM_TYPE_DEVICE_WIFI_CAPABILITIES, + NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWifi:access-points: + * + * List of all Wi-Fi access points the device can see. + * + * Element-type: NMAccessPoint + **/ + g_object_class_install_property + (object_class, PROP_ACCESS_POINTS, + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + + /** + * NMDeviceWifi::access-point-added: + * @device: the Wi-Fi device that received the signal + * @ap: the new access point + * + * Notifies that a #NMAccessPoint is added to the Wi-Fi device. + **/ + signals[ACCESS_POINT_ADDED] = + g_signal_new ("access-point-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + + /** + * NMDeviceWifi::access-point-removed: + * @device: the Wi-Fi device that received the signal + * @ap: the removed access point + * + * Notifies that a #NMAccessPoint is removed from the Wi-Fi device. + **/ + signals[ACCESS_POINT_REMOVED] = + g_signal_new ("access-point-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); +} diff --git a/libnm/nm-device-wifi.h b/libnm/nm-device-wifi.h new file mode 100644 index 00000000..24339fd3 --- /dev/null +++ b/libnm/nm-device-wifi.h @@ -0,0 +1,91 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_WIFI_H__ +#define __NM_DEVICE_WIFI_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type ()) +#define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) +#define NM_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) +#define NM_IS_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIFI)) +#define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) +#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) + +#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" +#define NM_DEVICE_WIFI_MODE "mode" +#define NM_DEVICE_WIFI_BITRATE "bitrate" +#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point" +#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" +#define NM_DEVICE_WIFI_ACCESS_POINTS "access-points" + +struct _NMDeviceWifi { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*access_point_added) (NMDeviceWifi *device, NMAccessPoint *ap); + void (*access_point_removed) (NMDeviceWifi *device, NMAccessPoint *ap); + + /*< private >*/ + gpointer padding[4]; +} NMDeviceWifiClass; + +GType nm_device_wifi_get_type (void); + +const char * nm_device_wifi_get_hw_address (NMDeviceWifi *device); +const char * nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device); +NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *device); +guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *device); +NMDeviceWifiCapabilities nm_device_wifi_get_capabilities (NMDeviceWifi *device); +NMAccessPoint * nm_device_wifi_get_active_access_point (NMDeviceWifi *device); + +NMAccessPoint * nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device, + const char *path); + +const GPtrArray * nm_device_wifi_get_access_points (NMDeviceWifi *device); + +gboolean nm_device_wifi_request_scan (NMDeviceWifi *device, + GCancellable *cancellable, + GError **error); + +void nm_device_wifi_request_scan_async (NMDeviceWifi *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_device_wifi_request_scan_finish (NMDeviceWifi *device, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIFI_H__ */ diff --git a/libnm/nm-device-wimax.c b/libnm/nm-device-wimax.c new file mode 100644 index 00000000..f199b669 --- /dev/null +++ b/libnm/nm-device-wimax.c @@ -0,0 +1,678 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2009 Novell, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-device-wimax.h" +#include "nm-wimax-nsp.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" +#include "nm-core-internal.h" +#include "nm-device-private.h" + +G_DEFINE_TYPE (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxPrivate)) + +void _nm_device_wimax_set_wireless_enabled (NMDeviceWimax *wimax, gboolean enabled); +static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data); + +typedef struct { + char *hw_address; + NMWimaxNsp *active_nsp; + GPtrArray *nsps; + + guint center_freq; + gint rssi; + gint cinr; + gint tx_power; + char *bsid; +} NMDeviceWimaxPrivate; + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_ACTIVE_NSP, + PROP_CENTER_FREQ, + PROP_RSSI, + PROP_CINR, + PROP_TX_POWER, + PROP_BSID, + PROP_NSPS, + + LAST_PROP +}; + +enum { + NSP_ADDED, + NSP_REMOVED, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * nm_device_wimax_get_hw_address: + * @wimax: a #NMDeviceWimax + * + * Gets the hardware (MAC) address of the #NMDeviceWimax + * + * Returns: the hardware address. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + + return NM_DEVICE_WIMAX_GET_PRIVATE (wimax)->hw_address; +} + +/** + * nm_device_wimax_get_active_nsp: + * @wimax: a #NMDeviceWimax + * + * Gets the active #NMWimaxNsp. + * + * Returns: (transfer full): the access point or %NULL if none is active + **/ +NMWimaxNsp * +nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) +{ + NMDeviceState state; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + + state = nm_device_get_state (NM_DEVICE (wimax)); + switch (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: + case NM_DEVICE_STATE_ACTIVATED: + case NM_DEVICE_STATE_DEACTIVATING: + break; + default: + return NULL; + break; + } + + return NM_DEVICE_WIMAX_GET_PRIVATE (wimax)->active_nsp; +} + +/** + * nm_device_wimax_get_nsps: + * @wimax: a #NMDeviceWimax + * + * Gets all the scanned NSPs of the #NMDeviceWimax. + * + * Returns: (element-type NMWimaxNsp): a #GPtrArray containing + * all the scanned #NMWimaxNsps. + * The returned array is owned by the client and should not be modified. + **/ +const GPtrArray * +nm_device_wimax_get_nsps (NMDeviceWimax *wimax) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + + return NM_DEVICE_WIMAX_GET_PRIVATE (wimax)->nsps; +} + +/** + * nm_device_wimax_get_nsp_by_path: + * @wimax: a #NMDeviceWimax + * @path: the object path of the NSP + * + * Gets a #NMWimaxNsp by path. + * + * Returns: (transfer none): the access point or %NULL if none is found. + **/ +NMWimaxNsp * +nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, + const char *path) +{ + const GPtrArray *nsps; + int i; + NMWimaxNsp *nsp = NULL; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + g_return_val_if_fail (path != NULL, NULL); + + nsps = nm_device_wimax_get_nsps (wimax); + if (!nsps) + return NULL; + + for (i = 0; i < nsps->len; i++) { + NMWimaxNsp *candidate = g_ptr_array_index (nsps, i); + if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), path)) { + nsp = candidate; + break; + } + } + + return nsp; +} + +static void +clean_up_nsps (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv; + + g_return_if_fail (NM_IS_DEVICE_WIMAX (self)); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->active_nsp) { + g_object_unref (priv->active_nsp); + priv->active_nsp = NULL; + } + + g_clear_pointer (&priv->nsps, g_ptr_array_unref); +} + +/** + * nm_device_wimax_get_center_frequency: + * @self: a #NMDeviceWimax + * + * Gets the center frequency (in KHz) of the radio channel the device is using + * to communicate with the network when connected. Has no meaning when the + * device is not connected. + * + * Returns: the center frequency in KHz, or 0 + **/ +guint +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; +} + +/** + * nm_device_wimax_get_rssi: + * @self: a #NMDeviceWimax + * + * Gets the RSSI of the current radio link in dBm. This value indicates how + * strong the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + * + * Returns: the RSSI in dBm, or 0 + **/ +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; +} + +/** + * nm_device_wimax_get_cinr: + * @self: a #NMDeviceWimax + * + * Gets the CINR (Carrier to Interference + Noise Ratio) of the current radio + * link in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + * + * Returns: the CINR in dB, or 0 + **/ +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; +} + +/** + * nm_device_wimax_get_tx_power: + * @self: a #NMDeviceWimax + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + * + * Returns: the TX power in dBm, or 0 + **/ +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; +} + +/** + * nm_device_wimax_get_bsid: + * @self: a #NMDeviceWimax + * + * Gets the ID of the serving Base Station when the device is connected. + * + * Returns: the ID of the serving Base Station, or %NULL + **/ +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 +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingWimax *s_wimax; + const char *hwaddr, *setting_hwaddr; + + if (!NM_DEVICE_CLASS (nm_device_wimax_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_WIMAX_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a WiMAX connection.")); + return FALSE; + } + + /* Check MAC address */ + hwaddr = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); + if (hwaddr) { + if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, + _("Invalid device MAC address.")); + return FALSE; + } + s_wimax = nm_connection_get_setting_wimax (connection); + setting_hwaddr = nm_setting_wimax_get_mac_address (s_wimax); + if (setting_hwaddr && !nm_utils_hwaddr_matches (setting_hwaddr, -1, hwaddr, -1)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The MACs of the device and the connection didn't match.")); + return FALSE; + } + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_WIMAX; +} + +static const char * +get_hw_address (NMDevice *device) +{ + return nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); +} + +/**************************************************************/ + +static void +nm_device_wimax_init (NMDeviceWimax *device) +{ + _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_WIMAX); + + g_signal_connect (device, + "notify::" NM_DEVICE_STATE, + G_CALLBACK (state_changed_cb), + NULL); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (object); + + switch (prop_id) { + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_wimax_get_hw_address (self)); + break; + case PROP_ACTIVE_NSP: + g_value_set_object (value, nm_device_wimax_get_active_nsp (self)); + break; + case PROP_CENTER_FREQ: + g_value_set_uint (value, nm_device_wimax_get_center_frequency (self)); + break; + case PROP_RSSI: + g_value_set_int (value, nm_device_wimax_get_rssi (self)); + break; + case PROP_CINR: + g_value_set_int (value, nm_device_wimax_get_cinr (self)); + break; + case PROP_TX_POWER: + g_value_set_int (value, nm_device_wimax_get_tx_power (self)); + break; + case PROP_BSID: + g_value_set_string (value, nm_device_wimax_get_bsid (self)); + break; + case PROP_NSPS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_wimax_get_nsps (self))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +clear_link_status (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->center_freq) { + priv->center_freq = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_CENTER_FREQUENCY); + } + + if (priv->rssi) { + priv->rssi = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_RSSI); + } + + if (priv->cinr) { + priv->cinr = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_CINR); + } + + if (priv->tx_power) { + priv->tx_power = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_TX_POWER); + } + + if (priv->bsid) { + g_free (priv->bsid); + priv->bsid = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_BSID); + } +} + +static void +state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + NMDeviceState state; + + state = nm_device_get_state (device); + switch (state) { + case NM_DEVICE_STATE_UNKNOWN: + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_FAILED: + if (priv->active_nsp) { + g_object_unref (priv->active_nsp); + priv->active_nsp = NULL; + } + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIMAX_ACTIVE_NSP); + clear_link_status (self); + break; + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + clear_link_status (self); + break; + default: + break; + } +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_WIMAX_HW_ADDRESS, &priv->hw_address }, + { NM_DEVICE_WIMAX_ACTIVE_NSP, &priv->active_nsp, NULL, NM_TYPE_WIMAX_NSP }, + { NM_DEVICE_WIMAX_CENTER_FREQUENCY, &priv->center_freq }, + { NM_DEVICE_WIMAX_RSSI, &priv->rssi }, + { NM_DEVICE_WIMAX_CINR, &priv->cinr }, + { NM_DEVICE_WIMAX_TX_POWER, &priv->tx_power }, + { NM_DEVICE_WIMAX_BSID, &priv->bsid }, + { NM_DEVICE_WIMAX_NSPS, &priv->nsps, NULL, NM_TYPE_WIMAX_NSP, "nsp" }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_wimax_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_WIMAX, + property_info); +} + +static void +nsp_removed (NMDeviceWimax *self, NMWimaxNsp *nsp) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (nsp == priv->active_nsp) { + g_object_unref (priv->active_nsp); + priv->active_nsp = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); + } +} + +static void +dispose (GObject *object) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); + + if (priv->hw_address) { + g_free (priv->hw_address); + priv->hw_address = NULL; + } + + if (priv->bsid) { + g_free (priv->bsid); + priv->bsid = NULL; + } + + if (priv->nsps) + clean_up_nsps (NM_DEVICE_WIMAX (object)); + + G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); +} + +static void +nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wimax_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wimax_class); + NMDeviceClass *device_class = NM_DEVICE_CLASS (wimax_class); + + g_type_class_add_private (wimax_class, sizeof (NMDeviceWimaxPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_WIMAX); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->dispose = dispose; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + device_class->get_hw_address = get_hw_address; + + wimax_class->nsp_removed = nsp_removed; + + /* properties */ + + /** + * NMDeviceWimax:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIMAX_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:active-nsp: + * + * The active #NMWimaxNsp of the device. + **/ + g_object_class_install_property + (object_class, PROP_ACTIVE_NSP, + g_param_spec_object (NM_DEVICE_WIMAX_ACTIVE_NSP, "", "", + NM_TYPE_WIMAX_NSP, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:center-frequency: + * + * The center frequency (in KHz) of the radio channel the device is using to + * communicate with the network when connected. Has no meaning when the + * device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_CENTER_FREQ, + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:rssi: + * + * RSSI of the current radio link in dBm. This value indicates how strong + * the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_RSSI, + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, "", "", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:cinr: + * + * CINR (Carrier to Interference + Noise Ratio) of the current radio link + * in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_CINR, + g_param_spec_int (NM_DEVICE_WIMAX_CINR, "", "", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:tx-power: + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_TX_POWER, + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, "", "", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:bsid: + * + * The ID of the serving base station as received from the network. Has + * no meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_BSID, + g_param_spec_string (NM_DEVICE_WIMAX_BSID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDeviceWimax:nsps: + * + * List of all WiMAX Network Service Providers the device can see. + * + * Element-type: NMWimaxNsp + **/ + g_object_class_install_property + (object_class, PROP_NSPS, + g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + + /** + * NMDeviceWimax::nsp-added: + * @self: the wimax device that received the signal + * @nsp: the new NSP + * + * Notifies that a #NMWimaxNsp is added to the wimax device. + **/ + 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); + + /** + * NMDeviceWimax::nsp-removed: + * @self: the wimax device that received the signal + * @nsp: the removed NSP + * + * Notifies that a #NMWimaxNsp is removed from the wimax device. + **/ + 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); +} diff --git a/libnm/nm-device-wimax.h b/libnm/nm-device-wimax.h new file mode 100644 index 00000000..60910984 --- /dev/null +++ b/libnm/nm-device-wimax.h @@ -0,0 +1,81 @@ +/* -*- 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. + * + * Copyright 2011 - 2012 Red Hat, Inc. + * Copyright 2009 Novell, Inc. + */ + +#ifndef __NM_DEVICE_WIMAX_H__ +#define __NM_DEVICE_WIMAX_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +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" +#define NM_DEVICE_WIMAX_NSPS "nsps" + +struct _NMDeviceWimax { + NMDevice parent; +}; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*nsp_added) (NMDeviceWimax *self, NMWimaxNsp *nsp); + void (*nsp_removed) (NMDeviceWimax *self, NMWimaxNsp *nsp); + + /*< private >*/ + gpointer padding[4]; +} NMDeviceWimaxClass; + +GType nm_device_wimax_get_type (void); + +const char *nm_device_wimax_get_hw_address (NMDeviceWimax *wimax); +NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax); +NMWimaxNsp *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, + const char *path); + +const GPtrArray *nm_device_wimax_get_nsps (NMDeviceWimax *wimax); + +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/libnm/nm-device.c b/libnm/nm-device.c new file mode 100644 index 00000000..e80ac707 --- /dev/null +++ b/libnm/nm-device.c @@ -0,0 +1,2232 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include +#include + +#include "nm-dbus-interface.h" +#include "nm-active-connection.h" +#include "nm-device-ethernet.h" +#include "nm-device-adsl.h" +#include "nm-device-wifi.h" +#include "nm-device-modem.h" +#include "nm-device-bt.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-wimax.h" +#include "nm-device-infiniband.h" +#include "nm-device-bond.h" +#include "nm-device-team.h" +#include "nm-device-bridge.h" +#include "nm-device-vlan.h" +#include "nm-device-generic.h" +#include "nm-device.h" +#include "nm-device-private.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" +#include "nm-remote-connection.h" +#include "nm-core-internal.h" +#include "nm-glib-compat.h" +#include "nm-utils.h" +#include "nm-dbus-helpers.h" +#include "nm-setting-connection.h" + +#include "nmdbus-device.h" + +static GType _nm_device_decide_type (GVariant *value); +gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); + +G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, + _nm_object_register_type_func (g_define_type_id, + _nm_device_decide_type, + NM_DBUS_INTERFACE_DEVICE, + "DeviceType"); + ) + +#define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) + +typedef struct { + NMDBusDevice *proxy; + + char *iface; + char *ip_iface; + NMDeviceType device_type; + char *udi; + char *driver; + char *driver_version; + char *firmware_version; + char *type_description; + NMDeviceCapabilities capabilities; + gboolean managed; + gboolean firmware_missing; + gboolean autoconnect; + NMIPConfig *ip4_config; + NMDhcpConfig *dhcp4_config; + NMIPConfig *ip6_config; + NMDhcpConfig *dhcp6_config; + NMDeviceState state; + NMDeviceState last_seen_state; + NMDeviceStateReason reason; + + NMActiveConnection *active_connection; + GPtrArray *available_connections; + + GUdevClient *client; + char *product, *short_product; + char *vendor, *short_vendor; + char *description, *bus_name; + + char *physical_port_id; + guint32 mtu; +} NMDevicePrivate; + +enum { + PROP_0, + PROP_INTERFACE, + PROP_UDI, + PROP_DRIVER, + PROP_DRIVER_VERSION, + PROP_FIRMWARE_VERSION, + PROP_CAPABILITIES, + PROP_MANAGED, + PROP_AUTOCONNECT, + PROP_FIRMWARE_MISSING, + PROP_IP4_CONFIG, + PROP_DHCP4_CONFIG, + PROP_IP6_CONFIG, + PROP_STATE, + PROP_STATE_REASON, + PROP_PRODUCT, + PROP_VENDOR, + PROP_DHCP6_CONFIG, + PROP_IP_INTERFACE, + PROP_DEVICE_TYPE, + PROP_ACTIVE_CONNECTION, + PROP_AVAILABLE_CONNECTIONS, + PROP_PHYSICAL_PORT_ID, + PROP_MTU, + + LAST_PROP +}; + +enum { + STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void +nm_device_init (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + + priv->state = NM_DEVICE_STATE_UNKNOWN; + priv->reason = NM_DEVICE_STATE_REASON_NONE; +} + +static gboolean +demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + guint32 *reason_field = field; + + g_variant_get (value, "(uu)", NULL, reason_field); + _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON); + return TRUE; +} + +static void +device_state_changed (NMDBusDevice *proxy, + guint new_state, + guint old_state, + guint reason, + gpointer user_data); + +static void +init_dbus (NMObject *object) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_UDI, &priv->udi }, + { NM_DEVICE_INTERFACE, &priv->iface }, + { NM_DEVICE_IP_INTERFACE, &priv->ip_iface }, + { NM_DEVICE_DRIVER, &priv->driver }, + { NM_DEVICE_DRIVER_VERSION, &priv->driver_version }, + { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version }, + { NM_DEVICE_CAPABILITIES, &priv->capabilities }, + { NM_DEVICE_MANAGED, &priv->managed }, + { NM_DEVICE_AUTOCONNECT, &priv->autoconnect }, + { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing }, + { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG }, + { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG }, + { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG }, + { NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG }, + { NM_DEVICE_STATE, &priv->state }, + { NM_DEVICE_STATE_REASON, &priv->reason, demarshal_state_reason }, + { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, + { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION }, + { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id }, + { NM_DEVICE_MTU, &priv->mtu }, + + /* Properties that exist in D-Bus but that we don't track */ + { "ip4-address", NULL }, + { "device-type", NULL }, + + { NULL }, + }; + + NM_OBJECT_CLASS (nm_device_parent_class)->init_dbus (object); + + priv->proxy = NMDBUS_DEVICE (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE)); + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE, + property_info); + + g_signal_connect (priv->proxy, "state-changed", + G_CALLBACK (device_state_changed), object); +} + +typedef struct { + NMDeviceState old_state; + NMDeviceState new_state; + NMDeviceStateReason reason; +} StateChangeData; + +static void +device_state_change_reloaded (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + StateChangeData *data = user_data; + NMDeviceState old_state = data->old_state; + NMDeviceState new_state = data->new_state; + NMDeviceStateReason reason = data->reason; + + g_slice_free (StateChangeData, data); + + _nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL); + + /* If the device changes state several times in rapid succession, then we'll + * queue several reload_properties() calls, and there's no guarantee that + * they'll finish in the right order. In that case, only emit the signal + * for the last one. + */ + if (priv->last_seen_state != new_state) + return; + + /* Ensure that nm_device_get_state() will return the right value even if + * we haven't processed the corresponding PropertiesChanged yet. + */ + priv->state = new_state; + + g_signal_emit (self, signals[STATE_CHANGED], 0, + new_state, old_state, reason); +} + +static void +device_state_changed (NMDBusDevice *proxy, + guint new_state, + guint old_state, + guint reason, + gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + StateChangeData *data; + + if (old_state == new_state) + return; + + /* Our object-valued properties (eg, ip4_config) will still + * have their old values at this point, because NMObject is + * in the process of asynchronously reading the new values. + * Wait for that to finish before emitting the signal. + */ + priv->last_seen_state = new_state; + + data = g_slice_new (StateChangeData); + data->old_state = old_state; + data->new_state = new_state; + data->reason = reason; + _nm_object_reload_properties_async (NM_OBJECT (user_data), + NULL, + device_state_change_reloaded, + data); +} + +static GType +_nm_device_gtype_from_dtype (NMDeviceType dtype) +{ + switch (dtype) { + case NM_DEVICE_TYPE_ETHERNET: + return NM_TYPE_DEVICE_ETHERNET; + case NM_DEVICE_TYPE_WIFI: + return NM_TYPE_DEVICE_WIFI; + case NM_DEVICE_TYPE_MODEM: + return NM_TYPE_DEVICE_MODEM; + case NM_DEVICE_TYPE_BT: + return NM_TYPE_DEVICE_BT; + case NM_DEVICE_TYPE_ADSL: + return NM_TYPE_DEVICE_ADSL; + case NM_DEVICE_TYPE_OLPC_MESH: + return NM_TYPE_DEVICE_OLPC_MESH; + case NM_DEVICE_TYPE_WIMAX: + return NM_TYPE_DEVICE_WIMAX; + case NM_DEVICE_TYPE_INFINIBAND: + return NM_TYPE_DEVICE_INFINIBAND; + case NM_DEVICE_TYPE_BOND: + return NM_TYPE_DEVICE_BOND; + case NM_DEVICE_TYPE_TEAM: + return NM_TYPE_DEVICE_TEAM; + case NM_DEVICE_TYPE_BRIDGE: + return NM_TYPE_DEVICE_BRIDGE; + case NM_DEVICE_TYPE_VLAN: + return NM_TYPE_DEVICE_VLAN; + case NM_DEVICE_TYPE_GENERIC: + return NM_TYPE_DEVICE_GENERIC; + default: + g_warning ("Unknown device type %d", dtype); + return G_TYPE_INVALID; + } +} + +static void +constructed (GObject *object) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); + + /* Catch failure of subclasses to call _nm_device_set_device_type() */ + g_warn_if_fail (priv->device_type != NM_DEVICE_TYPE_UNKNOWN); + /* Catch a subclass setting the wrong type */ + g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type)); +} + +static void +dispose (GObject *object) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + + g_clear_object (&priv->ip4_config); + g_clear_object (&priv->dhcp4_config); + g_clear_object (&priv->ip6_config); + g_clear_object (&priv->dhcp6_config); + g_clear_object (&priv->client); + g_clear_object (&priv->active_connection); + + g_clear_pointer (&priv->available_connections, g_ptr_array_unref); + + G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + + g_free (priv->iface); + g_free (priv->ip_iface); + g_free (priv->udi); + g_free (priv->driver); + g_free (priv->driver_version); + g_free (priv->firmware_version); + g_free (priv->product); + g_free (priv->short_product); + g_free (priv->vendor); + g_free (priv->short_vendor); + g_free (priv->description); + g_free (priv->bus_name); + g_free (priv->type_description); + g_free (priv->physical_port_id); + + G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDevice *device = NM_DEVICE (object); + + switch (prop_id) { + case PROP_DEVICE_TYPE: + g_value_set_enum (value, nm_device_get_device_type (device)); + break; + case PROP_UDI: + g_value_set_string (value, nm_device_get_udi (device)); + break; + case PROP_INTERFACE: + g_value_set_string (value, nm_device_get_iface (device)); + break; + case PROP_IP_INTERFACE: + g_value_set_string (value, nm_device_get_ip_iface (device)); + break; + case PROP_DRIVER: + g_value_set_string (value, nm_device_get_driver (device)); + break; + case PROP_DRIVER_VERSION: + g_value_set_string (value, nm_device_get_driver_version (device)); + break; + case PROP_FIRMWARE_VERSION: + g_value_set_string (value, nm_device_get_firmware_version (device)); + break; + case PROP_CAPABILITIES: + g_value_set_flags (value, nm_device_get_capabilities (device)); + break; + case PROP_MANAGED: + g_value_set_boolean (value, nm_device_get_managed (device)); + break; + case PROP_AUTOCONNECT: + g_value_set_boolean (value, nm_device_get_autoconnect (device)); + break; + case PROP_FIRMWARE_MISSING: + g_value_set_boolean (value, nm_device_get_firmware_missing (device)); + break; + case PROP_IP4_CONFIG: + g_value_set_object (value, nm_device_get_ip4_config (device)); + break; + case PROP_DHCP4_CONFIG: + g_value_set_object (value, nm_device_get_dhcp4_config (device)); + break; + case PROP_IP6_CONFIG: + g_value_set_object (value, nm_device_get_ip6_config (device)); + break; + case PROP_DHCP6_CONFIG: + g_value_set_object (value, nm_device_get_dhcp6_config (device)); + break; + case PROP_STATE: + g_value_set_enum (value, nm_device_get_state (device)); + break; + case PROP_STATE_REASON: + g_value_set_uint (value, nm_device_get_state_reason (device)); + break; + case PROP_ACTIVE_CONNECTION: + g_value_set_object (value, nm_device_get_active_connection (device)); + break; + case PROP_AVAILABLE_CONNECTIONS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_get_available_connections (device))); + break; + case PROP_PRODUCT: + g_value_set_string (value, nm_device_get_product (device)); + break; + case PROP_VENDOR: + g_value_set_string (value, nm_device_get_vendor (device)); + break; + case PROP_PHYSICAL_PORT_ID: + g_value_set_string (value, nm_device_get_physical_port_id (device)); + break; + case PROP_MTU: + g_value_set_uint (value, nm_device_get_mtu (device)); + 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) +{ + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean b; + + switch (prop_id) { + case PROP_DEVICE_TYPE: + /* Construct only */ + priv->device_type = g_value_get_enum (value); + break; + case PROP_AUTOCONNECT: + b = g_value_get_boolean (value); + if (priv->autoconnect != b) + nm_device_set_autoconnect (NM_DEVICE (object), b); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_class_init (NMDeviceClass *device_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (device_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (device_class); + + g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE, NMDBUS_TYPE_DEVICE_PROXY); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + device_class->connection_compatible = connection_compatible; + + /* properties */ + + /** + * NMDevice:interface: + * + * The interface of the device. + **/ + g_object_class_install_property + (object_class, PROP_INTERFACE, + g_param_spec_string (NM_DEVICE_INTERFACE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:ip-interface: + * + * The IP interface of the device which should be used for all IP-related + * operations like addressing and routing. + **/ + g_object_class_install_property + (object_class, PROP_IP_INTERFACE, + g_param_spec_string (NM_DEVICE_IP_INTERFACE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:device-type: + * + * The numeric type of the device. + **/ + g_object_class_install_property + (object_class, PROP_DEVICE_TYPE, + g_param_spec_enum (NM_DEVICE_DEVICE_TYPE, "", "", + NM_TYPE_DEVICE_TYPE, + NM_DEVICE_TYPE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + /** + * NMDevice:udi: + * + * An operating-system specific device hardware identifier; this is not + * unique to a specific hardware device across reboots or hotplugs. It + * is an opaque string which for some device types (Bluetooth, Modem) + * contains an identifier provided by the underlying hardware service daemon + * such as Bluez or ModemManager, and clients can use this property to + * request more information about the device from those services. + **/ + g_object_class_install_property + (object_class, PROP_UDI, + g_param_spec_string (NM_DEVICE_UDI, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:driver: + * + * The driver of the device. + **/ + g_object_class_install_property + (object_class, PROP_DRIVER, + g_param_spec_string (NM_DEVICE_DRIVER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:driver-version: + * + * The version of the device driver. + **/ + g_object_class_install_property + (object_class, PROP_DRIVER_VERSION, + g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:firmware-version: + * + * The firmware version of the device. + **/ + g_object_class_install_property + (object_class, PROP_FIRMWARE_VERSION, + g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:capabilities: + * + * The capabilities of the device. + **/ + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_flags (NM_DEVICE_CAPABILITIES, "", "", + NM_TYPE_DEVICE_CAPABILITIES, + NM_DEVICE_CAP_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:managed: + * + * Whether the device is managed by NetworkManager. + **/ + g_object_class_install_property + (object_class, PROP_MANAGED, + g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:autoconnect: + * + * Whether the device can auto-activate a connection. + **/ + g_object_class_install_property + (object_class, PROP_AUTOCONNECT, + g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:firmware-missing: + * + * When %TRUE indicates the device is likely missing firmware required + * for its operation. + **/ + g_object_class_install_property + (object_class, PROP_FIRMWARE_MISSING, + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:ip4-config: + * + * The #NMIP4Config of the device. + **/ + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_object (NM_DEVICE_IP4_CONFIG, "", "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:dhcp4-config: + * + * The IPv4 #NMDhcpConfig of the device. + **/ + g_object_class_install_property + (object_class, PROP_DHCP4_CONFIG, + g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, "", "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:ip6-config: + * + * The IPv6 #NMIPConfig of the device. + **/ + g_object_class_install_property + (object_class, PROP_IP6_CONFIG, + g_param_spec_object (NM_DEVICE_IP6_CONFIG, "", "", + NM_TYPE_IP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:dhcp6-config: + * + * The IPv6 #NMDhcpConfig of the device. + **/ + g_object_class_install_property + (object_class, PROP_DHCP6_CONFIG, + g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, "", "", + NM_TYPE_DHCP_CONFIG, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:state: + * + * The state of the device. + **/ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_DEVICE_STATE, "", "", + NM_TYPE_DEVICE_STATE, + NM_DEVICE_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:state-reason: + * + * The reason for the device state. + **/ + g_object_class_install_property + (object_class, PROP_STATE_REASON, + g_param_spec_uint (NM_DEVICE_STATE_REASON, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:active-connection: + * + * The #NMActiveConnection object that "owns" this device during activation. + **/ + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTION, + g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:available-connections: + * + * The available connections of the device + * + * Element-type: NMRemoteConnection + **/ + g_object_class_install_property + (object_class, PROP_AVAILABLE_CONNECTIONS, + g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:vendor: + * + * The vendor string of the device. + **/ + g_object_class_install_property + (object_class, PROP_VENDOR, + g_param_spec_string (NM_DEVICE_VENDOR, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:product: + * + * The product string of the device. + **/ + g_object_class_install_property + (object_class, PROP_PRODUCT, + g_param_spec_string (NM_DEVICE_PRODUCT, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:physical-port-id: + * + * The physical port ID of the device. (See + * nm_device_get_physical_port_id().) + **/ + g_object_class_install_property + (object_class, PROP_PHYSICAL_PORT_ID, + g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDevice:mtu: + * + * The MTU of the device. + **/ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_DEVICE_MTU, "", "", + 0, G_MAXUINT32, 1500, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + + /** + * NMDevice::state-changed: + * @device: the device object that received the signal + * @new_state: the new state of the device + * @old_state: the previous state of the device + * @reason: the reason describing the state change + * + * Notifies the state change of a #NMDevice. + **/ + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 3, + G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); +} + +/** + * _nm_device_set_device_type: + * @device: the device + * @dtype: the NM device type + * + * Sets the NM device type if it wasn't set during construction. INTERNAL + * ONLY METHOD. + **/ +void +_nm_device_set_device_type (NMDevice *device, NMDeviceType dtype) +{ + NMDevicePrivate *priv; + + g_return_if_fail (device != NULL); + g_return_if_fail (dtype != NM_DEVICE_TYPE_UNKNOWN); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (priv->device_type == NM_DEVICE_TYPE_UNKNOWN) + priv->device_type = dtype; + else + g_warn_if_fail (dtype == priv->device_type); +} + +static GType +_nm_device_decide_type (GVariant *value) +{ + return _nm_device_gtype_from_dtype (g_variant_get_uint32 (value)); +} + +/** + * nm_device_get_iface: + * @device: a #NMDevice + * + * Gets the interface name of the #NMDevice. + * + * Returns: the interface of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_iface (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->iface; +} + +/** + * nm_device_get_ip_iface: + * @device: a #NMDevice + * + * Gets the IP interface name of the #NMDevice over which IP traffic flows + * when the device is in the ACTIVATED state. + * + * Returns: the IP traffic interface of the device. This is the internal string + * used by the device, and must not be modified. + **/ +const char * +nm_device_get_ip_iface (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->ip_iface; +} + +/** + * nm_device_get_device_type: + * @device: a #NMDevice + * + * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc. + * + * Returns: the device type + **/ +NMDeviceType +nm_device_get_device_type (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE (self)->device_type; +} + +/** + * nm_device_get_udi: + * @device: a #NMDevice + * + * Gets the Unique Device Identifier of the #NMDevice. + * + * Returns: the Unique Device Identifier of the device. This identifier may be + * used to gather more information about the device from various operating + * system services like udev or sysfs. + **/ +const char * +nm_device_get_udi (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->udi; +} + +/** + * nm_device_get_driver: + * @device: a #NMDevice + * + * Gets the driver of the #NMDevice. + * + * Returns: the driver of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_driver (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->driver; +} + +/** + * nm_device_get_driver_version: + * @device: a #NMDevice + * + * Gets the driver version of the #NMDevice. + * + * Returns: the version of the device driver. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_driver_version (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->driver_version; +} + +/** + * nm_device_get_firmware_version: + * @device: a #NMDevice + * + * Gets the firmware version of the #NMDevice. + * + * Returns: the firmware version of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_firmware_version (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->firmware_version; +} + +/** + * nm_device_get_type_description: + * @device: a #NMDevice + * + * Gets a (non-localized) description of the type of device that + * @device is. + * + * Returns: the type description of the device. This is the internal + * string used by the device, and must not be modified. + **/ +const char * +nm_device_get_type_description (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + const char *desc, *typename; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + if (priv->type_description) + return priv->type_description; + + if (NM_DEVICE_GET_CLASS (device)->get_type_description) { + desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device); + if (desc) + return desc; + } + + typename = G_OBJECT_TYPE_NAME (device); + if (g_str_has_prefix (typename, "NMDevice")) + typename += 8; + priv->type_description = g_ascii_strdown (typename, -1); + + return priv->type_description; +} + +/** + * nm_device_get_hw_address: + * @device: a #NMDevice + * + * Gets the current a hardware address (MAC) for the @device. + * + * Returns: the current MAC of the device, or %NULL. + * This is the internal string used by the device, and must not be modified. + **/ +const char * +nm_device_get_hw_address (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + if (NM_DEVICE_GET_CLASS (device)->get_hw_address) + return NM_DEVICE_GET_CLASS (device)->get_hw_address (device); + + return NULL; +} + +/** + * nm_device_get_capabilities: + * @device: a #NMDevice + * + * Gets the device' capabilities. + * + * Returns: the capabilities + **/ +NMDeviceCapabilities +nm_device_get_capabilities (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + return NM_DEVICE_GET_PRIVATE (device)->capabilities; +} + +/** + * nm_device_get_managed: + * @device: a #NMDevice + * + * Whether the #NMDevice is managed by NetworkManager. + * + * Returns: %TRUE if the device is managed by NetworkManager + **/ +gboolean +nm_device_get_managed (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + return NM_DEVICE_GET_PRIVATE (device)->managed; +} + +/** + * nm_device_get_autoconnect: + * @device: a #NMDevice + * + * Whether the #NMDevice can be autoconnected. + * + * Returns: %TRUE if the device is allowed to be autoconnected + **/ +gboolean +nm_device_get_autoconnect (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return NM_DEVICE_GET_PRIVATE (device)->autoconnect; +} + +/** + * nm_device_set_autoconnect: + * @device: a #NMDevice + * @autoconnect: %TRUE to enable autoconnecting + * + * Enables or disables automatic activation of the #NMDevice. + **/ +void +nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect) +{ + g_return_if_fail (NM_IS_DEVICE (device)); + + NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect; + + _nm_object_set_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Autoconnect", + "b", autoconnect); +} + +/** + * nm_device_get_firmware_missing: + * @device: a #NMDevice + * + * Indicates that firmware required for the device's operation is likely + * to be missing. + * + * Returns: %TRUE if firmware required for the device's operation is likely + * to be missing. + **/ +gboolean +nm_device_get_firmware_missing (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + return NM_DEVICE_GET_PRIVATE (device)->firmware_missing; +} + +/** + * nm_device_get_ip4_config: + * @device: a #NMDevice + * + * Gets the current IPv4 #NMIPConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_ip4_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv4 #NMIPConfig, or %NULL if the device is not + * activated. + **/ +NMIPConfig * +nm_device_get_ip4_config (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->ip4_config; +} + +/** + * nm_device_get_dhcp4_config: + * @device: a #NMDevice + * + * Gets the current IPv4 #NMDhcpConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_dhcp4_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv4 #NMDhcpConfig, or %NULL if the device is + * not activated or not using DHCP. + **/ +NMDhcpConfig * +nm_device_get_dhcp4_config (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config; +} + +/** + * nm_device_get_ip6_config: + * @device: a #NMDevice + * + * Gets the current IPv6 #NMIPConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_ip6_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv6 #NMIPConfig or %NULL if the device is not activated. + **/ +NMIPConfig * +nm_device_get_ip6_config (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->ip6_config; +} + +/** + * nm_device_get_dhcp6_config: + * @device: a #NMDevice + * + * Gets the current IPv6 #NMDhcpConfig associated with the #NMDevice. + * + * You can alternatively use nm_active_connection_get_dhcp6_config(), which also + * works with VPN connections. + * + * Returns: (transfer none): the IPv6 #NMDhcpConfig, or %NULL if the device is + * not activated or not using DHCPv6. + **/ +NMDhcpConfig * +nm_device_get_dhcp6_config (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config; +} + +/** + * nm_device_get_state: + * @device: a #NMDevice + * + * Gets the current #NMDevice state. + * + * Returns: the current device state + **/ +NMDeviceState +nm_device_get_state (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE (device)->state; +} + +/** + * nm_device_get_state_reason: + * @device: a #NMDevice + * + * Gets the reason for entering the current #NMDevice state. + * + * Returns: the reason for entering the current device state + **/ +NMDeviceStateReason +nm_device_get_state_reason (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_REASON_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE (device)->reason; +} + +/** + * nm_device_get_active_connection: + * @device: a #NMDevice + * + * Gets the #NMActiveConnection object which owns this device during activation. + * + * Returns: (transfer none): the #NMActiveConnection or %NULL if the device is + * not part of an active connection + **/ +NMActiveConnection * +nm_device_get_active_connection (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->active_connection; +} + +/** + * nm_device_get_available_connections: + * @device: a #NMDevice + * + * Gets the #NMRemoteConnections currently known to the daemon that could + * be activated on @device. + * + * Returns: (element-type NMRemoteConnection): the #GPtrArray + * containing #NMRemoteConnections. This is the internal copy used by + * the connection, and must not be modified. + **/ +const GPtrArray * +nm_device_get_available_connections (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + return NM_DEVICE_GET_PRIVATE (device)->available_connections; +} + +static inline guint8 +hex2byte (const char *hex) +{ + int a, b; + a = g_ascii_xdigit_value (*hex++); + if (a < 0) + return -1; + b = g_ascii_xdigit_value (*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +static char * +get_decoded_property (GUdevDevice *device, const char *property) +{ + const char *orig, *p; + char *unescaped, *n; + guint len; + + p = orig = g_udev_device_get_property (device, property); + if (!orig) + return NULL; + + len = strlen (orig); + n = unescaped = g_malloc0 (len + 1); + while (*p) { + if ((len >= 4) && (*p == '\\') && (*(p+1) == 'x')) { + *n++ = (char) hex2byte (p + 2); + p += 4; + len -= 4; + } else { + *n++ = *p++; + len--; + } + } + + return unescaped; +} + +static gboolean +ensure_udev_client (NMDevice *device) +{ + static const char *const subsys[3] = { "net", "tty", NULL }; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->client) + priv->client = g_udev_client_new (subsys); + + return priv->client != NULL; +} + +static char * +_get_udev_property (NMDevice *device, + const char *enc_prop, /* ID_XXX_ENC */ + const char *db_prop) /* ID_XXX_FROM_DATABASE */ +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GUdevDevice *udev_device = NULL, *tmpdev, *olddev; + const char *ifname; + guint32 count = 0; + char *enc_value = NULL, *db_value = NULL; + + if (!ensure_udev_client (device)) + return NULL; + + ifname = nm_device_get_iface (device); + if (!ifname) + return NULL; + + udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname); + if (!udev_device) + udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname); + if (!udev_device) + return NULL; + + /* Walk up the chain of the device and its parents a few steps to grab + * vendor and device ID information off it. + */ + + /* Ref the device again because we have to unref it each iteration, + * as g_udev_device_get_parent() returns a ref-ed object. + */ + tmpdev = g_object_ref (udev_device); + while ((count++ < 3) && tmpdev && !enc_value) { + if (!enc_value) + enc_value = get_decoded_property (tmpdev, enc_prop); + if (!db_value) + db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop)); + + olddev = tmpdev; + tmpdev = g_udev_device_get_parent (tmpdev); + g_object_unref (olddev); + } + + /* Unref the last device if we found what we needed before running out + * of parents. + */ + if (tmpdev) + g_object_unref (tmpdev); + + /* Balance the initial g_udev_client_query_by_subsystem_and_name() */ + g_object_unref (udev_device); + + /* Prefer the encoded value which comes directly from the device + * over the hwdata database value. + */ + if (enc_value) { + g_free (db_value); + return enc_value; + } + + return db_value; +} + +/** + * nm_device_get_product: + * @device: a #NMDevice + * + * Gets the product string of the #NMDevice. + * + * Returns: the product name of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_product (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->product) { + priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); + if (!priv->product) { + /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ + priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); + } + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT); + } + return priv->product; +} + +/** + * nm_device_get_vendor: + * @device: a #NMDevice + * + * Gets the vendor string of the #NMDevice. + * + * Returns: the vendor name of the device. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_device_get_vendor (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->vendor) { + priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR); + } + return priv->vendor; +} + +static const char * const ignored_words[] = { + "Semiconductor", + "Components", + "Corporation", + "Communications", + "Company", + "Corp.", + "Corp", + "Co.", + "Inc.", + "Inc", + "Incorporated", + "Ltd.", + "Limited.", + "Intel?", + "chipset", + "adapter", + "[hex]", + "NDIS", + "Module", + NULL +}; + +static const char * const ignored_phrases[] = { + "Multiprotocol MAC/baseband processor", + "Wireless LAN Controller", + "Wireless LAN Adapter", + "Wireless Adapter", + "Network Connection", + "Wireless Cardbus Adapter", + "Wireless CardBus Adapter", + "54 Mbps Wireless PC Card", + "Wireless PC Card", + "Wireless PC", + "PC Card with XJACK(r) Antenna", + "Wireless cardbus", + "Wireless LAN PC Card", + "Technology Group Ltd.", + "Communication S.p.A.", + "Business Mobile Networks BV", + "Mobile Broadband Minicard Composite Device", + "Mobile Communications AB", + "(PC-Suite Mode)", + NULL +}; + +static char * +fixup_desc_string (const char *desc) +{ + char *p, *temp; + char **words, **item; + GString *str; + int i; + + if (!desc) + return NULL; + + p = temp = g_strdup (desc); + while (*p) { + if (*p == '_' || *p == ',') + *p = ' '; + p++; + } + + /* Attempt to shorten ID by ignoring certain phrases */ + for (i = 0; ignored_phrases[i]; i++) { + p = strstr (temp, ignored_phrases[i]); + if (p) { + guint32 ignored_len = strlen (ignored_phrases[i]); + + memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */ + } + } + + /* Attempt to shorten ID by ignoring certain individual words */ + words = g_strsplit (temp, " ", 0); + str = g_string_new_len (NULL, strlen (temp)); + g_free (temp); + + for (item = words; *item; item++) { + gboolean ignore = FALSE; + + if (**item == '\0') + continue; + + for (i = 0; ignored_words[i]; i++) { + if (!strcmp (*item, ignored_words[i])) { + ignore = TRUE; + break; + } + } + + if (!ignore) { + if (str->len) + g_string_append_c (str, ' '); + g_string_append (str, *item); + } + } + g_strfreev (words); + + temp = str->str; + g_string_free (str, FALSE); + + return temp; +} + +static void +get_description (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + const char *dev_product; + const char *dev_vendor; + char *pdown; + char *vdown; + GString *str; + + dev_product = nm_device_get_product (device); + priv->short_product = fixup_desc_string (dev_product); + + dev_vendor = nm_device_get_vendor (device); + priv->short_vendor = fixup_desc_string (dev_vendor); + + if (!dev_product || !dev_vendor) { + priv->description = g_strdup (nm_device_get_iface (device)); + return; + } + + str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1); + + /* Another quick hack; if all of the fixed up vendor string + * is found in product, ignore the vendor. + */ + pdown = g_ascii_strdown (priv->short_product, -1); + vdown = g_ascii_strdown (priv->short_vendor, -1); + if (!strstr (pdown, vdown)) { + g_string_append (str, priv->short_vendor); + g_string_append_c (str, ' '); + } + g_free (pdown); + g_free (vdown); + + g_string_append (str, priv->short_product); + + priv->description = g_string_free (str, FALSE); +} + +static const char * +get_short_vendor (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->description) + get_description (device); + + return priv->short_vendor; +} + +/** + * nm_device_get_description: + * @device: an #NMDevice + * + * Gets a description of @device, based on its vendor and product names. + * + * Returns: a description of @device. If either the vendor or the + * product name is unknown, this returns the interface name. + */ +const char * +nm_device_get_description (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + if (!priv->description) + get_description (device); + + return priv->description; +} + +static const char * +get_type_name (NMDevice *device) +{ + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_ETHERNET: + return _("Ethernet"); + case NM_DEVICE_TYPE_WIFI: + return _("Wi-Fi"); + case NM_DEVICE_TYPE_BT: + return _("Bluetooth"); + case NM_DEVICE_TYPE_OLPC_MESH: + return _("OLPC Mesh"); + case NM_DEVICE_TYPE_WIMAX: + return _("WiMAX"); + case NM_DEVICE_TYPE_MODEM: + return _("Mobile Broadband"); + case NM_DEVICE_TYPE_INFINIBAND: + return _("InfiniBand"); + case NM_DEVICE_TYPE_BOND: + return _("Bond"); + case NM_DEVICE_TYPE_TEAM: + return _("Team"); + case NM_DEVICE_TYPE_BRIDGE: + return _("Bridge"); + case NM_DEVICE_TYPE_VLAN: + return _("VLAN"); + case NM_DEVICE_TYPE_ADSL: + return _("ADSL"); + default: + return _("Unknown"); + } +} + +static char * +get_device_type_name_with_iface (NMDevice *device) +{ + const char *type_name = get_type_name (device); + + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: + case NM_DEVICE_TYPE_BRIDGE: + case NM_DEVICE_TYPE_VLAN: + return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device)); + default: + return g_strdup (type_name); + } +} + +static char * +get_device_generic_type_name_with_iface (NMDevice *device) +{ + switch (nm_device_get_device_type (device)) { + case NM_DEVICE_TYPE_ETHERNET: + case NM_DEVICE_TYPE_INFINIBAND: + return g_strdup (_("Wired")); + default: + return get_device_type_name_with_iface (device); + } +} + +static const char * +get_bus_name (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GUdevDevice *udevice; + const char *ifname, *bus; + + if (priv->bus_name) + goto out; + + if (!ensure_udev_client (device)) + return NULL; + + ifname = nm_device_get_iface (device); + if (!ifname) + return NULL; + + udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname); + if (!udevice) + udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname); + if (!udevice) + return NULL; + + bus = g_udev_device_get_property (udevice, "ID_BUS"); + if (!g_strcmp0 (bus, "pci")) + priv->bus_name = g_strdup (_("PCI")); + else if (!g_strcmp0 (bus, "usb")) + priv->bus_name = g_strdup (_("USB")); + else { + /* Use "" instead of NULL so we can tell later that we've + * already tried. + */ + priv->bus_name = g_strdup (""); + } + +out: + if (*priv->bus_name) + return priv->bus_name; + else + return NULL; +} + +static gboolean +find_duplicates (char **names, + gboolean *duplicates, + int num_devices) +{ + int i, j; + gboolean found_any = FALSE; + + memset (duplicates, 0, num_devices * sizeof (gboolean)); + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) + continue; + for (j = i + 1; j < num_devices; j++) { + if (duplicates[j]) + continue; + if (!strcmp (names[i], names[j])) + duplicates[i] = duplicates[j] = found_any = TRUE; + } + } + + return found_any; +} + +/** + * nm_device_disambiguate_names: + * @devices: (array length=num_devices): an array of #NMDevice + * @num_devices: length of @devices + * + * Generates a list of short-ish unique presentation names for the + * devices in @devices. + * + * Returns: (transfer full) (array zero-terminated=1): the device names + */ +char ** +nm_device_disambiguate_names (NMDevice **devices, + int num_devices) +{ + char **names; + gboolean *duplicates; + int i; + + names = g_new (char *, num_devices + 1); + duplicates = g_new (gboolean, num_devices); + + /* Generic device name */ + for (i = 0; i < num_devices; i++) + names[i] = get_device_generic_type_name_with_iface (devices[i]); + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try specific names (eg, "Ethernet" and "InfiniBand" rather + * than "Wired") + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + g_free (names[i]); + names[i] = get_device_type_name_with_iface (devices[i]); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *bus = get_bus_name (devices[i]); + char *name; + + if (!bus) + continue; + + g_free (names[i]); + name = get_device_type_name_with_iface (devices[i]); + /* Translators: the first %s is a bus name (eg, "USB") or + * product name, the second is a device type (eg, + * "Ethernet"). You can change this to something like + * "%2$s (%1$s)" if there's no grammatical way to combine + * the strings otherwise. + */ + names[i] = g_strdup_printf (C_("long device name", "%s %s"), + bus, name); + g_free (name); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* Try prefixing vendor name */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *vendor = get_short_vendor (devices[i]); + char *name; + + if (!vendor) + continue; + + g_free (names[i]); + name = get_device_type_name_with_iface (devices[i]); + names[i] = g_strdup_printf (C_("long device name", "%s %s"), + vendor, + get_type_name (devices[i])); + g_free (name); + } + } + if (!find_duplicates (names, duplicates, num_devices)) + goto done; + + /* We have multiple identical network cards, so we have to differentiate + * them by interface name. + */ + for (i = 0; i < num_devices; i++) { + if (duplicates[i]) { + const char *interface = nm_device_get_iface (devices[i]); + + if (!interface) + continue; + + g_free (names[i]); + names[i] = g_strdup_printf ("%s (%s)", + get_type_name (devices[i]), + interface); + } + } + +done: + g_free (duplicates); + names[num_devices] = NULL; + return names; +} + +/** + * nm_device_get_physical_port_id: + * @device: a #NMDevice + * + * Gets the physical port ID of the #NMDevice. If non-%NULL, this is + * an opaque string that can be used to recognize when + * seemingly-unrelated #NMDevices are actually just different virtual + * ports on a single physical port. (Eg, NPAR / SR-IOV.) + * + * Returns: the physical port ID of the device, or %NULL if the port + * ID is unknown. This is the internal string used by the device and + * must not be modified. + **/ +const char * +nm_device_get_physical_port_id (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + + priv = NM_DEVICE_GET_PRIVATE (device); + + if (priv->physical_port_id && *priv->physical_port_id) + return priv->physical_port_id; + else + return NULL; +} + +/** + * nm_device_get_mtu: + * @device: a #NMDevice + * + * Gets the MTU of the #NMDevice. + * + * Returns: the MTU of the device. + **/ +guint32 +nm_device_get_mtu (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + return NM_DEVICE_GET_PRIVATE (device)->mtu; +} + +/** + * nm_device_is_software: + * @device: a #NMDevice + * + * Whether the device is a software device. + * + * Returns: %TRUE if @device is a software device, %FALSE if it is a hardware device. + **/ +gboolean +nm_device_is_software (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); +} + +/** + * nm_device_disconnect: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Disconnects the device if currently connected, and prevents the device from + * automatically connecting to networks until the next manual network connection + * request. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_device_disconnect (NMDevice *device, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + ret = nmdbus_device_call_disconnect_sync (NM_DEVICE_GET_PRIVATE (device)->proxy, + cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +device_disconnect_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_device_call_disconnect_finish (NMDBUS_DEVICE (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_device_disconnect_async: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the disconnect operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins disconnecting the device if currently connected, and + * prevents the device from automatically connecting to networks until the next + * manual network connection request. + **/ +void +nm_device_disconnect_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_DEVICE (device)); + + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_disconnect_async); + + nmdbus_device_call_disconnect (NM_DEVICE_GET_PRIVATE (device)->proxy, + cancellable, + device_disconnect_cb, simple); +} + +/** + * nm_device_disconnect_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_disconnect_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_disconnect_finish (NMDevice *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_disconnect_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * nm_device_delete: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deletes the software device. Hardware devices can't be deleted. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_delete (NMDevice *device, + GCancellable *cancellable, + GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + ret = nmdbus_device_call_delete_sync (NM_DEVICE_GET_PRIVATE (device)->proxy, + cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +device_delete_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_device_call_delete_finish (NMDBUS_DEVICE (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_device_delete_async: + * @device: a #NMDevice + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when delete operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins deleteing the software device. Hardware devices can't + * be deleted. + **/ +void +nm_device_delete_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_DEVICE (device)); + + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_delete_async); + + nmdbus_device_call_delete (NM_DEVICE_GET_PRIVATE (device)->proxy, + cancellable, + device_delete_cb, simple); +} + +/** + * nm_device_delete_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_delete_finish (NMDevice *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_delete_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * nm_device_connection_valid: + * @device: an #NMDevice to validate @connection against + * @connection: an #NMConnection to validate against @device + * + * Validates a given connection for a given #NMDevice object and returns + * whether the connection may be activated with the device. For example if + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open + * network, and will not be valid if it describes a WPA network, or if it is + * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the + * device. + * + * Returns: %TRUE if the connection may be activated with this device, %FALSE + * if is incompatible with the device's capabilities and characteristics. + **/ +gboolean +nm_device_connection_valid (NMDevice *device, NMConnection *connection) +{ + return nm_device_connection_compatible (device, connection, NULL); +} + +gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + const char *config_iface, *device_iface; + GError *local = NULL; + + if (!nm_connection_verify (connection, &local)) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, + _("The connection was not valid: %s"), local->message); + g_error_free (local); + return FALSE; + } + + config_iface = nm_connection_get_interface_name (connection); + device_iface = nm_device_get_iface (device); + if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) { + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The interface names of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +/** + * nm_device_connection_compatible: + * @device: an #NMDevice to validate @connection against + * @connection: an #NMConnection to validate against @device + * @error: return location for a #GError, or %NULL + * + * Validates a given connection for a given #NMDevice object and returns + * whether the connection may be activated with the device. For example if + * @device is a Wi-Fi device that supports only WEP encryption, the connection + * will only be valid if it is a Wi-Fi connection which describes a WEP or open + * network, and will not be valid if it describes a WPA network, or if it is + * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the + * device. + * + * This function does the same as nm_device_connection_valid(), i.e. checking + * compatibility of the given device and connection. But, in addition, it sets + * GError when FALSE is returned. + * + * Returns: %TRUE if the connection may be activated with this device, %FALSE + * if is incompatible with the device's capabilities and characteristics. + **/ +gboolean +nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error); +} + +/** + * nm_device_filter_connections: + * @device: an #NMDevice to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to filter + * + * Filters a given array of connections for a given #NMDevice object and returns + * connections which may be activated with the device. For example if @device + * is a Wi-Fi device that supports only WEP encryption, the returned array will + * contain any Wi-Fi connections in @connections that allow connection to + * unencrypted or WEP-enabled SSIDs. The returned array will not contain + * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is + * incompatible with the device. To get the full list of connections see + * nm_client_get_connections(). + * + * Returns: (transfer container) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @device. The array + * should be freed with g_ptr_array_unref() when it is no longer required. + **/ +GPtrArray * +nm_device_filter_connections (NMDevice *device, const GPtrArray *connections) +{ + GPtrArray *filtered; + int i; + + filtered = g_ptr_array_new_with_free_func (g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + /* Connection applies to this device */ + if (nm_device_connection_valid (device, candidate)) + g_ptr_array_add (filtered, g_object_ref (candidate)); + } + + return filtered; +} + +/** + * nm_device_get_setting_type: + * @device: an #NMDevice + * + * Gets the (primary) #NMSetting subtype associated with connections + * that can be used on @device. + * + * Returns: @device's associated #NMSetting type + */ +GType +nm_device_get_setting_type (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), G_TYPE_INVALID); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (device)->get_setting_type != NULL, G_TYPE_INVALID); + + return NM_DEVICE_GET_CLASS (device)->get_setting_type (device); +} diff --git a/libnm/nm-device.h b/libnm/nm-device.h new file mode 100644 index 00000000..5cc37356 --- /dev/null +++ b/libnm/nm-device.h @@ -0,0 +1,161 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_H__ +#define __NM_DEVICE_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE (nm_device_get_type ()) +#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE, NMDevice)) +#define NM_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE, NMDeviceClass)) +#define NM_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE)) +#define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE)) +#define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass)) + +#define NM_DEVICE_DEVICE_TYPE "device-type" +#define NM_DEVICE_UDI "udi" +#define NM_DEVICE_INTERFACE "interface" +#define NM_DEVICE_IP_INTERFACE "ip-interface" +#define NM_DEVICE_DRIVER "driver" +#define NM_DEVICE_DRIVER_VERSION "driver-version" +#define NM_DEVICE_FIRMWARE_VERSION "firmware-version" +#define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_MANAGED "managed" +#define NM_DEVICE_AUTOCONNECT "autoconnect" +#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" +#define NM_DEVICE_IP6_CONFIG "ip6-config" +#define NM_DEVICE_DHCP6_CONFIG "dhcp6-config" +#define NM_DEVICE_STATE "state" +#define NM_DEVICE_STATE_REASON "state-reason" +#define NM_DEVICE_ACTIVE_CONNECTION "active-connection" +#define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" +#define NM_DEVICE_VENDOR "vendor" +#define NM_DEVICE_PRODUCT "product" +#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" +#define NM_DEVICE_MTU "mtu" + +struct _NMDevice { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /* Signals */ + void (*state_changed) (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason); + + /* Methods */ + gboolean (*connection_compatible) (NMDevice *device, + NMConnection *connection, + GError **error); + + const char * (*get_type_description) (NMDevice *device); + const char * (*get_hw_address) (NMDevice *device); + + GType (*get_setting_type) (NMDevice *device); + + /*< private >*/ + gpointer padding[8]; +} NMDeviceClass; + +GType nm_device_get_type (void); + +const char * nm_device_get_iface (NMDevice *device); +const char * nm_device_get_ip_iface (NMDevice *device); +NMDeviceType nm_device_get_device_type (NMDevice *device); +const char * nm_device_get_udi (NMDevice *device); +const char * nm_device_get_driver (NMDevice *device); +const char * nm_device_get_driver_version (NMDevice *device); +const char * nm_device_get_firmware_version (NMDevice *device); +const char * nm_device_get_type_description (NMDevice *device); +const char * nm_device_get_hw_address (NMDevice *device); +NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device); +gboolean nm_device_get_managed (NMDevice *device); +gboolean nm_device_get_autoconnect (NMDevice *device); +void nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect); +gboolean nm_device_get_firmware_missing (NMDevice *device); +NMIPConfig * nm_device_get_ip4_config (NMDevice *device); +NMDhcpConfig * nm_device_get_dhcp4_config (NMDevice *device); +NMIPConfig * nm_device_get_ip6_config (NMDevice *device); +NMDhcpConfig * nm_device_get_dhcp6_config (NMDevice *device); +NMDeviceState nm_device_get_state (NMDevice *device); +NMDeviceStateReason nm_device_get_state_reason (NMDevice *device); +NMActiveConnection * nm_device_get_active_connection(NMDevice *device); +const GPtrArray * nm_device_get_available_connections(NMDevice *device); +const char * nm_device_get_physical_port_id (NMDevice *device); +guint32 nm_device_get_mtu (NMDevice *device); +gboolean nm_device_is_software (NMDevice *device); + +const char * nm_device_get_product (NMDevice *device); +const char * nm_device_get_vendor (NMDevice *device); +const char * nm_device_get_description (NMDevice *device); +char ** nm_device_disambiguate_names (NMDevice **devices, + int num_devices); + +gboolean nm_device_disconnect (NMDevice *device, + GCancellable *cancellable, + GError **error); +void nm_device_disconnect_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_device_disconnect_finish (NMDevice *device, + GAsyncResult *result, + GError **error); + +gboolean nm_device_delete (NMDevice *device, + GCancellable *cancellable, + GError **error); +void nm_device_delete_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_device_delete_finish (NMDevice *device, + GAsyncResult *result, + GError **error); + +GPtrArray * nm_device_filter_connections (NMDevice *device, + const GPtrArray *connections); + +gboolean nm_device_connection_valid (NMDevice *device, + NMConnection *connection); + +gboolean nm_device_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error); + +GType nm_device_get_setting_type (NMDevice *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_H__ */ diff --git a/libnm/nm-dhcp-config.c b/libnm/nm-dhcp-config.c new file mode 100644 index 00000000..7227abac --- /dev/null +++ b/libnm/nm-dhcp-config.c @@ -0,0 +1,222 @@ +/* -*- 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. + * + * Copyright 2008 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include + +#include "nm-dhcp-config.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-utils.h" + +G_DEFINE_ABSTRACT_TYPE (NMDhcpConfig, nm_dhcp_config, NM_TYPE_OBJECT) + +#define NM_DHCP_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_CONFIG, NMDhcpConfigPrivate)) + +typedef struct { + GHashTable *options; +} NMDhcpConfigPrivate; + +enum { + PROP_0, + PROP_FAMILY, + PROP_OPTIONS, + + LAST_PROP +}; + +static void +nm_dhcp_config_init (NMDhcpConfig *config) +{ + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (config); + + priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +} + +static gboolean +demarshal_dhcp_options (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object); + GVariantIter iter; + const char *key; + GVariant *opt; + + g_hash_table_remove_all (priv->options); + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "{&sv}", &key, &opt)) { + g_hash_table_insert (priv->options, g_strdup (key), g_variant_dup_string (opt, NULL)); + g_variant_unref (opt); + } + + _nm_object_queue_notify (object, NM_DHCP_CONFIG_OPTIONS); + return TRUE; +} + +static void +init_dbus (NMObject *object) +{ + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DHCP_CONFIG_OPTIONS, &priv->options, demarshal_dhcp_options }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_dhcp_config_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + (NM_IS_DHCP4_CONFIG (object) ? + NM_DBUS_INTERFACE_DHCP4_CONFIG : + NM_DBUS_INTERFACE_DHCP6_CONFIG), + property_info); +} + +static void +finalize (GObject *object) +{ + NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object); + + if (priv->options) + g_hash_table_destroy (priv->options); + + G_OBJECT_CLASS (nm_dhcp_config_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDhcpConfig *self = NM_DHCP_CONFIG (object); + + switch (prop_id) { + case PROP_FAMILY: + g_value_set_int (value, nm_dhcp_config_get_family (self)); + break; + case PROP_OPTIONS: + g_value_set_boxed (value, nm_dhcp_config_get_options (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_dhcp_config_class_init (NMDhcpConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMDhcpConfigPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMDhcpConfig:family: + * + * The IP address family of the configuration; either + * AF_INET or AF_INET6. + **/ + g_object_class_install_property + (object_class, PROP_FAMILY, + g_param_spec_int (NM_DHCP_CONFIG_FAMILY, "", "", + 0, 255, AF_UNSPEC, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMDhcpConfig:options: + * + * The #GHashTable containing options of the configuration. + * + * Type: GLib.HashTable(utf8,utf8) + **/ + g_object_class_install_property + (object_class, PROP_OPTIONS, + g_param_spec_boxed (NM_DHCP_CONFIG_OPTIONS, "", "", + G_TYPE_HASH_TABLE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * nm_dhcp_config_get_family: + * @config: a #NMDhcpConfig + * + * Gets the IP address family of the configuration + * + * Returns: the IP address family; either AF_INET or + * AF_INET6 + **/ +int +nm_dhcp_config_get_family (NMDhcpConfig *config) +{ + g_return_val_if_fail (NM_IS_DHCP_CONFIG (config), AF_UNSPEC); + + return NM_IS_DHCP4_CONFIG (config) ? AF_INET : AF_INET6; +} + +/** + * nm_dhcp_config_get_options: + * @config: a #NMDhcpConfig + * + * Gets all the options contained in the configuration. + * + * Returns: (transfer none) (element-type utf8 utf8): the #GHashTable containing + * strings for keys and values. This is the internal copy used by the + * configuration, and must not be modified. + **/ +GHashTable * +nm_dhcp_config_get_options (NMDhcpConfig *config) +{ + g_return_val_if_fail (NM_IS_DHCP_CONFIG (config), NULL); + + return NM_DHCP_CONFIG_GET_PRIVATE (config)->options; +} + +/** + * nm_dhcp_config_get_one_option: + * @config: a #NMDhcpConfig + * @option: the option to retrieve + * + * Gets one option by option name. + * + * Returns: the configuration option's value. This is the internal string used by the + * configuration, and must not be modified. + **/ +const char * +nm_dhcp_config_get_one_option (NMDhcpConfig *config, const char *option) +{ + g_return_val_if_fail (NM_IS_DHCP_CONFIG (config), NULL); + + return g_hash_table_lookup (nm_dhcp_config_get_options (config), option); +} diff --git a/libnm/nm-dhcp-config.h b/libnm/nm-dhcp-config.h new file mode 100644 index 00000000..85aa3bd2 --- /dev/null +++ b/libnm/nm-dhcp-config.h @@ -0,0 +1,62 @@ +/* -*- 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. + * + * Copyright 2008 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_DHCP_CONFIG_H__ +#define __NM_DHCP_CONFIG_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DHCP_CONFIG (nm_dhcp_config_get_type ()) +#define NM_DHCP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CONFIG, NMDhcpConfig)) +#define NM_DHCP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CONFIG, NMDhcpConfigClass)) +#define NM_IS_DHCP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_CONFIG)) +#define NM_IS_DHCP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_CONFIG)) + +struct _NMDhcpConfig { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /*< private >*/ + gpointer padding[8]; +} NMDhcpConfigClass; + +#define NM_DHCP_CONFIG_FAMILY "family" +#define NM_DHCP_CONFIG_OPTIONS "options" + +GType nm_dhcp_config_get_type (void); + +int nm_dhcp_config_get_family (NMDhcpConfig *config); + +GHashTable *nm_dhcp_config_get_options (NMDhcpConfig *config); +const char *nm_dhcp_config_get_one_option (NMDhcpConfig *config, const char *option); + +G_END_DECLS + +#endif /* __NM_DHCP_CONFIG_H__ */ diff --git a/libnm/nm-dhcp4-config.c b/libnm/nm-dhcp4-config.c new file mode 100644 index 00000000..808edaa6 --- /dev/null +++ b/libnm/nm-dhcp4-config.c @@ -0,0 +1,39 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-dhcp4-config.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, NM_TYPE_DHCP_CONFIG) + +static void +nm_dhcp4_config_init (NMDhcp4Config *config) +{ +} + +static void +nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class) +{ + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DHCP4_CONFIG); +} diff --git a/libnm/nm-dhcp4-config.h b/libnm/nm-dhcp4-config.h new file mode 100644 index 00000000..3423740d --- /dev/null +++ b/libnm/nm-dhcp4-config.h @@ -0,0 +1,49 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NM_DHCP4_CONFIG_H__ +#define __NM_DHCP4_CONFIG_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DHCP4_CONFIG (nm_dhcp4_config_get_type ()) +#define NM_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4Config)) +#define NM_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass)) +#define NM_IS_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP4_CONFIG)) +#define NM_IS_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP4_CONFIG)) + +typedef struct { + NMDhcpConfig parent; +} NMDhcp4Config; + +typedef struct { + NMDhcpConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDhcp4ConfigClass; + +GType nm_dhcp4_config_get_type (void); + +G_END_DECLS + +#endif /* __NM_DHCP4_CONFIG_H__ */ diff --git a/libnm/nm-dhcp6-config.c b/libnm/nm-dhcp6-config.c new file mode 100644 index 00000000..0bd924c4 --- /dev/null +++ b/libnm/nm-dhcp6-config.c @@ -0,0 +1,39 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-dhcp6-config.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, NM_TYPE_OBJECT) + +static void +nm_dhcp6_config_init (NMDhcp6Config *config) +{ +} + +static void +nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class) +{ + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DHCP6_CONFIG); +} diff --git a/libnm/nm-dhcp6-config.h b/libnm/nm-dhcp6-config.h new file mode 100644 index 00000000..abb24adf --- /dev/null +++ b/libnm/nm-dhcp6-config.h @@ -0,0 +1,49 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NM_DHCP6_CONFIG_H__ +#define __NM_DHCP6_CONFIG_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type ()) +#define NM_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6Config)) +#define NM_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass)) +#define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP6_CONFIG)) +#define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP6_CONFIG)) + +typedef struct { + NMDhcpConfig parent; +} NMDhcp6Config; + +typedef struct { + NMDhcpConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMDhcp6ConfigClass; + +GType nm_dhcp6_config_get_type (void); + +G_END_DECLS + +#endif /* __NM_DHCP6_CONFIG_H__ */ diff --git a/libnm/nm-enum-types.c b/libnm/nm-enum-types.c new file mode 100644 index 00000000..1e5dcb0d --- /dev/null +++ b/libnm/nm-enum-types.c @@ -0,0 +1,152 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#include "nm-enum-types.h" + +#include "NetworkManager.h" +#include "nm-access-point.h" +#include "nm-active-connection.h" +#include "nm-client.h" +#include "nm-device-adsl.h" +#include "nm-device-bond.h" +#include "nm-device-bridge.h" +#include "nm-device-bt.h" +#include "nm-device-ethernet.h" +#include "nm-device-generic.h" +#include "nm-device-infiniband.h" +#include "nm-device-modem.h" +#include "nm-device-olpc-mesh.h" +#include "nm-device-team.h" +#include "nm-device-vlan.h" +#include "nm-device-wifi.h" +#include "nm-device-wimax.h" +#include "nm-device.h" +#include "nm-dhcp-config.h" +#include "nm-ip-config.h" +#include "nm-object.h" +#include "nm-remote-connection.h" +#include "nm-types.h" +#include "nm-vpn-connection.h" +#include "nm-vpn-editor-plugin.h" +#include "nm-wimax-nsp.h" +#include "nm-secret-agent-old.h" +#include "nm-vpn-plugin-old.h" + +GType +nm_client_permission_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CLIENT_PERMISSION_NONE, "NM_CLIENT_PERMISSION_NONE", "none" }, + { NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK, "NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK", "enable-disable-network" }, + { NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI, "NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI", "enable-disable-wifi" }, + { NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN, "NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN", "enable-disable-wwan" }, + { NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX, "NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX", "enable-disable-wimax" }, + { NM_CLIENT_PERMISSION_SLEEP_WAKE, "NM_CLIENT_PERMISSION_SLEEP_WAKE", "sleep-wake" }, + { NM_CLIENT_PERMISSION_NETWORK_CONTROL, "NM_CLIENT_PERMISSION_NETWORK_CONTROL", "network-control" }, + { NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED, "NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED", "wifi-share-protected" }, + { NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN, "NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN", "wifi-share-open" }, + { NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM, "NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM", "settings-modify-system" }, + { NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN, "NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN", "settings-modify-own" }, + { NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME, "NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME", "settings-modify-hostname" }, + { NM_CLIENT_PERMISSION_LAST, "NM_CLIENT_PERMISSION_LAST", "last" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMClientPermission"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_client_permission_result_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CLIENT_PERMISSION_RESULT_UNKNOWN, "NM_CLIENT_PERMISSION_RESULT_UNKNOWN", "unknown" }, + { NM_CLIENT_PERMISSION_RESULT_YES, "NM_CLIENT_PERMISSION_RESULT_YES", "yes" }, + { NM_CLIENT_PERMISSION_RESULT_AUTH, "NM_CLIENT_PERMISSION_RESULT_AUTH", "auth" }, + { NM_CLIENT_PERMISSION_RESULT_NO, "NM_CLIENT_PERMISSION_RESULT_NO", "no" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMClientPermissionResult"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_client_error_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_CLIENT_ERROR_FAILED, "NM_CLIENT_ERROR_FAILED", "failed" }, + { NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, "NM_CLIENT_ERROR_MANAGER_NOT_RUNNING", "manager-not-running" }, + { NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, "NM_CLIENT_ERROR_OBJECT_CREATION_FAILED", "object-creation-failed" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMClientError"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_vpn_editor_plugin_capability_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GFlagsValue values[] = { + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE", "none" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT", "import" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT", "export" }, + { NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6, "NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6", "ipv6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("NMVpnEditorPluginCapability"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_wimax_nsp_network_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, "NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN", "unknown" }, + { NM_WIMAX_NSP_NETWORK_TYPE_HOME, "NM_WIMAX_NSP_NETWORK_TYPE_HOME", "home" }, + { NM_WIMAX_NSP_NETWORK_TYPE_PARTNER, "NM_WIMAX_NSP_NETWORK_TYPE_PARTNER", "partner" }, + { NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER, "NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER", "roaming-partner" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMWimaxNspNetworkType"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + + + diff --git a/libnm/nm-enum-types.h b/libnm/nm-enum-types.h new file mode 100644 index 00000000..1db04ab8 --- /dev/null +++ b/libnm/nm-enum-types.h @@ -0,0 +1,28 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#ifndef __NM_ENUM_TYPES_H__ +#define __NM_ENUM_TYPES_H__ + +#include +#include + +G_BEGIN_DECLS +GType nm_client_permission_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CLIENT_PERMISSION (nm_client_permission_get_type ()) +GType nm_client_permission_result_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CLIENT_PERMISSION_RESULT (nm_client_permission_result_get_type ()) +GType nm_client_error_get_type (void) G_GNUC_CONST; +#define NM_TYPE_CLIENT_ERROR (nm_client_error_get_type ()) +GType nm_vpn_editor_plugin_capability_get_type (void) G_GNUC_CONST; +#define NM_TYPE_VPN_EDITOR_PLUGIN_CAPABILITY (nm_vpn_editor_plugin_capability_get_type ()) +GType nm_wimax_nsp_network_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_WIMAX_NSP_NETWORK_TYPE (nm_wimax_nsp_network_type_get_type ()) +G_END_DECLS + +#endif /* __NM_ENUM_TYPES_H__ */ + + + diff --git a/libnm/nm-ifcfg-rh-docs.xml b/libnm/nm-ifcfg-rh-docs.xml new file mode 100644 index 00000000..96ecfde8 --- /dev/null +++ b/libnm/nm-ifcfg-rh-docs.xml @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libnm/nm-ip-config.c b/libnm/nm-ip-config.c new file mode 100644 index 00000000..d057903e --- /dev/null +++ b/libnm/nm-ip-config.c @@ -0,0 +1,502 @@ +/* -*- 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. + * + * Copyright 2007 - 2011 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-ip-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-setting-ip-config.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-utils.h" +#include "nm-core-internal.h" + +G_DEFINE_ABSTRACT_TYPE (NMIPConfig, nm_ip_config, NM_TYPE_OBJECT) + +#define NM_IP_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP_CONFIG, NMIPConfigPrivate)) + +typedef struct { + char *gateway; + GPtrArray *addresses; + GPtrArray *routes; + char **nameservers; + char **domains; + char **searches; + char **wins; + + gboolean new_style_data; +} NMIPConfigPrivate; + +enum { + PROP_0, + PROP_FAMILY, + PROP_GATEWAY, + PROP_ADDRESSES, + PROP_ROUTES, + PROP_NAMESERVERS, + PROP_DOMAINS, + PROP_SEARCHES, + PROP_WINS_SERVERS, + + LAST_PROP +}; + +static void +nm_ip_config_init (NMIPConfig *config) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (config); + + priv->addresses = g_ptr_array_new (); + priv->routes = g_ptr_array_new (); + priv->nameservers = g_new0 (char *, 1); + priv->domains = g_new0 (char *, 1); + priv->searches = g_new0 (char *, 1); + priv->wins = g_new0 (char *, 1); +} + +static gboolean +demarshal_ip_addresses (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + + if (priv->new_style_data) + return TRUE; + + g_ptr_array_unref (priv->addresses); + if (NM_IS_IP4_CONFIG (object)) + priv->addresses = nm_utils_ip4_addresses_from_variant (value, NULL); + else + priv->addresses = nm_utils_ip6_addresses_from_variant (value, NULL); + _nm_object_queue_notify (object, NM_IP_CONFIG_ADDRESSES); + + return TRUE; +} + +static gboolean +demarshal_ip_address_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + + priv->new_style_data = TRUE; + + g_ptr_array_unref (priv->addresses); + if (NM_IS_IP4_CONFIG (object)) + priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET); + else + priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET6); + _nm_object_queue_notify (object, NM_IP_CONFIG_ADDRESSES); + + return TRUE; +} + +static gboolean +demarshal_ip_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + char ***obj_field; + + obj_field = field; + if (*obj_field) + g_strfreev (*obj_field); + + if (NM_IS_IP4_CONFIG (object)) + *obj_field = nm_utils_ip4_dns_from_variant (value); + else + *obj_field = nm_utils_ip6_dns_from_variant (value); + + _nm_object_queue_notify (object, pspec->name); + return TRUE; +} + +static gboolean +demarshal_ip_routes (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + + if (priv->new_style_data) + return TRUE; + + g_ptr_array_unref (priv->routes); + if (NM_IS_IP4_CONFIG (object)) + priv->routes = nm_utils_ip4_routes_from_variant (value); + else + priv->routes = nm_utils_ip6_routes_from_variant (value); + _nm_object_queue_notify (object, NM_IP_CONFIG_ROUTES); + + return TRUE; +} + +static gboolean +demarshal_ip_route_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + + priv->new_style_data = TRUE; + + g_ptr_array_unref (priv->routes); + if (NM_IS_IP4_CONFIG (object)) + priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET); + else + priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET6); + _nm_object_queue_notify (object, NM_IP_CONFIG_ROUTES); + + return TRUE; +} + +static void +init_dbus (NMObject *object) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_IP_CONFIG_GATEWAY, &priv->gateway, }, + { NM_IP_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip_addresses }, + { "address-data", &priv->addresses, demarshal_ip_address_data }, + { NM_IP_CONFIG_ROUTES, &priv->routes, demarshal_ip_routes }, + { "route-data", &priv->routes, demarshal_ip_route_data }, + { NM_IP_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip_array }, + { NM_IP_CONFIG_DOMAINS, &priv->domains, }, + { NM_IP_CONFIG_SEARCHES, &priv->searches, }, + { NM_IP_CONFIG_WINS_SERVERS, &priv->wins, demarshal_ip_array }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_ip_config_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + (NM_IS_IP4_CONFIG (object) ? + NM_DBUS_INTERFACE_IP4_CONFIG : + NM_DBUS_INTERFACE_IP6_CONFIG), + property_info); +} + +static void +finalize (GObject *object) +{ + NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object); + + g_free (priv->gateway); + + g_ptr_array_unref (priv->addresses); + g_ptr_array_unref (priv->routes); + + g_strfreev (priv->nameservers); + g_strfreev (priv->domains); + g_strfreev (priv->searches); + g_strfreev (priv->wins); + + G_OBJECT_CLASS (nm_ip_config_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMIPConfig *self = NM_IP_CONFIG (object); + + switch (prop_id) { + case PROP_FAMILY: + g_value_set_int (value, nm_ip_config_get_family (self)); + break; + case PROP_GATEWAY: + g_value_set_string (value, nm_ip_config_get_gateway (self)); + break; + case PROP_ADDRESSES: + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip_config_get_addresses (self), + (NMUtilsCopyFunc) nm_ip_address_dup, + (GDestroyNotify) nm_ip_address_unref)); + break; + case PROP_ROUTES: + g_value_take_boxed (value, _nm_utils_copy_array (nm_ip_config_get_routes (self), + (NMUtilsCopyFunc) nm_ip_route_dup, + (GDestroyNotify) nm_ip_route_unref)); + break; + case PROP_NAMESERVERS: + g_value_set_boxed (value, (char **) nm_ip_config_get_nameservers (self)); + break; + case PROP_DOMAINS: + g_value_set_boxed (value, (char **) nm_ip_config_get_domains (self)); + break; + case PROP_SEARCHES: + g_value_set_boxed (value, (char **) nm_ip_config_get_searches (self)); + break; + case PROP_WINS_SERVERS: + g_value_set_boxed (value, (char **) nm_ip_config_get_wins_servers (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_ip_config_class_init (NMIPConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMIPConfigPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMIPConfig:family: + * + * The IP address family of the configuration; either + * AF_INET or AF_INET6. + **/ + g_object_class_install_property + (object_class, PROP_FAMILY, + g_param_spec_int (NM_IP_CONFIG_FAMILY, "", "", + 0, 255, AF_UNSPEC, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:gateway: + * + * The IP gateway address of the configuration as string. + **/ + g_object_class_install_property + (object_class, PROP_GATEWAY, + g_param_spec_string (NM_IP_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:addresses: + * + * A #GPtrArray containing the addresses (#NMIPAddress) of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_ADDRESSES, + g_param_spec_boxed (NM_IP_CONFIG_ADDRESSES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:routes: + * + * A #GPtrArray containing the routes (#NMIPRoute) of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_ROUTES, + g_param_spec_boxed (NM_IP_CONFIG_ROUTES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:nameservers: + * + * The array containing name server IP addresses of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_NAMESERVERS, + g_param_spec_boxed (NM_IP_CONFIG_NAMESERVERS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:domains: + * + * The array containing domain strings of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_DOMAINS, + g_param_spec_boxed (NM_IP_CONFIG_DOMAINS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:searches: + * + * The array containing DNS search strings of the configuration. + **/ + g_object_class_install_property + (object_class, PROP_SEARCHES, + g_param_spec_boxed (NM_IP_CONFIG_SEARCHES, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMIPConfig:wins-servers: + * + * The array containing WINS server IP addresses of the configuration. + * (This will always be empty for IPv6 configurations.) + **/ + g_object_class_install_property + (object_class, PROP_WINS_SERVERS, + g_param_spec_boxed (NM_IP_CONFIG_WINS_SERVERS, "", "", + G_TYPE_STRV, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * nm_ip_config_get_family: + * @config: a #NMIPConfig + * + * Gets the IP address family + * + * Returns: the IP address family; either AF_INET or + * AF_INET6 + **/ +int +nm_ip_config_get_family (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), AF_UNSPEC); + + return NM_IS_IP4_CONFIG (config) ? AF_INET : AF_INET6; +} + +/** + * nm_ip_config_get_gateway: + * @config: a #NMIPConfig + * + * Gets the IP gateway address. + * + * Returns: (transfer none): the IP address of the gateway. + **/ +const char * +nm_ip_config_get_gateway (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return NM_IP_CONFIG_GET_PRIVATE (config)->gateway; +} + +/** + * nm_ip_config_get_addresses: + * @config: a #NMIPConfig + * + * Gets the IP addresses (containing the address, prefix, and gateway). + * + * Returns: (element-type NMIPAddress) (transfer none): the #GPtrArray + * containing #NMIPAddresses. This is the internal copy used by the + * configuration and must not be modified. + **/ +GPtrArray * +nm_ip_config_get_addresses (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return NM_IP_CONFIG_GET_PRIVATE (config)->addresses; +} + +/** + * nm_ip_config_get_nameservers: + * @config: a #NMIPConfig + * + * Gets the domain name servers (DNS). + * + * Returns: (transfer none): the array of nameserver IP addresses + **/ +const char * const * +nm_ip_config_get_nameservers (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->nameservers; +} + +/** + * nm_ip_config_get_domains: + * @config: a #NMIPConfig + * + * Gets the domain names. + * + * Returns: (transfer none): the array of domains. + * (This is never %NULL, though it may be 0-length). + **/ +const char * const * +nm_ip_config_get_domains (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->domains; +} + +/** + * nm_ip_config_get_searches: + * @config: a #NMIPConfig + * + * Gets the DNS searches. + * + * Returns: (transfer none): the array of DNS search strings. + * (This is never %NULL, though it may be 0-length). + **/ +const char * const * +nm_ip_config_get_searches (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->searches; +} + +/** + * nm_ip_config_get_wins_servers: + * @config: a #NMIPConfig + * + * Gets the Windows Internet Name Service servers (WINS). + * + * Returns: (transfer none): the arry of WINS server IP address strings. + * (This is never %NULL, though it may be 0-length.) + **/ +const char * const * +nm_ip_config_get_wins_servers (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->wins; +} + +/** + * nm_ip_config_get_routes: + * @config: a #NMIPConfig + * + * Gets the routes. + * + * Returns: (element-type NMIPRoute) (transfer none): the #GPtrArray containing + * #NMIPRoutes. This is the internal copy used by the configuration, and must + * not be modified. + **/ +GPtrArray * +nm_ip_config_get_routes (NMIPConfig *config) +{ + g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL); + + return NM_IP_CONFIG_GET_PRIVATE (config)->routes; +} diff --git a/libnm/nm-ip-config.h b/libnm/nm-ip-config.h new file mode 100644 index 00000000..815135a0 --- /dev/null +++ b/libnm/nm-ip-config.h @@ -0,0 +1,73 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_IP_CONFIG_H__ +#define __NM_IP_CONFIG_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_IP_CONFIG (nm_ip_config_get_type ()) +#define NM_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP_CONFIG, NMIPConfig)) +#define NM_IP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP_CONFIG, NMIPConfigClass)) +#define NM_IS_IP_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IP_CONFIG)) +#define NM_IS_IP_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP_CONFIG)) +#define NM_IP_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP_CONFIG, NMIPConfigClass)) + +struct _NMIPConfig { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /*< private >*/ + gpointer padding[8]; +} NMIPConfigClass; + +#define NM_IP_CONFIG_FAMILY "family" +#define NM_IP_CONFIG_GATEWAY "gateway" +#define NM_IP_CONFIG_ADDRESSES "addresses" +#define NM_IP_CONFIG_ROUTES "routes" +#define NM_IP_CONFIG_NAMESERVERS "nameservers" +#define NM_IP_CONFIG_DOMAINS "domains" +#define NM_IP_CONFIG_SEARCHES "searches" +#define NM_IP_CONFIG_WINS_SERVERS "wins-servers" + +GType nm_ip_config_get_type (void); + +int nm_ip_config_get_family (NMIPConfig *config); +const char * nm_ip_config_get_gateway (NMIPConfig *config); +GPtrArray * nm_ip_config_get_addresses (NMIPConfig *config); +GPtrArray * nm_ip_config_get_routes (NMIPConfig *config); +const char * const *nm_ip_config_get_nameservers (NMIPConfig *config); +const char * const *nm_ip_config_get_domains (NMIPConfig *config); +const char * const *nm_ip_config_get_searches (NMIPConfig *config); +const char * const *nm_ip_config_get_wins_servers (NMIPConfig *config); + +G_END_DECLS + +#endif /* __NM_IP_CONFIG_H__ */ diff --git a/libnm/nm-ip4-config.c b/libnm/nm-ip4-config.c new file mode 100644 index 00000000..26797dd7 --- /dev/null +++ b/libnm/nm-ip4-config.c @@ -0,0 +1,39 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-ip4-config.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_IP_CONFIG) + +static void +nm_ip4_config_init (NMIP4Config *config) +{ +} + +static void +nm_ip4_config_class_init (NMIP4ConfigClass *config_class) +{ + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_IP4_CONFIG); +} diff --git a/libnm/nm-ip4-config.h b/libnm/nm-ip4-config.h new file mode 100644 index 00000000..e2a18e0f --- /dev/null +++ b/libnm/nm-ip4-config.h @@ -0,0 +1,51 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 Red Hat, Inc. + */ + +#ifndef __NM_IP4_CONFIG_H__ +#define __NM_IP4_CONFIG_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ()) +#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP4_CONFIG, NMIP4Config)) +#define NM_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass)) +#define NM_IS_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IP4_CONFIG)) +#define NM_IS_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP4_CONFIG)) +#define NM_IP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass)) + +typedef struct { + NMIPConfig parent; +} NMIP4Config; + +typedef struct { + NMIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMIP4ConfigClass; + +GType nm_ip4_config_get_type (void); + +G_END_DECLS + +#endif /* __NM_IP4_CONFIG_H__ */ diff --git a/libnm/nm-ip6-config.c b/libnm/nm-ip6-config.c new file mode 100644 index 00000000..8a6c966c --- /dev/null +++ b/libnm/nm-ip6-config.c @@ -0,0 +1,39 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-ip6-config.h" +#include "nm-object-private.h" + +G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_IP_CONFIG) + +static void +nm_ip6_config_init (NMIP6Config *config) +{ +} + +static void +nm_ip6_config_class_init (NMIP6ConfigClass *config_class) +{ + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_IP6_CONFIG); +} diff --git a/libnm/nm-ip6-config.h b/libnm/nm-ip6-config.h new file mode 100644 index 00000000..1953476d --- /dev/null +++ b/libnm/nm-ip6-config.h @@ -0,0 +1,51 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_IP6_CONFIG_H__ +#define __NM_IP6_CONFIG_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_IP6_CONFIG (nm_ip6_config_get_type ()) +#define NM_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP6_CONFIG, NMIP6Config)) +#define NM_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass)) +#define NM_IS_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IP6_CONFIG)) +#define NM_IS_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IP6_CONFIG)) +#define NM_IP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IP6_CONFIG, NMIP6ConfigClass)) + +typedef struct { + NMIPConfig parent; +} NMIP6Config; + +typedef struct { + NMIPConfigClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMIP6ConfigClass; + +GType nm_ip6_config_get_type (void); + +G_END_DECLS + +#endif /* __NM_IP6_CONFIG_H__ */ diff --git a/libnm/nm-keyfile-docs.xml b/libnm/nm-keyfile-docs.xml new file mode 100644 index 00000000..d080a427 --- /dev/null +++ b/libnm/nm-keyfile-docs.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c new file mode 100644 index 00000000..1abb5130 --- /dev/null +++ b/libnm/nm-manager.c @@ -0,0 +1,1730 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "nm-manager.h" +#include "nm-device-ethernet.h" +#include "nm-device-wifi.h" +#include "nm-device-private.h" +#include "nm-core-internal.h" +#include "nm-object-private.h" +#include "nm-active-connection.h" +#include "nm-vpn-connection.h" +#include "nm-object-cache.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-manager.h" + +void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled); + +static void nm_manager_initable_iface_init (GInitableIface *iface); +static void nm_manager_async_initable_iface_init (GAsyncInitableIface *iface); +static GInitableIface *nm_manager_parent_initable_iface; +static GAsyncInitableIface *nm_manager_parent_async_initable_iface; + +G_DEFINE_TYPE_WITH_CODE (NMManager, nm_manager, NM_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_manager_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_manager_async_initable_iface_init); + ) + +#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate)) + +typedef struct { + NMDBusManager *manager_proxy; + GCancellable *props_cancellable; + char *version; + NMState state; + gboolean startup; + GPtrArray *devices; + GPtrArray *active_connections; + NMConnectivityState connectivity; + NMActiveConnection *primary_connection; + NMActiveConnection *activating_connection; + + GCancellable *perm_call_cancellable; + GHashTable *permissions; + + /* Activations waiting for their NMActiveConnection + * to appear and then their callback to be called. + */ + GSList *pending_activations; + + gboolean networking_enabled; + gboolean wireless_enabled; + gboolean wireless_hw_enabled; + + gboolean wwan_enabled; + gboolean wwan_hw_enabled; + + gboolean wimax_enabled; + gboolean wimax_hw_enabled; +} NMManagerPrivate; + +enum { + PROP_0, + PROP_VERSION, + PROP_STATE, + PROP_STARTUP, + PROP_NM_RUNNING, + PROP_NETWORKING_ENABLED, + PROP_WIRELESS_ENABLED, + PROP_WIRELESS_HARDWARE_ENABLED, + PROP_WWAN_ENABLED, + PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, + PROP_ACTIVE_CONNECTIONS, + PROP_CONNECTIVITY, + PROP_PRIMARY_CONNECTION, + PROP_ACTIVATING_CONNECTION, + PROP_DEVICES, + + LAST_PROP +}; + +enum { + DEVICE_ADDED, + DEVICE_REMOVED, + ACTIVE_CONNECTION_ADDED, + ACTIVE_CONNECTION_REMOVED, + PERMISSION_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void nm_running_changed_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data); + +/**********************************************************************/ + +static void +nm_manager_init (NMManager *manager) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + + priv->state = NM_STATE_UNKNOWN; + priv->connectivity = NM_CONNECTIVITY_UNKNOWN; + + priv->permissions = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->devices = g_ptr_array_new (); + priv->active_connections = g_ptr_array_new (); +} + +static void +poke_wireless_devices_with_rf_status (NMManager *manager) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + int i; + + for (i = 0; i < priv->devices->len; i++) { + NMDevice *device = g_ptr_array_index (priv->devices, i); + + if (NM_IS_DEVICE_WIFI (device)) + _nm_device_wifi_set_wireless_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled); + } +} + +static void +wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data) +{ + poke_wireless_devices_with_rf_status (NM_MANAGER (object)); +} + +static void manager_recheck_permissions (NMDBusManager *proxy, gpointer user_data); + +static void +init_dbus (NMObject *object) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_MANAGER_VERSION, &priv->version }, + { NM_MANAGER_STATE, &priv->state }, + { NM_MANAGER_STARTUP, &priv->startup }, + { NM_MANAGER_NETWORKING_ENABLED, &priv->networking_enabled }, + { NM_MANAGER_WIRELESS_ENABLED, &priv->wireless_enabled }, + { NM_MANAGER_WIRELESS_HARDWARE_ENABLED, &priv->wireless_hw_enabled }, + { NM_MANAGER_WWAN_ENABLED, &priv->wwan_enabled }, + { NM_MANAGER_WWAN_HARDWARE_ENABLED, &priv->wwan_hw_enabled }, + { NM_MANAGER_WIMAX_ENABLED, &priv->wimax_enabled }, + { NM_MANAGER_WIMAX_HARDWARE_ENABLED, &priv->wimax_hw_enabled }, + { NM_MANAGER_ACTIVE_CONNECTIONS, &priv->active_connections, NULL, NM_TYPE_ACTIVE_CONNECTION, "active-connection" }, + { NM_MANAGER_CONNECTIVITY, &priv->connectivity }, + { NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, + { NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, + { NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_manager_parent_class)->init_dbus (object); + + priv->manager_proxy = NMDBUS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE)); + _nm_object_register_properties (object, + NM_DBUS_INTERFACE, + property_info); + + /* Permissions */ + g_signal_connect (priv->manager_proxy, "check-permissions", + G_CALLBACK (manager_recheck_permissions), object); +} + +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" +#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_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#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" + +static NMClientPermission +nm_permission_to_client (const char *nm) +{ + if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK; + else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI; + else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SLEEP_WAKE)) + return NM_CLIENT_PERMISSION_SLEEP_WAKE; + else if (!strcmp (nm, NM_AUTH_PERMISSION_NETWORK_CONTROL)) + return NM_CLIENT_PERMISSION_NETWORK_CONTROL; + else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED)) + return NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED; + else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN)) + return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME; + + return NM_CLIENT_PERMISSION_NONE; +} + +static NMClientPermissionResult +nm_permission_result_to_client (const char *nm) +{ + if (!strcmp (nm, "yes")) + return NM_CLIENT_PERMISSION_RESULT_YES; + else if (!strcmp (nm, "no")) + return NM_CLIENT_PERMISSION_RESULT_NO; + else if (!strcmp (nm, "auth")) + return NM_CLIENT_PERMISSION_RESULT_AUTH; + return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; +} + +static void +update_permissions (NMManager *self, GVariant *permissions) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + gpointer key, value; + NMClientPermission perm; + NMClientPermissionResult perm_result; + GList *keys, *keys_iter; + + /* get list of old permissions for change notification */ + keys = g_hash_table_get_keys (priv->permissions); + g_hash_table_remove_all (priv->permissions); + + if (permissions) { + GVariantIter viter; + const char *pkey, *pvalue; + + /* Process new permissions */ + g_variant_iter_init (&viter, permissions); + while (g_variant_iter_next (&viter, "{&s&s}", &pkey, &pvalue)) { + perm = nm_permission_to_client (pkey); + perm_result = nm_permission_result_to_client (pvalue); + if (perm) { + g_hash_table_insert (priv->permissions, + GUINT_TO_POINTER (perm), + GUINT_TO_POINTER (perm_result)); + + /* Remove this permission from the list of previous permissions + * we'll be sending NM_CLIENT_PERMISSION_RESULT_UNKNOWN for + * in the change signal since it is still a known permission. + */ + keys = g_list_remove (keys, GUINT_TO_POINTER (perm)); + } + } + } + + /* Signal changes in all updated permissions */ + g_hash_table_iter_init (&iter, priv->permissions); + while (g_hash_table_iter_next (&iter, &key, &value)) { + g_signal_emit (self, signals[PERMISSION_CHANGED], 0, + GPOINTER_TO_UINT (key), + GPOINTER_TO_UINT (value)); + } + + /* And signal changes in all permissions that used to be valid but for + * some reason weren't received in the last request (if any). + */ + for (keys_iter = keys; keys_iter; keys_iter = g_list_next (keys_iter)) { + g_signal_emit (self, signals[PERMISSION_CHANGED], 0, + GPOINTER_TO_UINT (keys_iter->data), + NM_CLIENT_PERMISSION_RESULT_UNKNOWN); + } + g_list_free (keys); +} + +static gboolean +get_permissions_sync (NMManager *self, GError **error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GVariant *permissions; + + if (nmdbus_manager_call_get_permissions_sync (priv->manager_proxy, + &permissions, + NULL, error)) { + update_permissions (self, permissions); + g_variant_unref (permissions); + return TRUE; + } else { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + update_permissions (self, NULL); + return FALSE; + } +} + +static void +get_permissions_reply (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMManager *self; + NMManagerPrivate *priv; + GVariant *permissions = NULL; + GError *error = NULL; + + /* WARNING: this may be called after the manager is disposed, so we can't + * look at self/priv until after we've determined that that isn't the case. + */ + + nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object), + &permissions, + result, &error); + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + /* @self has been disposed. */ + g_error_free (error); + return; + } + + self = user_data; + priv = NM_MANAGER_GET_PRIVATE (self); + + update_permissions (self, permissions); + + g_clear_pointer (&permissions, g_variant_unref); + g_clear_error (&error); + g_clear_object (&priv->perm_call_cancellable); +} + +static void +manager_recheck_permissions (NMDBusManager *proxy, gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + if (priv->perm_call_cancellable) + return; + + priv->perm_call_cancellable = g_cancellable_new (); + nmdbus_manager_call_get_permissions (priv->manager_proxy, + priv->perm_call_cancellable, + get_permissions_reply, + self); +} + +const char * +nm_manager_get_version (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->version; +} + +NMState +nm_manager_get_state (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN); + + return NM_MANAGER_GET_PRIVATE (manager)->state; +} + +gboolean +nm_manager_get_startup (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN); + + return NM_MANAGER_GET_PRIVATE (manager)->startup; +} + +gboolean +nm_manager_get_nm_running (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return _nm_object_get_nm_running (NM_OBJECT (manager)); +} + +gboolean +nm_manager_networking_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->networking_enabled; +} + +gboolean +nm_manager_networking_set_enabled (NMManager *manager, gboolean enable, GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + ret = nmdbus_manager_call_enable_sync (NM_MANAGER_GET_PRIVATE (manager)->manager_proxy, + enable, + NULL, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +gboolean +nm_manager_wireless_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wireless_enabled; +} + +void +nm_manager_wireless_set_enabled (NMManager *manager, gboolean enabled) +{ + g_return_if_fail (NM_IS_MANAGER (manager)); + + _nm_object_set_property (NM_OBJECT (manager), + NM_DBUS_INTERFACE, + "WirelessEnabled", + "b", enabled); +} + +gboolean +nm_manager_wireless_hardware_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wireless_hw_enabled; +} + +gboolean +nm_manager_wwan_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wwan_enabled; +} + +void +nm_manager_wwan_set_enabled (NMManager *manager, gboolean enabled) +{ + g_return_if_fail (NM_IS_MANAGER (manager)); + + _nm_object_set_property (NM_OBJECT (manager), + NM_DBUS_INTERFACE, + "WwanEnabled", + "b", enabled); +} + +gboolean +nm_manager_wwan_hardware_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wwan_hw_enabled; +} + +gboolean +nm_manager_wimax_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wimax_enabled; +} + +void +nm_manager_wimax_set_enabled (NMManager *manager, gboolean enabled) +{ + g_return_if_fail (NM_IS_MANAGER (manager)); + + _nm_object_set_property (NM_OBJECT (manager), + NM_DBUS_INTERFACE, + "WimaxEnabled", + "b", enabled); +} + +gboolean +nm_manager_wimax_hardware_get_enabled (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + return NM_MANAGER_GET_PRIVATE (manager)->wimax_hw_enabled; +} + +gboolean +nm_manager_get_logging (NMManager *manager, char **level, char **domains, GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (level == NULL || *level == NULL, FALSE); + g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!level && !domains) + return TRUE; + + ret = nmdbus_manager_call_get_logging_sync (NM_MANAGER_GET_PRIVATE (manager)->manager_proxy, + level, domains, + NULL, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +gboolean +nm_manager_set_logging (NMManager *manager, const char *level, const char *domains, GError **error) +{ + gboolean ret; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!level && !domains) + return TRUE; + + if (!level) + level = ""; + if (!domains) + domains = ""; + + ret = nmdbus_manager_call_set_logging_sync (NM_MANAGER_GET_PRIVATE (manager)->manager_proxy, + level, domains, + NULL, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +NMClientPermissionResult +nm_manager_get_permission_result (NMManager *manager, NMClientPermission permission) +{ + gpointer result; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CLIENT_PERMISSION_RESULT_UNKNOWN); + + result = g_hash_table_lookup (NM_MANAGER_GET_PRIVATE (manager)->permissions, + GUINT_TO_POINTER (permission)); + return GPOINTER_TO_UINT (result); +} + +NMConnectivityState +nm_manager_get_connectivity (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN); + + return NM_MANAGER_GET_PRIVATE (manager)->connectivity; +} + +NMConnectivityState +nm_manager_check_connectivity (NMManager *manager, + GCancellable *cancellable, + GError **error) +{ + NMManagerPrivate *priv; + guint32 connectivity; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CONNECTIVITY_UNKNOWN); + priv = NM_MANAGER_GET_PRIVATE (manager); + + if (nmdbus_manager_call_check_connectivity_sync (priv->manager_proxy, + &connectivity, + cancellable, error)) + return connectivity; + else { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return NM_CONNECTIVITY_UNKNOWN; + } +} + +static void +check_connectivity_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + guint32 connectivity; + GError *error = NULL; + + if (nmdbus_manager_call_check_connectivity_finish (NMDBUS_MANAGER (object), + &connectivity, + result, &error)) + g_simple_async_result_set_op_res_gssize (simple, connectivity); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_manager_check_connectivity_async (NMManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMManagerPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_MANAGER (manager)); + priv = NM_MANAGER_GET_PRIVATE (manager); + + simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_check_connectivity_async); + nmdbus_manager_call_check_connectivity (priv->manager_proxy, + cancellable, + check_connectivity_cb, simple); +} + +NMConnectivityState +nm_manager_check_connectivity_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_check_connectivity_async), NM_CONNECTIVITY_UNKNOWN); + + simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return NM_CONNECTIVITY_UNKNOWN; + return (NMConnectivityState) g_simple_async_result_get_op_res_gssize (simple); +} + +/****************************************************************/ +/* Devices */ +/****************************************************************/ + +const GPtrArray * +nm_manager_get_devices (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->devices; +} + +NMDevice * +nm_manager_get_device_by_path (NMManager *manager, const char *object_path) +{ + const GPtrArray *devices; + int i; + NMDevice *device = NULL; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + g_return_val_if_fail (object_path, NULL); + + devices = nm_manager_get_devices (manager); + for (i = 0; i < devices->len; i++) { + NMDevice *candidate = g_ptr_array_index (devices, i); + if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), object_path)) { + device = candidate; + break; + } + } + + return device; +} + +NMDevice * +nm_manager_get_device_by_iface (NMManager *manager, const char *iface) +{ + const GPtrArray *devices; + int i; + NMDevice *device = NULL; + + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + g_return_val_if_fail (iface, NULL); + + devices = nm_manager_get_devices (manager); + for (i = 0; i < devices->len; i++) { + NMDevice *candidate = g_ptr_array_index (devices, i); + if (!strcmp (nm_device_get_iface (candidate), iface)) { + device = candidate; + break; + } + } + + return device; +} + +/****************************************************************/ +/* Active Connections */ +/****************************************************************/ + +const GPtrArray * +nm_manager_get_active_connections (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->active_connections; +} + +NMActiveConnection * +nm_manager_get_primary_connection (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->primary_connection; +} + +NMActiveConnection * +nm_manager_get_activating_connection (NMManager *manager) +{ + g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); + + return NM_MANAGER_GET_PRIVATE (manager)->activating_connection; +} + +typedef struct { + NMManager *manager; + GSimpleAsyncResult *simple; + GCancellable *cancellable; + gulong cancelled_id; + char *active_path; + char *new_connection_path; +} ActivateInfo; + +static void active_removed (NMObject *object, NMActiveConnection *active, gpointer user_data); + +static void +activate_info_complete (ActivateInfo *info, + NMActiveConnection *active, + GError *error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); + + g_signal_handlers_disconnect_by_func (info->manager, G_CALLBACK (active_removed), info); + if (active) + g_simple_async_result_set_op_res_gpointer (info->simple, g_object_ref (active), g_object_unref); + else + g_simple_async_result_set_from_error (info->simple, error); + g_simple_async_result_complete (info->simple); + + priv->pending_activations = g_slist_remove (priv->pending_activations, info); + + g_free (info->active_path); + g_free (info->new_connection_path); + g_object_unref (info->simple); + if (info->cancellable) { + if (info->cancelled_id) + g_signal_handler_disconnect (info->cancellable, info->cancelled_id); + g_object_unref (info->cancellable); + } + g_slice_free (ActivateInfo, info); +} + +static NMActiveConnection * +find_active_connection_by_path (NMManager *self, const char *ac_path) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + int i; + + for (i = 0; i < priv->active_connections->len; i++) { + NMActiveConnection *candidate = g_ptr_array_index (priv->active_connections, i); + const char *candidate_path = nm_object_get_path (NM_OBJECT (candidate)); + + if (g_strcmp0 (ac_path, candidate_path) == 0) + return candidate; + } + + return NULL; +} + +static void +recheck_pending_activations (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter, *next; + NMActiveConnection *candidate; + const GPtrArray *devices; + NMDevice *device; + + /* For each pending activation, look for an active connection that has the + * pending activation's object path, where the active connection and its + * device have both updated their properties to point to each other, and + * call the pending connection's callback. + */ + for (iter = priv->pending_activations; iter; iter = next) { + ActivateInfo *info = iter->data; + + next = g_slist_next (iter); + + candidate = find_active_connection_by_path (self, info->active_path); + if (!candidate) + continue; + + /* Check that the AC and device are both ready */ + devices = nm_active_connection_get_devices (candidate); + if (devices->len == 0) + continue; + + if (!NM_IS_VPN_CONNECTION (candidate)) { + device = devices->pdata[0]; + if (nm_device_get_active_connection (device) != candidate) + continue; + } + + activate_info_complete (info, candidate, NULL); + break; + } +} + +static void +activation_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error = NULL; + + if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) + return; + + activate_info_complete (info, NULL, error); + g_clear_error (&error); +} + +static void +active_removed (NMObject *object, NMActiveConnection *active, gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error = NULL; + + if (strcmp (info->active_path, nm_object_get_path (NM_OBJECT (active)))) + return; + + error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_FAILED, + _("Active connection could not be attached to the device")); + activate_info_complete (info, NULL, error); + g_clear_error (&error); +} + +static void +activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error = NULL; + + if (nmdbus_manager_call_activate_connection_finish (NMDBUS_MANAGER (object), + &info->active_path, + result, &error)) { + if (info->cancellable) { + info->cancelled_id = g_signal_connect (info->cancellable, "cancelled", + G_CALLBACK (activation_cancelled), info); + } + + g_signal_connect (info->manager, "active-connection-removed", + G_CALLBACK (active_removed), info); + + recheck_pending_activations (info->manager); + } else { + g_dbus_error_strip_remote_error (error); + activate_info_complete (info, NULL, error); + g_clear_error (&error); + } +} + +void +nm_manager_activate_connection_async (NMManager *manager, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMManagerPrivate *priv; + ActivateInfo *info; + + g_return_if_fail (NM_IS_MANAGER (manager)); + if (device) + g_return_if_fail (NM_IS_DEVICE (device)); + if (connection) + g_return_if_fail (NM_IS_CONNECTION (connection)); + + info = g_slice_new0 (ActivateInfo); + info->manager = manager; + info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_activate_connection_async); + info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + priv = NM_MANAGER_GET_PRIVATE (manager); + priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + + nmdbus_manager_call_activate_connection (priv->manager_proxy, + connection ? nm_connection_get_path (connection) : "/", + device ? nm_object_get_path (NM_OBJECT (device)) : "/", + specific_object ? specific_object : "/", + cancellable, + activate_cb, info); +} + +NMActiveConnection * +nm_manager_activate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_activate_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +add_activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error = NULL; + + if (nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object), + NULL, + &info->active_path, + result, &error)) { + if (info->cancellable) { + info->cancelled_id = g_signal_connect (info->cancellable, "cancelled", + G_CALLBACK (activation_cancelled), info); + } + + g_signal_connect (info->manager, "active-connection-removed", + G_CALLBACK (active_removed), info); + + recheck_pending_activations (info->manager); + } else { + g_dbus_error_strip_remote_error (error); + activate_info_complete (info, NULL, error); + g_clear_error (&error); + } +} + +void +nm_manager_add_and_activate_connection_async (NMManager *manager, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMManagerPrivate *priv; + GVariant *dict = NULL; + ActivateInfo *info; + + g_return_if_fail (NM_IS_MANAGER (manager)); + g_return_if_fail (NM_IS_DEVICE (device)); + if (partial) + g_return_if_fail (NM_IS_CONNECTION (partial)); + + info = g_slice_new0 (ActivateInfo); + info->manager = manager; + info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_add_and_activate_connection_async); + info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + priv = NM_MANAGER_GET_PRIVATE (manager); + priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + + if (partial) + dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); + if (!dict) + dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); + + nmdbus_manager_call_add_and_activate_connection (priv->manager_proxy, + dict, + nm_object_get_path (NM_OBJECT (device)), + specific_object ? specific_object : "/", + cancellable, + add_activate_cb, info); +} + +NMActiveConnection * +nm_manager_add_and_activate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_add_and_activate_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +static void +device_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +{ + NMManager *self = user_data; + + recheck_pending_activations (self); +} + +static void +device_added (NMManager *self, NMDevice *device) +{ + g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION, + G_CALLBACK (device_ac_changed), self); +} + +static void +device_removed (NMManager *self, NMDevice *device) +{ + g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_ac_changed), self); +} + +static void +ac_devices_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +{ + NMManager *self = user_data; + + recheck_pending_activations (self); +} + +static void +active_connection_added (NMManager *self, NMActiveConnection *ac) +{ + g_signal_connect (ac, "notify::" NM_ACTIVE_CONNECTION_DEVICES, + G_CALLBACK (ac_devices_changed), self); + recheck_pending_activations (self); +} + +static void +active_connection_removed (NMManager *self, NMActiveConnection *ac) +{ + g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (ac_devices_changed), self); +} + +static void +object_creation_failed (NMObject *object, const char *failed_path) +{ + NMManager *self = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GError *error; + GSList *iter; + + /* A newly activated connection failed due to some immediate error + * and disappeared from active connection list. Make sure the + * callback gets called. + */ + error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + _("Active connection removed before it was initialized")); + + for (iter = priv->pending_activations; iter; iter = iter->next) { + ActivateInfo *info = iter->data; + + if (g_strcmp0 (failed_path, info->active_path) == 0) { + activate_info_complete (info, NULL, error); + g_error_free (error); + return; + } + } +} + +gboolean +nm_manager_deactivate_connection (NMManager *manager, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error) +{ + const char *path; + gboolean ret; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); + + path = nm_object_get_path (NM_OBJECT (active)); + ret = nmdbus_manager_call_deactivate_connection_sync (NM_MANAGER_GET_PRIVATE (manager)->manager_proxy, + path, + cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +deactivated_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_manager_call_deactivate_connection_finish (NMDBUS_MANAGER (object), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_manager_deactivate_connection_async (NMManager *manager, + NMActiveConnection *active, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + const char *path; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_MANAGER (manager)); + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); + + simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data, + nm_manager_deactivate_connection_async); + + path = nm_object_get_path (NM_OBJECT (active)); + nmdbus_manager_call_deactivate_connection (NM_MANAGER_GET_PRIVATE (manager)->manager_proxy, + path, + cancellable, + deactivated_cb, simple); +} + +gboolean +nm_manager_deactivate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_deactivate_connection_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/****************************************************************/ + +static void +free_devices (NMManager *manager, gboolean in_dispose) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + GPtrArray *devices; + NMDevice *device; + int i; + + if (!priv->devices) + return; + + devices = priv->devices; + + if (in_dispose) + priv->devices = NULL; + else { + priv->devices = g_ptr_array_new (); + + for (i = 0; i < devices->len; i++) { + device = devices->pdata[i]; + g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); + } + } + + g_ptr_array_unref (devices); +} + +static void +free_active_connections (NMManager *manager, gboolean in_dispose) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + GPtrArray *active_connections; + NMActiveConnection *active_connection; + int i; + + if (!priv->active_connections) + return; + + active_connections = priv->active_connections; + if (in_dispose) + priv->active_connections = NULL; + else + priv->active_connections = g_ptr_array_new (); + + for (i = 0; i < active_connections->len; i++) { + active_connection = active_connections->pdata[i]; + g_signal_emit (manager, signals[ACTIVE_CONNECTION_REMOVED], 0, active_connection); + /* Break circular refs */ + g_object_run_dispose (G_OBJECT (active_connection)); + } + g_ptr_array_unref (active_connections); + + if (!in_dispose) + g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); +} + +static void +updated_properties (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMManager *manager = NM_MANAGER (user_data); + GError *error = NULL; + + if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: error reading NMManager properties: %s", __func__, error->message); + g_error_free (error); + } + + _nm_object_queue_notify (NM_OBJECT (manager), NM_MANAGER_NM_RUNNING); +} + +static void +nm_running_changed_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + NMManager *manager = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + + if (!nm_manager_get_nm_running (manager)) { + NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + + priv->state = NM_STATE_UNKNOWN; + priv->startup = FALSE; + _nm_object_queue_notify (NM_OBJECT (manager), NM_MANAGER_NM_RUNNING); + _nm_object_suppress_property_updates (NM_OBJECT (manager), TRUE); + poke_wireless_devices_with_rf_status (manager); + free_devices (manager, FALSE); + free_active_connections (manager, FALSE); + update_permissions (manager, NULL); + priv->wireless_enabled = FALSE; + priv->wireless_hw_enabled = FALSE; + priv->wwan_enabled = FALSE; + priv->wwan_hw_enabled = FALSE; + priv->wimax_enabled = FALSE; + priv->wimax_hw_enabled = FALSE; + g_free (priv->version); + priv->version = NULL; + + /* Clear object cache to ensure bad refcounting by managers doesn't + * keep objects in the cache. + */ + _nm_object_cache_clear (); + } else { + _nm_object_suppress_property_updates (NM_OBJECT (manager), FALSE); + + NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + priv->props_cancellable = g_cancellable_new (); + _nm_object_reload_properties_async (NM_OBJECT (manager), priv->props_cancellable, updated_properties, manager); + + manager_recheck_permissions (priv->manager_proxy, manager); + } +} + +/****************************************************************/ + +static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object); + + g_signal_connect (object, "notify::" NM_OBJECT_NM_RUNNING, + G_CALLBACK (nm_running_changed_cb), NULL); + + g_signal_connect (object, "notify::" NM_MANAGER_WIRELESS_ENABLED, + G_CALLBACK (wireless_enabled_cb), NULL); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMManager *manager = NM_MANAGER (initable); + + if (!nm_manager_parent_initable_iface->init (initable, cancellable, error)) + return FALSE; + + if ( nm_manager_get_nm_running (manager) + && !get_permissions_sync (manager, error)) + return FALSE; + + return TRUE; +} + +typedef struct { + NMManager *manager; + GCancellable *cancellable; + GSimpleAsyncResult *result; +} NMManagerInitData; + +static void +init_async_complete (NMManagerInitData *init_data) +{ + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); + g_slice_free (NMManagerInitData, init_data); +} + +static void +init_async_got_permissions (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMManagerInitData *init_data = user_data; + GVariant *permissions; + + if (nmdbus_manager_call_get_permissions_finish (NMDBUS_MANAGER (object), + &permissions, + result, NULL)) { + update_permissions (init_data->manager, permissions); + g_variant_unref (permissions); + } else + update_permissions (init_data->manager, NULL); + + init_async_complete (init_data); +} + +static void +init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMManagerInitData *init_data = user_data; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (init_data->manager); + GError *error = NULL; + + if (!nm_manager_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error)) { + g_simple_async_result_take_error (init_data->result, error); + init_async_complete (init_data); + return; + } + + if (!nm_manager_get_nm_running (init_data->manager)) { + init_async_complete (init_data); + return; + } + + nmdbus_manager_call_get_permissions (priv->manager_proxy, + init_data->cancellable, + init_async_got_permissions, init_data); +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMManagerInitData *init_data; + + init_data = g_slice_new0 (NMManagerInitData); + init_data->manager = NM_MANAGER (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + + nm_manager_parent_async_initable_iface->init_async (initable, io_priority, cancellable, + init_async_parent_inited, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +static void +dispose (GObject *object) +{ + NMManager *manager = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object); + + if (priv->perm_call_cancellable) { + g_cancellable_cancel (priv->perm_call_cancellable); + g_clear_object (&priv->perm_call_cancellable); + } + + free_devices (manager, TRUE); + free_active_connections (manager, TRUE); + g_clear_object (&priv->primary_connection); + g_clear_object (&priv->activating_connection); + + /* Each activation should hold a ref on @manager, so if we're being disposed, + * there shouldn't be any pending. + */ + g_warn_if_fail (priv->pending_activations == NULL); + + g_hash_table_destroy (priv->permissions); + priv->permissions = NULL; + + G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object); + + g_free (priv->version); + + G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object); + gboolean b; + + switch (prop_id) { + case PROP_NETWORKING_ENABLED: + b = g_value_get_boolean (value); + if (priv->networking_enabled != b) { + nm_manager_networking_set_enabled (NM_MANAGER (object), b, NULL); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WIRELESS_ENABLED: + b = g_value_get_boolean (value); + if (priv->wireless_enabled != b) { + nm_manager_wireless_set_enabled (NM_MANAGER (object), b); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WWAN_ENABLED: + b = g_value_get_boolean (value); + if (priv->wwan_enabled != b) { + nm_manager_wwan_set_enabled (NM_MANAGER (object), b); + /* Let the property value flip when we get the change signal from NM */ + } + break; + case PROP_WIMAX_ENABLED: + b = g_value_get_boolean (value); + if (priv->wimax_enabled != b) { + nm_manager_wimax_set_enabled (NM_MANAGER (object), b); + /* Let the property value flip when we get the change signal from NM */ + } + 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) +{ + NMManager *self = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + switch (prop_id) { + case PROP_VERSION: + g_value_set_string (value, nm_manager_get_version (self)); + break; + case PROP_STATE: + g_value_set_enum (value, nm_manager_get_state (self)); + break; + case PROP_STARTUP: + g_value_set_boolean (value, nm_manager_get_startup (self)); + break; + case PROP_NM_RUNNING: + g_value_set_boolean (value, nm_manager_get_nm_running (self)); + break; + case PROP_NETWORKING_ENABLED: + g_value_set_boolean (value, nm_manager_networking_get_enabled (self)); + break; + case PROP_WIRELESS_ENABLED: + g_value_set_boolean (value, priv->wireless_enabled); + break; + case PROP_WIRELESS_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wireless_hw_enabled); + break; + case PROP_WWAN_ENABLED: + g_value_set_boolean (value, priv->wwan_enabled); + break; + case PROP_WWAN_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wwan_hw_enabled); + break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, priv->wimax_enabled); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wimax_hw_enabled); + break; + case PROP_ACTIVE_CONNECTIONS: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_active_connections (self))); + break; + case PROP_CONNECTIVITY: + g_value_set_enum (value, priv->connectivity); + break; + case PROP_PRIMARY_CONNECTION: + g_value_set_object (value, priv->primary_connection); + break; + case PROP_ACTIVATING_CONNECTION: + g_value_set_object (value, priv->activating_connection); + break; + case PROP_DEVICES: + g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_manager_class_init (NMManagerClass *manager_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (manager_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (manager_class); + + g_type_class_add_private (manager_class, sizeof (NMManagerPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE, NMDBUS_TYPE_MANAGER_PROXY); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + nm_object_class->object_creation_failed = object_creation_failed; + + manager_class->device_added = device_added; + manager_class->device_removed = device_removed; + manager_class->active_connection_added = active_connection_added; + manager_class->active_connection_removed = active_connection_removed; + + /* properties */ + + g_object_class_install_property + (object_class, PROP_VERSION, + g_param_spec_string (NM_MANAGER_VERSION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_CLIENT_STATE, "", "", + NM_TYPE_STATE, + NM_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_STARTUP, + g_param_spec_boolean (NM_MANAGER_STARTUP, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_NM_RUNNING, + g_param_spec_boolean (NM_MANAGER_NM_RUNNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_NETWORKING_ENABLED, + g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WIRELESS_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WIRELESS_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "", + TRUE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WWAN_ENABLED, + g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WWAN_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTIONS, + g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_CONNECTIVITY, + g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "", + NM_TYPE_CONNECTIVITY_STATE, + NM_CONNECTIVITY_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_PRIMARY_CONNECTION, + g_param_spec_object (NM_MANAGER_PRIMARY_CONNECTION, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_ACTIVATING_CONNECTION, + g_param_spec_object (NM_MANAGER_ACTIVATING_CONNECTION, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_MANAGER_DEVICES, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + + signals[DEVICE_ADDED] = + g_signal_new ("device-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, device_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, device_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[ACTIVE_CONNECTION_ADDED] = + g_signal_new ("active-connection-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, active_connection_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[ACTIVE_CONNECTION_REMOVED] = + g_signal_new ("active-connection-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMManagerClass, active_connection_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); + signals[PERMISSION_CHANGED] = + g_signal_new ("permission-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); +} + +static void +nm_manager_initable_iface_init (GInitableIface *iface) +{ + nm_manager_parent_initable_iface = g_type_interface_peek_parent (iface); + + iface->init = init_sync; +} + +static void +nm_manager_async_initable_iface_init (GAsyncInitableIface *iface) +{ + nm_manager_parent_async_initable_iface = g_type_interface_peek_parent (iface); + + iface->init_async = init_async; + iface->init_finish = init_finish; +} diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h new file mode 100644 index 00000000..ca9f7dd6 --- /dev/null +++ b/libnm/nm-manager.h @@ -0,0 +1,170 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef __NM_MANAGER_H__ +#define __NM_MANAGER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_MANAGER (nm_manager_get_type ()) +#define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) +#define NM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MANAGER, NMManagerClass)) +#define NM_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MANAGER)) +#define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MANAGER)) +#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass)) + +#define NM_MANAGER_VERSION "version" +#define NM_MANAGER_STATE "state" +#define NM_MANAGER_STARTUP "startup" +#define NM_MANAGER_NM_RUNNING "nm-running" +#define NM_MANAGER_NETWORKING_ENABLED "networking-enabled" +#define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled" +#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" +#define NM_MANAGER_CONNECTIVITY "connectivity" +#define NM_MANAGER_PRIMARY_CONNECTION "primary-connection" +#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection" +#define NM_MANAGER_DEVICES "devices" + +typedef struct { + NMObject parent; +} NMManager; + +typedef struct { + NMObjectClass parent; + + /* Signals */ + void (*device_added) (NMManager *manager, NMDevice *device); + void (*device_removed) (NMManager *manager, NMDevice *device); + void (*active_connection_added) (NMManager *manager, NMActiveConnection *ac); + void (*active_connection_removed) (NMManager *manager, NMActiveConnection *ac); + void (*permission_changed) (NMManager *manager, + NMClientPermission permission, + NMClientPermissionResult result); +} NMManagerClass; + +GType nm_manager_get_type (void); + +const char *nm_manager_get_version (NMManager *manager); +NMState nm_manager_get_state (NMManager *manager); +gboolean nm_manager_get_startup (NMManager *manager); +gboolean nm_manager_get_nm_running (NMManager *manager); + +gboolean nm_manager_networking_get_enabled (NMManager *manager); +gboolean nm_manager_networking_set_enabled (NMManager *manager, + gboolean enabled, + GError **error); + +gboolean nm_manager_wireless_get_enabled (NMManager *manager); +void nm_manager_wireless_set_enabled (NMManager *manager, gboolean enabled); +gboolean nm_manager_wireless_hardware_get_enabled (NMManager *manager); + +gboolean nm_manager_wwan_get_enabled (NMManager *manager); +void nm_manager_wwan_set_enabled (NMManager *manager, gboolean enabled); +gboolean nm_manager_wwan_hardware_get_enabled (NMManager *manager); + +gboolean nm_manager_wimax_get_enabled (NMManager *manager); +void nm_manager_wimax_set_enabled (NMManager *manager, gboolean enabled); +gboolean nm_manager_wimax_hardware_get_enabled (NMManager *manager); + +gboolean nm_manager_get_logging (NMManager *manager, + char **level, + char **domains, + GError **error); +gboolean nm_manager_set_logging (NMManager *manager, + const char *level, + const char *domains, + GError **error); + +NMClientPermissionResult nm_manager_get_permission_result (NMManager *manager, + NMClientPermission permission); + +NMConnectivityState nm_manager_get_connectivity (NMManager *manager); + +NMConnectivityState nm_manager_check_connectivity (NMManager *manager, + GCancellable *cancellable, + GError **error); +void nm_manager_check_connectivity_async (NMManager *manager, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMConnectivityState nm_manager_check_connectivity_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + +/* Devices */ + +const GPtrArray *nm_manager_get_devices (NMManager *manager); +NMDevice *nm_manager_get_device_by_path (NMManager *manager, const char *object_path); +NMDevice *nm_manager_get_device_by_iface (NMManager *manager, const char *iface); + +/* Active Connections */ + +const GPtrArray *nm_manager_get_active_connections (NMManager *manager); + +NMActiveConnection *nm_manager_get_primary_connection (NMManager *manager); +NMActiveConnection *nm_manager_get_activating_connection (NMManager *manager); + +void nm_manager_activate_connection_async (NMManager *manager, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_manager_activate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + +void nm_manager_add_and_activate_connection_async (NMManager *manager, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_manager_add_and_activate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + +gboolean nm_manager_deactivate_connection (NMManager *manager, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error); +void nm_manager_deactivate_connection_async (NMManager *manager, + NMActiveConnection *active, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_manager_deactivate_connection_finish (NMManager *manager, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __NM_MANAGER_H__ */ diff --git a/libnm/nm-object-cache.c b/libnm/nm-object-cache.c new file mode 100644 index 00000000..752c606a --- /dev/null +++ b/libnm/nm-object-cache.c @@ -0,0 +1,90 @@ +/* -*- 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. + * + * Copyright 2008 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include "nm-object-cache.h" +#include "nm-object.h" + +static GHashTable *cache = NULL; + +static void +_init_cache (void) +{ + if (G_UNLIKELY (cache == NULL)) + cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +} + +static void +_nm_object_cache_remove_by_path (char *path) +{ + _init_cache (); + g_hash_table_remove (cache, path); + g_free (path); +} + +void +_nm_object_cache_add (NMObject *object) +{ + char *path; + + _init_cache (); + path = g_strdup (nm_object_get_path (object)); + g_hash_table_insert (cache, path, object); + g_object_set_data_full (G_OBJECT (object), "nm-object-cache-tag", + g_strdup (path), (GDestroyNotify) _nm_object_cache_remove_by_path); +} + +NMObject * +_nm_object_cache_get (const char *path) +{ + NMObject *object; + + _init_cache (); + object = g_hash_table_lookup (cache, path); + return object ? g_object_ref (object) : NULL; +} + +void +_nm_object_cache_clear (void) +{ + GHashTableIter iter; + GObject *obj; + const char *path; + char *foo; + + if (!cache) + return; + + g_hash_table_iter_init (&iter, cache); + while (g_hash_table_iter_next (&iter, (gpointer) &path, (gpointer) &obj)) { + /* Remove the callback so that if the object isn't yet released + * by a client, when it does finally get unrefed, it won't trigger + * the cache removal for a new object with the same path as the + * one being released. + */ + foo = g_object_steal_data (obj, "nm-object-cache-tag"); + g_free (foo); + + g_hash_table_iter_remove (&iter); + } +} diff --git a/libnm/nm-object-cache.h b/libnm/nm-object-cache.h new file mode 100644 index 00000000..ebadbaa8 --- /dev/null +++ b/libnm/nm-object-cache.h @@ -0,0 +1,37 @@ +/* -*- 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. + * + * Copyright 2008 Red Hat, Inc. + */ + +#ifndef __NM_OBJECT_CACHE_H__ +#define __NM_OBJECT_CACHE_H__ + +#include +#include +#include "nm-object.h" + +G_BEGIN_DECLS + +/* Returns referenced object from the cache */ +NMObject *_nm_object_cache_get (const char *path); +void _nm_object_cache_add (NMObject *object); +void _nm_object_cache_clear (void); + +G_END_DECLS + +#endif /* __NM_OBJECT_CACHE_H__ */ diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h new file mode 100644 index 00000000..0b13cbb6 --- /dev/null +++ b/libnm/nm-object-private.h @@ -0,0 +1,83 @@ +/* -*- 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. + * + * Copyright 2008 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_OBJECT_PRIVATE_H__ +#define __NM_OBJECT_PRIVATE_H__ + +#include +#include "nm-object.h" + +typedef gboolean (*PropertyMarshalFunc) (NMObject *, GParamSpec *, GVariant *, gpointer); + +typedef GObject * (*NMObjectCreatorFunc) (GDBusConnection *, const char *); + +typedef struct { + const char *name; + gpointer field; + PropertyMarshalFunc func; + GType object_type; + const char *signal_prefix; +} NMPropertiesInfo; + +void _nm_object_register_properties (NMObject *object, + const char *interface, + const NMPropertiesInfo *info); + +void _nm_object_reload_properties_async (NMObject *object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean _nm_object_reload_properties_finish (NMObject *object, + GAsyncResult *result, + GError **error); + +void _nm_object_queue_notify (NMObject *object, const char *property); + +void _nm_object_suppress_property_updates (NMObject *object, gboolean suppress); + +/* DBus property accessors */ + +void _nm_object_reload_property (NMObject *object, + const char *interface, + const char *prop_name); + +void _nm_object_set_property (NMObject *object, + const char *interface, + const char *prop_name, + const char *format_string, + ...); + +/* object demarshalling support */ +typedef GType (*NMObjectDecideTypeFunc) (GVariant *); + +void _nm_object_register_type_func (GType base_type, + NMObjectDecideTypeFunc type_func, + const char *interface, + const char *property); + +#define NM_OBJECT_NM_RUNNING "nm-running-internal" +gboolean _nm_object_get_nm_running (NMObject *self); + +void _nm_object_class_add_interface (NMObjectClass *object_class, + const char *interface); +GDBusProxy *_nm_object_get_proxy (NMObject *object, + const char *interface); + +#endif /* __NM_OBJECT_PRIVATE_H__ */ diff --git a/libnm/nm-object.c b/libnm/nm-object.c new file mode 100644 index 00000000..391166b2 --- /dev/null +++ b/libnm/nm-object.c @@ -0,0 +1,1761 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include "nm-dbus-interface.h" +#include "nm-object.h" +#include "nm-object-cache.h" +#include "nm-object-private.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" +#include "nm-client.h" + +static gboolean debug = FALSE; +#define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); } + +static void nm_object_initable_iface_init (GInitableIface *iface); +static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface); + +typedef struct { + NMObjectDecideTypeFunc type_func; + char *interface; + char *property; +} NMObjectTypeFuncData; + +static GHashTable *type_funcs; + +typedef struct { + GSList *interfaces; +} NMObjectClassPrivate; + +#define NM_OBJECT_CLASS_GET_PRIVATE(k) (G_TYPE_CLASS_GET_PRIVATE ((k), NM_TYPE_OBJECT, NMObjectClassPrivate)) + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT, + type_funcs = g_hash_table_new (NULL, NULL); + g_type_add_class_private (g_define_type_id, sizeof (NMObjectClassPrivate)); + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init); + ) + +#define NM_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OBJECT, NMObjectPrivate)) + +typedef struct { + PropertyMarshalFunc func; + GType object_type; + gpointer field; + const char *signal_prefix; +} PropertyInfo; + +static void reload_complete (NMObject *object, gboolean emit_now); +static gboolean demarshal_generic (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field); + +typedef struct { + GDBusConnection *connection; + gboolean nm_running; + + char *path; + GHashTable *proxies; + GDBusProxy *properties_proxy; + GSList *property_tables; + NMObject *parent; + gboolean suppress_property_updates; + + GSList *notify_items; + guint32 notify_id; + + GSList *reload_results; + guint reload_remaining; + GError *reload_error; +} NMObjectPrivate; + +enum { + PROP_0, + PROP_PATH, + PROP_DBUS_CONNECTION, + PROP_NM_RUNNING, + + LAST_PROP +}; + +/** + * _nm_object_class_add_interface: + * @object_class: an #NMObjectClass + * @interface: a D-Bus interface name + * + * Registers that @object_class implements @interface. A proxy for that + * interface will automatically be created at construction time, and can + * be retrieved with _nm_object_get_proxy(). + */ +void +_nm_object_class_add_interface (NMObjectClass *object_class, + const char *interface) +{ + NMObjectClassPrivate *cpriv; + + g_return_if_fail (NM_IS_OBJECT_CLASS (object_class)); + g_return_if_fail (interface); + + cpriv = NM_OBJECT_CLASS_GET_PRIVATE (object_class); + + g_return_if_fail (g_slist_find_custom (cpriv->interfaces, interface, (GCompareFunc) g_strcmp0) == NULL); + + cpriv->interfaces = g_slist_prepend (cpriv->interfaces, g_strdup (interface)); +} + +/** + * nm_object_get_path: + * @object: a #NMObject + * + * Gets the DBus path of the #NMObject. + * + * Returns: the object's path. This is the internal string used by the + * device, and must not be modified. + **/ +const char * +nm_object_get_path (NMObject *object) +{ + g_return_val_if_fail (NM_IS_OBJECT (object), NULL); + + return NM_OBJECT_GET_PRIVATE (object)->path; +} + +/** + * _nm_object_get_proxy: + * @object: an #NMObject + * @interface: a D-Bus interface implemented by @object + * + * Gets the D-Bus proxy for @interface on @object. + * + * Returns: (transfer none): a D-Bus proxy + */ +GDBusProxy * +_nm_object_get_proxy (NMObject *object, + const char *interface) +{ + GDBusProxy *proxy; + + g_return_val_if_fail (NM_IS_OBJECT (object), NULL); + + proxy = g_hash_table_lookup (NM_OBJECT_GET_PRIVATE (object)->proxies, interface); + g_return_val_if_fail (proxy != NULL, NULL); + return proxy; +} + +typedef enum { + NOTIFY_SIGNAL_PENDING_NONE, + NOTIFY_SIGNAL_PENDING_ADDED, + NOTIFY_SIGNAL_PENDING_REMOVED, + NOTIFY_SIGNAL_PENDING_ADDED_REMOVED, +} NotifySignalPending; + +typedef struct { + const char *property; + const char *signal_prefix; + NotifySignalPending pending; + NMObject *changed; +} NotifyItem; + +static void +notify_item_free (NotifyItem *item) +{ + g_clear_object (&item->changed); + g_slice_free (NotifyItem, item); +} + +static gboolean +deferred_notify_cb (gpointer data) +{ + NMObject *object = NM_OBJECT (data); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + NMObjectClass *object_class = NM_OBJECT_GET_CLASS (object); + GSList *props, *iter; + + priv->notify_id = 0; + + /* Wait until all reloads are done before notifying */ + if (priv->reload_remaining) + return G_SOURCE_REMOVE; + + /* Clear priv->notify_items early so that an NMObject subclass that + * listens to property changes can queue up other property changes + * during the g_object_notify() call separately from the property + * list we're iterating. + */ + props = g_slist_reverse (priv->notify_items); + priv->notify_items = NULL; + + g_object_ref (object); + + /* Emit added/removed signals first since some of our internal objects + * use the added/removed signals for new object processing. + */ + for (iter = props; iter; iter = g_slist_next (iter)) { + NotifyItem *item = iter->data; + char buf[50]; + gint ret = 0; + + switch (item->pending) { + case NOTIFY_SIGNAL_PENDING_ADDED: + ret = g_snprintf (buf, sizeof (buf), "%s-added", item->signal_prefix); + break; + case NOTIFY_SIGNAL_PENDING_REMOVED: + ret = g_snprintf (buf, sizeof (buf), "%s-removed", item->signal_prefix); + break; + case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED: + if (object_class->object_creation_failed) + object_class->object_creation_failed (object, nm_object_get_path (item->changed)); + break; + case NOTIFY_SIGNAL_PENDING_NONE: + default: + break; + } + if (ret > 0) { + g_assert (ret < sizeof (buf)); + g_signal_emit_by_name (object, buf, item->changed); + } + } + + /* Emit property change notifications second */ + for (iter = props; iter; iter = g_slist_next (iter)) { + NotifyItem *item = iter->data; + + if (item->property) + g_object_notify (G_OBJECT (object), item->property); + } + + g_object_unref (object); + + g_slist_free_full (props, (GDestroyNotify) notify_item_free); + return G_SOURCE_REMOVE; +} + +static void +_nm_object_defer_notify (NMObject *object) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + if (!priv->notify_id) + priv->notify_id = g_idle_add_full (G_PRIORITY_LOW, deferred_notify_cb, object, NULL); +} + +static void +_nm_object_queue_notify_full (NMObject *object, + const char *property, + const char *signal_prefix, + gboolean added, + NMObject *changed) +{ + NMObjectPrivate *priv; + NotifyItem *item; + GSList *iter; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (!signal_prefix != !property); + g_return_if_fail (!signal_prefix == !changed); + + priv = NM_OBJECT_GET_PRIVATE (object); + _nm_object_defer_notify (object); + + property = g_intern_string (property); + signal_prefix = g_intern_string (signal_prefix); + for (iter = priv->notify_items; iter; iter = g_slist_next (iter)) { + item = iter->data; + + if (property && (property == item->property)) + return; + + /* Collapse signals for the same object (such as "added->removed") to + * ensure we don't emit signals when their sum should have no effect. + * The "added->removed->removed" sequence requires special handling, + * hence the addition of the ADDED_REMOVED state to ensure that no + * signal is emitted in this case: + * + * Without the ADDED_REMOVED state: + * NONE + added -> ADDED + * ADDED + removed -> NONE + * NONE + removed -> REMOVED (would emit 'removed' signal) + * + * With the ADDED_REMOVED state: + * NONE | ADDED_REMOVED + added -> ADDED + * ADDED + removed -> ADDED_REMOVED + * ADDED_REMOVED + removed -> ADDED_REMOVED (emits no signal) + */ + if (signal_prefix && (changed == item->changed) && (item->signal_prefix == signal_prefix)) { + switch (item->pending) { + case NOTIFY_SIGNAL_PENDING_ADDED: + if (!added) + item->pending = NOTIFY_SIGNAL_PENDING_ADDED_REMOVED; + break; + case NOTIFY_SIGNAL_PENDING_REMOVED: + if (added) + item->pending = NOTIFY_SIGNAL_PENDING_NONE; + break; + case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED: + if (added) + item->pending = NOTIFY_SIGNAL_PENDING_ADDED; + break; + case NOTIFY_SIGNAL_PENDING_NONE: + item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED; + break; + default: + g_assert_not_reached (); + } + return; + } + } + + item = g_slice_new0 (NotifyItem); + item->property = property; + if (signal_prefix) { + item->signal_prefix = signal_prefix; + item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED; + item->changed = changed ? g_object_ref (changed) : NULL; + } + priv->notify_items = g_slist_prepend (priv->notify_items, item); +} + +void +_nm_object_queue_notify (NMObject *object, const char *property) +{ + _nm_object_queue_notify_full (object, property, NULL, FALSE, NULL); +} + +void +_nm_object_register_type_func (GType base_type, + NMObjectDecideTypeFunc type_func, + const char *interface, + const char *property) +{ + NMObjectTypeFuncData *type_data; + + g_return_if_fail (type_func != NULL); + g_return_if_fail (interface != NULL); + g_return_if_fail (property != NULL); + + type_data = g_slice_new (NMObjectTypeFuncData); + type_data->type_func = type_func; + type_data->interface = g_strdup (interface); + type_data->property = g_strdup (property); + + g_hash_table_insert (type_funcs, + GSIZE_TO_POINTER (base_type), + type_data); +} + +static GObject * +_nm_object_create (GType type, GDBusConnection *connection, const char *path) +{ + NMObjectTypeFuncData *type_data; + GObject *object; + GError *error = NULL; + + type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); + if (type_data) { + GDBusProxy *proxy; + GVariant *ret, *value; + + proxy = _nm_dbus_new_proxy_for_connection (connection, path, + DBUS_INTERFACE_PROPERTIES, + NULL, &error); + if (!proxy) { + g_warning ("Could not create proxy for %s: %s.", path, error->message); + g_error_free (error); + return NULL; + } + + ret = g_dbus_proxy_call_sync (proxy, + "Get", + g_variant_new ("(ss)", + type_data->interface, + type_data->property), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + g_object_unref (proxy); + if (!ret) { + dbgmsg ("Could not fetch property '%s' of interface '%s' on %s: %s\n", + type_data->property, type_data->interface, path, error->message); + g_error_free (error); + return NULL; + } + + g_variant_get (ret, "(v)", &value); + type = type_data->type_func (value); + g_variant_unref (value); + g_variant_unref (ret); + } + + if (type == G_TYPE_INVALID) { + dbgmsg ("Could not create object for %s: unknown object type", path); + return NULL; + } + + object = g_object_new (type, + NM_OBJECT_PATH, path, + NM_OBJECT_DBUS_CONNECTION, connection, + NULL); + /* Cache the object before initializing it (and in particular, loading its + * property values); this is necessary to make circular references work (eg, + * when creating an NMActiveConnection, it will create an NMDevice which + * will in turn try to create the parent NMActiveConnection). Since we don't + * support multi-threaded use, we know that we will have inited the object + * before any external code sees it. + */ + _nm_object_cache_add (NM_OBJECT (object)); + if (!g_initable_init (G_INITABLE (object), NULL, &error)) { + dbgmsg ("Could not create object for %s: %s", path, error->message); + g_error_free (error); + g_clear_object (&object); + } + + return object; +} + +typedef void (*NMObjectCreateCallbackFunc) (GObject *, const char *, gpointer); +typedef struct { + char *path; + NMObjectCreateCallbackFunc callback; + gpointer user_data; + NMObjectTypeFuncData *type_data; + GDBusConnection *connection; +} NMObjectTypeAsyncData; + +static void +create_async_complete (GObject *object, NMObjectTypeAsyncData *async_data) +{ + async_data->callback (object, async_data->path, async_data->user_data); + + g_free (async_data->path); + g_object_unref (async_data->connection); + g_slice_free (NMObjectTypeAsyncData, async_data); +} + +static void +create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data = user_data; + GError *error = NULL; + + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) { + dbgmsg ("Could not create object for %s: %s", + nm_object_get_path (NM_OBJECT (object)), + error->message); + g_error_free (error); + g_clear_object (&object); + } + + create_async_complete (object, async_data); +} + +static void +create_async_got_type (NMObjectTypeAsyncData *async_data, GType type) +{ + GObject *object; + + /* Ensure we don't have the object already; we may get multiple type + * requests for the same object if there are multiple properties on + * other objects that refer to the object at this path. One of those + * other requests may have already completed. + */ + object = (GObject *) _nm_object_cache_get (async_data->path); + if (object) { + create_async_complete (object, async_data); + return; + } + + if (type == G_TYPE_INVALID) { + /* Don't know how to create this object */ + create_async_complete (NULL, async_data); + return; + } + + object = g_object_new (type, + NM_OBJECT_PATH, async_data->path, + NM_OBJECT_DBUS_CONNECTION, async_data->connection, + NULL); + _nm_object_cache_add (NM_OBJECT (object)); + g_async_initable_init_async (G_ASYNC_INITABLE (object), G_PRIORITY_DEFAULT, + NULL, create_async_inited, async_data); +} + +static void +create_async_got_property (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data = user_data; + NMObjectTypeFuncData *type_data = async_data->type_data; + GVariant *ret, *value; + GError *error = NULL; + GType type; + + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + if (ret) { + g_variant_get (ret, "(v)", &value); + type = type_data->type_func (value); + g_variant_unref (value); + g_variant_unref (ret); + } else { + dbgmsg ("Could not fetch property '%s' of interface '%s' on %s: %s\n", + type_data->property, type_data->interface, async_data->path, + error->message); + g_clear_error (&error); + type = G_TYPE_INVALID; + } + + create_async_got_type (async_data, type); +} + +static void +create_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data = user_data; + GDBusProxy *proxy; + GError *error = NULL; + + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error); + if (!proxy) { + g_warning ("Could not create proxy for %s: %s.", async_data->path, error->message); + g_error_free (error); + create_async_complete (NULL, async_data); + return; + } + + g_dbus_proxy_call (proxy, + "Get", + g_variant_new ("(ss)", + async_data->type_data->interface, + async_data->type_data->property), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + create_async_got_property, async_data); +} + +static void +_nm_object_create_async (GType type, GDBusConnection *connection, const char *path, + NMObjectCreateCallbackFunc callback, gpointer user_data) +{ + NMObjectTypeAsyncData *async_data; + + async_data = g_slice_new (NMObjectTypeAsyncData); + async_data->path = g_strdup (path); + async_data->callback = callback; + async_data->user_data = user_data; + async_data->connection = g_object_ref (connection); + + async_data->type_data = g_hash_table_lookup (type_funcs, GSIZE_TO_POINTER (type)); + if (async_data->type_data) { + _nm_dbus_new_proxy_for_connection_async (connection, path, + DBUS_INTERFACE_PROPERTIES, + NULL, + create_async_got_proxy, async_data); + return; + } + + create_async_got_type (async_data, type); +} + +/* Stolen from dbus-glib */ +static char* +wincaps_to_dash (const char *caps) +{ + const char *p; + GString *str; + + str = g_string_new (NULL); + p = caps; + while (*p) { + if (g_ascii_isupper (*p)) { + if (str->len > 0 && (str->len < 2 || str->str[str->len-2] != '-')) + g_string_append_c (str, '-'); + g_string_append_c (str, g_ascii_tolower (*p)); + } else + g_string_append_c (str, *p); + ++p; + } + + return g_string_free (str, FALSE); +} + +/* Adds object to array if it's not already there */ +static void +add_to_object_array_unique (GPtrArray *array, GObject *obj) +{ + guint i; + + g_return_if_fail (array != NULL); + + if (obj != NULL) { + for (i = 0; i < array->len; i++) { + if (g_ptr_array_index (array, i) == obj) { + g_object_unref (obj); + return; + } + } + g_ptr_array_add (array, obj); + } +} + +typedef struct { + NMObject *self; + PropertyInfo *pi; + + GObject **objects; + int length, remaining; + + gboolean array; + const char *property_name; +} ObjectCreatedData; + +/* Places items from 'needles' that are not in 'haystack' into 'diff' */ +static void +array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff) +{ + guint i, j; + GObject *obj; + + g_assert (needles); + g_assert (haystack); + g_assert (diff); + + for (i = 0; i < needles->len; i++) { + obj = g_ptr_array_index (needles, i); + + for (j = 0; j < haystack->len; j++) { + if (g_ptr_array_index (haystack, j) == obj) + break; + } + + if (j == haystack->len) + g_ptr_array_add (diff, obj); + } +} + +static void +queue_added_removed_signal (NMObject *self, + const char *signal_prefix, + NMObject *changed, + gboolean added) +{ + _nm_object_queue_notify_full (self, NULL, signal_prefix, added, changed); +} + +static void +object_property_complete (ObjectCreatedData *odata) +{ + NMObject *self = odata->self; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + PropertyInfo *pi = odata->pi; + gboolean different = TRUE; + + if (odata->array) { + GPtrArray *old = *((GPtrArray **) pi->field); + GPtrArray *new; + int i; + + /* Build up new array */ + new = g_ptr_array_new_full (odata->length, g_object_unref); + for (i = 0; i < odata->length; i++) + add_to_object_array_unique (new, odata->objects[i]); + + if (pi->signal_prefix) { + GPtrArray *added = g_ptr_array_sized_new (3); + GPtrArray *removed = g_ptr_array_sized_new (3); + + if (old) { + /* Find objects in 'old' that do not exist in 'new' */ + array_diff (old, new, removed); + + /* Find objects in 'new' that do not exist in old */ + array_diff (new, old, added); + } else { + for (i = 0; i < new->len; i++) + g_ptr_array_add (added, g_ptr_array_index (new, i)); + } + + *((GPtrArray **) pi->field) = new; + + /* Emit added & removed */ + for (i = 0; i < removed->len; i++) { + queue_added_removed_signal (self, + pi->signal_prefix, + g_ptr_array_index (removed, i), + FALSE); + } + + for (i = 0; i < added->len; i++) { + queue_added_removed_signal (self, + pi->signal_prefix, + g_ptr_array_index (added, i), + TRUE); + } + + different = removed->len || added->len; + g_ptr_array_unref (added); + g_ptr_array_unref (removed); + } else { + /* No added/removed signals to send, just replace the property with + * the new values. + */ + *((GPtrArray **) pi->field) = new; + different = TRUE; + } + + /* Free old array last since it will release references, thus freeing + * any objects in the 'removed' array. + */ + if (old) + g_ptr_array_unref (old); + } else { + GObject **obj_p = pi->field; + + different = (*obj_p != odata->objects[0]); + if (*obj_p) + g_object_unref (*obj_p); + *obj_p = odata->objects[0]; + } + + if (different && odata->property_name) + _nm_object_queue_notify (self, odata->property_name); + + if (--priv->reload_remaining == 0) + reload_complete (self, FALSE); + + g_object_unref (self); + g_free (odata->objects); + g_slice_free (ObjectCreatedData, odata); +} + +static void +object_created (GObject *obj, const char *path, gpointer user_data) +{ + ObjectCreatedData *odata = user_data; + + /* We assume that on error, the creator_func printed something */ + + if (obj == NULL && g_strcmp0 (path, "/") != 0 ) { + NMObjectClass *object_class = NM_OBJECT_GET_CLASS (odata->self); + + if (object_class->object_creation_failed) + object_class->object_creation_failed (odata->self, path); + } + + odata->objects[--odata->remaining] = obj; + if (!odata->remaining) + object_property_complete (odata); +} + +static gboolean +handle_object_property (NMObject *self, const char *property_name, GVariant *value, + PropertyInfo *pi, gboolean synchronously) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GObject *obj; + const char *path; + ObjectCreatedData *odata; + + odata = g_slice_new (ObjectCreatedData); + odata->self = g_object_ref (self); + odata->pi = pi; + odata->objects = g_new (GObject *, 1); + odata->length = odata->remaining = 1; + odata->array = FALSE; + odata->property_name = property_name; + + priv->reload_remaining++; + + path = g_variant_get_string (value, NULL); + + if (!strcmp (path, "/")) { + object_created (NULL, path, odata); + return TRUE; + } + + obj = G_OBJECT (_nm_object_cache_get (path)); + if (obj) { + object_created (obj, path, odata); + return TRUE; + } else if (synchronously) { + obj = _nm_object_create (pi->object_type, priv->connection, path); + object_created (obj, path, odata); + return obj != NULL; + } else { + _nm_object_create_async (pi->object_type, priv->connection, path, + object_created, odata); + /* Assume success */ + return TRUE; + } +} + +static gboolean +handle_object_array_property (NMObject *self, const char *property_name, GVariant *value, + PropertyInfo *pi, gboolean synchronously) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GObject *obj; + GVariantIter iter; + gsize npaths; + GPtrArray **array = pi->field; + const char *path; + ObjectCreatedData *odata; + + npaths = g_variant_n_children (value); + + odata = g_slice_new (ObjectCreatedData); + odata->self = g_object_ref (self); + odata->pi = pi; + odata->objects = g_new0 (GObject *, npaths); + odata->length = odata->remaining = npaths; + odata->array = TRUE; + odata->property_name = property_name; + + priv->reload_remaining++; + + if (npaths == 0) { + object_property_complete (odata); + return TRUE; + } + + g_variant_iter_init (&iter, value); + while (g_variant_iter_next (&iter, "&o", &path)) { + if (!strcmp (path, "/")) { + /* FIXME: can't happen? */ + continue; + } + + obj = G_OBJECT (_nm_object_cache_get (path)); + if (obj) { + object_created (obj, path, odata); + } else if (synchronously) { + obj = _nm_object_create (pi->object_type, priv->connection, path); + object_created (obj, path, odata); + } else { + _nm_object_create_async (pi->object_type, priv->connection, path, + object_created, odata); + } + } + + if (!synchronously) { + /* Assume success */ + return TRUE; + } + + return *array && ((*array)->len == npaths); +} + +static void +handle_property_changed (NMObject *self, const char *dbus_name, + GVariant *value, gboolean synchronously) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + char *prop_name; + PropertyInfo *pi; + GParamSpec *pspec; + gboolean success = FALSE, found = FALSE; + GSList *iter; + + prop_name = wincaps_to_dash (dbus_name); + + /* Iterate through the object and its parents to find the property */ + for (iter = priv->property_tables; iter; iter = g_slist_next (iter)) { + pi = g_hash_table_lookup ((GHashTable *) iter->data, prop_name); + if (pi) { + if (!pi->field) { + /* We know about this property but aren't tracking changes on it. */ + goto out; + } + + found = TRUE; + break; + } + } + + if (!found) { + dbgmsg ("Property '%s' unhandled.", prop_name); + goto out; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name); + if (!pspec && pi->func == demarshal_generic) { + dbgmsg ("%s: property '%s' changed but wasn't defined by object type %s.", + __func__, + prop_name, + G_OBJECT_TYPE_NAME (self)); + goto out; + } + + if (G_UNLIKELY (debug)) { + char *s; + s = g_variant_print (value, FALSE); + dbgmsg ("PC: (%p) %s:%s => '%s' (%s%s%s)", + self, G_OBJECT_TYPE_NAME (self), + prop_name, + s, + g_variant_get_type_string (value), + pi->object_type ? " / " : "", + pi->object_type ? g_type_name (pi->object_type) : ""); + g_free (s); + } + + if (pspec && pi->object_type) { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) + success = handle_object_property (self, pspec->name, value, pi, synchronously); + else if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao"))) + success = handle_object_array_property (self, pspec->name, value, pi, synchronously); + else { + g_warn_if_reached (); + goto out; + } + } else + success = (*(pi->func)) (self, pspec, value, pi->field); + + if (!success) { + dbgmsg ("%s: failed to update property '%s' of object type %s.", + __func__, + prop_name, + G_OBJECT_TYPE_NAME (self)); + } + +out: + g_free (prop_name); +} + +static void +process_properties_changed (NMObject *self, GVariant *properties, gboolean synchronously) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GVariantIter iter; + const char *name; + GVariant *value; + + if (priv->suppress_property_updates) + return; + + g_variant_iter_init (&iter, properties); + while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) + handle_property_changed (self, name, value, synchronously); +} + +static void +property_proxy_signal (GDBusProxy *proxy, + const char *sender_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GVariant *properties; + + if (strcmp (signal_name, "PropertiesChanged") != 0) + return; + + g_variant_get (parameters, "(@a{sv})", &properties); + process_properties_changed (NM_OBJECT (user_data), properties, FALSE); + g_variant_unref (properties); +} + +#define HANDLE_TYPE(vtype, ctype, getter) \ + G_STMT_START { \ + if (g_variant_is_of_type (value, vtype)) { \ + ctype *param = (ctype *) field; \ + *param = getter (value); \ + } else { \ + success = FALSE; \ + goto done; \ + } \ + } G_STMT_END + +static gboolean +demarshal_generic (NMObject *object, + GParamSpec *pspec, + GVariant *value, + gpointer field) +{ + gboolean success = TRUE; + + if (pspec->value_type == G_TYPE_STRING) { + if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) { + char **param = (char **) field; + g_free (*param); + *param = g_variant_dup_string (value, NULL); + } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) { + char **param = (char **) field; + g_free (*param); + *param = g_variant_dup_string (value, NULL); + /* Handle "NULL" object paths */ + if (g_strcmp0 (*param, "/") == 0) { + g_free (*param); + *param = NULL; + } + } else { + success = FALSE; + goto done; + } + } else if (pspec->value_type == G_TYPE_STRV) { + char ***param = (char ***)field; + if (*param) + g_strfreev (*param); + *param = g_variant_dup_strv (value, NULL); + } else if (pspec->value_type == G_TYPE_BYTES) { + GBytes **param = (GBytes **)field; + gconstpointer val; + gsize length; + + if (*param) + g_bytes_unref (*param); + val = g_variant_get_fixed_array (value, &length, 1); + if (length) + *param = g_bytes_new (val, length); + else + *param = NULL; + } else if (G_IS_PARAM_SPEC_ENUM (pspec)) { + int *param = (int *) field; + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) + *param = g_variant_get_int32 (value); + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)) + *param = g_variant_get_uint32 (value); + else { + success = FALSE; + goto done; + } + } else if (G_IS_PARAM_SPEC_FLAGS (pspec)) { + guint *param = (guint *) field; + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) + *param = g_variant_get_int32 (value); + else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)) + *param = g_variant_get_uint32 (value); + else { + success = FALSE; + goto done; + } + } else if (pspec->value_type == G_TYPE_BOOLEAN) + HANDLE_TYPE (G_VARIANT_TYPE_BOOLEAN, gboolean, g_variant_get_boolean); + else if (pspec->value_type == G_TYPE_UCHAR) + HANDLE_TYPE (G_VARIANT_TYPE_BYTE, guchar, g_variant_get_byte); + else if (pspec->value_type == G_TYPE_DOUBLE) + HANDLE_TYPE (G_VARIANT_TYPE_DOUBLE, gdouble, g_variant_get_double); + else if (pspec->value_type == G_TYPE_INT) + HANDLE_TYPE (G_VARIANT_TYPE_INT32, gint, g_variant_get_int32); + else if (pspec->value_type == G_TYPE_UINT) + HANDLE_TYPE (G_VARIANT_TYPE_UINT32, guint, g_variant_get_uint32); + else if (pspec->value_type == G_TYPE_INT64) + HANDLE_TYPE (G_VARIANT_TYPE_INT64, gint, g_variant_get_int64); + else if (pspec->value_type == G_TYPE_UINT64) + HANDLE_TYPE (G_VARIANT_TYPE_UINT64, guint, g_variant_get_uint64); + else if (pspec->value_type == G_TYPE_LONG) + HANDLE_TYPE (G_VARIANT_TYPE_INT64, glong, g_variant_get_int64); + else if (pspec->value_type == G_TYPE_ULONG) + HANDLE_TYPE (G_VARIANT_TYPE_UINT64, gulong, g_variant_get_uint64); + else { + g_warning ("%s: %s:%s unhandled type %s.", + __func__, + G_OBJECT_TYPE_NAME (object), + pspec->name, + g_type_name (pspec->value_type)); + success = FALSE; + } + +done: + if (success) { + _nm_object_queue_notify (object, pspec->name); + } else { + dbgmsg ("%s: %s:%s (type %s) couldn't be set from D-Bus type %s.", + __func__, G_OBJECT_TYPE_NAME (object), pspec->name, + g_type_name (pspec->value_type), g_variant_get_type_string (value)); + } + return success; +} + +void +_nm_object_register_properties (NMObject *object, + const char *interface, + const NMPropertiesInfo *info) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GDBusProxy *proxy; + static gsize dval = 0; + const char *debugstr; + NMPropertiesInfo *tmp; + GHashTable *instance; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (interface != NULL); + g_return_if_fail (info != NULL); + + if (g_once_init_enter (&dval)) { + debugstr = getenv ("LIBNM_GLIB_DEBUG"); + if (debugstr && strstr (debugstr, "properties-changed")) + debug = TRUE; + g_once_init_leave (&dval, 1); + } + + proxy = _nm_object_get_proxy (object, interface); + g_return_if_fail (proxy != NULL); + + g_signal_connect (proxy, "g-signal", + G_CALLBACK (property_proxy_signal), object); + + instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->property_tables = g_slist_prepend (priv->property_tables, instance); + + for (tmp = (NMPropertiesInfo *) info; tmp->name; tmp++) { + PropertyInfo *pi; + + if (!tmp->name || (tmp->func && !tmp->field)) { + g_warning ("%s: missing field in NMPropertiesInfo", __func__); + continue; + } + + pi = g_malloc0 (sizeof (PropertyInfo)); + pi->func = tmp->func ? tmp->func : demarshal_generic; + pi->object_type = tmp->object_type; + pi->field = tmp->field; + pi->signal_prefix = tmp->signal_prefix; + g_hash_table_insert (instance, g_strdup (tmp->name), pi); + } +} + +static gboolean +_nm_object_reload_properties (NMObject *object, GError **error) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GVariant *ret, *props; + GHashTableIter iter; + const char *interface; + GDBusProxy *proxy; + + if (!g_hash_table_size (priv->proxies) || !priv->nm_running) + return TRUE; + + priv->reload_remaining++; + + g_hash_table_iter_init (&iter, priv->proxies); + while (g_hash_table_iter_next (&iter, (gpointer *) &interface, (gpointer *) &proxy)) { + ret = g_dbus_proxy_call_sync (priv->properties_proxy, + "GetAll", + g_variant_new ("(s)", interface), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, error); + if (!ret) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return FALSE; + } + + g_variant_get (ret, "(@a{sv})", &props); + process_properties_changed (object, props, TRUE); + g_variant_unref (props); + g_variant_unref (ret); + } + + if (--priv->reload_remaining == 0) + reload_complete (object, TRUE); + + return TRUE; +} + +void +_nm_object_suppress_property_updates (NMObject *object, gboolean suppress) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + priv->suppress_property_updates = suppress; +} + + +void +_nm_object_reload_property (NMObject *object, + const char *interface, + const char *prop_name) +{ + GVariant *ret, *value; + GError *err = NULL; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (interface != NULL); + g_return_if_fail (prop_name != NULL); + + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + + ret = g_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, + "Get", + g_variant_new ("(ss)", interface, prop_name), + G_DBUS_CALL_FLAGS_NONE, 15000, + NULL, &err); + if (!ret) { + dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n", + __func__, + prop_name, + nm_object_get_path (object), + err->code, + err->message); + g_clear_error (&err); + return; + } + + g_variant_get (ret, "(v)", &value); + handle_property_changed (object, prop_name, value, TRUE); + g_variant_unref (value); + g_variant_unref (ret); +} + +void +_nm_object_set_property (NMObject *object, + const char *interface, + const char *prop_name, + const char *format_string, + ...) +{ + GVariant *val, *ret; + va_list ap; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (interface != NULL); + g_return_if_fail (prop_name != NULL); + g_return_if_fail (format_string != NULL); + + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + + va_start (ap, format_string); + val = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + g_return_if_fail (val != NULL); + + ret = g_dbus_proxy_call_sync (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, + "Set", + g_variant_new ("(ssv)", interface, prop_name, val), + G_DBUS_CALL_FLAGS_NONE, 2000, + NULL, NULL); + /* Ignore errors. */ + if (ret) + g_variant_unref (ret); +} + +static void +reload_complete (NMObject *object, gboolean emit_now) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GSimpleAsyncResult *simple; + GSList *results, *iter; + GError *error; + + if (emit_now) { + if (priv->notify_id) { + g_source_remove (priv->notify_id); + priv->notify_id = 0; + } + deferred_notify_cb (object); + } else + _nm_object_defer_notify (object); + + results = priv->reload_results; + priv->reload_results = NULL; + error = priv->reload_error; + priv->reload_error = NULL; + + for (iter = results; iter; iter = iter->next) { + simple = iter->data; + + if (error) + g_simple_async_result_set_from_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + + g_simple_async_result_complete (simple); + g_object_unref (simple); + } + g_slist_free (results); + g_clear_error (&error); +} + +static void +reload_got_properties (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + NMObject *object = user_data; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GVariant *ret, *props; + GError *error = NULL; + + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + if (ret) { + g_variant_get (ret, "(@a{sv})", &props); + process_properties_changed (object, props, FALSE); + g_variant_unref (props); + g_variant_unref (ret); + } else { + g_dbus_error_strip_remote_error (error); + if (priv->reload_error) + g_error_free (error); + else + priv->reload_error = error; + } + + if (--priv->reload_remaining == 0) + reload_complete (object, FALSE); +} + +void +_nm_object_reload_properties_async (NMObject *object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GSimpleAsyncResult *simple; + GHashTableIter iter; + const char *interface; + GDBusProxy *proxy; + + simple = g_simple_async_result_new (G_OBJECT (object), callback, + user_data, _nm_object_reload_properties_async); + + if (!g_hash_table_size (priv->proxies) || !priv->nm_running) { + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + priv->reload_results = g_slist_prepend (priv->reload_results, simple); + + /* If there was already a reload happening, we don't need to + * re-read the properties again, we just need to wait for the + * existing reload to finish. + */ + if (priv->reload_results->next) + return; + + g_hash_table_iter_init (&iter, priv->proxies); + while (g_hash_table_iter_next (&iter, (gpointer *) &interface, (gpointer *) &proxy)) { + priv->reload_remaining++; + g_dbus_proxy_call (priv->properties_proxy, + "GetAll", + g_variant_new ("(s)", interface), + G_DBUS_CALL_FLAGS_NONE, -1, + cancellable, + reload_got_properties, object); + } +} + +gboolean +_nm_object_reload_properties_finish (NMObject *object, GAsyncResult *result, GError **error) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + GSimpleAsyncResult *simple; + + g_return_val_if_fail (NM_IS_OBJECT (object), FALSE); + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (object), _nm_object_reload_properties_async), FALSE); + + /* NM might have disappeared meanwhile. That would cause a NoReply error to be emitted, + * but we don't care if property updates were disabled. */ + if (priv->suppress_property_updates) + return TRUE; + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + + return g_simple_async_result_get_op_res_gboolean (simple); +} + +gboolean +_nm_object_get_nm_running (NMObject *self) +{ + return NM_OBJECT_GET_PRIVATE (self)->nm_running; +} + +/**************************************************************/ + +static void +on_name_owner_changed (GObject *proxy, + GParamSpec *pspec, + gpointer user_data) +{ + NMObject *self = NM_OBJECT (user_data); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + gboolean now_running; + char *owner; + + now_running = ((owner = g_dbus_proxy_get_name_owner (priv->properties_proxy)) != NULL); + g_free (owner); + if (now_running != priv->nm_running) { + priv->nm_running = now_running; + g_object_notify (G_OBJECT (self), NM_OBJECT_NM_RUNNING); + } +} + +static void +init_dbus (NMObject *object) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + char *owner; + + if (_nm_dbus_is_connection_private (priv->connection)) + priv->nm_running = TRUE; + else { + priv->nm_running = ((owner = g_dbus_proxy_get_name_owner (priv->properties_proxy)) != NULL); + g_free (owner); + g_signal_connect (priv->properties_proxy, "notify::g-name-owner", + G_CALLBACK (on_name_owner_changed), object); + } +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMObject *self = NM_OBJECT (initable); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + NMObjectClassPrivate *cpriv = NM_OBJECT_CLASS_GET_PRIVATE (NM_OBJECT_GET_CLASS (self)); + GSList *iter; + + if (!priv->path) { + g_set_error_literal (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + _("Caller did not specify D-Bus path for object")); + return FALSE; + } + + if (!priv->connection) + priv->connection = _nm_dbus_new_connection (cancellable, error); + if (!priv->connection) + return FALSE; + + /* Create proxies */ + for (iter = cpriv->interfaces; iter; iter = iter->next) { + const char *interface = iter->data; + GDBusProxy *proxy; + + proxy = _nm_dbus_new_proxy_for_connection (priv->connection, priv->path, interface, + cancellable, error); + if (!proxy) + return FALSE; + g_hash_table_insert (priv->proxies, (char *) interface, proxy); + } + + priv->properties_proxy = _nm_dbus_new_proxy_for_connection (priv->connection, + priv->path, + DBUS_INTERFACE_PROPERTIES, + cancellable, error); + if (!priv->properties_proxy) + return FALSE; + + NM_OBJECT_GET_CLASS (self)->init_dbus (self); + + return _nm_object_reload_properties (self, error); +} + +/**************************************************************/ + +typedef struct { + NMObject *object; + GSimpleAsyncResult *simple; + GCancellable *cancellable; + int proxies_pending; + GError *error; +} NMObjectInitData; + +static void +init_async_complete (NMObjectInitData *init_data) +{ + if (init_data->error) + g_simple_async_result_take_error (init_data->simple, init_data->error); + else + g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE); + g_simple_async_result_complete (init_data->simple); + g_object_unref (init_data->simple); + g_clear_object (&init_data->cancellable); + g_slice_free (NMObjectInitData, init_data); +} + +static void +init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectInitData *init_data = user_data; + + _nm_object_reload_properties_finish (NM_OBJECT (object), result, &init_data->error); + init_async_complete (init_data); +} + +static void +init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectInitData *init_data = user_data; + NMObject *self = init_data->object; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GDBusProxy *proxy; + + if (!init_data->error) { + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &init_data->error); + if (proxy) { + const char *interface = g_dbus_proxy_get_interface_name (proxy); + + if (!strcmp (interface, DBUS_INTERFACE_PROPERTIES)) + priv->properties_proxy = proxy; + else + g_hash_table_insert (priv->proxies, (char *) interface, proxy); + } + } + + init_data->proxies_pending--; + if (init_data->proxies_pending) + return; + + if (init_data->error) { + init_async_complete (init_data); + return; + } + + NM_OBJECT_GET_CLASS (self)->init_dbus (self); + + _nm_object_reload_properties_async (init_data->object, init_data->cancellable, init_async_got_properties, init_data); +} + +static void +init_async_got_bus (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMObjectInitData *init_data = user_data; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (init_data->object); + NMObjectClassPrivate *cpriv = NM_OBJECT_CLASS_GET_PRIVATE (NM_OBJECT_GET_CLASS (init_data->object)); + GSList *iter; + + priv->connection = _nm_dbus_new_connection_finish (result, &init_data->error); + if (!priv->connection) { + init_async_complete (init_data); + return; + } + + for (iter = cpriv->interfaces; iter; iter = iter->next) { + const char *interface = iter->data; + + _nm_dbus_new_proxy_for_connection_async (priv->connection, + priv->path, interface, + init_data->cancellable, + init_async_got_proxy, init_data); + init_data->proxies_pending++; + } + + _nm_dbus_new_proxy_for_connection_async (priv->connection, + priv->path, + DBUS_INTERFACE_PROPERTIES, + init_data->cancellable, + init_async_got_proxy, init_data); + init_data->proxies_pending++; +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMObject *self = NM_OBJECT (initable); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + NMObjectInitData *init_data; + + if (!priv->path) { + g_simple_async_report_error_in_idle (G_OBJECT (initable), + callback, user_data, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + "%s", + _("Caller did not specify D-Bus path for object")); + return; + } + + init_data = g_slice_new0 (NMObjectInitData); + init_data->object = self; + init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +/**************************************************************/ + +static void +nm_object_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} + +static void +nm_object_async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = init_async; + iface->init_finish = init_finish; +} + +static void +nm_object_init (NMObject *object) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + priv->proxies = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PATH: + /* Construct only */ + priv->path = g_value_dup_string (value); + break; + case PROP_DBUS_CONNECTION: + /* Construct only */ + priv->connection = g_value_dup_object (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) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string (value, priv->path); + break; + case PROP_DBUS_CONNECTION: + g_value_set_object (value, priv->connection); + break; + case PROP_NM_RUNNING: + g_value_set_boolean (value, priv->nm_running); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + if (priv->notify_id) { + g_source_remove (priv->notify_id); + priv->notify_id = 0; + } + + g_slist_free_full (priv->notify_items, (GDestroyNotify) notify_item_free); + priv->notify_items = NULL; + + g_clear_pointer (&priv->proxies, g_hash_table_unref); + g_clear_object (&priv->properties_proxy); + + g_clear_object (&priv->connection); + + G_OBJECT_CLASS (nm_object_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + + g_slist_free_full (priv->property_tables, (GDestroyNotify) g_hash_table_destroy); + g_free (priv->path); + + G_OBJECT_CLASS (nm_object_parent_class)->finalize (object); +} + +static void +nm_object_class_init (NMObjectClass *nm_object_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (nm_object_class); + + g_type_class_add_private (nm_object_class, sizeof (NMObjectPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* Properties */ + + /** + * NMObject:path: + * + * The D-Bus object path. + **/ + g_object_class_install_property + (object_class, PROP_PATH, + g_param_spec_string (NM_OBJECT_PATH, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMObject:dbus-connection: (skip) + * + * The #GDBusConnection of the object. + **/ + g_object_class_install_property + (object_class, PROP_DBUS_CONNECTION, + g_param_spec_object (NM_OBJECT_DBUS_CONNECTION, "", "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMObject:manager-running: (skip) + * + * Internal use only. + */ + g_object_class_install_property + (object_class, PROP_NM_RUNNING, + g_param_spec_boolean (NM_OBJECT_NM_RUNNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + diff --git a/libnm/nm-object.h b/libnm/nm-object.h new file mode 100644 index 00000000..b42f160d --- /dev/null +++ b/libnm/nm-object.h @@ -0,0 +1,70 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#ifndef __NM_OBJECT_H__ +#define __NM_OBJECT_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_OBJECT (nm_object_get_type ()) +#define NM_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_OBJECT, NMObject)) +#define NM_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_OBJECT, NMObjectClass)) +#define NM_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_OBJECT)) +#define NM_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_OBJECT)) +#define NM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OBJECT, NMObjectClass)) + +#define NM_OBJECT_PATH "path" +#define NM_OBJECT_DBUS_CONNECTION "dbus-connection" + +struct _NMObject { + GObject parent; +}; + +typedef struct { + GObjectClass parent; + + /* Methods */ + void (*init_dbus) (NMObject *object); + + /* The "object-creation-failed" method is PRIVATE for libnm and + * is not meant for any external usage. It indicates that an error + * occured during creation of an object. + */ + void (*object_creation_failed) (NMObject *master_object, + const char *failed_path); + + /*< private >*/ + gpointer padding[8]; +} NMObjectClass; + +GType nm_object_get_type (void); + +const char *nm_object_get_path (NMObject *object); + +G_END_DECLS + +#endif /* __NM_OBJECT_H__ */ diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml new file mode 100644 index 00000000..1520e0f9 --- /dev/null +++ b/libnm/nm-property-docs.xml @@ -0,0 +1,296 @@ + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libnm/nm-remote-connection-private.h b/libnm/nm-remote-connection-private.h new file mode 100644 index 00000000..e3f35428 --- /dev/null +++ b/libnm/nm-remote-connection-private.h @@ -0,0 +1,33 @@ +/* -*- 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. + * + * Copyright 2009 Red Hat, Inc. + */ + +#ifndef __NM_REMOTE_CONNECTION_PRIVATE_H__ +#define __NM_REMOTE_CONNECTION_PRIVATE_H__ + +#define NM_REMOTE_CONNECTION_INIT_RESULT "init-result" + +typedef enum { + NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN = 0, + NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS, + NM_REMOTE_CONNECTION_INIT_RESULT_ERROR, + NM_REMOTE_CONNECTION_INIT_RESULT_INVISIBLE, +} NMRemoteConnectionInitResult; + +#endif /* __NM_REMOTE_CONNECTION_PRIVATE__ */ diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c new file mode 100644 index 00000000..3afe7f8e --- /dev/null +++ b/libnm/nm-remote-connection.c @@ -0,0 +1,857 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include "nm-remote-connection.h" +#include "nm-remote-connection-private.h" +#include "nm-object-private.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-settings-connection.h" + +static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface); +static void nm_remote_connection_initable_iface_init (GInitableIface *iface); +static void nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface); +static GInitableIface *nm_remote_connection_parent_initable_iface; +static GAsyncInitableIface *nm_remote_connection_parent_async_initable_iface; + +G_DEFINE_TYPE_WITH_CODE (NMRemoteConnection, nm_remote_connection, NM_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_remote_connection_connection_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_remote_connection_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_remote_connection_async_initable_iface_init); + ) + +enum { + PROP_0, + PROP_UNSAVED, + PROP_VISIBLE, + + LAST_PROP +}; + +typedef struct { + NMDBusSettingsConnection *proxy; + + gboolean unsaved; + + gboolean visible; +} NMRemoteConnectionPrivate; + +#define NM_REMOTE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionPrivate)) + +/****************************************************************/ + +/** + * nm_remote_connection_commit_changes: + * @connection: the #NMRemoteConnection + * @save_to_disk: whether to persist the changes to disk + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Send any local changes to the settings and properties of @connection to + * NetworkManager. If @save_to_disk is %TRUE, the updated connection will be saved to + * disk; if %FALSE, then only the in-memory representation will be changed. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_commit_changes (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + GVariant *settings; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); + if (save_to_disk) { + ret = nmdbus_settings_connection_call_update_sync (priv->proxy, + settings, + cancellable, error); + } else { + ret = nmdbus_settings_connection_call_update_unsaved_sync (priv->proxy, + settings, + cancellable, error); + } + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +update_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + gboolean (*finish_func) (NMDBusSettingsConnection *, GAsyncResult *, GError **); + GError *error = NULL; + + finish_func = g_object_get_data (G_OBJECT (simple), "finish_func"); + if (finish_func (NMDBUS_SETTINGS_CONNECTION (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_remote_connection_commit_changes_async: + * @connection: the #NMRemoteConnection + * @save_to_disk: whether to save the changes to persistent storage + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the commit operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously sends any local changes to the settings and properties of + * @connection to NetworkManager. If @save is %TRUE, the updated connection will + * be saved to disk; if %FALSE, then only the in-memory representation will be + * changed. + **/ +void +nm_remote_connection_commit_changes_async (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + GVariant *settings; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_commit_changes_async); + + settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); + if (save_to_disk) { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_finish); + nmdbus_settings_connection_call_update (priv->proxy, + settings, + cancellable, + update_cb, simple); + } else { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_unsaved_finish); + nmdbus_settings_connection_call_update_unsaved (priv->proxy, + settings, + cancellable, + update_cb, simple); + } +} + +/** + * nm_remote_connection_commit_changes_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_commit_changes_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_commit_changes_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * nm_remote_connection_save: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_save (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + ret = nmdbus_settings_connection_call_save_sync (priv->proxy, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +save_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_settings_connection_call_save_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_remote_connection_save_async: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the save operation completes + * @user_data: caller-specific data passed to @callback + * + * Saves the connection to disk if the connection has changes that have not yet + * been written to disk, or if the connection has never been saved. + **/ +void +nm_remote_connection_save_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_save_async); + nmdbus_settings_connection_call_save (priv->proxy, cancellable, save_cb, simple); +} + +/** + * nm_remote_connection_save_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_save_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_save_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_save_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * nm_remote_connection_delete: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Deletes the connection. + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_delete (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + ret = nmdbus_settings_connection_call_delete_sync (priv->proxy, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +delete_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_settings_connection_call_delete_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_remote_connection_delete_async: + * @connection: the #NMRemoteConnection + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the delete operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously deletes the connection. + **/ +void +nm_remote_connection_delete_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_delete_async); + nmdbus_settings_connection_call_delete (priv->proxy, cancellable, delete_cb, simple); +} + +/** + * nm_remote_connection_delete_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_delete_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_delete_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * nm_remote_connection_get_secrets: + * @connection: the #NMRemoteConnection + * @setting_name: the #NMSetting object name to get secrets for + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL + * + * Request the connection's secrets. Note that this is a blocking D-Bus call, + * not a simple property accessor. + * + * Returns: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing + * @connection's secrets, or %NULL on error. + **/ +GVariant * +nm_remote_connection_get_secrets (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + GVariant *secrets; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + if (nmdbus_settings_connection_call_get_secrets_sync (priv->proxy, + setting_name, + &secrets, + cancellable, error)) + return secrets; + else { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return NULL; + } +} + +static void +get_secrets_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GVariant *secrets = NULL; + GError *error = NULL; + + if (nmdbus_settings_connection_call_get_secrets_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + &secrets, result, &error)) + g_simple_async_result_set_op_res_gpointer (simple, secrets, (GDestroyNotify) g_variant_unref); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_remote_connection_get_secrets_async: + * @connection: the #NMRemoteConnection + * @setting_name: the #NMSetting object name to get secrets for + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the secret request completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously requests the connection's secrets. + **/ +void +nm_remote_connection_get_secrets_async (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_get_secrets_async); + + nmdbus_settings_connection_call_get_secrets (priv->proxy, + setting_name, + cancellable, + get_secrets_cb, simple); +} + +/** + * nm_remote_connection_get_secrets_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_get_secrets_async(). + * + * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION + * containing @connection's secrets, or %NULL on error. + **/ +GVariant * +nm_remote_connection_get_secrets_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_get_secrets_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +/** + * nm_remote_connection_get_unsaved: + * @connection: the #NMRemoteConnection + * + * Returns: %TRUE if the remote connection contains changes that have not + * been saved to disk, %FALSE if the connection is the same as its on-disk + * representation. + **/ +gboolean +nm_remote_connection_get_unsaved (NMRemoteConnection *connection) +{ + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + return NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->unsaved; +} + +/** + * nm_remote_connection_get_visible: + * @connection: the #NMRemoteConnection + * + * Checks if the connection is visible to the current user. If the + * connection is not visible then it is essentially useless; it will + * not contain any settings, and operations such as + * nm_remote_connection_save() and nm_remote_connection_delete() will + * always fail. (#NMRemoteSettings will not normally return + * non-visible connections to callers, but it is possible for a + * connection's visibility to change after you already have a + * reference to it.) + * + * Returns: %TRUE if the remote connection is visible to the current + * user, %FALSE if not. + **/ +gboolean +nm_remote_connection_get_visible (NMRemoteConnection *connection) +{ + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + return NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->visible; +} + +/****************************************************************/ + +static void +replace_settings (NMRemoteConnection *self, GVariant *new_settings) +{ + GError *error = NULL; + + if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) { + g_warning ("%s: error updating connection %s settings: (%d) %s", + __func__, + nm_connection_get_path (NM_CONNECTION (self)), + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + } +} + +static void +updated_get_settings_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + NMRemoteConnection *self = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + GVariant *new_settings; + gboolean visible; + + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &new_settings, + result, NULL)) { + /* Connection is no longer visible to this user. */ + nm_connection_clear_settings (NM_CONNECTION (self)); + + visible = FALSE; + } else { + replace_settings (self, new_settings); + g_variant_unref (new_settings); + + visible = TRUE; + } + + if (visible != priv->visible) { + priv->visible = visible; + g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_VISIBLE); + } +} + +static void +updated_cb (NMDBusSettingsConnection *proxy, gpointer user_data) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + + /* The connection got updated; request the replacement settings */ + nmdbus_settings_connection_call_get_settings (priv->proxy, + NULL, + updated_get_settings_cb, self); +} + +/****************************************************************/ + +static void +init_dbus (NMObject *object) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_REMOTE_CONNECTION_UNSAVED, &priv->unsaved }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_remote_connection_parent_class)->init_dbus (object); + + priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS_CONNECTION)); + g_assert (priv->proxy); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + property_info); + + g_signal_connect (priv->proxy, "updated", + G_CALLBACK (updated_cb), object); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); + GVariant *settings; + + if (!nm_remote_connection_parent_initable_iface->init (initable, cancellable, error)) + return FALSE; + + if (!nmdbus_settings_connection_call_get_settings_sync (priv->proxy, + &settings, + cancellable, error)) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return FALSE; + } + + priv->visible = TRUE; + replace_settings (self, settings); + g_variant_unref (settings); + + return TRUE; +} + +typedef struct { + NMRemoteConnection *connection; + GCancellable *cancellable; + GSimpleAsyncResult *result; +} NMRemoteConnectionInitData; + +static void +init_async_complete (NMRemoteConnectionInitData *init_data, GError *error) +{ + if (error) + g_simple_async_result_take_error (init_data->result, error); + else + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); + g_slice_free (NMRemoteConnectionInitData, init_data); +} + +static void +init_get_settings_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GVariant *settings; + GError *error = NULL; + + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &settings, + result, &error)) { + g_dbus_error_strip_remote_error (error); + init_async_complete (init_data, error); + return; + } + + priv->visible = TRUE; + replace_settings (init_data->connection, settings); + g_variant_unref (settings); + + init_async_complete (init_data, NULL); +} + +static void +init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GError *error = NULL; + + if (!nm_remote_connection_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error)) { + init_async_complete (init_data, error); + return; + } + + nmdbus_settings_connection_call_get_settings (priv->proxy, + init_data->cancellable, + init_get_settings_cb, init_data); +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionInitData *init_data; + + init_data = g_slice_new0 (NMRemoteConnectionInitData); + init_data->connection = NM_REMOTE_CONNECTION (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); + + nm_remote_connection_parent_async_initable_iface-> + init_async (initable, io_priority, cancellable, init_async_parent_inited, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +static void +nm_remote_connection_init (NMRemoteConnection *self) +{ +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_UNSAVED: + g_value_set_boolean (value, NM_REMOTE_CONNECTION_GET_PRIVATE (object)->unsaved); + break; + case PROP_VISIBLE: + g_value_set_boolean (value, NM_REMOTE_CONNECTION_GET_PRIVATE (object)->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +constructed (GObject *object) +{ + nm_connection_set_path (NM_CONNECTION (object), + nm_object_get_path (NM_OBJECT (object))); +} + +static void +nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (remote_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (remote_class); + + g_type_class_add_private (object_class, sizeof (NMRemoteConnectionPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NMDBUS_TYPE_SETTINGS_CONNECTION_PROXY); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + /* Properties */ + /** + * NMRemoteConnection:unsaved: + * + * %TRUE if the remote connection contains changes that have not been saved + * to disk, %FALSE if the connection is the same as its on-disk representation. + **/ + g_object_class_install_property + (object_class, PROP_UNSAVED, + g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMRemoteConnection:visible: + * + * %TRUE if the remote connection is visible to the current user, %FALSE if + * not. If the connection is not visible then it is essentially useless; it + * will not contain any settings, and operations such as + * nm_remote_connection_save() and nm_remote_connection_delete() will always + * fail. (#NMRemoteSettings will not normally return non-visible connections + * to callers, but it is possible for a connection's visibility to change + * after you already have a reference to it.) + **/ + g_object_class_install_property + (object_class, PROP_VISIBLE, + g_param_spec_boolean (NM_REMOTE_CONNECTION_VISIBLE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +static void +nm_remote_connection_connection_iface_init (NMConnectionInterface *iface) +{ +} + +static void +nm_remote_connection_initable_iface_init (GInitableIface *iface) +{ + nm_remote_connection_parent_initable_iface = g_type_interface_peek_parent (iface); + + iface->init = init_sync; +} + +static void +nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface) +{ + nm_remote_connection_parent_async_initable_iface = g_type_interface_peek_parent (iface); + + iface->init_async = init_async; + iface->init_finish = init_finish; +} diff --git a/libnm/nm-remote-connection.h b/libnm/nm-remote-connection.h new file mode 100644 index 00000000..3ea8037f --- /dev/null +++ b/libnm/nm-remote-connection.h @@ -0,0 +1,114 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_REMOTE_CONNECTION_H__ +#define __NM_REMOTE_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_REMOTE_CONNECTION (nm_remote_connection_get_type ()) +#define NM_REMOTE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnection)) +#define NM_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) +#define NM_IS_REMOTE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_CONNECTION)) +#define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_REMOTE_CONNECTION)) +#define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) + + +/* Properties */ +#define NM_REMOTE_CONNECTION_DBUS_CONNECTION "dbus-connection" +#define NM_REMOTE_CONNECTION_PATH "path" +#define NM_REMOTE_CONNECTION_UNSAVED "unsaved" +#define NM_REMOTE_CONNECTION_VISIBLE "visible" + +struct _NMRemoteConnection { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent_class; + + /*< private >*/ + gpointer padding[8]; +} NMRemoteConnectionClass; + +GType nm_remote_connection_get_type (void); + +gboolean nm_remote_connection_commit_changes (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GError **error); +void nm_remote_connection_commit_changes_async (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_connection_save (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error); +void nm_remote_connection_save_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_save_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_connection_delete (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error); +void nm_remote_connection_delete_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_delete_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +GVariant *nm_remote_connection_get_secrets (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GError **error); +void nm_remote_connection_get_secrets_async (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GVariant *nm_remote_connection_get_secrets_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_connection_get_unsaved (NMRemoteConnection *connection); + +gboolean nm_remote_connection_get_visible (NMRemoteConnection *connection); + +G_END_DECLS + +#endif /* __NM_REMOTE_CONNECTION__ */ diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c new file mode 100644 index 00000000..d37e3666 --- /dev/null +++ b/libnm/nm-remote-settings.c @@ -0,0 +1,832 @@ +/* -*- 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. + * + * Copyright 2008 Novell, Inc. + * Copyright 2009 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-remote-settings.h" +#include "nm-client.h" +#include "nm-remote-connection.h" +#include "nm-remote-connection-private.h" +#include "nm-object-private.h" +#include "nm-dbus-helpers.h" +#include "nm-glib-compat.h" +#include "nm-object-private.h" +#include "nm-core-internal.h" + +#include "nmdbus-settings.h" + +G_DEFINE_TYPE (NMRemoteSettings, nm_remote_settings, NM_TYPE_OBJECT) + +#define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate)) + +typedef struct { + NMDBusSettings *proxy; + GPtrArray *all_connections; + GPtrArray *visible_connections; + GCancellable *props_cancellable; + + /* AddConnectionInfo objects that are waiting for the connection to become initialized */ + GSList *add_list; + + char *hostname; + gboolean can_modify; +} NMRemoteSettingsPrivate; + +enum { + PROP_0, + PROP_CONNECTIONS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, + + LAST_PROP +}; + +/* Signals */ +enum { + CONNECTION_ADDED, + CONNECTION_REMOVED, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/**********************************************************************/ + +typedef struct { + NMRemoteSettings *self; + GSimpleAsyncResult *simple; + char *path; + gboolean saved; +} AddConnectionInfo; + +static AddConnectionInfo * +add_connection_info_find (NMRemoteSettings *self, const char *path) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->add_list; iter; iter = g_slist_next (iter)) { + AddConnectionInfo *info = iter->data; + + if (!g_strcmp0 (info->path, path)) + return info; + } + + return NULL; +} + +static void +add_connection_info_complete (NMRemoteSettings *self, + AddConnectionInfo *info, + NMRemoteConnection *connection, + GError *error) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + g_return_if_fail (info != NULL); + + if (connection) { + g_simple_async_result_set_op_res_gpointer (info->simple, + g_object_ref (connection), + g_object_unref); + } else + g_simple_async_result_set_from_error (info->simple, error); + g_simple_async_result_complete (info->simple); + + g_object_unref (info->simple); + priv->add_list = g_slist_remove (priv->add_list, info); + + g_free (info->path); + g_slice_free (AddConnectionInfo, info); +} + +typedef const char * (*ConnectionStringGetter) (NMConnection *); + +static NMRemoteConnection * +get_connection_by_string (NMRemoteSettings *settings, + const char *string, + ConnectionStringGetter get_comparison_string) +{ + NMRemoteSettingsPrivate *priv; + NMConnection *candidate; + int i; + + if (!_nm_object_get_nm_running (NM_OBJECT (settings))) + return NULL; + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + for (i = 0; i < priv->visible_connections->len; i++) { + candidate = priv->visible_connections->pdata[i]; + if (!g_strcmp0 (string, get_comparison_string (candidate))) + return NM_REMOTE_CONNECTION (candidate); + } + + return NULL; +} + +NMRemoteConnection * +nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, const char *id) +{ + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + g_return_val_if_fail (id != NULL, NULL); + + return get_connection_by_string (settings, id, nm_connection_get_id); +} + +NMRemoteConnection * +nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path) +{ + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + g_return_val_if_fail (path != NULL, NULL); + + return get_connection_by_string (settings, path, nm_connection_get_path); +} + +NMRemoteConnection * +nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid) +{ + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + g_return_val_if_fail (uuid != NULL, NULL); + + return get_connection_by_string (settings, uuid, nm_connection_get_uuid); +} + +static void +connection_visible_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + NMRemoteConnection *connection = NM_REMOTE_CONNECTION (object); + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + + if (nm_remote_connection_get_visible (connection)) + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); + else + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); +} + +static void +cleanup_connection (NMRemoteSettings *self, + NMRemoteConnection *remote) +{ + g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (connection_visible_changed), self); +} + +static void +connection_removed (NMRemoteSettings *self, + NMRemoteConnection *remote) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + gboolean still_exists = FALSE; + int i; + + /* Check if the connection was actually removed or if it just turned invisible. */ + for (i = 0; i < priv->all_connections->len; i++) { + if (remote == priv->all_connections->pdata[i]) { + still_exists = TRUE; + break; + } + } + + if (!still_exists) + cleanup_connection (self, remote); + + /* Allow the signal to propagate if and only if @remote was in visible_connections */ + if (!g_ptr_array_remove (priv->visible_connections, remote)) + g_signal_stop_emission (self, signals[CONNECTION_REMOVED], 0); +} + +static void +connection_added (NMRemoteSettings *self, + NMRemoteConnection *remote) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + AddConnectionInfo *addinfo; + const char *path; + + if (!g_signal_handler_find (remote, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, + G_CALLBACK (connection_visible_changed), self)) { + g_signal_connect (remote, + "notify::" NM_REMOTE_CONNECTION_VISIBLE, + G_CALLBACK (connection_visible_changed), + self); + } + + if (nm_remote_connection_get_visible (remote)) + g_ptr_array_add (priv->visible_connections, remote); + else + g_signal_stop_emission (self, signals[CONNECTION_ADDED], 0); + + path = nm_connection_get_path (NM_CONNECTION (remote)); + addinfo = add_connection_info_find (self, path); + if (addinfo) + add_connection_info_complete (self, addinfo, remote, NULL); +} + +static void +object_creation_failed (NMObject *object, const char *failed_path) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); + AddConnectionInfo *addinfo; + GError *add_error; + + addinfo = add_connection_info_find (self, failed_path); + if (addinfo) { + add_error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_OBJECT_CREATION_FAILED, + _("Connection removed before it was initialized")); + add_connection_info_complete (self, addinfo, NULL, add_error); + g_error_free (add_error); + } +} + +const GPtrArray * +nm_remote_settings_get_connections (NMRemoteSettings *settings) +{ + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + + return NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->visible_connections; +} + +static void +add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + AddConnectionInfo *info = user_data; + GError *error = NULL; + + if (info->saved) { + nmdbus_settings_call_add_connection_finish (NMDBUS_SETTINGS (proxy), + &info->path, + result, &error); + } else { + nmdbus_settings_call_add_connection_unsaved_finish (NMDBUS_SETTINGS (proxy), + &info->path, + result, &error); + } + + if (error) { + g_dbus_error_strip_remote_error (error); + add_connection_info_complete (info->self, info, NULL, error); + g_clear_error (&error); + } + + /* On success, we still have to wait until the connection is fully + * initialized before calling the callback. + */ +} + +void +nm_remote_settings_add_connection_async (NMRemoteSettings *settings, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + AddConnectionInfo *info; + GVariant *new_settings; + + g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + info = g_slice_new0 (AddConnectionInfo); + info->self = settings; + info->simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_add_connection_async); + info->saved = save_to_disk; + + new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + + if (save_to_disk) { + nmdbus_settings_call_add_connection (priv->proxy, + new_settings, + NULL, + add_connection_done, info); + } else { + nmdbus_settings_call_add_connection_unsaved (priv->proxy, + new_settings, + NULL, + add_connection_done, info); + } + + priv->add_list = g_slist_append (priv->add_list, info); +} + +NMRemoteConnection * +nm_remote_settings_add_connection_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_add_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +gboolean +nm_remote_settings_load_connections (NMRemoteSettings *settings, + char **filenames, + char ***failures, + GCancellable *cancellable, + GError **error) +{ + NMRemoteSettingsPrivate *priv; + gboolean success; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (filenames != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + if (!nmdbus_settings_call_load_connections_sync (priv->proxy, + (const char * const *) filenames, + &success, + failures, + cancellable, error)) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + success = FALSE; + } + return success; +} + +static void +load_connections_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + gboolean success; + char **failures = NULL; + + if (nmdbus_settings_call_load_connections_finish (NMDBUS_SETTINGS (proxy), + &success, &failures, + result, &error)) + g_simple_async_result_set_op_res_gpointer (simple, failures, (GDestroyNotify) g_strfreev); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_remote_settings_load_connections_async (NMRemoteSettings *settings, + char **filenames, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings)); + g_return_if_fail (filenames != NULL); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_load_connections_async); + + nmdbus_settings_call_load_connections (priv->proxy, + (const char * const *) filenames, + cancellable, load_connections_cb, simple); +} + +gboolean +nm_remote_settings_load_connections_finish (NMRemoteSettings *settings, + char ***failures, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_load_connections_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else { + *failures = g_strdupv (g_simple_async_result_get_op_res_gpointer (simple)); + return TRUE; + } +} + +gboolean +nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GCancellable *cancellable, + GError **error) +{ + NMRemoteSettingsPrivate *priv; + gboolean success; + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + if (!nmdbus_settings_call_reload_connections_sync (priv->proxy, &success, + cancellable, error)) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + success = FALSE; + } + + return success; +} + +static void +reload_connections_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + gboolean success; + GError *error = NULL; + + if (nmdbus_settings_call_reload_connections_finish (NMDBUS_SETTINGS (proxy), + &success, + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, success); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_remote_settings_reload_connections_async (NMRemoteSettings *settings, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings)); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_reload_connections_async); + + nmdbus_settings_call_reload_connections (priv->proxy, cancellable, + reload_connections_cb, simple); +} + +gboolean +nm_remote_settings_reload_connections_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_reload_connections_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +gboolean +nm_remote_settings_save_hostname (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GError **error) +{ + NMRemoteSettingsPrivate *priv; + gboolean ret; + + + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + ret = nmdbus_settings_call_save_hostname_sync (priv->proxy, + hostname ? hostname : "", + cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +save_hostname_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_settings_call_save_hostname_finish (NMDBUS_SETTINGS (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +void +nm_remote_settings_save_hostname_async (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings)); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + + simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_save_hostname_async); + + nmdbus_settings_call_save_hostname (priv->proxy, + hostname ? hostname : "", + cancellable, save_hostname_cb, simple); +} + +gboolean +nm_remote_settings_save_hostname_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_save_hostname_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +static void +updated_properties (GObject *object, GAsyncResult *result, gpointer user_data) +{ + GError *error = NULL; + + if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: error reading NMRemoteSettings properties: %s", __func__, error->message); + g_error_free (error); + } +} + +static void +nm_running_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + g_object_freeze_notify (object); + + if (!_nm_object_get_nm_running (NM_OBJECT (self))) { + GPtrArray *connections; + int i; + + NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + + /* Clear connections */ + connections = priv->all_connections; + priv->all_connections = g_ptr_array_new (); + for (i = 0; i < connections->len; i++) + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connections->pdata[i]); + g_ptr_array_unref (connections); + + /* Clear properties */ + if (priv->hostname) { + g_free (priv->hostname); + priv->hostname = NULL; + g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_HOSTNAME); + } + + if (priv->can_modify) { + priv->can_modify = FALSE; + g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY); + } + + _nm_object_suppress_property_updates (NM_OBJECT (self), TRUE); + } else { + _nm_object_suppress_property_updates (NM_OBJECT (self), FALSE); + + NM_UTILS_CLEAR_CANCELLABLE (priv->props_cancellable); + priv->props_cancellable = g_cancellable_new (); + _nm_object_reload_properties_async (NM_OBJECT (self), priv->props_cancellable, updated_properties, self); + } + + g_object_thaw_notify (object); +} + +/****************************************************************/ + +static void +nm_remote_settings_init (NMRemoteSettings *self) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + priv->all_connections = g_ptr_array_new (); + priv->visible_connections = g_ptr_array_new (); +} + +static void +init_dbus (NMObject *object) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_REMOTE_SETTINGS_CONNECTIONS, &priv->all_connections, NULL, NM_TYPE_REMOTE_CONNECTION, "connection" }, + { NM_REMOTE_SETTINGS_HOSTNAME, &priv->hostname }, + { NM_REMOTE_SETTINGS_CAN_MODIFY, &priv->can_modify }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_remote_settings_parent_class)->init_dbus (object); + + priv->proxy = NMDBUS_SETTINGS (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS)); + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_SETTINGS, + property_info); + + g_signal_connect (object, "notify::" NM_OBJECT_NM_RUNNING, + G_CALLBACK (nm_running_changed), object); +} + +static GObject * +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + guint i; + const char *dbus_path; + + /* Fill in the right D-Bus path if none was specified */ + for (i = 0; i < n_construct_params; i++) { + if (strcmp (construct_params[i].pspec->name, NM_OBJECT_PATH) == 0) { + dbus_path = g_value_get_string (construct_params[i].value); + if (dbus_path == NULL) { + g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS); + } else { + if (!g_variant_is_object_path (dbus_path)) { + g_warning ("Passed D-Bus object path '%s' is invalid; using default '%s' instead", + dbus_path, NM_DBUS_PATH); + g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS); + } + } + break; + } + } + + return G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type, + n_construct_params, + construct_params); +} + +static void +dispose (GObject *object) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + int i; + + if (priv->all_connections) { + for (i = 0; i < priv->all_connections->len; i++) + cleanup_connection (self, priv->all_connections->pdata[i]); + g_clear_pointer (&priv->all_connections, g_ptr_array_unref); + } + + g_signal_handlers_disconnect_by_func (object, G_CALLBACK (nm_running_changed), self); + + g_clear_pointer (&priv->visible_connections, g_ptr_array_unref); + g_clear_pointer (&priv->hostname, g_free); + + G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_CONNECTIONS: + g_value_take_boxed (value, _nm_utils_copy_object_array (priv->visible_connections)); + break; + case PROP_HOSTNAME: + g_value_set_string (value, priv->hostname); + break; + case PROP_CAN_MODIFY: + g_value_set_boolean (value, priv->can_modify); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_remote_settings_class_init (NMRemoteSettingsClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS, NMDBUS_TYPE_SETTINGS_PROXY); + + /* Virtual methods */ + object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->dispose = dispose; + + nm_object_class->init_dbus = init_dbus; + nm_object_class->object_creation_failed = object_creation_failed; + + class->connection_added = connection_added; + class->connection_removed = connection_removed; + + /* Properties */ + + g_object_class_install_property + (object_class, PROP_CONNECTIONS, + g_param_spec_boxed (NM_REMOTE_SETTINGS_CONNECTIONS, "", "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* Signals */ + signals[CONNECTION_ADDED] = + g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_ADDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_added), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_REMOTE_CONNECTION); + + signals[CONNECTION_REMOVED] = + g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_removed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + NM_TYPE_REMOTE_CONNECTION); +} diff --git a/libnm/nm-remote-settings.h b/libnm/nm-remote-settings.h new file mode 100644 index 00000000..1ffc0bf2 --- /dev/null +++ b/libnm/nm-remote-settings.h @@ -0,0 +1,127 @@ +/* -*- 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. + * + * Copyright 2008 Novell, Inc. + * Copyright 2009 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_REMOTE_SETTINGS_H__ +#define __NM_REMOTE_SETTINGS_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_REMOTE_SETTINGS (nm_remote_settings_get_type ()) +#define NM_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettings)) +#define NM_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) +#define NM_IS_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS)) +#define NM_IS_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_REMOTE_SETTINGS)) +#define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) + +#define NM_REMOTE_SETTINGS_CONNECTIONS "connections" +#define NM_REMOTE_SETTINGS_HOSTNAME "hostname" +#define NM_REMOTE_SETTINGS_CAN_MODIFY "can-modify" + +#define NM_REMOTE_SETTINGS_CONNECTION_ADDED "connection-added" +#define NM_REMOTE_SETTINGS_CONNECTION_REMOVED "connection-removed" + +typedef struct _NMRemoteSettings NMRemoteSettings; +typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass; + +struct _NMRemoteSettings { + NMObject parent; +}; + +struct _NMRemoteSettingsClass { + NMObjectClass parent; + + /* Signals */ + void (*connection_added) (NMRemoteSettings *settings, + NMRemoteConnection *connection); + void (*connection_removed) (NMRemoteSettings *settings, + NMRemoteConnection *connection); + + /*< private >*/ + gpointer padding[8]; +}; + +GType nm_remote_settings_get_type (void); + +const GPtrArray *nm_remote_settings_get_connections (NMRemoteSettings *settings); + +NMRemoteConnection *nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, + const char *id); + +NMRemoteConnection *nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, + const char *path); + +NMRemoteConnection *nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, + const char *uuid); + +void nm_remote_settings_add_connection_async (NMRemoteSettings *settings, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMRemoteConnection *nm_remote_settings_add_connection_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings, + char **filenames, + char ***failures, + GCancellable *cancellable, + GError **error); +void nm_remote_settings_load_connections_async (NMRemoteSettings *settings, + char **filenames, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_settings_load_connections_finish (NMRemoteSettings *settings, + char ***failures, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GCancellable *cancellable, + GError **error); +void nm_remote_settings_reload_connections_async (NMRemoteSettings *settings, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_settings_reload_connections_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error); + +gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GError **error); +void nm_remote_settings_save_hostname_async (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_settings_save_hostname_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif /* __NM_REMOTE_SETTINGS_H__ */ diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c new file mode 100644 index 00000000..606c4099 --- /dev/null +++ b/libnm/nm-secret-agent-old.c @@ -0,0 +1,1366 @@ +/* -*- 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. + * + * Copyright 2010 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-glib-compat.h" +#include "nm-dbus-interface.h" +#include "nm-secret-agent-old.h" +#include "nm-enum-types.h" +#include "nm-dbus-helpers.h" +#include "nm-simple-connection.h" + +#include "nmdbus-secret-agent.h" +#include "nmdbus-agent-manager.h" + +static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface); +static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface); +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init); + ) + +#define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) + +typedef struct { + gboolean registered; + gboolean registering; + NMSecretAgentCapabilities capabilities; + + GDBusConnection *bus; + gboolean private_bus; + gboolean session_bus; + NMDBusAgentManager *manager_proxy; + NMDBusSecretAgent *dbus_secret_agent; + + /* GetSecretsInfo structs of in-flight GetSecrets requests */ + GSList *pending_gets; + + char *identifier; + gboolean auto_register; + gboolean suppress_auto; +} NMSecretAgentOldPrivate; + +enum { + PROP_0, + PROP_IDENTIFIER, + PROP_AUTO_REGISTER, + PROP_REGISTERED, + PROP_CAPABILITIES, + + LAST_PROP +}; + +/*************************************************************/ + +static void +_internal_unregister (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (priv->registered) { + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent)); + priv->registered = FALSE; + priv->registering = FALSE; + g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + } +} + +typedef struct { + char *path; + char *setting_name; + GDBusMethodInvocation *context; +} GetSecretsInfo; + +static void +get_secrets_info_finalize (NMSecretAgentOld *self, GetSecretsInfo *info) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_if_fail (info != NULL); + + priv->pending_gets = g_slist_remove (priv->pending_gets, info); + + g_free (info->path); + g_free (info->setting_name); + memset (info, 0, sizeof (*info)); + g_free (info); +} + +static inline gboolean +should_auto_register (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + return ( priv->auto_register + && !priv->suppress_auto + && !priv->registered + && !priv->registering); +} + +static void +name_owner_changed (GObject *proxy, + GParamSpec *pspec, + gpointer user_data) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + GSList *iter; + char *owner; + + owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)); + if (owner != NULL) { + if (should_auto_register (self)) + nm_secret_agent_old_register_async (self, NULL, NULL, NULL); + g_free (owner); + } else { + /* Cancel any pending secrets requests */ + for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *info = iter->data; + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, + info->path, + info->setting_name); + } + g_slist_free (priv->pending_gets); + priv->pending_gets = NULL; + + _internal_unregister (self); + } +} + +static gboolean +verify_sender (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + GError **error) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + char *nm_owner; + const char *sender; + guint32 sender_uid; + GVariant *ret; + GError *local = NULL; + + g_return_val_if_fail (context != NULL, FALSE); + + /* Private bus connection is always to NetworkManager, which is always + * UID 0. + */ + if (priv->private_bus) + return TRUE; + + /* Verify that the sender is the same as NetworkManager's bus name owner. */ + + nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); + if (!nm_owner) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "NetworkManager bus name owner unknown."); + return FALSE; + } + + sender = g_dbus_method_invocation_get_sender (context); + if (!sender) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Failed to get request sender."); + g_free (nm_owner); + return FALSE; + } + + /* Check that the sender matches the current NM bus name owner */ + if (strcmp (sender, nm_owner) != 0) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Request sender does not match NetworkManager bus name owner."); + g_free (nm_owner); + return FALSE; + } + g_free (nm_owner); + + /* If we're connected to the session bus, then this must be a test program, + * so skip the UID check. + */ + if (priv->session_bus) + return TRUE; + + /* Check the UID of the sender */ + ret = g_dbus_connection_call_sync (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixUser", + g_variant_new ("(s)", sender), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &local); + if (!ret) { + char *remote_error = g_dbus_error_get_remote_error (local); + + g_dbus_error_strip_remote_error (local); + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Failed to request unix user: (%s) %s.", + remote_error ? remote_error : "", + local->message); + g_free (remote_error); + g_error_free (local); + return FALSE; + } + g_variant_get (ret, "(u)", &sender_uid); + g_variant_unref (ret); + + /* We only accept requests from NM, which always runs as root */ + if (0 != sender_uid) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Request sender is not root."); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_request (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + GVariant *connection_dict, + const char *connection_path, + NMConnection **out_connection, + GError **error) +{ + NMConnection *connection = NULL; + GError *local = NULL; + + if (!verify_sender (self, context, error)) + return FALSE; + + /* No connection? If the sender verified, then we allow the request */ + if (connection_dict == NULL) + return TRUE; + + /* If we have a connection dictionary, we require a path too */ + if (connection_path == NULL) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: no connection path given."); + return FALSE; + } + + /* Make sure the given connection is valid */ + g_assert (out_connection); + connection = nm_simple_connection_new_from_dbus (connection_dict, &local); + if (connection) { + nm_connection_set_path (connection, connection_path); + *out_connection = connection; + } else { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: %s", local->message); + g_clear_error (&local); + } + + return !!connection; +} + +static void +get_secrets_cb (NMSecretAgentOld *self, + NMConnection *connection, + GVariant *secrets, + GError *error, + gpointer user_data) +{ + GetSecretsInfo *info = user_data; + + if (error) + g_dbus_method_invocation_return_gerror (info->context, error); + else { + g_dbus_method_invocation_return_value (info->context, + g_variant_new ("(@a{sa{sv}})", secrets)); + } + + /* Remove the request from internal tracking */ + get_secrets_info_finalize (self, info); +} + +static void +impl_secret_agent_old_get_secrets (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + GVariant *connection_dict, + const char *connection_path, + const char *setting_name, + const char * const *hints, + guint flags, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + GError *error = NULL; + NMConnection *connection = NULL; + GetSecretsInfo *info; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + info = g_malloc0 (sizeof (GetSecretsInfo)); + info->path = g_strdup (connection_path); + info->setting_name = g_strdup (setting_name); + info->context = context; + priv->pending_gets = g_slist_append (priv->pending_gets, info); + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self, + connection, + connection_path, + setting_name, + (const char **) hints, + flags, + get_secrets_cb, + info); + g_object_unref (connection); +} + +static GetSecretsInfo * +find_get_secrets_info (GSList *list, const char *path, const char *setting_name) +{ + GSList *iter; + + for (iter = list; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *candidate = iter->data; + + if ( g_strcmp0 (path, candidate->path) == 0 + && g_strcmp0 (setting_name, candidate->setting_name) == 0) + return candidate; + } + return NULL; +} + +static void +impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + const char *connection_path, + const char *setting_name, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + GError *error = NULL; + GetSecretsInfo *info; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, NULL, NULL, NULL, &error)) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name); + if (!info) { + g_dbus_method_invocation_return_error (context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "No secrets request in progress for this connection."); + return; + } + + /* Send the cancel request up to the subclass and finalize it */ + NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, + info->path, + info->setting_name); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +save_secrets_cb (NMSecretAgentOld *self, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + GDBusMethodInvocation *context = user_data; + + if (error) + g_dbus_method_invocation_return_gerror (context, error); + else + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_secret_agent_old_save_secrets (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + GVariant *connection_dict, + const char *connection_path, + gpointer user_data) +{ + GError *error = NULL; + NMConnection *connection = NULL; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self, + connection, + connection_path, + save_secrets_cb, + context); + g_object_unref (connection); +} + +static void +delete_secrets_cb (NMSecretAgentOld *self, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + GDBusMethodInvocation *context = user_data; + + if (error) + g_dbus_method_invocation_return_gerror (context, error); + else + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self, + GDBusMethodInvocation *context, + GVariant *connection_dict, + const char *connection_path, + gpointer user_data) +{ + GError *error = NULL; + NMConnection *connection = NULL; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self, + connection, + connection_path, + delete_secrets_cb, + context); + g_object_unref (connection); +} + +/**************************************************************/ + +static gboolean +check_nm_running (NMSecretAgentOld *self, GError **error) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + char *owner; + + if (priv->private_bus) + return TRUE; + owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); + if (owner) { + g_free (owner); + return TRUE; + } + + g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, + "NetworkManager is not running"); + return FALSE; +} + +/**************************************************************/ + +/** + * nm_secret_agent_old_register: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Registers the #NMSecretAgentOld with the NetworkManager secret manager, + * indicating to NetworkManager that the agent is able to provide and save + * secrets for connections on behalf of its user. + * + * It is a programmer error to attempt to register an agent that is already + * registered, or in the process of registering. + * + * Returns: %TRUE if registration was successful, %FALSE on error. + **/ +gboolean +nm_secret_agent_old_register (NMSecretAgentOld *self, + GCancellable *cancellable, + GError **error) +{ + NMSecretAgentOldPrivate *priv; + NMSecretAgentOldClass *class; + + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_val_if_fail (priv->registered == FALSE, FALSE); + g_return_val_if_fail (priv->registering == FALSE, FALSE); + g_return_val_if_fail (priv->bus != NULL, FALSE); + g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + + /* Also make sure the subclass can actually respond to secrets requests */ + class = NM_SECRET_AGENT_OLD_GET_CLASS (self); + g_return_val_if_fail (class->get_secrets != NULL, FALSE); + g_return_val_if_fail (class->save_secrets != NULL, FALSE); + g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + + if (!check_nm_running (self, error)) + return FALSE; + + priv->suppress_auto = FALSE; + + /* Export our secret agent interface before registering with the manager */ + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), + priv->bus, + NM_DBUS_PATH_SECRET_AGENT, + error)) + return FALSE; + + priv->registering = TRUE; + if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy, + priv->identifier, + priv->capabilities, + cancellable, NULL)) + goto success; + + /* Might be an old NetworkManager that doesn't support capabilities; + * fall back to old Register() method instead. + */ + if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy, + priv->identifier, + cancellable, NULL)) + goto success; + + /* Failure */ + priv->registering = FALSE; + _internal_unregister (self); + return FALSE; + +success: + priv->registering = FALSE; + priv->registered = TRUE; + g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + return TRUE; +} + +static void +reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + priv->registering = FALSE; + + if (error) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + + /* If registration failed we shouldn't expose ourselves on the bus */ + _internal_unregister (self); + } else { + priv->registered = TRUE; + g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED); + + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + } + + g_object_unref (simple); +} + +static void +reg_request_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMSecretAgentOld *self; + NMSecretAgentOldPrivate *priv; + GError *error = NULL; + + self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + g_object_unref (self); /* drop extra ref added by get_source_object() */ + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (!nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error)) + g_dbus_error_strip_remote_error (error); + reg_result (self, simple, error); + g_clear_error (&error); +} + +static void +reg_with_caps_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMSecretAgentOld *self; + NMSecretAgentOldPrivate *priv; + + self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + g_object_unref (self); /* drop extra ref added by get_source_object() */ + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) { + reg_result (self, simple, NULL); + return; + } + + /* Might be an old NetworkManager that doesn't support capabilities; + * fall back to old Register() method instead. + */ + nmdbus_agent_manager_call_register (priv->manager_proxy, + priv->identifier, + NULL, reg_request_cb, simple); +} + +/** + * nm_secret_agent_old_register_async: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the agent is registered + * @user_data: data for @callback + * + * Asynchronously registers the #NMSecretAgentOld with the NetworkManager secret + * manager, indicating to NetworkManager that the agent is able to provide and + * save secrets for connections on behalf of its user. + * + * It is a programmer error to attempt to register an agent that is already + * registered, or in the process of registering. + **/ +void +nm_secret_agent_old_register_async (NMSecretAgentOld *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv; + NMSecretAgentOldClass *class; + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_if_fail (priv->registered == FALSE); + g_return_if_fail (priv->registering == FALSE); + g_return_if_fail (priv->bus != NULL); + g_return_if_fail (priv->manager_proxy != NULL); + + /* Also make sure the subclass can actually respond to secrets requests */ + class = NM_SECRET_AGENT_OLD_GET_CLASS (self); + g_return_if_fail (class->get_secrets != NULL); + g_return_if_fail (class->save_secrets != NULL); + g_return_if_fail (class->delete_secrets != NULL); + + simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + nm_secret_agent_old_register_async); + + if (!check_nm_running (self, &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + /* Export our secret agent interface before registering with the manager */ + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), + priv->bus, + NM_DBUS_PATH_SECRET_AGENT, + &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + priv->suppress_auto = FALSE; + priv->registering = TRUE; + + nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy, + priv->identifier, + priv->capabilities, + NULL, + reg_with_caps_cb, simple); +} + +/** + * nm_secret_agent_old_register_finish: + * @self: a #NMSecretAgentOld + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Gets the result of a call to nm_secret_agent_old_register_async(). + * + * Returns: %TRUE if registration was successful, %FALSE on error. + **/ +gboolean +nm_secret_agent_old_register_finish (NMSecretAgentOld *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_register_async), FALSE); + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) + return FALSE; + else + return TRUE; +} + +/** + * nm_secret_agent_old_unregister: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Unregisters the #NMSecretAgentOld with the NetworkManager secret manager, + * indicating to NetworkManager that the agent will no longer provide or + * store secrets on behalf of this user. + * + * It is a programmer error to attempt to unregister an agent that is not + * registered. + * + * Returns: %TRUE if unregistration was successful, %FALSE on error + **/ +gboolean +nm_secret_agent_old_unregister (NMSecretAgentOld *self, + GCancellable *cancellable, + GError **error) +{ + NMSecretAgentOldPrivate *priv; + gboolean success; + + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_val_if_fail (priv->registered == TRUE, FALSE); + g_return_val_if_fail (priv->bus != NULL, FALSE); + g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + + priv->suppress_auto = TRUE; + + success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + _internal_unregister (self); + + return success; +} + +static void +unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMSecretAgentOld *self; + GError *error = NULL; + + self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + g_object_unref (self); /* drop extra ref added by get_source_object() */ + + _internal_unregister (self); + + if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * nm_secret_agent_old_unregister_async: + * @self: a #NMSecretAgentOld + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to call when the agent is unregistered + * @user_data: data for @callback + * + * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret + * manager, indicating to NetworkManager that the agent will no longer provide + * or store secrets on behalf of this user. + * + * It is a programmer error to attempt to unregister an agent that is not + * registered. + **/ +void +nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOldPrivate *priv; + GSimpleAsyncResult *simple; + GError *error = NULL; + + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_if_fail (priv->registered == TRUE); + g_return_if_fail (priv->bus != NULL); + g_return_if_fail (priv->manager_proxy != NULL); + + simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + nm_secret_agent_old_unregister_async); + + if (!check_nm_running (self, &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } + + priv->suppress_auto = TRUE; + + nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable, + unregister_cb, simple); +} + +/** + * nm_secret_agent_old_unregister_finish: + * @self: a #NMSecretAgentOld + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for a #GError, or %NULL + * + * Gets the result of a call to nm_secret_agent_old_unregister_async(). + * + * Returns: %TRUE if unregistration was successful, %FALSE on error. + **/ +gboolean +nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_unregister_async), FALSE); + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) + return FALSE; + else + return TRUE; +} + +/** + * nm_secret_agent_old_get_registered: + * @self: a #NMSecretAgentOld + * + * Returns: a %TRUE if the agent is registered, %FALSE if it is not. + **/ +gboolean +nm_secret_agent_old_get_registered (NMSecretAgentOld *self) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->registered; +} + +/**************************************************************/ + +/** + * nm_secret_agent_old_get_secrets: + * @self: a #NMSecretAgentOld + * @connection: the #NMConnection for which we're asked secrets + * @setting_name: the name of the secret setting + * @hints: (array zero-terminated=1): hints to the agent + * @flags: flags that modify the behavior of the request + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously retrieves secrets belonging to @connection for the + * setting @setting_name. @flags indicate specific behavior that the secret + * agent should use when performing the request, for example returning only + * existing secrets without user interaction, or requesting entirely new + * secrets from the user. + * + * Virtual: get_secrets + */ +void +nm_secret_agent_old_get_secrets (NMSecretAgentOld *self, + NMConnection *connection, + const char *setting_name, + const char **hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + g_return_if_fail (setting_name != NULL); + g_return_if_fail (strlen (setting_name) > 0); + g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)); + g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS)); + g_return_if_fail (callback != NULL); + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self, + connection, + nm_connection_get_path (connection), + setting_name, + hints, + flags, + callback, + user_data); +} + +/** + * nm_secret_agent_old_save_secrets: + * @self: a #NMSecretAgentOld + * @connection: a #NMConnection + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously ensures that all secrets inside @connection are stored to + * disk. + * + * Virtual: save_secrets + */ +void +nm_secret_agent_old_save_secrets (NMSecretAgentOld *self, + NMConnection *connection, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self, + connection, + nm_connection_get_path (connection), + callback, + user_data); +} + +/** + * nm_secret_agent_old_delete_secrets: + * @self: a #NMSecretAgentOld + * @connection: a #NMConnection + * @callback: (scope async): a callback, to be invoked when the operation is done + * @user_data: (closure): caller-specific data to be passed to @callback + * + * Asynchronously asks the agent to delete all saved secrets belonging to + * @connection. + * + * Virtual: delete_secrets + */ +void +nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self, + NMConnection *connection, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + + NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self, + connection, + nm_connection_get_path (connection), + callback, + user_data); +} + +/**************************************************************/ + +static gboolean +validate_identifier (const char *identifier) +{ + const char *p = identifier; + size_t id_len; + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen (identifier); + if (id_len < 3 || id_len > 255) + return FALSE; + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) + return FALSE; + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) + return FALSE; + if ((*p == '.') && (*(p + 1) == '.')) + return FALSE; + p++; + } + + return TRUE; +} + +static void +nm_secret_agent_old_init (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new (); + _nm_dbus_bind_properties (self, priv->dbus_secret_agent); + _nm_dbus_bind_methods (self, priv->dbus_secret_agent, + "GetSecrets", impl_secret_agent_old_get_secrets, + "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets, + "DeleteSecrets", impl_secret_agent_old_delete_secrets, + "SaveSecrets", impl_secret_agent_old_save_secrets, + NULL); +} + +static void +init_common (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + priv->private_bus = _nm_dbus_is_connection_private (priv->bus); + + if (priv->private_bus == FALSE) { + priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION; + + g_signal_connect (priv->manager_proxy, "notify::g-name-owner", + G_CALLBACK (name_owner_changed), self); + } +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + GDBusProxy *proxy; + + priv->bus = _nm_dbus_new_connection (cancellable, error); + if (!priv->bus) + return FALSE; + + proxy = _nm_dbus_new_proxy_for_connection (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + cancellable, error); + if (!proxy) + return FALSE; + priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy); + + init_common (self); + + if (priv->auto_register) + return nm_secret_agent_old_register (self, cancellable, error); + else + return TRUE; +} + +typedef struct { + NMSecretAgentOld *self; + GCancellable *cancellable; + GSimpleAsyncResult *simple; +} NMSecretAgentOldInitData; + +static void +init_async_complete (NMSecretAgentOldInitData *init_data, GError *error) +{ + if (!error) + g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE); + else + g_simple_async_result_take_error (init_data->simple, error); + + g_simple_async_result_complete_in_idle (init_data->simple); + + g_object_unref (init_data->simple); + g_clear_object (&init_data->cancellable); + g_slice_free (NMSecretAgentOldInitData, init_data); +} + +static void +init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); + NMSecretAgentOldInitData *init_data = user_data; + GError *error = NULL; + + nm_secret_agent_old_register_finish (self, result, &error); + init_async_complete (init_data, error); +} + +static void +init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOldInitData *init_data = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self); + GDBusProxy *proxy; + GError *error = NULL; + + proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error); + if (!proxy) { + init_async_complete (init_data, error); + return; + } + priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy); + + init_common (init_data->self); + + if (priv->auto_register) { + nm_secret_agent_old_register_async (init_data->self, init_data->cancellable, + init_async_registered, init_data); + } else + init_async_complete (init_data, NULL); +} + +static void +init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOldInitData *init_data = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self); + GError *error = NULL; + + priv->bus = _nm_dbus_new_connection_finish (result, &error); + if (!priv->bus) { + init_async_complete (init_data, error); + return; + } + + _nm_dbus_new_proxy_for_connection_async (priv->bus, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + init_data->cancellable, + init_async_got_proxy, init_data); +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); + NMSecretAgentOldInitData *init_data; + + init_data = g_slice_new (NMSecretAgentOldInitData); + init_data->self = self; + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); + + _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IDENTIFIER: + g_value_set_string (value, priv->identifier); + break; + case PROP_AUTO_REGISTER: + g_value_set_boolean (value, priv->auto_register); + break; + case PROP_REGISTERED: + g_value_set_boolean (value, priv->registered); + break; + case PROP_CAPABILITIES: + g_value_set_flags (value, priv->capabilities); + 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) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object); + const char *identifier; + + switch (prop_id) { + case PROP_IDENTIFIER: + identifier = g_value_get_string (value); + + g_return_if_fail (validate_identifier (identifier)); + + g_free (priv->identifier); + priv->identifier = g_strdup (identifier); + break; + case PROP_AUTO_REGISTER: + priv->auto_register = g_value_get_boolean (value); + break; + case PROP_CAPABILITIES: + priv->capabilities = g_value_get_flags (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (priv->registered) + nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL); + + g_clear_pointer (&priv->identifier, g_free); + + while (priv->pending_gets) + get_secrets_info_finalize (self, priv->pending_gets->data); + + g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, self); + g_object_unref (priv->dbus_secret_agent); + + g_clear_object (&priv->manager_proxy); + g_clear_object (&priv->bus); + + G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object); +} + +static void +nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + /** + * NMSecretAgentOld:identifier: + * + * Identifies this agent; only one agent in each user session may use the + * same identifier. Identifier formatting follows the same rules as + * D-Bus bus names with the exception that the ':' character is not + * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the + * identifier is limited in length to 255 characters with a minimum + * of 3 characters. An example valid identifier is 'org.gnome.nm-applet' + * (without quotes). + **/ + g_object_class_install_property + (object_class, PROP_IDENTIFIER, + g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSecretAgentOld:auto-register: + * + * If %TRUE (the default), the agent will always be registered when + * NetworkManager is running; if NetworkManager exits and restarts, the + * agent will re-register itself automatically. + * + * In particular, if this property is %TRUE at construct time, then the + * agent will register itself with NetworkManager during + * construction/initialization, and initialization will fail with an error + * if the agent is unable to register itself. + * + * If the property is %FALSE, the agent will not automatically register with + * NetworkManager, and nm_secret_agent_old_register() or + * nm_secret_agent_old_register_async() must be called to register it. + * + * Calling nm_secret_agent_old_unregister() will suppress auto-registration + * until nm_secret_agent_old_register() is called, which re-enables + * auto-registration. This ensures that the agent remains un-registered when + * you expect it to be unregistered. + **/ + g_object_class_install_property + (object_class, PROP_AUTO_REGISTER, + g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSecretAgentOld:registered: + * + * %TRUE if the agent is registered with NetworkManager, %FALSE if not. + **/ + g_object_class_install_property + (object_class, PROP_REGISTERED, + g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMSecretAgentOld:capabilities: + * + * A bitfield of %NMSecretAgentCapabilities. + **/ + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "", + NM_TYPE_SECRET_AGENT_CAPABILITIES, + NM_SECRET_AGENT_CAPABILITY_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_AGENT_MANAGER, + NMDBUS_TYPE_AGENT_MANAGER_PROXY); +} + +static void +nm_secret_agent_old_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} + +static void +nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = init_async; + iface->init_finish = init_finish; +} diff --git a/libnm/nm-secret-agent-old.h b/libnm/nm-secret-agent-old.h new file mode 100644 index 00000000..6198e2c0 --- /dev/null +++ b/libnm/nm-secret-agent-old.h @@ -0,0 +1,238 @@ +/* -*- 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. + * + * Copyright 2010 - 2011 Red Hat, Inc. + */ + +#ifndef __NM_SECRET_AGENT_OLD_H__ +#define __NM_SECRET_AGENT_OLD_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SECRET_AGENT_OLD (nm_secret_agent_old_get_type ()) +#define NM_SECRET_AGENT_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOld)) +#define NM_SECRET_AGENT_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass)) +#define NM_IS_SECRET_AGENT_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT_OLD)) +#define NM_IS_SECRET_AGENT_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT_OLD)) +#define NM_SECRET_AGENT_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass)) + +#define NM_SECRET_AGENT_OLD_IDENTIFIER "identifier" +#define NM_SECRET_AGENT_OLD_AUTO_REGISTER "auto-register" +#define NM_SECRET_AGENT_OLD_REGISTERED "registered" +#define NM_SECRET_AGENT_OLD_CAPABILITIES "capabilities" + +typedef struct { + GObject parent; +} NMSecretAgentOld; + +/** + * NMSecretAgentOldGetSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were requested, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @secrets: the #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing the requested + * secrets (as created by nm_connection_to_dbus() for example). Each key in @secrets + * should be the name of a #NMSetting object (like "802-11-wireless-security") + * and each value should be an %NM_VARIANT_TYPE_SETTING variant. The sub-dicts + * map string:value, where the string is the setting property name (like "psk") + * and the value is the secret + * @error: if the secrets request failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to retrieve secrets. When the + * #NMSecretAgentOld subclass has finished retrieving secrets and is ready to + * return them, or to return an error, this function should be called with + * those secrets or the error. + * + * To easily create the dictionary to return the Wi-Fi PSK, you could do + * something like this: + * + * Creating a secrets dictionary + * + * NMConnection *secrets; + * NMSettingWirelessSecurity *s_wsec; + * GVariant *secrets_dict; + * + * secrets = nm_simple_connection_new (); + * s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + * g_object_set (G_OBJECT (s_wsec), + * NM_SETTING_WIRELESS_SECURITY_PSK, "my really cool PSK", + * NULL); + * nm_connection_add_setting (secrets, NM_SETTING (s_wsec)); + * secrets_dict = nm_connection_to_dbus (secrets, NM_CONNECTION_SERIALIZE_ALL); + * + * (call the NMSecretAgentOldGetSecretsFunc with secrets_dict) + * + * g_object_unref (secrets); + * g_variant_unref (secrets_dict); + * + * + */ +typedef void (*NMSecretAgentOldGetSecretsFunc) (NMSecretAgentOld *agent, + NMConnection *connection, + GVariant *secrets, + GError *error, + gpointer user_data); + +/** + * NMSecretAgentOldSaveSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were to be saved, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @error: if the saving secrets failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to save secrets. When the + * #NMSecretAgentOld subclass has finished saving the secrets, this function + * should be called. + */ +typedef void (*NMSecretAgentOldSaveSecretsFunc) (NMSecretAgentOld *agent, + NMConnection *connection, + GError *error, + gpointer user_data); + +/** + * NMSecretAgentOldDeleteSecretsFunc: + * @agent: the secret agent object + * @connection: (transfer none): the connection for which secrets were to be deleted, + * note that this object will be unrefed after the callback has returned, use + * g_object_ref()/g_object_unref() if you want to use this object after the callback + * has returned + * @error: if the deleting secrets failed, give a descriptive error here + * @user_data: caller-specific data to be passed to the function + * + * Called as a result of a request by NM to delete secrets. When the + * #NMSecretAgentOld subclass has finished deleting the secrets, this function + * should be called. + */ +typedef void (*NMSecretAgentOldDeleteSecretsFunc) (NMSecretAgentOld *agent, + NMConnection *connection, + GError *error, + gpointer user_data); + +typedef struct { + GObjectClass parent; + + /* Virtual methods for subclasses */ + + /* Called when the subclass should retrieve and return secrets. Subclass + * must copy or reference any arguments it may require after returning from + * this method, as the arguments will freed (except for 'self', 'callback', + * and 'user_data' of course). If the request is canceled, the callback + * should still be called, but with the + * NM_SECRET_AGENT_OLD_ERROR_AGENT_CANCELED error. + */ + void (*get_secrets) (NMSecretAgentOld *self, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data); + + /* Called when the subclass should cancel an outstanding request to + * get secrets for a given connection. Canceling the request MUST + * call the callback that was passed along with the initial get_secrets + * call, sending the NM_SECRET_AGENT_OLD_ERROR/ + * NM_SECRET_AGENT_OLD_ERROR_AGENT_CANCELED error to that callback. + */ + void (*cancel_get_secrets) (NMSecretAgentOld *self, + const char *connection_path, + const char *setting_name); + + /* Called when the subclass should save the secrets contained in the + * connection to backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'self', 'callback', and 'user_data' + * of course). + */ + void (*save_secrets) (NMSecretAgentOld *self, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data); + + /* Called when the subclass should delete the secrets contained in the + * connection from backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'self', 'callback', and 'user_data' + * of course). + */ + void (*delete_secrets) (NMSecretAgentOld *self, + NMConnection *connection, + const char *connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data); + + /*< private >*/ + gpointer padding[8]; +} NMSecretAgentOldClass; + +GType nm_secret_agent_old_get_type (void); + +gboolean nm_secret_agent_old_register (NMSecretAgentOld *self, + GCancellable *cancellable, + GError **error); +void nm_secret_agent_old_register_async (NMSecretAgentOld *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_secret_agent_old_register_finish (NMSecretAgentOld *self, + GAsyncResult *result, + GError **error); + +gboolean nm_secret_agent_old_unregister (NMSecretAgentOld *self, + GCancellable *cancellable, + GError **error); +void nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self, + GAsyncResult *result, + GError **error); + +gboolean nm_secret_agent_old_get_registered (NMSecretAgentOld *self); + +void nm_secret_agent_old_get_secrets (NMSecretAgentOld *self, + NMConnection *connection, + const char *setting_name, + const char **hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer user_data); + +void nm_secret_agent_old_save_secrets (NMSecretAgentOld *self, + NMConnection *connection, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer user_data); + +void nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self, + NMConnection *connection, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer user_data); + +G_END_DECLS + +#endif /* __NM_SECRET_AGENT_OLD_H__ */ diff --git a/libnm/nm-setting-docs-overrides.xml b/libnm/nm-setting-docs-overrides.xml new file mode 100644 index 00000000..3a52fd7c --- /dev/null +++ b/libnm/nm-setting-docs-overrides.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libnm/nm-setting-docs.xml b/libnm/nm-setting-docs.xml new file mode 100644 index 00000000..50acecf1 --- /dev/null +++ b/libnm/nm-setting-docs.xml @@ -0,0 +1,305 @@ + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libnm/nm-types.h b/libnm/nm-types.h new file mode 100644 index 00000000..ee1ed643 --- /dev/null +++ b/libnm/nm-types.h @@ -0,0 +1,53 @@ +/* -*- 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 2014 Red Hat, Inc. + */ + +#ifndef __NM_TYPES_H__ +#define __NM_TYPES_H__ + +#include + +#include +#include + +typedef struct _NMAccessPoint NMAccessPoint; +typedef struct _NMActiveConnection NMActiveConnection; +typedef struct _NMClient NMClient; +typedef struct _NMDevice NMDevice; +typedef struct _NMDeviceAdsl NMDeviceAdsl; +typedef struct _NMDeviceBond NMDeviceBond; +typedef struct _NMDeviceBridge NMDeviceBridge; +typedef struct _NMDeviceBt NMDeviceBt; +typedef struct _NMDeviceEthernet NMDeviceEthernet; +typedef struct _NMDeviceGeneric NMDeviceGeneric; +typedef struct _NMDeviceInfiniband NMDeviceInfiniband; +typedef struct _NMDeviceModem NMDeviceModem; +typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh; +typedef struct _NMDeviceTeam NMDeviceTeam; +typedef struct _NMDeviceVlan NMDeviceVlan; +typedef struct _NMDeviceWifi NMDeviceWifi; +typedef struct _NMDeviceWimax NMDeviceWimax; +typedef struct _NMDhcpConfig NMDhcpConfig; +typedef struct _NMIPConfig NMIPConfig; +typedef struct _NMObject NMObject; +typedef struct _NMRemoteConnection NMRemoteConnection; +typedef struct _NMVpnConnection NMVpnConnection; +typedef struct _NMWimaxNsp NMWimaxNsp; + +#endif /* NM_TYPES_H */ diff --git a/libnm/nm-vpn-connection.c b/libnm/nm-vpn-connection.c new file mode 100644 index 00000000..f46dc0ca --- /dev/null +++ b/libnm/nm-vpn-connection.c @@ -0,0 +1,233 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include "nm-vpn-connection.h" +#include "nm-dbus-interface.h" +#include "nm-utils.h" +#include "nm-object-private.h" +#include "nm-active-connection.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-vpn-connection.h" + +G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) + +#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVpnConnectionPrivate)) + +typedef struct { + char *banner; + NMVpnConnectionState vpn_state; +} NMVpnConnectionPrivate; + +enum { + PROP_0, + PROP_VPN_STATE, + PROP_BANNER, + + LAST_PROP +}; + +enum { + VPN_STATE_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +/** + * nm_vpn_connection_get_banner: + * @vpn: a #NMVpnConnection + * + * Gets the VPN login banner of the active #NMVpnConnection. + * + * Returns: the VPN login banner of the VPN connection. This is the internal + * string used by the connection, and must not be modified. + **/ +const char * +nm_vpn_connection_get_banner (NMVpnConnection *vpn) +{ + NMVpnConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL); + + priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn); + + if (priv->vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED) + return NULL; + + return priv->banner; +} + +/** + * nm_vpn_connection_get_vpn_state: + * @vpn: a #NMVpnConnection + * + * Gets the current #NMVpnConnection state. + * + * Returns: the VPN state of the active VPN connection. + **/ +NMVpnConnectionState +nm_vpn_connection_get_vpn_state (NMVpnConnection *vpn) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_CONNECTION_STATE_UNKNOWN); + + return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->vpn_state; +} + +static void +vpn_state_changed_proxy (NMDBusVpnConnection *proxy, + guint vpn_state, + guint reason, + gpointer user_data) +{ + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + if (priv->vpn_state != vpn_state) { + priv->vpn_state = vpn_state; + g_signal_emit (connection, signals[VPN_STATE_CHANGED], 0, vpn_state, reason); + g_object_notify (G_OBJECT (connection), NM_VPN_CONNECTION_VPN_STATE); + } +} + +/*****************************************************************************/ + +static void +nm_vpn_connection_init (NMVpnConnection *connection) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + priv->vpn_state = NM_VPN_CONNECTION_STATE_UNKNOWN; +} + +static void +init_dbus (NMObject *object) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_VPN_CONNECTION_BANNER, &priv->banner }, + { NM_VPN_CONNECTION_VPN_STATE, &priv->vpn_state }, + { NULL }, + }; + GDBusProxy *proxy; + + NM_OBJECT_CLASS (nm_vpn_connection_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_VPN_CONNECTION, + property_info); + + proxy = _nm_object_get_proxy (object, NM_DBUS_INTERFACE_VPN_CONNECTION); + g_signal_connect (proxy, "vpn-state-changed", + G_CALLBACK (vpn_state_changed_proxy), object); +} + +static void +finalize (GObject *object) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + + g_free (priv->banner); + + G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMVpnConnection *self = NM_VPN_CONNECTION (object); + + switch (prop_id) { + case PROP_VPN_STATE: + g_value_set_enum (value, nm_vpn_connection_get_vpn_state (self)); + break; + case PROP_BANNER: + g_value_set_string (value, nm_vpn_connection_get_banner (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (connection_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (connection_class); + + g_type_class_add_private (connection_class, sizeof (NMVpnConnectionPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_VPN_CONNECTION); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_VPN_CONNECTION, + NMDBUS_TYPE_VPN_CONNECTION_PROXY); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMVpnConnection:vpn-state: + * + * The VPN state of the active VPN connection. + **/ + g_object_class_install_property + (object_class, PROP_VPN_STATE, + g_param_spec_enum (NM_VPN_CONNECTION_VPN_STATE, "", "", + NM_TYPE_VPN_CONNECTION_STATE, + NM_VPN_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnConnection:banner: + * + * The VPN login banner of the active VPN connection. + **/ + g_object_class_install_property + (object_class, PROP_BANNER, + g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + signals[VPN_STATE_CHANGED] = + g_signal_new ("vpn-state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnConnectionClass, vpn_state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + G_TYPE_UINT, G_TYPE_UINT); +} diff --git a/libnm/nm-vpn-connection.h b/libnm/nm-vpn-connection.h new file mode 100644 index 00000000..349de41e --- /dev/null +++ b/libnm/nm-vpn-connection.h @@ -0,0 +1,67 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef __NM_VPN_CONNECTION_H__ +#define __NM_VPN_CONNECTION_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) +#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnection)) +#define NM_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) +#define NM_IS_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION)) +#define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_CONNECTION)) +#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) + +#define NM_VPN_CONNECTION_VPN_STATE "vpn-state" +#define NM_VPN_CONNECTION_BANNER "banner" + +struct _NMVpnConnection { + NMActiveConnection parent; +}; + +typedef struct { + NMActiveConnectionClass parent; + + /* Signals */ + void (*vpn_state_changed) (NMVpnConnection *connection, + NMVpnConnectionState state, + NMVpnConnectionStateReason reason); + + /*< private >*/ + gpointer padding[4]; +} NMVpnConnectionClass; + +GType nm_vpn_connection_get_type (void); + +NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *vpn); +const char * nm_vpn_connection_get_banner (NMVpnConnection *vpn); + +G_END_DECLS + +#endif /* __NM_VPN_CONNECTION_H__ */ diff --git a/libnm/nm-vpn-editor-plugin.c b/libnm/nm-vpn-editor-plugin.c new file mode 100644 index 00000000..904a6be4 --- /dev/null +++ b/libnm/nm-vpn-editor-plugin.c @@ -0,0 +1,181 @@ +/* -*- 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. + * + * Copyright 2008 - 2010 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#include "config.h" + +#include "nm-vpn-editor-plugin.h" + +static void nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface); + +G_DEFINE_INTERFACE (NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT) + +static void +nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface) +{ + /* Properties */ + + /** + * NMVpnEditorPlugin:name: + * + * Short display name of the VPN plugin. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:description: + * + * Longer description of the VPN plugin. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_DESCRIPTION, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnEditorPlugin:service: + * + * D-Bus service name of the plugin's VPN service. + */ + g_object_interface_install_property (iface, + g_param_spec_string (NM_VPN_EDITOR_PLUGIN_SERVICE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +/** + * nm_vpn_editor_plugin_get_editor: + * + * Returns: (transfer full): + */ +NMVpnEditor * +nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_editor (plugin, connection, error); +} + +NMVpnEditorPluginCapability +nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), 0); + + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_capabilities (plugin); +} + +/** + * nm_vpn_editor_plugin_import: + * + * Returns: (transfer full): + */ +NMConnection * +nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin, + const char *path, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) { + g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file != NULL, NULL); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file (plugin, path, error); + } + return NULL; +} + +gboolean +nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE); + + if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) { + g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file != NULL, FALSE); + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file (plugin, path, connection, error); + } + return FALSE; +} + +char * +nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin, + NMConnection *connection) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL); + + if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename) + return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename (plugin, connection); + return NULL; +} + + +static void nm_vpn_editor_default_init (NMVpnEditorInterface *iface); + +G_DEFINE_INTERFACE (NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT) + +static void +nm_vpn_editor_default_init (NMVpnEditorInterface *iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (iface); + + /* Signals */ + g_signal_new ("changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnEditorInterface, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * nm_vpn_editor_get_widget: + * + * Returns: (transfer none): + */ +GObject * +nm_vpn_editor_get_widget (NMVpnEditor *editor) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL); + + return NM_VPN_EDITOR_GET_INTERFACE (editor)->get_widget (editor); +} + +gboolean +nm_vpn_editor_update_connection (NMVpnEditor *editor, + NMConnection *connection, + GError **error) +{ + g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), FALSE); + + if (error) + g_return_val_if_fail (*error == NULL, FALSE); + + return NM_VPN_EDITOR_GET_INTERFACE (editor)->update_connection (editor, connection, error); +} diff --git a/libnm/nm-vpn-editor-plugin.h b/libnm/nm-vpn-editor-plugin.h new file mode 100644 index 00000000..5910aa36 --- /dev/null +++ b/libnm/nm-vpn-editor-plugin.h @@ -0,0 +1,189 @@ +/* -*- 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. + * + * Copyright 2008 - 2014 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_VPN_EDITOR_PLUGIN_H__ +#define __NM_VPN_EDITOR_PLUGIN_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin; +typedef struct _NMVpnEditor NMVpnEditor; + +/* Plugin's factory function that returns a GObject that implements + * NMVpnEditorPlugin. + */ +#ifndef __GI_SCANNER__ +typedef NMVpnEditorPlugin * (*NMVpnEditorPluginFactory) (GError **error); +NMVpnEditorPlugin *nm_vpn_editor_plugin_factory (GError **error); +#endif + + +/**************************************************/ +/* Editor plugin interface */ +/**************************************************/ + +#define NM_TYPE_VPN_EDITOR_PLUGIN (nm_vpn_editor_plugin_get_type ()) +#define NM_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPlugin)) +#define NM_IS_VPN_EDITOR_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN)) +#define NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR_PLUGIN, NMVpnEditorPluginInterface)) + +/** + * NMVpnEditorPluginCapability: + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: unknown or no capability + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: the plugin can import new connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: the plugin can export connections + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: the plugin supports IPv6 addressing + * + * Flags that indicate certain capabilities of the plugin to editor programs. + **/ +typedef enum /*< flags >*/ { + NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04 +} NMVpnEditorPluginCapability; + +/* Short display name of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_NAME "name" + +/* Longer description of the VPN plugin */ +#define NM_VPN_EDITOR_PLUGIN_DESCRIPTION "description" + +/* D-Bus service name of the plugin's VPN service */ +#define NM_VPN_EDITOR_PLUGIN_SERVICE "service" + +/** + * NMVpnEditorPluginInterface: + * @g_iface: the parent interface + * @get_editor: returns an #NMVpnEditor, pre-filled with values from @connection + * if non-%NULL. + * @get_capabilities: returns a bitmask of capabilities. + * @import_from_file: Try to import a connection from the specified path. On + * success, return a partial #NMConnection object. On error, return %NULL and + * set @error with additional information. Note that @error can be %NULL, in + * which case no additional error information should be provided. + * @export_to_file: Export the given connection to the specified path. Return + * %TRUE on success. On error, return %FALSE and set @error with additional + * error information. Note that @error can be %NULL, in which case no + * additional error information should be provided. + * @get_suggested_filename: For a given connection, return a suggested file + * name. Returned value will be %NULL or a suggested file name to be freed by + * the caller. + * + * Interface for VPN editor plugins. + */ +typedef struct { + GTypeInterface g_iface; + + NMVpnEditor * (*get_editor) (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error); + + NMVpnEditorPluginCapability (*get_capabilities) (NMVpnEditorPlugin *plugin); + + NMConnection * (*import_from_file) (NMVpnEditorPlugin *plugin, + const char *path, + GError **error); + + gboolean (*export_to_file) (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error); + + char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection); +} NMVpnEditorPluginInterface; + +GType nm_vpn_editor_plugin_get_type (void); + +NMVpnEditor *nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin, + NMConnection *connection, + GError **error); + +NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin); + +NMConnection *nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin, + const char *path, + GError **error); +gboolean nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin, + const char *path, + NMConnection *connection, + GError **error); +char *nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin, + NMConnection *connection); + +/**************************************************/ +/* Editor interface */ +/**************************************************/ + +#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type ()) +#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor)) +#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR)) +#define NM_VPN_EDITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface)) + +/** + * NMVpnEditorInterface: + * @g_iface: the parent interface + * @get_widget: return the #GtkWidget for the VPN editor's UI + * @placeholder: not currently used + * @update_connection: called to save the user-entered options to the connection + * object. Should return %FALSE and set @error if the current options are + * invalid. @error should contain enough information for the plugin to + * determine which UI widget is invalid at a later point in time. For + * example, creating unique error codes for what error occurred and populating + * the message field of @error with the name of the invalid property. + * @changed: emitted when the value of a UI widget changes. May trigger a + * validity check via @update_connection to write values to the connection. + * + * Interface for editing a specific #NMConnection + */ +typedef struct { + GTypeInterface g_iface; + + GObject * (*get_widget) (NMVpnEditor *editor); + + void (*placeholder) (void); + + gboolean (*update_connection) (NMVpnEditor *editor, + NMConnection *connection, + GError **error); + + void (*changed) (NMVpnEditor *editor); +} NMVpnEditorInterface; + +GType nm_vpn_editor_get_type (void); + +GObject * nm_vpn_editor_get_widget (NMVpnEditor *editor); + +gboolean nm_vpn_editor_update_connection (NMVpnEditor *editor, + NMConnection *connection, + GError **error); + +G_END_DECLS + +#endif /* NM_VPN_EDITOR_PLUGIN_H */ diff --git a/libnm/nm-vpn-plugin-old.c b/libnm/nm-vpn-plugin-old.c new file mode 100644 index 00000000..e6843f7e --- /dev/null +++ b/libnm/nm-vpn-plugin-old.c @@ -0,0 +1,1206 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2008 Red Hat, Inc. + */ + +/* This interface is expected to be deprecated in NM 1.2, at which point there + * will be a new "NMVpnPlugin" class to replace it. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include "nm-glib-compat.h" +#include "nm-vpn-plugin-old.h" +#include "nm-enum-types.h" +#include "nm-utils.h" +#include "nm-connection.h" +#include "nm-dbus-helpers.h" +#include "nm-core-internal.h" +#include "nm-simple-connection.h" + +#include "nmdbus-vpn-plugin.h" + +#define NM_VPN_PLUGIN_OLD_QUIT_TIMER 20 + +static void nm_vpn_plugin_old_initable_iface_init (GInitableIface *iface); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMVpnPluginOld, nm_vpn_plugin_old, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_vpn_plugin_old_initable_iface_init); + ) + +typedef struct { + NMVpnServiceState state; + + /* DBUS-y stuff */ + GDBusConnection *connection; + NMDBusVpnPlugin *dbus_vpn_plugin_old; + char *dbus_service_name; + + /* Temporary stuff */ + guint connect_timer; + guint quit_timer; + guint fail_stop_id; + gboolean interactive; + + gboolean got_config; + gboolean has_ip4, got_ip4; + gboolean has_ip6, got_ip6; + + /* Config stuff copied from config to ip4config */ + char *banner, *tundev, *gateway, *mtu; +} NMVpnPluginOldPrivate; + +#define NM_VPN_PLUGIN_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldPrivate)) + +enum { + STATE_CHANGED, + CONFIG, + IP4_CONFIG, + IP6_CONFIG, + LOGIN_BANNER, + FAILURE, + QUIT, + SECRETS_REQUIRED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + PROP_DBUS_SERVICE_NAME, + PROP_STATE, + + LAST_PROP +}; + +static GSList *active_plugins = NULL; + + +static void +nm_vpn_plugin_old_set_connection (NMVpnPluginOld *plugin, + GDBusConnection *connection) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + g_clear_object (&priv->connection); + + priv->connection = g_object_ref (connection); +} + +/** + * nm_vpn_plugin_old_get_connection: + * + * Returns: (transfer full): + */ +GDBusConnection * +nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin) +{ + GDBusConnection *connection; + + g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), NULL); + + connection = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->connection; + + if (connection) + g_object_ref (connection); + + return connection; +} + +NMVpnServiceState +nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin) +{ + g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), NM_VPN_SERVICE_STATE_UNKNOWN); + + return NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin)->state; +} + +void +nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin, + NMVpnServiceState state) +{ + NMVpnPluginOldPrivate *priv; + + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + + priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + if (priv->state != state) { + priv->state = state; + g_signal_emit (plugin, signals[STATE_CHANGED], 0, state); + } +} + +void +nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin, + const char *banner) +{ + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + g_return_if_fail (banner != NULL); + + g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner); +} + +void +nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin, + NMVpnPluginFailure reason) +{ + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + + g_signal_emit (plugin, signals[FAILURE], 0, reason); +} + +gboolean +nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, GError **err) +{ + gboolean ret = FALSE; + NMVpnServiceState state; + + g_return_val_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin), FALSE); + + state = nm_vpn_plugin_old_get_state (plugin); + switch (state) { + case NM_VPN_SERVICE_STATE_STOPPING: + g_set_error (err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, + "%s", + "Could not process the request because the VPN connection is already being stopped."); + break; + case NM_VPN_SERVICE_STATE_STOPPED: + g_set_error (err, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, + "%s", + "Could not process the request because no VPN connection was active."); + break; + case NM_VPN_SERVICE_STATE_STARTING: + case NM_VPN_SERVICE_STATE_STARTED: + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING); + ret = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->disconnect (plugin, err); + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED); + break; + case NM_VPN_SERVICE_STATE_INIT: + ret = TRUE; + break; + + default: + g_warning ("Unhandled VPN service state %d", state); + g_assert_not_reached (); + break; + } + + return ret; +} + +static void +nm_vpn_plugin_old_emit_quit (NMVpnPluginOld *plugin) +{ + g_signal_emit (plugin, signals[QUIT], 0); +} + +static gboolean +connect_timer_expired (gpointer data) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data); + GError *err = NULL; + + g_message ("Connect timer expired, disconnecting."); + nm_vpn_plugin_old_disconnect (plugin, &err); + if (err) { + g_warning ("Disconnect failed: %s", err->message); + g_error_free (err); + } + + return FALSE; +} + +static gboolean +quit_timer_expired (gpointer data) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data); + + nm_vpn_plugin_old_emit_quit (plugin); + + return FALSE; +} + +static gboolean +fail_stop (gpointer data) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (data); + + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED); + return FALSE; +} + +static void +schedule_fail_stop (NMVpnPluginOld *plugin) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + if (priv->fail_stop_id) + g_source_remove (priv->fail_stop_id); + priv->fail_stop_id = g_idle_add (fail_stop, plugin); +} + +void +nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, + GVariant *config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + g_return_if_fail (config != NULL); + + priv->got_config = TRUE; + + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &priv->has_ip4); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &priv->has_ip6); + + g_warn_if_fail (priv->has_ip4 || priv->has_ip6); + + /* Record the items that need to also be inserted into the + * ip4config, for compatibility with older daemons. + */ + g_clear_pointer (&priv->banner, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &priv->banner); + g_clear_pointer (&priv->tundev, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &priv->tundev); + g_clear_pointer (&priv->gateway, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "&s", &priv->gateway); + g_clear_pointer (&priv->mtu, g_free); + g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU, "&s", &priv->mtu); + + g_signal_emit (plugin, signals[CONFIG], 0, config); +} + +void +nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, + GVariant *ip4_config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + GVariant *combined_config; + GVariantBuilder builder; + GVariantIter iter; + const char *key, *value; + + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + g_return_if_fail (ip4_config != NULL); + + priv->got_ip4 = TRUE; + + /* Old plugins won't send the "config" signal and thus can't send + * NM_VPN_PLUGIN_OLD_CONFIG_HAS_IP4 either. But since they don't support IPv6, + * we can safely assume that, if we don't receive a "config" signal but do + * receive an "ip4-config" signal, the old plugin supports IPv4. + */ + if (!priv->got_config) + priv->has_ip4 = TRUE; + + /* Older NetworkManager daemons expect all config info to be in + * the ip4 config, so they won't even notice the "config" signal + * being emitted. So just copy all of that data into the ip4 + * config too. + */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + g_variant_iter_init (&iter, ip4_config); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) + g_variant_builder_add (&builder, "{ss}", key, value); + + if (priv->banner) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner); + if (priv->tundev) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev); + if (priv->gateway) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway); + if (priv->mtu) + g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu); + + combined_config = g_variant_builder_end (&builder); + g_variant_ref_sink (combined_config); + g_signal_emit (plugin, signals[IP4_CONFIG], 0, combined_config); + g_variant_unref (combined_config); + + if ( priv->has_ip4 == priv->got_ip4 + && priv->has_ip6 == priv->got_ip6) + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +void +nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, + GVariant *ip6_config) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin)); + g_return_if_fail (ip6_config != NULL); + + priv->got_ip6 = TRUE; + g_signal_emit (plugin, signals[IP6_CONFIG], 0, ip6_config); + + if ( priv->has_ip4 == priv->got_ip4 + && priv->has_ip6 == priv->got_ip6) + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED); +} + +static void +connect_timer_removed (gpointer data) +{ + NM_VPN_PLUGIN_OLD_GET_PRIVATE (data)->connect_timer = 0; +} + +static void +connect_timer_start (NMVpnPluginOld *plugin) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + priv->connect_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + 60, + connect_timer_expired, + plugin, + connect_timer_removed); +} + +static void +_connect_generic (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + GVariant *details) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + NMVpnPluginOldClass *vpn_class = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin); + NMConnection *connection; + gboolean success = FALSE; + GError *error = NULL; + + if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && + priv->state != NM_VPN_SERVICE_STATE_INIT) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not start connection: wrong plugin state %d", + priv->state); + return; + } + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); + } + + priv->interactive = FALSE; + if (details && !vpn_class->connect_interactive) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Plugin does not implement ConnectInteractive()"); + return; + } + + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + + if (details) { + priv->interactive = TRUE; + success = vpn_class->connect_interactive (plugin, connection, details, &error); + } else + success = vpn_class->connect (plugin, connection, &error); + + if (success) { + g_dbus_method_invocation_return_value (context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); + } else { + g_dbus_method_invocation_take_error (context, error); + + /* Stop the plugin from an idle handler so that the Connect + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); + } + + g_object_unref (connection); +} + +static void +impl_vpn_plugin_old_connect (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *connection, + gpointer user_data) +{ + _connect_generic (plugin, context, connection, NULL); +} + +static void +impl_vpn_plugin_old_connect_interactive (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *connection, + GVariant *details, + gpointer user_data) +{ + _connect_generic (plugin, context, connection, details); +} + +/***************************************************************/ + +static void +impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) +{ + NMConnection *connection; + char *setting_name; + gboolean needed; + GError *error = NULL; + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + error->message); + g_error_free (error); + return; + } + + if (!NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->need_secrets) { + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); + return; + } + + needed = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->need_secrets (plugin, connection, &setting_name, &error); + if (error) { + g_dbus_method_invocation_take_error (context, error); + return; + } + + if (needed) { + g_assert (setting_name); + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", setting_name)); + g_free (setting_name); + } else { + /* No secrets required */ + g_dbus_method_invocation_return_value (context, + g_variant_new ("(s)", "")); + } +} + +static void +impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *properties, + gpointer user_data) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + NMConnection *connection; + GError *error = NULL; + gboolean success; + + if (priv->state != NM_VPN_SERVICE_STATE_STARTING) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_WRONG_STATE, + "Could not accept new secrets: wrong plugin state %d", + priv->state); + return; + } + + connection = nm_simple_connection_new_from_dbus (properties, &error); + if (!connection) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + "Invalid connection: (%d) %s", + error->code, error->message); + g_clear_error (&error); + return; + } + + if (!NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets) { + g_dbus_method_invocation_return_error (context, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED, + "Could not accept new secrets: plugin cannot process interactive secrets"); + g_object_unref (connection); + return; + } + + success = NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets (plugin, connection, &error); + if (success) { + g_dbus_method_invocation_return_value (context, NULL); + + /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ + connect_timer_start (plugin); + } else { + g_dbus_method_invocation_take_error (context, error); + + /* Stop the plugin from and idle handler so that the NewSecrets + * method return gets sent before the STOP StateChanged signal. + */ + schedule_fail_stop (plugin); + } + + g_object_unref (connection); +} + +/** + * nm_vpn_plugin_old_secrets_required: + * @plugin: the #NMVpnPluginOld + * @message: an information message about why secrets are required, if any + * @hints: VPN specific secret names for required new secrets + * + * Called by VPN plugin implementations to signal to NetworkManager that secrets + * are required during the connection process. This signal may be used to + * request new secrets when the secrets originally provided by NetworkManager + * are insufficient, or the VPN process indicates that it needs additional + * information to complete the request. + */ +void +nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, + const char *message, + const char **hints) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + /* Plugin must be able to accept the new secrets if it calls this method */ + g_return_if_fail (NM_VPN_PLUGIN_OLD_GET_CLASS (plugin)->new_secrets); + + /* Plugin cannot call this method if NetworkManager didn't originally call + * ConnectInteractive(). + */ + g_return_if_fail (priv->interactive == TRUE); + + /* Cancel the connect timer since secrets might take a while. It'll + * get restarted when the secrets come back via NewSecrets(). + */ + if (priv->connect_timer) + g_source_remove (priv->connect_timer); + + g_signal_emit (plugin, signals[SECRETS_REQUIRED], 0, message, hints); +} + +/***************************************************************/ + +#define DATA_KEY_TAG "DATA_KEY=" +#define DATA_VAL_TAG "DATA_VAL=" +#define SECRET_KEY_TAG "SECRET_KEY=" +#define SECRET_VAL_TAG "SECRET_VAL=" + +static void +free_secret (gpointer data) +{ + char *secret = data; + + memset (secret, 0, strlen (secret)); + g_free (secret); +} + +/** + * nm_vpn_plugin_old_read_vpn_details: + * @fd: file descriptor to read from, usually stdin (0) + * @out_data: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairs of VPN data items + * @out_secrets: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairsof VPN secrets + * + * Parses key/value pairs from a file descriptor (normally stdin) passed by + * an applet when the applet calls the authentication dialog of the VPN plugin. + * + * Returns: %TRUE if reading values was successful, %FALSE if not + **/ +gboolean +nm_vpn_plugin_old_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets) +{ + GHashTable *data, *secrets; + gboolean success = FALSE; + char *key = NULL, *val = NULL; + GString *line; + gchar c; + + if (out_data) + g_return_val_if_fail (*out_data == NULL, FALSE); + if (out_secrets) + g_return_val_if_fail (*out_secrets == NULL, FALSE); + + data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_secret); + + line = g_string_new (NULL); + + /* Read stdin for data and secret items until we get a DONE */ + while (1) { + ssize_t nr; + GHashTable *hash = NULL; + + errno = 0; + nr = read (fd, &c, 1); + if (nr == -1) { + if (errno == EAGAIN) { + g_usleep (100); + continue; + } + break; + } + + if (c != '\n') { + g_string_append_c (line, c); + continue; + } + + /* Check for the finish marker */ + if (strcmp (line->str, "DONE") == 0) + break; + + /* Otherwise it's a data/secret item */ + if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) { + hash = data; + key = g_strdup (line->str + strlen (DATA_KEY_TAG)); + } else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) { + hash = data; + val = g_strdup (line->str + strlen (DATA_VAL_TAG)); + } else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) { + hash = secrets; + key = g_strdup (line->str + strlen (SECRET_KEY_TAG)); + } else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) { + hash = secrets; + val = g_strdup (line->str + strlen (SECRET_VAL_TAG)); + } + g_string_truncate (line, 0); + + if (key && val && hash) { + g_hash_table_insert (hash, key, val); + key = NULL; + val = NULL; + success = TRUE; /* Got at least one value */ + } + } + + if (success) { + if (out_data) + *out_data = data; + else + g_hash_table_destroy (data); + + if (out_secrets) + *out_secrets = secrets; + else + g_hash_table_destroy (secrets); + } else { + g_hash_table_destroy (data); + g_hash_table_destroy (secrets); + } + + g_string_free (line, TRUE); + return success; +} + +/** + * nm_vpn_plugin_old_get_secret_flags: + * @data: hash table containing VPN key/value pair data items + * @secret_name: VPN secret key name for which to retrieve flags for + * @out_flags: (out): on success, the flags associated with @secret_name + * + * Given a VPN secret key name, attempts to find the corresponding flags data + * item in @data. If found, converts the flags data item to + * #NMSettingSecretFlags and returns it. + * + * Returns: %TRUE if the flag data item was found and successfully converted + * to flags, %FALSE if not + **/ +gboolean +nm_vpn_plugin_old_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags) +{ + char *flag_name; + const char *val; + unsigned long tmp; + gboolean success = FALSE; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (out_flags != NULL, FALSE); + g_return_val_if_fail (*out_flags == NM_SETTING_SECRET_FLAG_NONE, FALSE); + + flag_name = g_strdup_printf ("%s-flags", secret_name); + + /* Try new flags value first */ + val = g_hash_table_lookup (data, flag_name); + if (val) { + errno = 0; + tmp = strtoul (val, NULL, 10); + if (errno == 0 && tmp <= NM_SETTING_SECRET_FLAGS_ALL) { + *out_flags = (NMSettingSecretFlags) tmp; + success = TRUE; + } + } + + g_free (flag_name); + return success; +} + +/***************************************************************/ + +static void +impl_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + gpointer user_data) +{ + GError *error = NULL; + + if (nm_vpn_plugin_old_disconnect (plugin, &error)) + g_dbus_method_invocation_return_value (context, NULL); + else + g_dbus_method_invocation_take_error (context, error); +} + +static void +impl_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_ip4_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + GVariant *config, + gpointer user_data) +{ + nm_vpn_plugin_old_set_ip6_config (plugin, config); + g_dbus_method_invocation_return_value (context, NULL); +} + +static void +impl_vpn_plugin_old_set_failure (NMVpnPluginOld *plugin, + GDBusMethodInvocation *context, + char *reason, + gpointer user_data) +{ + nm_vpn_plugin_old_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG); + g_dbus_method_invocation_return_value (context, NULL); +} + +/*********************************************************************/ + +static void +sigterm_handler (int signum) +{ + g_slist_foreach (active_plugins, (GFunc) nm_vpn_plugin_old_emit_quit, NULL); +} + +static void +setup_unix_signal_handler (void) +{ + struct sigaction action; + sigset_t block_mask; + + action.sa_handler = sigterm_handler; + sigemptyset (&block_mask); + action.sa_mask = block_mask; + action.sa_flags = 0; + sigaction (SIGINT, &action, NULL); + sigaction (SIGTERM, &action, NULL); +} + +/*********************************************************************/ + +static void +one_plugin_destroyed (gpointer data, + GObject *object) +{ + active_plugins = g_slist_remove (active_plugins, object); +} + +static void +nm_vpn_plugin_old_init (NMVpnPluginOld *plugin) +{ + active_plugins = g_slist_append (active_plugins, plugin); + g_object_weak_ref (G_OBJECT (plugin), + one_plugin_destroyed, + NULL); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (initable); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + GDBusConnection *connection = NULL; + GDBusProxy *proxy; + GVariant *ret; + gboolean success = FALSE; + + if (!priv->dbus_service_name) { + g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("No service name specified")); + return FALSE; + } + + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); + if (!connection) + return FALSE; + + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + cancellable, error); + if (!proxy) + goto out; + + ret = g_dbus_proxy_call_sync (proxy, + "RequestName", + g_variant_new ("(s)", priv->dbus_service_name), + G_DBUS_CALL_FLAGS_NONE, 0, + cancellable, error); + g_object_unref (proxy); + if (!ret) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + goto out; + } + g_variant_unref (ret); + + priv->dbus_vpn_plugin_old = nmdbus_vpn_plugin_skeleton_new (); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_vpn_plugin_old), + connection, + NM_VPN_DBUS_PLUGIN_PATH, + error)) + goto out; + + _nm_dbus_bind_properties (plugin, priv->dbus_vpn_plugin_old); + _nm_dbus_bind_methods (plugin, priv->dbus_vpn_plugin_old, + "Connect", impl_vpn_plugin_old_connect, + "ConnectInteractive", impl_vpn_plugin_old_connect_interactive, + "NeedSecrets", impl_vpn_plugin_old_need_secrets, + "NewSecrets", impl_vpn_plugin_old_new_secrets, + "Disconnect", impl_vpn_plugin_old_disconnect, + "SetConfig", impl_vpn_plugin_old_set_config, + "SetIp4Config", impl_vpn_plugin_old_set_ip4_config, + "SetIp6Config", impl_vpn_plugin_old_set_ip6_config, + "SetFailure", impl_vpn_plugin_old_set_failure, + NULL); + + nm_vpn_plugin_old_set_connection (plugin, connection); + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_INIT); + + success = TRUE; + + out: + g_clear_object (&connection); + + return success; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + /* Construct-only */ + priv->dbus_service_name = g_value_dup_string (value); + break; + case PROP_STATE: + nm_vpn_plugin_old_set_state (NM_VPN_PLUGIN_OLD (object), + (NMVpnServiceState) g_value_get_enum (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) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_DBUS_SERVICE_NAME: + g_value_set_string (value, priv->dbus_service_name); + break; + case PROP_STATE: + g_value_set_enum (value, nm_vpn_plugin_old_get_state (NM_VPN_PLUGIN_OLD (object))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (object); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + NMVpnServiceState state; + GError *err = NULL; + + if (priv->fail_stop_id) { + g_source_remove (priv->fail_stop_id); + priv->fail_stop_id = 0; + } + + state = nm_vpn_plugin_old_get_state (plugin); + + if (state == NM_VPN_SERVICE_STATE_STARTED || + state == NM_VPN_SERVICE_STATE_STARTING) + nm_vpn_plugin_old_disconnect (plugin, &err); + + if (err) { + g_warning ("Error disconnecting VPN connection: %s", err->message); + g_error_free (err); + } + + G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMVpnPluginOld *plugin = NM_VPN_PLUGIN_OLD (object); + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + nm_vpn_plugin_old_set_connection (plugin, NULL); + g_free (priv->dbus_service_name); + + g_clear_pointer (&priv->banner, g_free); + g_clear_pointer (&priv->tundev, g_free); + g_clear_pointer (&priv->gateway, g_free); + g_clear_pointer (&priv->mtu, g_free); + + G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->finalize (object); +} + +static void +quit_timer_removed (gpointer data) +{ + NM_VPN_PLUGIN_OLD_GET_PRIVATE (data)->quit_timer = 0; +} + +static void +state_changed (NMVpnPluginOld *plugin, NMVpnServiceState state) +{ + NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); + + switch (state) { + case NM_VPN_SERVICE_STATE_STARTING: + /* Remove the quit timer. */ + if (priv->quit_timer) + g_source_remove (priv->quit_timer); + + if (priv->fail_stop_id) { + g_source_remove (priv->fail_stop_id); + priv->fail_stop_id = 0; + } + break; + case NM_VPN_SERVICE_STATE_STOPPED: + priv->quit_timer = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + NM_VPN_PLUGIN_OLD_QUIT_TIMER, + quit_timer_expired, + plugin, + quit_timer_removed); + break; + default: + /* Clean up all timers we might have set up. */ + if (priv->connect_timer) + g_source_remove (priv->connect_timer); + + if (priv->quit_timer) + g_source_remove (priv->quit_timer); + + if (priv->fail_stop_id) { + g_source_remove (priv->fail_stop_id); + priv->fail_stop_id = 0; + } + break; + } +} + +static void +nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (plugin_class); + + g_type_class_add_private (object_class, sizeof (NMVpnPluginOldPrivate)); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + plugin_class->state_changed = state_changed; + + /* properties */ + + /** + * NMVpnPluginOld:service-name: + * + * The D-Bus service name of this plugin. + */ + g_object_class_install_property + (object_class, PROP_DBUS_SERVICE_NAME, + g_param_spec_string (NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /** + * NMVpnPluginOld:state: + * + * The state of the plugin. + */ + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_enum (NM_VPN_PLUGIN_OLD_STATE, "", "", + NM_TYPE_VPN_SERVICE_STATE, + NM_VPN_SERVICE_STATE_INIT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + /* signals */ + signals[STATE_CHANGED] = + g_signal_new ("state-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, state_changed), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + signals[SECRETS_REQUIRED] = + g_signal_new ("secrets-required", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRV); + + signals[CONFIG] = + g_signal_new ("config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[IP4_CONFIG] = + g_signal_new ("ip4-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, ip4_config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[IP6_CONFIG] = + g_signal_new ("ip6-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, ip6_config), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT); + + signals[LOGIN_BANNER] = + g_signal_new ("login-banner", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, login_banner), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + signals[FAILURE] = + g_signal_new ("failure", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, failure), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + signals[QUIT] = + g_signal_new ("quit", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVpnPluginOldClass, quit), + NULL, NULL, + NULL, + G_TYPE_NONE, 0, + G_TYPE_NONE); + + setup_unix_signal_handler (); +} + +static void +nm_vpn_plugin_old_initable_iface_init (GInitableIface *iface) +{ + iface->init = init_sync; +} diff --git a/libnm/nm-vpn-plugin-old.h b/libnm/nm-vpn-plugin-old.h new file mode 100644 index 00000000..7fcc1c1c --- /dev/null +++ b/libnm/nm-vpn-plugin-old.h @@ -0,0 +1,136 @@ +/* -*- 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. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2013 Red Hat, Inc. + */ + +#ifndef __NM_VPN_PLUGIN_OLD_H__ +#define __NM_VPN_PLUGIN_OLD_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_VPN_PLUGIN_OLD (nm_vpn_plugin_old_get_type ()) +#define NM_VPN_PLUGIN_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOld)) +#define NM_VPN_PLUGIN_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldClass)) +#define NM_IS_VPN_PLUGIN_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_PLUGIN_OLD)) +#define NM_IS_VPN_PLUGIN_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_PLUGIN_OLD)) +#define NM_VPN_PLUGIN_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldClass)) + +#define NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME "service-name" +#define NM_VPN_PLUGIN_OLD_STATE "state" + +typedef struct { + GObject parent; +} NMVpnPluginOld; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*state_changed) (NMVpnPluginOld *plugin, + NMVpnServiceState state); + + void (*ip4_config) (NMVpnPluginOld *plugin, + GVariant *ip4_config); + + void (*login_banner) (NMVpnPluginOld *plugin, + const char *banner); + + void (*failure) (NMVpnPluginOld *plugin, + NMVpnPluginFailure reason); + + void (*quit) (NMVpnPluginOld *plugin); + + void (*config) (NMVpnPluginOld *plugin, + GVariant *config); + + void (*ip6_config) (NMVpnPluginOld *plugin, + GVariant *config); + + /* virtual methods */ + gboolean (*connect) (NMVpnPluginOld *plugin, + NMConnection *connection, + GError **err); + + gboolean (*need_secrets) (NMVpnPluginOld *plugin, + NMConnection *connection, + char **setting_name, + GError **error); + + gboolean (*disconnect) (NMVpnPluginOld *plugin, + GError **err); + + gboolean (*new_secrets) (NMVpnPluginOld *plugin, + NMConnection *connection, + GError **error); + + gboolean (*connect_interactive) (NMVpnPluginOld *plugin, + NMConnection *connection, + GVariant *details, + GError **error); + + /*< private >*/ + gpointer padding[8]; +} NMVpnPluginOldClass; + +GType nm_vpn_plugin_old_get_type (void); + +GDBusConnection *nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin); +NMVpnServiceState nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin); +void nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin, + NMVpnServiceState state); + +void nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, + const char *message, + const char **hints); + +void nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin, + const char *banner); + +void nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin, + NMVpnPluginFailure reason); + +void nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, + GVariant *config); + +void nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, + GVariant *ip4_config); + +void nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, + GVariant *ip6_config); + +gboolean nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, + GError **err); + +/* Utility functions */ + +gboolean nm_vpn_plugin_old_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets); + +gboolean nm_vpn_plugin_old_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags); + +G_END_DECLS + +#endif /* __NM_VPN_PLUGIN_OLD_H__ */ diff --git a/libnm/nm-wimax-nsp.c b/libnm/nm-wimax-nsp.c new file mode 100644 index 00000000..0fed1c6e --- /dev/null +++ b/libnm/nm-wimax-nsp.c @@ -0,0 +1,290 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-glib-compat.h" + +#include +#include +#include + +#include "nm-wimax-nsp.h" +#include "nm-dbus-interface.h" +#include "nm-object-private.h" +#include "nm-enum-types.h" + +G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, NM_TYPE_OBJECT) + +#define NM_WIMAX_NSP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_NSP, NMWimaxNspPrivate)) + +typedef struct { + char *name; + guint32 signal_quality; + NMWimaxNspNetworkType network_type; +} NMWimaxNspPrivate; + +enum { + PROP_0, + PROP_NAME, + PROP_SIGNAL_QUALITY, + PROP_NETWORK_TYPE, + + LAST_PROP +}; + +/** + * nm_wimax_nsp_get_name: + * @nsp: a #NMWimaxNsp + * + * Gets the name of the wimax NSP + * + * Returns: the name + **/ +const char * +nm_wimax_nsp_get_name (NMWimaxNsp *nsp) +{ + g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), NULL); + + return NM_WIMAX_NSP_GET_PRIVATE (nsp)->name; +} + +/** + * nm_wimax_nsp_get_signal_quality: + * @nsp: a #NMWimaxNsp + * + * Gets the WPA signal quality of the wimax NSP. + * + * Returns: the signal quality + **/ +guint32 +nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp) +{ + g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), 0); + + return NM_WIMAX_NSP_GET_PRIVATE (nsp)->signal_quality; +} + +/** + * nm_wimax_nsp_get_network_type: + * @nsp: a #NMWimaxNsp + * + * Gets the network type of the wimax NSP. + * + * Returns: the network type + **/ +NMWimaxNspNetworkType +nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp) +{ + g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN); + + return NM_WIMAX_NSP_GET_PRIVATE (nsp)->network_type; +} + +/** + * nm_wimax_nsp_connection_valid: + * @nsp: an #NMWimaxNsp to validate @connection against + * @connection: an #NMConnection to validate against @nsp + * + * Validates a given connection against a given WiMAX NSP to ensure that the + * connection may be activated with that NSP. The connection must match the + * @nsp's network name and other attributes. + * + * Returns: %TRUE if the connection may be activated with this WiMAX NSP, + * %FALSE if it cannot be. + **/ +gboolean +nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, NMConnection *connection) +{ + NMSettingConnection *s_con; + NMSettingWimax *s_wimax; + const char *ctype; + const char *nsp_name; + const char *setting_name; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + ctype = nm_setting_connection_get_connection_type (s_con); + if (strcmp (ctype, NM_SETTING_WIMAX_SETTING_NAME) != 0) + return FALSE; + + s_wimax = nm_connection_get_setting_wimax (connection); + if (!s_wimax) + return FALSE; + + setting_name = nm_setting_wimax_get_network_name (s_wimax); + if (!setting_name) + return FALSE; + + nsp_name = nm_wimax_nsp_get_name (nsp); + g_warn_if_fail (nsp_name != NULL); + if (g_strcmp0 (nsp_name, setting_name) != 0) + return FALSE; + + return TRUE; +} + +/** + * nm_wimax_nsp_filter_connections: + * @nsp: an #NMWimaxNsp to filter connections for + * @connections: (element-type NMConnection): an array of #NMConnections to + * filter + * + * Filters a given array of connections for a given #NMWimaxNsp object and + * return connections which may be activated with the NSP. Any returned + * connections will match the @nsp's network name and other attributes. + * + * Returns: (transfer container) (element-type NMConnection): an array of + * #NMConnections that could be activated with the given @nsp. The array should + * be freed with g_ptr_array_unref() when it is no longer required. + **/ +GPtrArray * +nm_wimax_nsp_filter_connections (NMWimaxNsp *nsp, const GPtrArray *connections) +{ + GPtrArray *filtered; + int i; + + filtered = g_ptr_array_new_with_free_func (g_object_unref); + for (i = 0; i < connections->len; i++) { + NMConnection *candidate = connections->pdata[i]; + + if (nm_wimax_nsp_connection_valid (nsp, candidate)) + g_ptr_array_add (filtered, g_object_ref (candidate)); + } + + return filtered; +} + +/************************************************************/ + +static void +nm_wimax_nsp_init (NMWimaxNsp *nsp) +{ +} + +static void +finalize (GObject *object) +{ + NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object); + + g_free (priv->name); + + G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMWimaxNsp *nsp = NM_WIMAX_NSP (object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, nm_wimax_nsp_get_name (nsp)); + break; + case PROP_SIGNAL_QUALITY: + g_value_set_uint (value, nm_wimax_nsp_get_signal_quality (nsp)); + break; + case PROP_NETWORK_TYPE: + g_value_set_enum (value, nm_wimax_nsp_get_network_type (nsp)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +init_dbus (NMObject *object) +{ + NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_WIMAX_NSP_NAME, &priv->name }, + { NM_WIMAX_NSP_SIGNAL_QUALITY, &priv->signal_quality }, + { NM_WIMAX_NSP_NETWORK_TYPE, &priv->network_type }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_wimax_nsp_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_WIMAX_NSP, + property_info); +} + +static void +nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (nsp_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (nsp_class); + + g_type_class_add_private (nsp_class, sizeof (NMWimaxNspPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_WIMAX_NSP); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->finalize = finalize; + + nm_object_class->init_dbus = init_dbus; + + /* properties */ + + /** + * NMWimaxNsp:name: + * + * The name of the WiMAX NSP. + **/ + g_object_class_install_property + (object_class, PROP_NAME, + g_param_spec_string (NM_WIMAX_NSP_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMWimaxNsp:signal-quality: + * + * The signal quality of the WiMAX NSP. + **/ + g_object_class_install_property + (object_class, PROP_SIGNAL_QUALITY, + g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, "", "", + 0, 100, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + /** + * NMWimaxNsp:network-type: + * + * The network type of the WiMAX NSP. + **/ + g_object_class_install_property + (object_class, PROP_NETWORK_TYPE, + g_param_spec_enum (NM_WIMAX_NSP_NETWORK_TYPE, "", "", + NM_TYPE_WIMAX_NSP_NETWORK_TYPE, + NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} diff --git a/libnm/nm-wimax-nsp.h b/libnm/nm-wimax-nsp.h new file mode 100644 index 00000000..cdc7b236 --- /dev/null +++ b/libnm/nm-wimax-nsp.h @@ -0,0 +1,85 @@ +/* -*- 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. + * + * Copyright 2011 Red Hat, Inc. + * Copyright 2009 Novell, Inc. + */ + +#ifndef __NM_WIMAX_NSP_H__ +#define __NM_WIMAX_NSP_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#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" + +/** + * NMWimaxNspNetworkType: + * @NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN: unknown network type + * @NM_WIMAX_NSP_NETWORK_TYPE_HOME: home network + * @NM_WIMAX_NSP_NETWORK_TYPE_PARTNER: partner network + * @NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER: roaming partner network + * + * WiMAX network type. + */ +typedef enum { + NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN = 0, + NM_WIMAX_NSP_NETWORK_TYPE_HOME = 1, + NM_WIMAX_NSP_NETWORK_TYPE_PARTNER = 2, + NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER = 3 +} NMWimaxNspNetworkType; + +struct _NMWimaxNsp { + NMObject parent; +}; + +typedef struct { + NMObjectClass parent; + + /*< private >*/ + gpointer padding[4]; +} NMWimaxNspClass; + +GType nm_wimax_nsp_get_type (void); + +const char * nm_wimax_nsp_get_name (NMWimaxNsp *nsp); +guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp); +NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp); + +GPtrArray * nm_wimax_nsp_filter_connections (NMWimaxNsp *nsp, + const GPtrArray *connections); + +gboolean nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, + NMConnection *connection); + +G_END_DECLS + +#endif /* __NM_WIMAX_NSP_H__ */ diff --git a/libnm/tests/Makefile.am b/libnm/tests/Makefile.am new file mode 100644 index 00000000..38449fad --- /dev/null +++ b/libnm/tests/Makefile.am @@ -0,0 +1,41 @@ +if ENABLE_TESTS + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm \ + -I$(top_builddir)/libnm \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ + $(GLIB_CFLAGS) + +LDADD = \ + $(top_builddir)/libnm/libnm.la \ + $(GLIB_LIBS) + +noinst_PROGRAMS = $(TESTS) + +TESTS = test-nm-client test-remote-settings-client test-secret-agent + +test_nm_client_SOURCES = \ + common.c \ + common.h \ + test-nm-client.c + +test_remote_settings_client_SOURCES = \ + common.c \ + common.h \ + test-remote-settings-client.c + +test_secret_agent_SOURCES = \ + common.c \ + common.h \ + test-secret-agent.c + +TESTS_ENVIRONMENT = $(srcdir)/libnm-test-launch.sh + +endif + +EXTRA_DIST = libnm-test-launch.sh diff --git a/libnm/tests/Makefile.in b/libnm/tests/Makefile.in new file mode 100644 index 00000000..ab5f794c --- /dev/null +++ b/libnm/tests/Makefile.in @@ -0,0 +1,918 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 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@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +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@ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = $(am__EXEEXT_1) +@ENABLE_TESTS_TRUE@TESTS = test-nm-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-secret-agent$(EXEEXT) +subdir = libnm/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.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/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)/m4/vapigen.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 = +@ENABLE_TESTS_TRUE@am__EXEEXT_1 = test-nm-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client$(EXEEXT) \ +@ENABLE_TESTS_TRUE@ test-secret-agent$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am__test_nm_client_SOURCES_DIST = common.c common.h test-nm-client.c +@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = common.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ test-nm-client.$(OBJEXT) +test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS) +test_nm_client_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +@ENABLE_TESTS_TRUE@test_nm_client_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +am__test_remote_settings_client_SOURCES_DIST = common.c common.h \ + test-remote-settings-client.c +@ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS = \ +@ENABLE_TESTS_TRUE@ common.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client.$(OBJEXT) +test_remote_settings_client_OBJECTS = \ + $(am_test_remote_settings_client_OBJECTS) +test_remote_settings_client_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_remote_settings_client_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +am__test_secret_agent_SOURCES_DIST = common.c common.h \ + test-secret-agent.c +@ENABLE_TESTS_TRUE@am_test_secret_agent_OBJECTS = common.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ test-secret-agent.$(OBJEXT) +test_secret_agent_OBJECTS = $(am_test_secret_agent_OBJECTS) +test_secret_agent_LDADD = $(LDADD) +@ENABLE_TESTS_TRUE@test_secret_agent_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +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_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +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_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(test_nm_client_SOURCES) \ + $(test_remote_settings_client_SOURCES) \ + $(test_secret_agent_SOURCES) +DIST_SOURCES = $(am__test_nm_client_SOURCES_DIST) \ + $(am__test_remote_settings_client_SOURCES_DIST) \ + $(am__test_secret_agent_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +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@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +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@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +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@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_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@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +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@ +PERL = @PERL@ +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_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +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_CXX = @ac_ct_CXX@ +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@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +@ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ -DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \ +@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) + +@ENABLE_TESTS_TRUE@LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm/libnm.la \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) + +@ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \ +@ENABLE_TESTS_TRUE@ common.c \ +@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ test-nm-client.c + +@ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \ +@ENABLE_TESTS_TRUE@ common.c \ +@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ test-remote-settings-client.c + +@ENABLE_TESTS_TRUE@test_secret_agent_SOURCES = \ +@ENABLE_TESTS_TRUE@ common.c \ +@ENABLE_TESTS_TRUE@ common.h \ +@ENABLE_TESTS_TRUE@ test-secret-agent.c + +@ENABLE_TESTS_TRUE@TESTS_ENVIRONMENT = $(srcdir)/libnm-test-launch.sh +EXTRA_DIST = libnm-test-launch.sh +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 libnm/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libnm/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-nm-client$(EXEEXT): $(test_nm_client_OBJECTS) $(test_nm_client_DEPENDENCIES) $(EXTRA_test_nm_client_DEPENDENCIES) + @rm -f test-nm-client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_nm_client_OBJECTS) $(test_nm_client_LDADD) $(LIBS) + +test-remote-settings-client$(EXEEXT): $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_DEPENDENCIES) $(EXTRA_test_remote_settings_client_DEPENDENCIES) + @rm -f test-remote-settings-client$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_remote_settings_client_OBJECTS) $(test_remote_settings_client_LDADD) $(LIBS) + +test-secret-agent$(EXEEXT): $(test_secret_agent_OBJECTS) $(test_secret_agent_DEPENDENCIES) $(EXTRA_test_secret_agent_DEPENDENCIES) + @rm -f test-secret-agent$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_secret_agent_OBJECTS) $(test_secret_agent_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-secret-agent.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + 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-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + 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" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +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 $(AM_TESTS_FD_REDIRECT); 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 \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$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-TESTS +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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +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 TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am 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 tags-am 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/libnm/tests/common.c b/libnm/tests/common.c new file mode 100644 index 00000000..a28e5112 --- /dev/null +++ b/libnm/tests/common.c @@ -0,0 +1,187 @@ +/* -*- 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 2010 - 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include "NetworkManager.h" + +#include "common.h" + +static gboolean +name_exists (GDBusConnection *c, const char *name) +{ + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync (c, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetNameOwner", + g_variant_new ("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref (reply); + } + + return exists; +} + +NMTestServiceInfo * +nm_test_service_init (void) +{ + NMTestServiceInfo *info; + const char *args[2] = { TEST_NM_SERVICE, NULL }; + GError *error = NULL; + int i; + + info = g_malloc0 (sizeof (*info)); + + info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + /* Spawn the test service. info->keepalive_fd will be a pipe to the service's + * stdin; if it closes, the service will exit immediately. We use this to + * make sure the service exits if the test program crashes. + */ + g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL, + &info->pid, &info->keepalive_fd, NULL, NULL, &error); + g_assert_no_error (error); + + /* Wait until the service is registered on the bus */ + for (i = 100; i > 0; i--) { + if (name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + /* Grab a proxy to our fake NM service to trigger tests */ + info->proxy = g_dbus_proxy_new_sync (info->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, &error); + g_assert_no_error (error); + + return info; +} + +void +nm_test_service_cleanup (NMTestServiceInfo *info) +{ + int i; + + g_object_unref (info->proxy); + kill (info->pid, SIGTERM); + + /* Wait until the bus notices the service is gone */ + for (i = 100; i > 0; i--) { + if (!name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + g_object_unref (info->bus); + close (info->keepalive_fd); + + memset (info, 0, sizeof (*info)); + g_free (info); +} + +typedef struct { + GMainLoop *loop; + const char *ifname; + char *path; + NMDevice *device; +} AddDeviceInfo; + +static void +device_added_cb (NMClient *client, + NMDevice *device, + gpointer user_data) +{ + AddDeviceInfo *info = user_data; + + g_assert (device); + g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path); + g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname); + + info->device = device; + g_main_loop_quit (info->loop); +} + +static gboolean +timeout (gpointer user_data) +{ + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +NMDevice * +nm_test_service_add_device (NMTestServiceInfo *sinfo, NMClient *client, + const char *method, const char *ifname) +{ + AddDeviceInfo info; + GError *error = NULL; + GVariant *ret; + guint timeout_id; + + ret = g_dbus_proxy_call_sync (sinfo->proxy, + method, + g_variant_new ("(s)", ifname), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &info.path); + g_variant_unref (ret); + + /* Wait for libnm to find the device */ + info.ifname = ifname; + info.loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (client, "device-added", + G_CALLBACK (device_added_cb), &info); + timeout_id = g_timeout_add_seconds (5, timeout, NULL); + g_main_loop_run (info.loop); + + g_source_remove (timeout_id); + g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); + g_free (info.path); + g_main_loop_unref (info.loop); + + return info.device; +} diff --git a/libnm/tests/common.h b/libnm/tests/common.h new file mode 100644 index 00000000..aa15167b --- /dev/null +++ b/libnm/tests/common.h @@ -0,0 +1,37 @@ +/* -*- 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. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include +#include + +typedef struct { + GDBusConnection *bus; + GDBusProxy *proxy; + GPid pid; + int keepalive_fd; +} NMTestServiceInfo; + +NMTestServiceInfo *nm_test_service_init (void); +void nm_test_service_cleanup (NMTestServiceInfo *info); + +NMDevice *nm_test_service_add_device (NMTestServiceInfo *info, + NMClient *client, + const char *method, + const char *ifname); diff --git a/libnm/tests/libnm-test-launch.sh b/libnm/tests/libnm-test-launch.sh new file mode 100755 index 00000000..42d9fbe2 --- /dev/null +++ b/libnm/tests/libnm-test-launch.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Spawn DBus if there's none +if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then + eval `dbus-launch --sh-syntax` + trap "kill $DBUS_SESSION_BUS_PID" EXIT +fi + +"$@" diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c new file mode 100644 index 00000000..3541c741 --- /dev/null +++ b/libnm/tests/test-nm-client.c @@ -0,0 +1,1193 @@ +/* -*- 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 2010 - 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include "nm-glib-compat.h" + +#include "common.h" + +#include "nm-test-utils.h" + +static GMainLoop *loop = NULL; +static NMTestServiceInfo *sinfo; + +/*******************************************************************/ + +static gboolean +loop_quit (gpointer user_data) +{ + g_main_loop_quit ((GMainLoop *) user_data); + return G_SOURCE_REMOVE; +} + +/*******************************************************************/ + +static void +devices_notify_cb (NMClient *c, + GParamSpec *pspec, + gpointer user_data) +{ + gboolean *notified = user_data; + const GPtrArray *devices; + NMDevice *device; + + devices = nm_client_get_devices (c); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + *notified = TRUE; +} + +static void +test_device_added (void) +{ + NMClient *client; + const GPtrArray *devices; + NMDevice *device; + gboolean notified = FALSE; + GError *error = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + devices = nm_client_get_devices (client); + g_assert (devices->len == 0); + + g_signal_connect (client, + "notify::devices", + (GCallback) devices_notify_cb, + ¬ified); + + /* Tell the test service to add a new device */ + nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + + /* coverity[loop_condition] */ + while (!notified) + g_main_context_iteration (NULL, TRUE); + + g_signal_handlers_disconnect_by_func (client, devices_notify_cb, ¬ified); + + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + /* Try deleting the device via the ordinary NM interface, which should fail */ + nm_device_delete (device, NULL, &error); + g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_SOFTWARE); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +/*******************************************************************/ + +typedef enum { + SIGNAL_FIRST = 0x01, + SIGNAL_SECOND = 0x02, + SIGNAL_MASK = 0x0F, + NOTIFY_FIRST = 0x10, + NOTIFY_SECOND = 0x20, + NOTIFY_MASK = 0xF0 +} DeviceSignaledAfterInitType; + +static void +device_sai_added_cb (NMClient *c, + NMDevice *device, + gpointer user_data) +{ + guint *result = user_data; + + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + g_assert ((*result & SIGNAL_MASK) == 0); + *result |= *result ? SIGNAL_SECOND : SIGNAL_FIRST; +} + +static void +devices_sai_notify_cb (NMClient *c, + GParamSpec *pspec, + gpointer user_data) +{ + guint *result = user_data; + const GPtrArray *devices; + NMDevice *device; + + devices = nm_client_get_devices (c); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + g_assert ((*result & NOTIFY_MASK) == 0); + *result |= *result ? NOTIFY_SECOND : NOTIFY_FIRST; +} + +static void +test_device_added_signal_after_init (void) +{ + NMClient *client; + const GPtrArray *devices; + NMDevice *device; + guint result = 0; + GError *error = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + devices = nm_client_get_devices (client); + g_assert (devices->len == 0); + + g_signal_connect (client, + NM_CLIENT_DEVICE_ADDED, + (GCallback) device_sai_added_cb, + &result); + + g_signal_connect (client, + "notify::" NM_CLIENT_DEVICES, + (GCallback) devices_sai_notify_cb, + &result); + + /* Tell the test service to add a new device */ + nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + + /* Ensure the 'device-added' signal doesn't show up before + * the 'Devices' property change notification */ + /* coverity[loop_condition] */ + while (!(result & SIGNAL_MASK) && !(result & NOTIFY_MASK)) + g_main_context_iteration (NULL, TRUE); + + g_signal_handlers_disconnect_by_func (client, device_sai_added_cb, &result); + g_signal_handlers_disconnect_by_func (client, devices_sai_notify_cb, &result); + + g_assert ((result & SIGNAL_MASK) == SIGNAL_FIRST); + g_assert ((result & NOTIFY_MASK) == NOTIFY_SECOND); + + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 1); + + device = g_ptr_array_index (devices, 0); + g_assert (device); + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +/*******************************************************************/ + +static const char *expected_bssid = "66:55:44:33:22:11"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *ap_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WifiApInfo; + +static void +wifi_check_quit (WifiApInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +got_ap_path (WifiApInfo *info, const char *path) +{ + if (info->ap_path) + g_assert_cmpstr (info->ap_path, ==, path); + else + info->ap_path = g_strdup (path); +} + +static void +wifi_ap_added_cb (NMDeviceWifi *w, + NMAccessPoint *ap, + WifiApInfo *info) +{ + g_assert (ap); + g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, expected_bssid); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_add_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + NMAccessPoint *ap; + + aps = nm_device_wifi_get_access_points (w); + g_assert (aps); + g_assert_cmpint (aps->len, ==, 1); + + ap = g_ptr_array_index (aps, 0); + g_assert (ap); + g_assert_cmpstr (nm_access_point_get_bssid (ap), ==, "66:55:44:33:22:11"); + got_ap_path (info, nm_object_get_path (NM_OBJECT (ap))); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_removed_cb (NMDeviceWifi *w, + NMAccessPoint *ap, + WifiApInfo *info) +{ + g_assert (ap); + g_assert_cmpstr (info->ap_path, ==, nm_object_get_path (NM_OBJECT (ap))); + + info->signaled = TRUE; + wifi_check_quit (info); +} + +static void +wifi_ap_remove_notify_cb (NMDeviceWifi *w, + GParamSpec *pspec, + WifiApInfo *info) +{ + const GPtrArray *aps; + + aps = nm_device_wifi_get_access_points (w); + g_assert (aps->len == 0); + + info->notified = TRUE; + wifi_check_quit (info); +} + +static void +test_wifi_ap_added_removed (void) +{ + NMClient *client; + NMDeviceWifi *wifi; + WifiApInfo info = { loop, FALSE, FALSE, 0, 0 }; + GVariant *ret; + GError *error = NULL; + char *expected_path = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + /*************************************/ + /* Add the wifi device */ + wifi = (NMDeviceWifi *) nm_test_service_add_device (sinfo, client, "AddWifiDevice", "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (wifi)); + + /*************************************/ + /* Add the wifi AP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "AddWifiAp", + g_variant_new ("(sss)", "wlan0", "test-ap", expected_bssid), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wifi, + "access-point-added", + (GCallback) wifi_ap_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + g_assert (info.signaled); + g_assert (info.notified); + g_assert (info.ap_path); + g_assert_cmpstr (info.ap_path, ==, expected_path); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_added_cb, &info); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_add_notify_cb, &info); + + /*************************************/ + /* Remove the wifi device */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "RemoveWifiAp", + g_variant_new ("(so)", "wlan0", expected_path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wifi, + "access-point-removed", + (GCallback) wifi_ap_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wifi, + "notify::access-points", + (GCallback) wifi_ap_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + g_assert (info.signaled); + g_assert (info.notified); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_removed_cb, &info); + g_signal_handlers_disconnect_by_func (wifi, wifi_ap_remove_notify_cb, &info); + + g_free (info.ap_path); + g_free (expected_path); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +/*******************************************************************/ + +static const char *expected_nsp_name = "Clear"; + +typedef struct { + GMainLoop *loop; + gboolean found; + char *nsp_path; + gboolean signaled; + gboolean notified; + guint quit_id; + guint quit_count; +} WimaxNspInfo; + +static void +wimax_check_quit (WimaxNspInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +got_nsp_path (WimaxNspInfo *info, const char *path) +{ + if (info->nsp_path) + g_assert_cmpstr (info->nsp_path, ==, path); + else + info->nsp_path = g_strdup (path); +} + +static void +wimax_nsp_added_cb (NMDeviceWimax *w, + NMWimaxNsp *nsp, + WimaxNspInfo *info) +{ + g_assert (nsp); + g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_add_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + NMWimaxNsp *nsp; + + nsps = nm_device_wimax_get_nsps (w); + g_assert (nsps); + g_assert_cmpint (nsps->len, ==, 1); + + nsp = g_ptr_array_index (nsps, 0); + g_assert (nsp); + g_assert_cmpstr (nm_wimax_nsp_get_name (nsp), ==, expected_nsp_name); + got_nsp_path (info, nm_object_get_path (NM_OBJECT (nsp))); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_removed_cb (NMDeviceWimax *w, + NMWimaxNsp *nsp, + WimaxNspInfo *info) +{ + g_assert (nsp); + g_assert_cmpstr (info->nsp_path, ==, nm_object_get_path (NM_OBJECT (nsp))); + + info->signaled = TRUE; + wimax_check_quit (info); +} + +static void +wimax_nsp_remove_notify_cb (NMDeviceWimax *w, + GParamSpec *pspec, + WimaxNspInfo *info) +{ + const GPtrArray *nsps; + + nsps = nm_device_wimax_get_nsps (w); + g_assert (nsps->len == 0); + + info->notified = TRUE; + wimax_check_quit (info); +} + +static void +test_wimax_nsp_added_removed (void) +{ + NMClient *client; + NMDeviceWimax *wimax; + WimaxNspInfo info = { loop, FALSE, FALSE, 0, 0 }; + GVariant *ret; + GError *error = NULL; + char *expected_path = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + /*************************************/ + /* Add the wimax device */ + wimax = (NMDeviceWimax *) nm_test_service_add_device (sinfo, client, "AddWimaxDevice", "wmx0"); + g_assert (NM_IS_DEVICE_WIMAX (wimax)); + + /*************************************/ + /* Add the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "AddWimaxNsp", + g_variant_new ("(ss)", "wmx0", expected_nsp_name), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &expected_path); + g_variant_unref (ret); + + g_signal_connect (wimax, + "nsp-added", + (GCallback) wimax_nsp_added_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_add_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + g_assert (info.signaled); + g_assert (info.notified); + g_assert (info.nsp_path); + g_assert_cmpstr (info.nsp_path, ==, expected_path); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_added_cb, &info); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_add_notify_cb, &info); + + /*************************************/ + /* Remove the wimax NSP */ + info.signaled = FALSE; + info.notified = FALSE; + info.quit_id = 0; + + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "RemoveWimaxNsp", + g_variant_new ("(so)", "wmx0", expected_path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_clear_pointer (&ret, g_variant_unref); + + g_signal_connect (wimax, + "nsp-removed", + (GCallback) wimax_nsp_removed_cb, + &info); + info.quit_count = 1; + + g_signal_connect (wimax, + "notify::nsps", + (GCallback) wimax_nsp_remove_notify_cb, + &info); + info.quit_count++; + + /* Wait for libnm to find the AP */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + g_assert (info.signaled); + g_assert (info.notified); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_removed_cb, &info); + g_signal_handlers_disconnect_by_func (wimax, wimax_nsp_remove_notify_cb, &info); + + g_free (info.nsp_path); + g_free (expected_path); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +/*******************************************************************/ + +typedef struct { + GMainLoop *loop; + gboolean signaled; + gboolean notified; + guint quit_count; + guint quit_id; +} DaInfo; + +static void +da_check_quit (DaInfo *info) +{ + info->quit_count--; + if (info->quit_count == 0) { + g_source_remove (info->quit_id); + info->quit_id = 0; + g_main_loop_quit (info->loop); + } +} + +static void +da_device_removed_cb (NMClient *c, + NMDevice *device, + DaInfo *info) +{ + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0"); + info->signaled = TRUE; + da_check_quit (info); +} + +static void +da_devices_notify_cb (NMClient *c, + GParamSpec *pspec, + DaInfo *info) +{ + const GPtrArray *devices; + NMDevice *device; + guint i; + const char *iface; + + devices = nm_client_get_devices (c); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 2); + + for (i = 0; i < devices->len; i++) { + device = g_ptr_array_index (devices, i); + iface = nm_device_get_iface (device); + + g_assert (!strcmp (iface, "wlan0") || !strcmp (iface, "eth1")); + } + + info->notified = TRUE; + da_check_quit (info); +} + +static void +new_client_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient **out_client = user_data; + GError *error = NULL; + + *out_client = nm_client_new_finish (result, &error); + g_assert_no_error (error); + g_assert (*out_client != NULL); + + g_main_loop_quit (loop); +} + +static void +test_devices_array (void) +{ + NMClient *client = NULL; + DaInfo info = { loop }; + NMDevice *wlan0, *eth0, *eth1, *device; + const GPtrArray *devices; + GError *error = NULL; + GVariant *ret; + + sinfo = nm_test_service_init (); + + /* Make sure that we test the async codepath in at least one test... */ + nm_client_new_async (NULL, new_client_cb, &client); + g_main_loop_run (loop); + g_assert (client != NULL); + + /*************************************/ + /* Add some devices */ + wlan0 = nm_test_service_add_device (sinfo, client,"AddWifiDevice", "wlan0"); + eth0 = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + eth1 = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth1"); + + /* Ensure the devices now exist */ + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 3); + + device = nm_client_get_device_by_iface (client, "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (device)); + g_assert (device == wlan0); + + device = nm_client_get_device_by_iface (client, "eth0"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); + g_assert (device == eth0); + + device = nm_client_get_device_by_iface (client, "eth1"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); + g_assert (device == eth1); + + /********************************/ + /* Now remove the device in the middle */ + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "RemoveDevice", + g_variant_new ("(o)", nm_object_get_path (NM_OBJECT (eth0))), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (ret); + g_variant_unref (ret); + + g_signal_connect (client, + "device-removed", + (GCallback) da_device_removed_cb, + &info); + + g_signal_connect (client, + "notify::devices", + (GCallback) da_devices_notify_cb, + &info); + info.quit_count = 2; + + /* Wait for libnm to notice the changes */ + info.quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + + g_assert_cmpint (info.quit_count, ==, 0); + g_signal_handlers_disconnect_by_func (client, da_device_removed_cb, &info); + g_signal_handlers_disconnect_by_func (client, da_devices_notify_cb, &info); + + /* Ensure only two are left */ + devices = nm_client_get_devices (client); + g_assert (devices); + g_assert_cmpint (devices->len, ==, 2); + + device = nm_client_get_device_by_iface (client, "wlan0"); + g_assert (NM_IS_DEVICE_WIFI (device)); + g_assert (device == wlan0); + + device = nm_client_get_device_by_iface (client, "eth1"); + g_assert (NM_IS_DEVICE_ETHERNET (device)); + g_assert (device == eth1); + + g_object_unref (client); + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +static void +nm_running_changed (GObject *client, + GParamSpec *pspec, + gpointer user_data) +{ + int *running_changed = user_data; + + (*running_changed)++; + g_main_loop_quit (loop); +} + +static void +test_client_nm_running (void) +{ + NMClient *client1, *client2; + guint quit_id; + int running_changed = 0; + GError *error = NULL; + + client1 = nm_client_new (NULL, &error); + g_assert_no_error (error); + + g_assert (!nm_client_get_nm_running (client1)); + g_assert_cmpstr (nm_client_get_version (client1), ==, NULL); + + g_assert (!nm_client_networking_get_enabled (client1)); + /* This will have no effect, but it shouldn't cause any warnings either. */ + nm_client_networking_set_enabled (client1, TRUE, NULL); + g_assert (!nm_client_networking_get_enabled (client1)); + + /* OTOH, this should result in an error */ + nm_client_set_logging (client1, "DEFAULT", "INFO", &error); + g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_MANAGER_NOT_RUNNING); + g_clear_error (&error); + + /* Now start the test service. */ + sinfo = nm_test_service_init (); + client2 = nm_client_new (NULL, &error); + g_assert_no_error (error); + + /* client2 should know that NM is running, but the previously-created + * client1 hasn't gotten the news yet. + */ + g_assert (!nm_client_get_nm_running (client1)); + g_assert (nm_client_get_nm_running (client2)); + + g_signal_connect (client1, "notify::" NM_CLIENT_NM_RUNNING, + G_CALLBACK (nm_running_changed), &running_changed); + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 1); + g_assert (nm_client_get_nm_running (client1)); + g_source_remove (quit_id); + + /* And kill it */ + g_clear_pointer (&sinfo, nm_test_service_cleanup); + + g_assert (nm_client_get_nm_running (client1)); + + quit_id = g_timeout_add_seconds (5, loop_quit, loop); + g_main_loop_run (loop); + g_assert_cmpint (running_changed, ==, 2); + g_assert (!nm_client_get_nm_running (client1)); + g_source_remove (quit_id); + + g_object_unref (client1); + g_object_unref (client2); +} + +typedef struct { + GMainLoop *loop; + NMActiveConnection *ac; + + int remaining; +} TestACInfo; + +static void +assert_ac_and_device (NMClient *client) +{ + const GPtrArray *devices, *acs, *ac_devices; + NMDevice *device, *ac_device; + NMActiveConnection *ac, *device_ac; + + acs = nm_client_get_active_connections (client); + g_assert (acs != NULL); + g_assert_cmpint (acs->len, ==, 1); + devices = nm_client_get_devices (client); + g_assert (devices != NULL); + g_assert_cmpint (devices->len, >=, 1); + + ac = acs->pdata[0]; + ac_devices = nm_active_connection_get_devices (ac); + g_assert (ac_devices != NULL); + g_assert_cmpint (ac_devices->len, ==, 1); + ac_device = ac_devices->pdata[0]; + g_assert (ac_device != NULL); + + device = devices->pdata[0]; + if (device != ac_device && devices->len > 1) + device = devices->pdata[1]; + device_ac = nm_device_get_active_connection (device); + g_assert (device_ac != NULL); + + g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, nm_object_get_path (NM_OBJECT (ac_device))); + g_assert (device == ac_device); + g_assert_cmpstr (nm_object_get_path (NM_OBJECT (ac)), ==, nm_object_get_path (NM_OBJECT (device_ac))); + g_assert (ac == device_ac); +} + +static void +add_and_activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient *client = NM_CLIENT (object); + TestACInfo *info = user_data; + GError *error = NULL; + + info->ac = nm_client_add_and_activate_connection_finish (client, result, &error); + g_assert_no_error (error); + g_assert (info->ac != NULL); + + assert_ac_and_device (client); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit (info->loop); +} + +static void +client_acs_changed_cb (GObject *client, + GParamSpec *pspec, + gpointer user_data) +{ + TestACInfo *info = user_data; + const GPtrArray *acs; + + acs = nm_client_get_active_connections (NM_CLIENT (client)); + g_assert (acs != NULL); + g_assert_cmpint (acs->len, ==, 1); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit (info->loop); +} + +static void +device_ac_changed_cb (GObject *device, + GParamSpec *pspec, + gpointer user_data) +{ + TestACInfo *info = user_data; + + g_assert (nm_device_get_active_connection (NM_DEVICE (device)) != NULL); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit (info->loop); +} + +static void +test_active_connections (void) +{ + NMClient *client; + NMDevice *device; + NMConnection *conn; + TestACInfo info = { loop, NULL, 0 }; + GError *error = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + /* Tell the test service to add a new device */ + device = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + + conn = nmtst_create_minimal_connection ("test-ac", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_client_add_and_activate_connection_async (client, conn, device, NULL, + NULL, add_and_activate_cb, &info); + g_object_unref (conn); + + g_signal_connect (client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + G_CALLBACK (client_acs_changed_cb), &info); + g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION, + G_CALLBACK (device_ac_changed_cb), &info); + + /* Two signals plus activate_cb */ + info.remaining = 3; + g_main_loop_run (loop); + g_signal_handlers_disconnect_by_func (client, client_acs_changed_cb, &info); + g_signal_handlers_disconnect_by_func (device, device_ac_changed_cb, &info); + + g_assert (info.ac != NULL); + + g_object_unref (info.ac); + g_object_unref (client); + + /* Ensure that we can correctly resolve the recursive property link between the + * AC and the Device in a newly-created client. + */ + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + assert_ac_and_device (client); + g_object_unref (client); + + client = NULL; + nm_client_new_async (NULL, new_client_cb, &client); + g_main_loop_run (loop); + assert_ac_and_device (client); + g_object_unref (client); + + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +static void +client_devices_changed_cb (GObject *client, + GParamSpec *pspec, + gpointer user_data) +{ + TestACInfo *info = user_data; + const GPtrArray *devices; + NMDevice *device; + + devices = nm_client_get_devices (NM_CLIENT (client)); + g_assert (devices != NULL); + if (devices->len < 2) + return; + g_assert_cmpint (devices->len, ==, 2); + + if (NM_IS_DEVICE_VLAN (devices->pdata[0])) + device = devices->pdata[0]; + else if (NM_IS_DEVICE_VLAN (devices->pdata[1])) + device = devices->pdata[1]; + else + g_assert_not_reached (); + + g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0.1"); + + if (nm_device_get_active_connection (device)) + info->remaining--; + else { + g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION, + G_CALLBACK (device_ac_changed_cb), info); + } + + info->remaining--; + if (!info->remaining) + g_main_loop_quit (info->loop); +} + +typedef struct { + GMainLoop *loop; + NMRemoteConnection *remote; +} TestConnectionInfo; + +static void +add_connection_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + TestConnectionInfo *info = user_data; + GError *error = NULL; + + info->remote = nm_client_add_connection_finish (NM_CLIENT (object), result, &error); + g_assert_no_error (error); + g_main_loop_quit (info->loop); +} + +static void +activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient *client = NM_CLIENT (object); + TestACInfo *info = user_data; + GError *error = NULL; + + info->ac = nm_client_activate_connection_finish (client, result, &error); + g_assert_no_error (error); + g_assert (info->ac != NULL); + + assert_ac_and_device (client); + + info->remaining--; + if (!info->remaining) + g_main_loop_quit (info->loop); +} + +static void +test_activate_virtual (void) +{ + NMClient *client; + NMConnection *conn; + NMSettingConnection *s_con; + NMSettingVlan *s_vlan; + TestACInfo info = { loop, NULL, 0 }; + TestConnectionInfo conn_info = { loop, NULL }; + GError *error = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + + conn = nmtst_create_minimal_connection ("test-ac", NULL, NM_SETTING_VLAN_SETTING_NAME, &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0.1", + NULL); + s_vlan = nm_connection_get_setting_vlan (conn); + g_object_set (s_vlan, + NM_SETTING_VLAN_ID, 1, + NM_SETTING_VLAN_PARENT, "eth0", + NULL); + + nm_client_add_connection_async (client, conn, TRUE, + NULL, add_connection_cb, &conn_info); + g_main_loop_run (loop); + g_object_unref (conn); + conn = NM_CONNECTION (conn_info.remote); + + nm_client_activate_connection_async (client, conn, NULL, NULL, + NULL, activate_cb, &info); + g_object_unref (conn); + + g_signal_connect (client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + G_CALLBACK (client_acs_changed_cb), &info); + g_signal_connect (client, "notify::" NM_CLIENT_DEVICES, + G_CALLBACK (client_devices_changed_cb), &info); + + /* As with test_active_connections() above, except that now we're waiting + * for NMClient:devices to change rather than NMDevice:active-connections. + */ + info.remaining = 3; + + g_main_loop_run (loop); + g_signal_handlers_disconnect_by_func (client, client_acs_changed_cb, &info); + g_signal_handlers_disconnect_by_func (client, client_devices_changed_cb, &info); + + g_assert (info.ac != NULL); + + g_object_unref (info.ac); + g_object_unref (client); + + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +static void +activate_failed_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient *client = NM_CLIENT (object); + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (client, result, &error); + g_assert (ac == NULL); + g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED); + g_clear_error (&error); + + g_main_loop_quit (loop); +} + +static void +test_activate_failed (void) +{ + NMClient *client; + NMDevice *device; + NMConnection *conn; + GError *error = NULL; + + sinfo = nm_test_service_init (); + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + device = nm_test_service_add_device (sinfo, client, "AddWiredDevice", "eth0"); + + /* Note that test-networkmanager-service.py checks for this exact name */ + conn = nmtst_create_minimal_connection ("object-creation-failed-test", NULL, + NM_SETTING_WIRED_SETTING_NAME, NULL); + + nm_client_add_and_activate_connection_async (client, conn, device, NULL, + NULL, activate_failed_cb, NULL); + g_main_loop_run (loop); + + g_object_unref (conn); + g_object_unref (client); + + g_clear_pointer (&sinfo, nm_test_service_cleanup); +} + +/*******************************************************************/ + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + nmtst_init (&argc, &argv, TRUE); + + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/libnm/device-added", test_device_added); + g_test_add_func ("/libnm/device-added-signal-after-init", test_device_added_signal_after_init); + g_test_add_func ("/libnm/wifi-ap-added-removed", test_wifi_ap_added_removed); + g_test_add_func ("/libnm/wimax-nsp-added-removed", test_wimax_nsp_added_removed); + g_test_add_func ("/libnm/devices-array", test_devices_array); + g_test_add_func ("/libnm/client-nm-running", test_client_nm_running); + g_test_add_func ("/libnm/active-connections", test_active_connections); + g_test_add_func ("/libnm/activate-virtual", test_activate_virtual); + g_test_add_func ("/libnm/activate-failed", test_activate_failed); + + return g_test_run (); +} + diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c new file mode 100644 index 00000000..8f9dc27f --- /dev/null +++ b/libnm/tests/test-remote-settings-client.c @@ -0,0 +1,547 @@ +/* -*- 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 2010 - 2011 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include "common.h" + +#include "nm-test-utils.h" + +static NMTestServiceInfo *sinfo; +static NMClient *client = NULL; +GDBusConnection *bus = NULL; +NMRemoteConnection *remote = NULL; + +/*******************************************************************/ + +static void +add_cb (GObject *s, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *done = user_data; + GError *error = NULL; + + remote = nm_client_add_connection_finish (client, result, &error); + g_assert_no_error (error); + + *done = TRUE; + g_object_add_weak_pointer (G_OBJECT (remote), (void **) &remote); + + /* nm_client_add_connection_finish() adds a ref to @remote, but we + * want the weak pointer to be cleared as soon as @client drops its own ref. + * So drop ours. + */ + g_object_unref (remote); +} + +#define TEST_CON_ID "blahblahblah" + +static void +test_add_connection (void) +{ + NMConnection *connection; + time_t start, now; + gboolean done = FALSE; + + connection = nmtst_create_minimal_connection (TEST_CON_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nm_client_add_connection_async (client, + connection, + TRUE, + NULL, + add_cb, + &done); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + g_assert (done == TRUE); + g_assert (remote != NULL); + + /* Make sure the connection is the same as what we added */ + g_assert (nm_connection_compare (connection, + NM_CONNECTION (remote), + NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); + g_object_unref (connection); +} + +/*******************************************************************/ + +static void +set_visible_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + GVariant *ret; + + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + g_assert_no_error (error); + g_variant_unref (ret); +} + +static void +visible_changed_cb (GObject *object, GParamSpec *pspec, gboolean *done) +{ + if (!nm_remote_connection_get_visible (NM_REMOTE_CONNECTION (object))) + *done = TRUE; +} + +static void +connection_removed_cb (NMClient *s, NMRemoteConnection *connection, gboolean *done) +{ + if (connection == remote) + *done = TRUE; +} + +static void +invis_has_settings_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + *((gboolean *) user_data) = TRUE; +} + +static void +test_make_invisible (void) +{ + time_t start, now; + const GPtrArray *conns; + int i; + GDBusProxy *proxy; + gboolean visible_changed = FALSE, connection_removed = FALSE; + gboolean has_settings = FALSE; + char *path; + + g_assert (remote != NULL); + + /* Listen for the remove event when the connection becomes invisible */ + g_signal_connect (remote, "notify::" NM_REMOTE_CONNECTION_VISIBLE, G_CALLBACK (visible_changed_cb), &visible_changed); + g_signal_connect (client, "connection-removed", G_CALLBACK (connection_removed_cb), &connection_removed); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert (proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call (proxy, + "SetVisible", + g_variant_new ("(b)", FALSE), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + set_visible_cb, NULL); + + /* Wait for the connection to be removed */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((!visible_changed || !connection_removed) && (now - start < 5)); + g_assert (visible_changed == TRUE); + g_assert (connection_removed == TRUE); + + g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (visible_changed_cb), &visible_changed); + g_signal_handlers_disconnect_by_func (client, G_CALLBACK (connection_removed_cb), &connection_removed); + + /* Ensure NMClient no longer has the connection */ + conns = nm_client_get_connections (client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION (conns->pdata[i]); + + g_assert ((gpointer) remote != (gpointer) candidate); + g_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + } + + /* And ensure the invisible connection no longer has any settings */ + g_assert (remote); + nm_connection_for_each_setting_value (NM_CONNECTION (remote), + invis_has_settings_cb, + &has_settings); + g_assert (has_settings == FALSE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +static void +vis_new_connection_cb (NMClient *foo, + NMRemoteConnection *connection, + NMRemoteConnection **new) +{ + *new = connection; +} + +static void +test_make_visible (void) +{ + time_t start, now; + const GPtrArray *conns; + int i; + GDBusProxy *proxy; + gboolean found = FALSE; + char *path; + NMRemoteConnection *new = NULL; + + g_assert (remote != NULL); + + /* Wait for the new-connection signal when the connection is visible again */ + g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (vis_new_connection_cb), &new); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert (proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call (proxy, + "SetVisible", + g_variant_new ("(b)", TRUE), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + set_visible_cb, NULL); + + /* Wait for the settings service to announce the connection again */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((new == NULL) && (now - start < 5)); + + /* Ensure the new connection is the same as the one we made visible again */ + g_assert (new); + g_assert (new == remote); + + g_signal_handlers_disconnect_by_func (client, G_CALLBACK (vis_new_connection_cb), &new); + + /* Ensure NMClient has the connection */ + conns = nm_client_get_connections (client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION (conns->pdata[i]); + + if ((gpointer) remote == (gpointer) candidate) { + g_assert_cmpstr (path, ==, nm_connection_get_path (candidate)); + g_assert_cmpstr (TEST_CON_ID, ==, nm_connection_get_id (candidate)); + found = TRUE; + break; + } + } + g_assert (found == TRUE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +static void +deleted_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + GVariant *ret; + + ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result, &error); + g_assert_no_error (error); + g_variant_unref (ret); +} + +static void +removed_cb (NMClient *s, NMRemoteConnection *connection, gboolean *done) +{ + if (connection == remote) + *done = TRUE; +} + +static void +test_remove_connection (void) +{ + NMRemoteConnection *connection; + time_t start, now; + const GPtrArray *conns; + int i; + GDBusProxy *proxy; + gboolean done = FALSE; + char *path; + + /* Find a connection to delete */ + conns = nm_client_get_connections (client); + g_assert_cmpint (conns->len, >, 0); + + connection = NM_REMOTE_CONNECTION (conns->pdata[0]); + g_assert (connection); + g_assert (remote == connection); + path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); + g_signal_connect (client, "connection-removed", G_CALLBACK (removed_cb), &done); + + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + NM_DBUS_SERVICE, + path, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NULL, + NULL); + g_assert (proxy != NULL); + + /* Bypass the NMClient object so we can test it independently */ + g_dbus_proxy_call (proxy, + "Delete", + NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + deleted_cb, NULL); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + g_assert (done == TRUE); + + g_assert (!remote); + + /* Ensure NMClient no longer has the connection */ + conns = nm_client_get_connections (client); + for (i = 0; i < conns->len; i++) { + NMConnection *candidate = NM_CONNECTION (conns->pdata[i]); + + g_assert ((gpointer) connection != (gpointer) candidate); + g_assert_cmpstr (path, ==, nm_connection_get_path (candidate)); + } + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +#define TEST_ADD_REMOVE_ID "add-remove-test-connection" + +static void +add_remove_cb (GObject *s, + GAsyncResult *result, + gpointer user_data) +{ + NMRemoteConnection *connection; + gboolean *done = user_data; + GError *error = NULL; + + connection = nm_client_add_connection_finish (client, result, &error); + g_assert_error (error, NM_CLIENT_ERROR, NM_CLIENT_ERROR_OBJECT_CREATION_FAILED); + g_assert (connection == NULL); + + *done = TRUE; +} + +static void +test_add_remove_connection (void) +{ + GVariant *ret; + GError *error = NULL; + NMConnection *connection; + time_t start, now; + gboolean done = FALSE; + + /* This will cause the test server to immediately delete the connection + * after creating it. + */ + ret = g_dbus_proxy_call_sync (sinfo->proxy, + "AutoRemoveNextConnection", + NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + &error); + g_assert_no_error (error); + g_variant_unref (ret); + + connection = nmtst_create_minimal_connection (TEST_ADD_REMOVE_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_client_add_connection_async (client, + connection, + TRUE, + NULL, + add_remove_cb, + &done); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + g_assert (done == TRUE); + + g_object_unref (connection); +} + +/*******************************************************************/ + +static void +add_bad_cb (GObject *s, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *done = user_data; + GError *error = NULL; + + remote = nm_client_add_connection_finish (client, result, &error); + g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); + + *done = TRUE; +} + +static void +test_add_bad_connection (void) +{ + NMConnection *connection; + time_t start, now; + gboolean done = FALSE; + + /* The test daemon doesn't support bond connections */ + connection = nmtst_create_minimal_connection ("bad connection test", NULL, NM_SETTING_BOND_SETTING_NAME, NULL); + + nm_client_add_connection_async (client, + connection, + TRUE, + NULL, + add_bad_cb, + &done); + g_object_unref (connection); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + g_assert (done == TRUE); + g_assert (remote == NULL); +} + +/*******************************************************************/ + +static void +save_hostname_cb (GObject *s, + GAsyncResult *result, + gpointer user_data) +{ + gboolean *done = user_data; + GError *error = NULL; + + nm_client_save_hostname_finish (client, result, &error); + g_assert_no_error (error); + + *done = TRUE; +} + +static void +test_save_hostname (void) +{ + time_t start, now; + gboolean done = FALSE; + GError *error = NULL; + + /* test-networkmanager-service.py requires the hostname to contain a '.' */ + nm_client_save_hostname (client, "foo", NULL, &error); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_HOSTNAME); + g_clear_error (&error); + + nm_client_save_hostname_async (client, "example.com", NULL, save_hostname_cb, &done); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + g_assert (done == TRUE); + g_assert (remote == NULL); +} + +/*******************************************************************/ + +int +main (int argc, char **argv) +{ + int ret; + GError *error = NULL; + + g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + g_test_init (&argc, &argv, NULL); + + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + sinfo = nm_test_service_init (); + + client = nm_client_new (NULL, &error); + g_assert_no_error (error); + g_assert (client != NULL); + + /* FIXME: these tests assume that they get run in order, but g_test_run() + * does not actually guarantee that! + */ + g_test_add_func ("/client/add_connection", test_add_connection); + g_test_add_func ("/client/make_invisible", test_make_invisible); + g_test_add_func ("/client/make_visible", test_make_visible); + g_test_add_func ("/client/remove_connection", test_remove_connection); + g_test_add_func ("/client/add_remove_connection", test_add_remove_connection); + g_test_add_func ("/client/add_bad_connection", test_add_bad_connection); + g_test_add_func ("/client/save_hostname", test_save_hostname); + + ret = g_test_run (); + + nm_test_service_cleanup (sinfo); + g_object_unref (client); + g_object_unref (bus); + + return ret; +} + diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c new file mode 100644 index 00000000..0424b74e --- /dev/null +++ b/libnm/tests/test-secret-agent.c @@ -0,0 +1,655 @@ +/* -*- 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 2010 - 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include "nm-glib-compat.h" +#include "nm-test-utils.h" + +#include "common.h" + +/*******************************************************************/ + +enum { + SECRET_REQUESTED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef NMSecretAgentOld TestSecretAgent; +typedef NMSecretAgentOldClass TestSecretAgentClass; + +GType test_secret_agent_get_type (void); +G_DEFINE_TYPE (TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD) + +static void +test_secret_agent_init (TestSecretAgent *agent) +{ +} + +static void +test_secret_agent_get_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + NMSecretAgentGetSecretsFlags flags, + NMSecretAgentOldGetSecretsFunc callback, + gpointer callback_data) +{ + NMSettingWirelessSecurity *s_wsec; + GVariant *secrets = NULL; + GVariantBuilder secrets_builder, setting_builder; + char *secret = NULL; + GError *error = NULL; + + g_assert_cmpstr (setting_name, ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); + g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, NULL); + + g_signal_emit (agent, signals[SECRET_REQUESTED], 0, + connection, + connection_path, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK, + &secret); + + if (!secret) { + error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS, + "No secrets"); + goto done; + } + + if (!strcmp (secret, "CANCEL")) { + error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_USER_CANCELED, + "User canceled"); + goto done; + } + + g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING); + g_variant_builder_add (&setting_builder, "{sv}", + NM_SETTING_WIRELESS_SECURITY_PSK, + g_variant_new_string (secret)); + + g_variant_builder_init (&secrets_builder, NM_VARIANT_TYPE_CONNECTION); + g_variant_builder_add (&secrets_builder, "{sa{sv}}", + setting_name, + &setting_builder); + secrets = g_variant_ref_sink (g_variant_builder_end (&secrets_builder)); + +done: + callback (agent, connection, secrets, error, callback_data); + g_clear_error (&error); + g_clear_pointer (&secrets, g_variant_unref); + g_free (secret); +} + +static void +test_secret_agent_cancel_get_secrets (NMSecretAgentOld *agent, + const gchar *connection_path, + const gchar *setting_name) +{ + g_assert_not_reached (); +} + +static void +test_secret_agent_save_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const gchar *connection_path, + NMSecretAgentOldSaveSecretsFunc callback, + gpointer callback_data) +{ + g_assert_not_reached (); +} + +static void +test_secret_agent_delete_secrets (NMSecretAgentOld *agent, + NMConnection *connection, + const gchar *connection_path, + NMSecretAgentOldDeleteSecretsFunc callback, + gpointer callback_data) +{ + g_assert_not_reached (); +} + +static void +test_secret_agent_class_init (TestSecretAgentClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS (klass); + + agent_class->get_secrets = test_secret_agent_get_secrets; + agent_class->cancel_get_secrets = test_secret_agent_cancel_get_secrets; + agent_class->save_secrets = test_secret_agent_save_secrets; + agent_class->delete_secrets = test_secret_agent_delete_secrets; + + signals[SECRET_REQUESTED] = + g_signal_new ("secret-requested", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_STRING, 4, + NM_TYPE_CONNECTION, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + +} + +static NMSecretAgentOld * +test_secret_agent_new (void) +{ + NMSecretAgentOld *agent; + GError *error = NULL; + + agent = g_initable_new (test_secret_agent_get_type (), NULL, &error, + NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", + NM_SECRET_AGENT_OLD_AUTO_REGISTER, FALSE, + NULL); + g_assert_no_error (error); + + return agent; +} + +/*******************************************************************/ + +typedef struct { + NMTestServiceInfo *sinfo; + NMClient *client; + + NMSecretAgentOld *agent; + NMDevice *device; + NMConnection *connection; + + GMainLoop *loop; + guint timeout_id; + + char *ifname; + char *con_id; + + int secrets_requested; +} TestSecretAgentData; + +static gboolean +timeout_assert (gpointer user_data) +{ + g_assert_not_reached (); +} + +static void +connection_added_cb (GObject *s, + GAsyncResult *result, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMRemoteConnection *connection; + GError *error = NULL; + + connection = nm_client_add_connection_finish (sadata->client, result, &error); + + g_assert_no_error (error); + g_assert_cmpstr (nm_connection_get_id (NM_CONNECTION (connection)), ==, sadata->con_id); + + sadata->connection = NM_CONNECTION (connection); + g_main_loop_quit (sadata->loop); +} + +static void +register_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + GError *error = NULL; + + nm_secret_agent_old_register_finish (sadata->agent, result, &error); + g_assert_no_error (error); + g_assert (nm_secret_agent_old_get_registered (sadata->agent)); + + g_main_loop_quit (sadata->loop); +} + +#define TEST_CON_ID_PREFIX "test-secret-agent" + +static void +test_setup (TestSecretAgentData *sadata, gconstpointer test_data) +{ + static int counter = 0; + const char *agent_notes = test_data; + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + GBytes *ssid; + NMSetting *s_wsec; + GError *error = NULL; + + sadata->sinfo = nm_test_service_init (); + sadata->client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + sadata->loop = g_main_loop_new (NULL, FALSE); + sadata->timeout_id = g_timeout_add_seconds (5, timeout_assert, NULL); + + sadata->ifname = g_strdup_printf ("wlan%d", counter); + sadata->con_id = g_strdup_printf ("%s-%d", TEST_CON_ID_PREFIX, counter); + counter++; + + /* Create the device */ + sadata->device = nm_test_service_add_device (sadata->sinfo, sadata->client, + "AddWifiDevice", sadata->ifname); + + /* Create the connection */ + connection = nmtst_create_minimal_connection (sadata->con_id, NULL, NM_SETTING_WIRELESS_SETTING_NAME, &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, sadata->ifname, + NULL); + + s_wireless = nm_connection_get_setting_wireless (connection); + ssid = g_bytes_new ("foo", 3); + g_object_set (s_wireless, + NM_SETTING_WIRELESS_SSID, ssid, + NULL); + g_bytes_unref (ssid); + + s_wsec = g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NULL); + nm_connection_add_setting (connection, s_wsec); + + nm_client_add_connection_async (sadata->client, + connection, + TRUE, + NULL, + connection_added_cb, + sadata); + g_object_unref (connection); + + g_main_loop_run (sadata->loop); + g_assert (sadata->connection); + + if (agent_notes) { + sadata->agent = test_secret_agent_new (); + + if (!strcmp (agent_notes, "sync")) { + nm_secret_agent_old_register (sadata->agent, NULL, &error); + g_assert_no_error (error); + g_assert (nm_secret_agent_old_get_registered (sadata->agent)); + } else { + nm_secret_agent_old_register_async (sadata->agent, NULL, + register_cb, sadata); + g_main_loop_run (sadata->loop); + } + } +} + +static void +test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) +{ + GVariant *ret; + GError *error = NULL; + + if (sadata->agent) { + if (nm_secret_agent_old_get_registered (sadata->agent)) { + nm_secret_agent_old_unregister (sadata->agent, NULL, &error); + g_assert_no_error (error); + } + g_object_unref (sadata->agent); + } + + ret = g_dbus_proxy_call_sync (sadata->sinfo->proxy, + "RemoveDevice", + g_variant_new ("(s)", nm_object_get_path (NM_OBJECT (sadata->device))), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_variant_unref (ret); + + g_object_unref (sadata->connection); + g_object_unref (sadata->client); + + nm_test_service_cleanup (sadata->sinfo); + + g_source_remove (sadata->timeout_id); + g_main_loop_unref (sadata->loop); + + g_free (sadata->ifname); + g_free (sadata->con_id); +} + +/*******************************************************************/ + +static void +connection_activated_none_cb (GObject *c, + GAsyncResult *result, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); + g_assert_error (error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS); + + g_main_loop_quit (sadata->loop); +} + +static void +test_secret_agent_none (TestSecretAgentData *sadata, gconstpointer test_data) +{ + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_none_cb, + sadata); + g_main_loop_run (sadata->loop); +} + +/*******************************************************************/ + +static char * +secrets_requested_no_secrets_cb (TestSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char *secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr (connection_path, ==, nm_connection_get_path (sadata->connection)); + sadata->secrets_requested++; + + return NULL; +} + +static void +connection_activated_no_secrets_cb (GObject *c, + GAsyncResult *result, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); + g_assert_error (error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS); + g_main_loop_quit (sadata->loop); +} + +static void +test_secret_agent_no_secrets (TestSecretAgentData *sadata, gconstpointer test_data) +{ + g_signal_connect (sadata->agent, "secret-requested", + G_CALLBACK (secrets_requested_no_secrets_cb), + sadata); + + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_no_secrets_cb, + sadata); + g_main_loop_run (sadata->loop); + + g_assert_cmpint (sadata->secrets_requested, ==, 1); +} + +/*******************************************************************/ + +static void +connection_activated_cancel_cb (GObject *c, + GAsyncResult *result, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); + g_assert_error (error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_USER_CANCELED); + g_main_loop_quit (sadata->loop); +} + +static char * +secrets_requested_cancel_cb (TestSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char *secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr (connection_path, ==, nm_connection_get_path (sadata->connection)); + sadata->secrets_requested++; + + return g_strdup ("CANCEL"); +} + +static void +test_secret_agent_cancel (TestSecretAgentData *sadata, gconstpointer test_data) +{ + g_signal_connect (sadata->agent, "secret-requested", + G_CALLBACK (secrets_requested_cancel_cb), + sadata); + + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_cancel_cb, + sadata); + g_main_loop_run (sadata->loop); + + g_assert_cmpint (sadata->secrets_requested, ==, 1); +} + +/*******************************************************************/ + +static void +connection_activated_good_cb (GObject *c, + GAsyncResult *result, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); + g_assert_no_error (error); + + g_object_unref (ac); + + g_main_loop_quit (sadata->loop); +} + +static char * +secrets_requested_good_cb (TestSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char *secret_name, + gpointer user_data) +{ + TestSecretAgentData *sadata = user_data; + + g_assert_cmpstr (connection_path, ==, nm_connection_get_path (sadata->connection)); + sadata->secrets_requested++; + + return g_strdup ("password"); +} + +static void +test_secret_agent_good (TestSecretAgentData *sadata, gconstpointer test_data) +{ + g_signal_connect (sadata->agent, "secret-requested", + G_CALLBACK (secrets_requested_good_cb), + sadata); + + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_good_cb, + sadata); + g_main_loop_run (sadata->loop); + + g_assert_cmpint (sadata->secrets_requested, ==, 1); +} + + +static void +async_init_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + GMainLoop *loop = user_data; + GError *error = NULL; + GObject *agent; + + agent = g_async_initable_new_finish (G_ASYNC_INITABLE (object), result, &error); + g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED); + g_assert (agent == NULL); + g_clear_error (&error); + + g_main_loop_quit (loop); +} + +static void +test_secret_agent_nm_not_running (void) +{ + NMSecretAgentOld *agent; + GMainLoop *loop; + GError *error = NULL; + + agent = g_initable_new (test_secret_agent_get_type (), NULL, &error, + NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", + NULL); + g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED); + g_assert (agent == NULL); + g_clear_error (&error); + + loop = g_main_loop_new (NULL, FALSE); + g_async_initable_new_async (test_secret_agent_get_type (), + G_PRIORITY_DEFAULT, + NULL, async_init_cb, loop, + NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", + NULL); + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + + +static void +registered_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); +} + +static void +test_secret_agent_auto_register (void) +{ + NMTestServiceInfo *sinfo; + NMSecretAgentOld *agent; + GMainLoop *loop; + GError *error = NULL; + + sinfo = nm_test_service_init (); + loop = g_main_loop_new (NULL, FALSE); + + agent = test_secret_agent_new (); + g_object_set (agent, + NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE, + NULL); + g_signal_connect (agent, "notify::" NM_SECRET_AGENT_OLD_REGISTERED, + G_CALLBACK (registered_changed), loop); + + g_assert (!nm_secret_agent_old_get_registered (agent)); + nm_secret_agent_old_register (agent, NULL, &error); + g_assert_no_error (error); + g_assert (nm_secret_agent_old_get_registered (agent)); + + /* Shut down test service */ + nm_test_service_cleanup (sinfo); + g_main_loop_run (loop); + g_assert (!nm_secret_agent_old_get_registered (agent)); + + /* Restart test service */ + sinfo = nm_test_service_init (); + g_main_loop_run (loop); + g_assert (nm_secret_agent_old_get_registered (agent)); + + /* Shut down test service again */ + nm_test_service_cleanup (sinfo); + g_main_loop_run (loop); + g_assert (!nm_secret_agent_old_get_registered (agent)); + + g_object_unref (agent); + g_main_loop_unref (loop); +} + +/*******************************************************************/ + +int +main (int argc, char **argv) +{ + int ret; + + g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + g_test_init (&argc, &argv, NULL); + + g_test_add ("/libnm/secret-agent/none", TestSecretAgentData, NULL, + test_setup, test_secret_agent_none, test_cleanup); + g_test_add ("/libnm/secret-agent/no-secrets", TestSecretAgentData, "sync", + test_setup, test_secret_agent_no_secrets, test_cleanup); + g_test_add ("/libnm/secret-agent/cancel", TestSecretAgentData, "async", + test_setup, test_secret_agent_cancel, test_cleanup); + g_test_add ("/libnm/secret-agent/good", TestSecretAgentData, "async", + test_setup, test_secret_agent_good, test_cleanup); + g_test_add_func ("/libnm/secret-agent/nm-not-running", test_secret_agent_nm_not_running); + g_test_add_func ("/libnm/secret-agent/auto-register", test_secret_agent_auto_register); + + ret = g_test_run (); + + return ret; +} + diff --git a/m4/ax_lib_readline.m4 b/m4/ax_lib_readline.m4 index 72764fba..fe56c5bf 100644 --- a/m4/ax_lib_readline.m4 +++ b/m4/ax_lib_readline.m4 @@ -90,8 +90,11 @@ AC_DEFUN([AX_LIB_READLINE], [ AC_MSG_ERROR([readline library with terminfo support is required (one of ncurses, curses, or termcap)]) fi + ORIG_LIBS="$LIBS" LIBS="$LIBS $ax_cv_lib_readline" AC_CHECK_HEADERS(readline.h readline/readline.h) + + # Check history AC_CACHE_CHECK([whether readline supports history], ax_cv_lib_readline_history, [ ax_cv_lib_readline_history="no" @@ -101,6 +104,18 @@ AC_DEFUN([AX_LIB_READLINE], [ AC_MSG_ERROR(readline history support is required) fi AC_CHECK_HEADERS(history.h readline/history.h) + + # check rl_echo_signal_char() + AC_CACHE_CHECK([whether readline supports rl_echo_signal_char()], + ax_cv_lib_readline_echo_signal_char, [ + ax_cv_lib_readline_echo_signal_char="no" + AC_TRY_LINK_FUNC(rl_echo_signal_char, ax_cv_lib_readline_echo_signal_char="yes") + ]) + if test "$ax_cv_lib_readline_echo_signal_char" != "yes"; then + AC_MSG_ERROR(rl_echo_signal_char() is required (install readline6?)) + fi + + LIBS="$ORIG_LIBS" READLINE_LIBS="$ax_cv_lib_readline" AC_SUBST(READLINE_LIBS) ])dnl diff --git a/m4/compiler_warnings.m4 b/m4/compiler_warnings.m4 index 357ff0e7..c05a26d0 100644 --- a/m4/compiler_warnings.m4 +++ b/m4/compiler_warnings.m4 @@ -5,32 +5,49 @@ AC_DEFUN([NM_COMPILER_WARNINGS], AC_MSG_CHECKING(for more warnings) if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then AC_MSG_RESULT(yes) - CFLAGS="-Wall -std=gnu89 $CFLAGS" + CFLAGS_SAVED="$CFLAGS" + CFLAGS_MORE_WARNINGS="-Wall -std=gnu89" + + dnl clang only warns about unknown warnings, unless + dnl called with "-Werror=unknown-warning-option" + dnl Test if the compiler supports that, and if it does + dnl attach it to the CFLAGS. + CFLAGS_EXTRA="-Werror=unknown-warning-option" + CFLAGS="$CFLAGS_MORE_WARNINGS $CFLAGS_EXTRA $CFLAGS_SAVED" + AC_TRY_COMPILE([], [], + has_option=yes, + has_option=no,) + if test $has_option = no; then + CFLAGS_EXTRA= + fi + unset has_option for option in -Wshadow -Wmissing-declarations -Wmissing-prototypes \ -Wdeclaration-after-statement -Wformat-security \ -Wfloat-equal -Wno-unused-parameter -Wno-sign-compare \ + -Wstrict-prototypes \ -fno-strict-aliasing -Wno-unused-but-set-variable \ -Wundef -Wimplicit-function-declaration \ -Wpointer-arith -Winit-self \ - -Wmissing-include-dirs -Waggregate-return; do - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $option" + -Wmissing-include-dirs; do + CFLAGS="$CFLAGS_MORE_WARNINGS $CFLAGS_EXTRA $option $CFLAGS_SAVED" AC_MSG_CHECKING([whether gcc understands $option]) AC_TRY_COMPILE([], [], has_option=yes, has_option=no,) - if test $has_option = no; then - CFLAGS="$SAVE_CFLAGS" + if test $has_option != no; then + CFLAGS_MORE_WARNINGS="$CFLAGS_MORE_WARNINGS $option" fi AC_MSG_RESULT($has_option) unset has_option - unset SAVE_CFLAGS done unset option + unset CFLAGS_EXTRA if test "x$set_more_warnings" = xerror; then - CFLAGS="$CFLAGS -Werror" + CFLAGS_MORE_WARNINGS="$CFLAGS_MORE_WARNINGS -Werror" fi + CFLAGS="$CFLAGS_MORE_WARNINGS $CFLAGS_SAVED" + unset CFLAGS_SAVED else AC_MSG_RESULT(no) fi diff --git a/man/Makefile.am b/man/Makefile.am index 64469685..4577cb41 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -4,16 +4,16 @@ EXTRA_DIST = XSLTPROC = xsltproc -XSLTPROC_FLAGS = \ - --xinclude \ - --nonet \ +XSLTPROC_FLAGS = --xinclude --nonet + +XSLTPROC_MAN_FLAGS = \ + $(XSLTPROC_FLAGS) \ --stringparam man.output.quietly 1 \ --stringparam funcsynopsis.style ansi \ --stringparam man.th.extra1.suppress 1 \ --stringparam man.authors.section.enabled 0 \ - --stringparam man.copyright.section.enabled 0 - -XSLTPROC_MAN_FLAGS = $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl + --stringparam man.copyright.section.enabled 0 \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl if ENABLE_GTK_DOC @@ -23,14 +23,41 @@ if ENABLE_GTK_DOC %.5: %.xml $(AM_V_GEN) xsltproc $(XSLTPROC_MAN_FLAGS) $< -nm-settings.xml: $(top_builddir)/tools/generate-settings-spec $(top_builddir)/libnm-util/libnm-util.la - rm -f $(builddir)/$@ - $(top_builddir)/tools/generate-settings-spec refentry $(builddir)/$@ +endif + +if BUILD_SETTING_DOCS + +nm-settings.xml: nm-settings.xsl $(top_builddir)/libnm/nm-setting-docs.xml + $(AM_V_GEN) xsltproc \ + --output $@ \ + --stringparam version $(NM_VERSION) \ + --stringparam date "`date +'%d %B %Y'`" \ + $^ + +nm-settings-keyfile.xml: nm-settings-keyfile.xsl $(top_builddir)/libnm/nm-keyfile-docs.xml + $(AM_V_GEN) xsltproc \ + --output $@ \ + --stringparam version $(NM_VERSION) \ + --stringparam date "`date +'%d %B %Y'`" \ + $^ + +nm-settings-ifcfg-rh.xml: nm-settings-ifcfg-rh.xsl $(top_builddir)/libnm/nm-ifcfg-rh-docs.xml + $(AM_V_GEN) xsltproc \ + --output $@ \ + --stringparam version $(NM_VERSION) \ + --stringparam date "`date +'%d %B %Y'`" \ + $^ + +CLEANFILES += \ + nm-settings.xml \ + nm-settings-keyfile.xml \ + nm-settings-ifcfg-rh.xml endif configure_generated_man_pages = \ nmcli.1 \ + nmtui.1 \ nm-online.1 \ nm-system-settings.conf.5 @@ -40,29 +67,46 @@ docbook_generated_man_pages = \ nmcli-examples.5 docbook_autogenerated_man_pages = \ - nm-settings.5 - -generated_man_pages = \ - $(docbook_generated_man_pages) \ - $(docbook_autogenerated_man_pages) + nm-settings.5 \ + nm-settings-keyfile.5 \ + nm-settings-ifcfg-rh.5 EXTRA_DIST += \ + nm-settings.xml \ + nm-settings.xsl \ + nm-settings-keyfile.xml \ + nm-settings-keyfile.xsl \ + nm-settings-ifcfg-rh.xml \ + nm-settings-ifcfg-rh.xsl \ $(docbook_generated_man_pages:.%=.xml) \ $(docbook_autogenerated_man_pages) -CLEANFILES += \ - nm-settings.xml - man_MANS += $(configure_generated_man_pages) +links = nmtui-edit nmtui-connect nmtui-hostname + +install-data-hook: + for link in $(links); do \ + ln -f $(DESTDIR)$(mandir)/man1/nmtui.1 $(DESTDIR)$(mandir)/man1/$$link.1; \ + done + +uninstall-hook: + for link in $(links); do \ + rm -f $(DESTDIR)$(mandir)/man1/$$link.1; \ + done + if ENABLE_GTK_DOC -man_MANS += $(generated_man_pages) -CLEANFILES += \ - $(docbook_autogenerated_man_pages) \ - $(docbook_generated_man_pages) +man_MANS += $(docbook_generated_man_pages) +CLEANFILES += $(docbook_generated_man_pages) +if SETTING_DOCS_AVAILABLE +man_MANS += $(docbook_autogenerated_man_pages) +CLEANFILES += $(docbook_autogenerated_man_pages) +endif else if INSTALL_PREGEN_MANPAGES -man_MANS += $(generated_man_pages) +man_MANS += \ + $(docbook_generated_man_pages) \ + $(docbook_autogenerated_man_pages) endif endif diff --git a/man/Makefile.in b/man/Makefile.in index a48bf680..503b900c 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -77,16 +77,25 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@ENABLE_GTK_DOC_TRUE@am__append_1 = $(generated_man_pages) -@ENABLE_GTK_DOC_TRUE@am__append_2 = \ -@ENABLE_GTK_DOC_TRUE@ $(docbook_autogenerated_man_pages) \ -@ENABLE_GTK_DOC_TRUE@ $(docbook_generated_man_pages) +@BUILD_SETTING_DOCS_TRUE@am__append_1 = \ +@BUILD_SETTING_DOCS_TRUE@ nm-settings.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-settings-keyfile.xml \ +@BUILD_SETTING_DOCS_TRUE@ nm-settings-ifcfg-rh.xml + +@ENABLE_GTK_DOC_TRUE@am__append_2 = $(docbook_generated_man_pages) +@ENABLE_GTK_DOC_TRUE@am__append_3 = $(docbook_generated_man_pages) +@ENABLE_GTK_DOC_TRUE@@SETTING_DOCS_AVAILABLE_TRUE@am__append_4 = $(docbook_autogenerated_man_pages) +@ENABLE_GTK_DOC_TRUE@@SETTING_DOCS_AVAILABLE_TRUE@am__append_5 = $(docbook_autogenerated_man_pages) +@ENABLE_GTK_DOC_FALSE@@INSTALL_PREGEN_MANPAGES_TRUE@am__append_6 = \ +@ENABLE_GTK_DOC_FALSE@@INSTALL_PREGEN_MANPAGES_TRUE@ $(docbook_generated_man_pages) \ +@ENABLE_GTK_DOC_FALSE@@INSTALL_PREGEN_MANPAGES_TRUE@ $(docbook_autogenerated_man_pages) -@ENABLE_GTK_DOC_FALSE@@INSTALL_PREGEN_MANPAGES_TRUE@am__append_3 = $(generated_man_pages) subdir = man DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/NetworkManager.conf.xml.in \ $(srcdir)/nm-system-settings.conf.5.in \ - $(srcdir)/nm-online.1.in $(srcdir)/nmcli.1.in + $(srcdir)/nm-online.1.in $(srcdir)/nmcli.1.in \ + $(srcdir)/nmtui.1.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -105,7 +114,8 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = nm-system-settings.conf.5 nm-online.1 nmcli.1 +CONFIG_CLEAN_FILES = NetworkManager.conf.xml nm-system-settings.conf.5 \ + nm-online.1 nmcli.1 nmtui.1 CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -171,6 +181,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -294,6 +306,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -313,6 +326,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -339,7 +353,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -418,24 +432,28 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -man_MANS = $(configure_generated_man_pages) $(am__append_1) \ - $(am__append_3) -CLEANFILES = nm-settings.xml $(am__append_2) -EXTRA_DIST = $(docbook_generated_man_pages:.%=.xml) \ +man_MANS = $(configure_generated_man_pages) $(am__append_2) \ + $(am__append_4) $(am__append_6) +CLEANFILES = $(am__append_1) $(am__append_3) $(am__append_5) +EXTRA_DIST = nm-settings.xml nm-settings.xsl nm-settings-keyfile.xml \ + nm-settings-keyfile.xsl nm-settings-ifcfg-rh.xml \ + nm-settings-ifcfg-rh.xsl \ + $(docbook_generated_man_pages:.%=.xml) \ $(docbook_autogenerated_man_pages) XSLTPROC = xsltproc -XSLTPROC_FLAGS = \ - --xinclude \ - --nonet \ +XSLTPROC_FLAGS = --xinclude --nonet +XSLTPROC_MAN_FLAGS = \ + $(XSLTPROC_FLAGS) \ --stringparam man.output.quietly 1 \ --stringparam funcsynopsis.style ansi \ --stringparam man.th.extra1.suppress 1 \ --stringparam man.authors.section.enabled 0 \ - --stringparam man.copyright.section.enabled 0 + --stringparam man.copyright.section.enabled 0 \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl -XSLTPROC_MAN_FLAGS = $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl configure_generated_man_pages = \ nmcli.1 \ + nmtui.1 \ nm-online.1 \ nm-system-settings.conf.5 @@ -445,12 +463,11 @@ docbook_generated_man_pages = \ nmcli-examples.5 docbook_autogenerated_man_pages = \ - nm-settings.5 - -generated_man_pages = \ - $(docbook_generated_man_pages) \ - $(docbook_autogenerated_man_pages) + nm-settings.5 \ + nm-settings-keyfile.5 \ + nm-settings-ifcfg-rh.5 +links = nmtui-edit nmtui-connect nmtui-hostname all: all-am .SUFFIXES: @@ -484,12 +501,16 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +NetworkManager.conf.xml: $(top_builddir)/config.status $(srcdir)/NetworkManager.conf.xml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nm-system-settings.conf.5: $(top_builddir)/config.status $(srcdir)/nm-system-settings.conf.5.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nm-online.1: $(top_builddir)/config.status $(srcdir)/nm-online.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nmcli.1: $(top_builddir)/config.status $(srcdir)/nmcli.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +nmtui.1: $(top_builddir)/config.status $(srcdir)/nmtui.1.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo @@ -721,7 +742,8 @@ info: info-am info-am: install-data-am: install-man - + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: @@ -765,24 +787,25 @@ ps: ps-am ps-am: uninstall-am: uninstall-man - + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 -.MAKE: install-am install-strip +.MAKE: install-am install-data-am install-strip uninstall-am .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am 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-man1 install-man5 install-man8 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 tags-am uninstall \ - uninstall-am uninstall-man uninstall-man1 uninstall-man5 \ - uninstall-man8 + 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-man1 install-man5 \ + install-man8 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 tags-am uninstall uninstall-am uninstall-hook \ + uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 @ENABLE_GTK_DOC_TRUE@%.8: %.xml @@ -791,9 +814,36 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 @ENABLE_GTK_DOC_TRUE@%.5: %.xml @ENABLE_GTK_DOC_TRUE@ $(AM_V_GEN) xsltproc $(XSLTPROC_MAN_FLAGS) $< -@ENABLE_GTK_DOC_TRUE@nm-settings.xml: $(top_builddir)/tools/generate-settings-spec $(top_builddir)/libnm-util/libnm-util.la -@ENABLE_GTK_DOC_TRUE@ rm -f $(builddir)/$@ -@ENABLE_GTK_DOC_TRUE@ $(top_builddir)/tools/generate-settings-spec refentry $(builddir)/$@ +@BUILD_SETTING_DOCS_TRUE@nm-settings.xml: nm-settings.xsl $(top_builddir)/libnm/nm-setting-docs.xml +@BUILD_SETTING_DOCS_TRUE@ $(AM_V_GEN) xsltproc \ +@BUILD_SETTING_DOCS_TRUE@ --output $@ \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam version $(NM_VERSION) \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam date "`date +'%d %B %Y'`" \ +@BUILD_SETTING_DOCS_TRUE@ $^ + +@BUILD_SETTING_DOCS_TRUE@nm-settings-keyfile.xml: nm-settings-keyfile.xsl $(top_builddir)/libnm/nm-keyfile-docs.xml +@BUILD_SETTING_DOCS_TRUE@ $(AM_V_GEN) xsltproc \ +@BUILD_SETTING_DOCS_TRUE@ --output $@ \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam version $(NM_VERSION) \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam date "`date +'%d %B %Y'`" \ +@BUILD_SETTING_DOCS_TRUE@ $^ + +@BUILD_SETTING_DOCS_TRUE@nm-settings-ifcfg-rh.xml: nm-settings-ifcfg-rh.xsl $(top_builddir)/libnm/nm-ifcfg-rh-docs.xml +@BUILD_SETTING_DOCS_TRUE@ $(AM_V_GEN) xsltproc \ +@BUILD_SETTING_DOCS_TRUE@ --output $@ \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam version $(NM_VERSION) \ +@BUILD_SETTING_DOCS_TRUE@ --stringparam date "`date +'%d %B %Y'`" \ +@BUILD_SETTING_DOCS_TRUE@ $^ + +install-data-hook: + for link in $(links); do \ + ln -f $(DESTDIR)$(mandir)/man1/nmtui.1 $(DESTDIR)$(mandir)/man1/$$link.1; \ + done + +uninstall-hook: + for link in $(links); do \ + rm -f $(DESTDIR)$(mandir)/man1/$$link.1; \ + 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. diff --git a/man/NetworkManager.8 b/man/NetworkManager.8 index 5022eadb..483f61a4 100644 --- a/man/NetworkManager.8 +++ b/man/NetworkManager.8 @@ -2,12 +2,12 @@ .\" Title: NetworkManager .\" Author: .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 07/03/2014 +.\" Date: 12/19/2014 .\" Manual: Network management daemons -.\" Source: NetworkManager 0.9.10 +.\" Source: NetworkManager 1.0 .\" Language: English .\" -.TH "NETWORKMANAGER" "8" "" "NetworkManager 0\&.9\&.10" "Network management daemons" +.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.0" "Network management daemons" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -122,7 +122,7 @@ The IP interface name of the device\&. .PP \fIIP4_ADDRESS_N\fR .RS 4 -The IPv4 address in the format "address/prefix gateway", where N is a number from 0 to (# IPv4 address \e\- 1)\&. +The IPv4 address in the format "address/prefix gateway", where N is a number from 0 to (# IPv4 addresses \- 1)\&. gateway item in this variable is deprecated, use IP4_GATEWAY instead\&. .RE .PP \fIIP4_NUM_ADDRESSES\fR @@ -130,9 +130,14 @@ The IPv4 address in the format "address/prefix gateway", where N is a number fro The variable contains the number of IPv4 addresses the script may expect\&. .RE .PP +\fIIP4_GATEWAY\fR +.RS 4 +The gateway IPv4 address in traditional numbers\-and\-dots notation\&. +.RE +.PP \fIIP4_ROUTE_N\fR .RS 4 -The IPv4 route in the format "address/prefix next\-hop metric", where N is a number from 0 to (# IPv4 routes \e\- 1)\&. +The IPv4 route in the format "address/prefix next\-hop metric", where N is a number from 0 to (# IPv4 routes \- 1)\&. .RE .PP \fIIP4_NUM_ROUTES\fR @@ -199,7 +204,7 @@ Specify file for storing state of the NetworkManager persistently\&. If not spec .PP \fB\-\-config\fR .RS 4 -Specify configuration file to set up various settings for NetworkManager\&. If not specified, the default value of /etc/NetworkManager/NetworkManager\&.conf is used with a fallback to the older \*(Aqnm\e\-system\e\-settings\&.conf\*(Aq if located in the same directory\&. See +Specify configuration file to set up various settings for NetworkManager\&. If not specified, the default value of /etc/NetworkManager/NetworkManager\&.conf is used with a fallback to the older \*(Aqnm\-system\-settings\&.conf\*(Aq if located in the same directory\&. See \fBNetworkManager.conf\fR(5) for more information on configuration file\&. .RE diff --git a/man/NetworkManager.conf.5 b/man/NetworkManager.conf.5 index ef7641bc..f34fa63a 100644 --- a/man/NetworkManager.conf.5 +++ b/man/NetworkManager.conf.5 @@ -2,12 +2,12 @@ .\" Title: NetworkManager.conf .\" Author: .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 07/03/2014 +.\" Date: 12/19/2014 .\" Manual: Configuration -.\" Source: NetworkManager 0.9.10 +.\" Source: NetworkManager 1.0 .\" Language: English .\" -.TH "NETWORKMANAGER\&.CON" "5" "" "NetworkManager 0\&.9\&.10" "Configuration" +.TH "NETWORKMANAGER\&.CON" "5" "" "NetworkManager 1\&.0" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -87,7 +87,7 @@ Lists system settings plugin names separated by \*(Aq,\*(Aq\&. These plugins are .sp If NetworkManager defines a distro\-specific network\-configuration plugin for your system, then that will normally be listed here\&. (See below for the available plugins\&.) Note that the keyfile -plugin is always appended to the end of this list (if it doesn\*(Aqt already appear earlier in the list), so if there is no distro\-specific plugin for your system then you can leave this key unset and NetworkManager will default to using +plugin is always appended to the end of this list (if it doesn\*(Aqt already appear earlier in the list), so if there is no distro\-specific plugin for your system then you can leave this key unset and NetworkManager will fall back to using keyfile\&. .RE .PP @@ -96,13 +96,31 @@ keyfile\&. Whether the configured settings plugin(s) should set up file monitors and immediately pick up changes made to connection files while NetworkManager is running\&. This is disabled by default; NetworkManager will only read the connection files at startup, and when explicitly requested via the ReloadConnections D\-Bus call\&. If this key is set to \*(Aqtrue\*(Aq, then NetworkManager will reload connection files any time they changed\&. .RE .PP +\fIauth\-polkit\fR +.RS 4 +Whether the system uses PolicyKit for authorization\&. If +false, all requests will be allowed\&. If +true, non\-root requests are authorized using PolicyKit\&. The default value is +true\&. +.RE +.PP \fIdhcp\fR .RS 4 -This key sets up what DHCP client NetworkManager will use\&. Presently +This key sets up what DHCP client NetworkManager will use\&. Allowed values are +dhclient, +dhcpcd, and +internal\&. The dhclient and dhcpcd -are supported\&. The client configured here should be available on your system too\&. If this key is missing, available DHCP clients are looked for in this order: dhclient, dhcpcd\&. +options require the indicated clients to be installed\&. The +internal +option uses a built\-in DHCP client which is not currently as featureful as the external clients (and in particular, does not yet support DHCPv6)\&. +.sp +If this key is missing, available DHCP clients are looked for in this order: +dhclient, +dhcpcd, +internal\&. .RE .PP \fIno\-auto\-default\fR @@ -143,6 +161,14 @@ to apply to all devices\&. Note that the "carrier" property of NMDevices and device D\-Bus interfaces will still reflect the actual device state; it\*(Aqs just that NetworkManager will not make use of that information\&. .RE .PP +\fIconfigure\-and\-quit\fR +.RS 4 +When set to +true, NetworkManager quits after performing initial network configuration but spawns small helpers to preserve DHCP leases and IPv6 addresses\&. This is useful in environments where network setup is more or less static or it is desirable to save process time but still handle some dynamic configurations\&. When this option is +true, network configuration for WiFi, WWAN, Bluetooth, ADSL, and PPPoE interfaces cannot be preserved due to their use of external services, and these devices will be deconfigured when NetworkManager quits even though other interface\*(Aqs configuration may be preserved\&. The default value is +false, meaning that NetworkManager will continue running after initial network configuration and continue responding to system and hardware events, D\-Bus requests, and user commands\&. +.RE +.PP \fIdns\fR .RS 4 Set the DNS (resolv\&.conf) processing mode\&. @@ -243,7 +269,8 @@ The default logging verbosity level\&. One of ERR, WARN, INFO, -DEBUG\&. The ERR level logs only critical errors\&. WARN logs warnings that may reflect operation\&. INFO logs various informational messages that are useful for tracking state and operations\&. DEBUG enables verbose logging for debugging purposes\&. Subsequent levels also log all messages from earlier levels; thus setting the log level to INFO also logs error and warning messages\&. +DEBUG, +TRACE\&. The ERR level logs only critical errors\&. WARN logs warnings that may reflect operation\&. INFO logs various informational messages that are useful for tracking state and operations\&. DEBUG enables verbose logging for debugging purposes\&. TRACE enables even more verbose logging then DEBUG level\&. Subsequent levels also log all messages from earlier levels; thus setting the log level to INFO also logs error and warning messages\&. .RE .PP \fIdomains\fR @@ -447,6 +474,11 @@ This plugin is read\-only; any connections (of any type) added from within Netwo keyfile plugin instead\&. .RE +.PP +\fIibft\fR +.RS 4 +This plugin allows to read iBFT configuration (iSCSI Boot Firmware Table)\&. The configuration is read using /sbin/iscsiadm\&. Users are expected to configure iBFT connections via the firmware interfaces\&. +.RE .SH "SEE ALSO" .PP \fBNetworkManager\fR(8), diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in new file mode 100644 index 00000000..d9d51b84 --- /dev/null +++ b/man/NetworkManager.conf.xml.in @@ -0,0 +1,560 @@ + + + + + + + + NetworkManager.conf + NetworkManager developers + + + + NetworkManager.conf + 5 + NetworkManager + Configuration + 1.0 + + + + NetworkManager.conf + NetworkManager configuration file + + + + /etc/NetworkManager/NetworkManager.conf, + /etc/NetworkManager/conf.d/name.conf + + + + + Description + This is a configuration file for NetworkManager. It is used + to set up various aspects of NetworkManager's behavior. The + location of the file may be changed through use of the + argument for NetworkManager. + + If a default NetworkManager.conf is + provided by your distribution's packages, you should not modify + it, since your changes may get overwritten by package + updates. Instead, you can add additional .conf + files to the conf.d directory. These will be read in order, + with later files overriding earlier ones. + + + + + + File Format + + The configuration file format is so-called key file (sort of + ini-style format). It consists of sections (groups) of + key-value pairs. Lines beginning with a '#' and blank lines are + considered comments. Sections are started by a header line + containing the section enclosed in '[' and ']', and ended + implicitly by the start of the next section or the end of the + file. Each key-value pair must be contained in a section. + + + For keys that take a list of devices as their value, you can + specify devices by their MAC addresses or interface names, or + "*" to specify all devices. + + + Minimal system settings configuration file looks like this: + + [main] + plugins=keyfile + + + + As an extension to the normal keyfile format, you can also + append a value to a previously-set list-valued key by doing: + + plugins+=another-plugin + + + + + + <literal>main</literal> section + + + plugins + + + Lists system settings plugin names separated by ','. These + plugins are used to read and write system-wide + connections. When multiple plugins are specified, the + connections are read from all listed plugins. When writing + connections, the plugins will be asked to save the + connection in the order listed here; if the first plugin + cannot write out that connection type (or can't write out + any connections) the next plugin is tried, etc. If none of + the plugins can save the connection, an error is returned + to the user. + + + If NetworkManager defines a distro-specific + network-configuration plugin for your system, then that + will normally be listed here. (See below for the available + plugins.) Note that the keyfile plugin + is always appended to the end of this list (if it doesn't + already appear earlier in the list), so if there is no + distro-specific plugin for your system then you can leave + this key unset and NetworkManager will fall back to using + keyfile. + + + + + monitor-connection-files + Whether the configured settings plugin(s) + should set up file monitors and immediately pick up changes + made to connection files while NetworkManager is running. This + is disabled by default; NetworkManager will only read + the connection files at startup, and when explicitly requested + via the ReloadConnections D-Bus call. If this key is set to + 'true', then NetworkManager will reload + connection files any time they changed. + + + auth-polkit + Whether the system uses PolicyKit for authorization. + If false, all requests will be allowed. If + true, non-root requests are authorized using PolicyKit. + The default value is @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@. + + + + dhcp + This key sets up what DHCP client + NetworkManager will use. Allowed values are + dhclient, dhcpcd, and + internal. The dhclient + and dhcpcd options require the indicated + clients to be installed. The internal + option uses a built-in DHCP client which is not currently as + featureful as the external clients (and in particular, does + not yet support DHCPv6). + If this key is missing, available DHCP clients are + looked for in this order: dhclient, + dhcpcd, + internal. + + + no-auto-default + Comma-separated list of devices for which + NetworkManager shouldn't create default wired connection + (Auto eth0). By default, NetworkManager creates a temporary + wired connection for any Ethernet device that is managed and + doesn't have a connection configured. List a device in this + option to inhibit creating the default connection for the + device. May have the special value * to + apply to all devices. + When the default wired connection is deleted or saved + to a new persistent connection by a plugin, the device is + added to a list in the file + /var/run/NetworkManager/no-auto-default.state + to prevent creating the default connection for that device + again. + + + no-auto-default=00:22:68:5c:5d:c4,00:1e:65:ff:aa:ee + no-auto-default=eth0,eth1 + no-auto-default=* + + + + + + + ignore-carrier + + + Comma-separated list of devices for which NetworkManager + will (partially) ignore the carrier state. Normally, for + device types that support carrier-detect, such as Ethernet + and InfiniBand, NetworkManager will only allow a + connection to be activated on the device if carrier is + present (ie, a cable is plugged in), and it will + deactivate the device if carrier drops for more than a few + seconds. + + + Listing a device here will allow activating connections on + that device even when it does not have carrier, provided + that the connection uses only statically-configured IP + addresses. Additionally, it will allow any active + connection (whether static or dynamic) to remain active on + the device when carrier is lost. + + + May have the special value * to apply + to all devices. + + + Note that the "carrier" property of NMDevices and device D-Bus + interfaces will still reflect the actual device state; it's just + that NetworkManager will not make use of that information. + + + + + + configure-and-quit + + + When set to true, NetworkManager quits after + performing initial network configuration but spawns small helpers + to preserve DHCP leases and IPv6 addresses. This is useful in + environments where network setup is more or less static or it is + desirable to save process time but still handle some dynamic + configurations. When this option is true, + network configuration for WiFi, WWAN, Bluetooth, ADSL, and PPPoE + interfaces cannot be preserved due to their use of external + services, and these devices will be deconfigured when NetworkManager + quits even though other interface's configuration may be preserved. + The default value is false, meaning that + NetworkManager will continue running after initial network + configuration and continue responding to system and hardware events, + D-Bus requests, and user commands. + + + + + + dns + Set the DNS (resolv.conf) processing mode. + default: The default if the key is + not specified. NetworkManager will update + resolv.conf to reflect the nameservers + provided by currently active connections. + dnsmasq: NetworkManager will run + dnsmasq as a local caching nameserver, using a "split DNS" + configuration if you are connected to a VPN, and then update + resolv.conf to point to the local + nameserver. + unbound: NetworkManager will talk + to unbound and dnssec-triggerd, providing a "split DNS" + configuration with DNSSEC support. The /etc/resolv.conf + will be managed by dnssec-trigger daemon. + none: NetworkManager will not + modify resolv.conf. + + + + + debug + Comma separated list of options to aid + debugging. This value will be combined with the environment + variable NM_DEBUG. Currently the following + values are supported: + + RLIMIT_CORE: set ulimit -c unlimited + to write out core dumps. + + + + + + + + + <literal>keyfile</literal> section + This section contains keyfile-plugin-specific options, and + is normally only used when you are not using any other + distro-specific plugin. + + + + + hostname + Set a persistent hostname. + + + unmanaged-devices + Set devices that should be ignored by + NetworkManager when using the keyfile + plugin. Devices are specified in the following + format: + mac:<hwaddr> or + interface-name:<ifname>. Here + hwaddr is the MAC address of the device + to be ignored, in hex-digits-and-colons notation. + ifname is the interface name of the + ignored device. + Multiple entries are separated with semicolons. No + spaces are allowed in the value. + + Example: + +unmanaged-devices=interface-name:em4 +unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth2 + + + + + + + + + + <literal>ifupdown</literal> section + This section contains ifupdown-specific options and thus only + has effect when using the ifupdown plugin. + + + + + managed + If set to true, then + interfaces listed in + /etc/network/interfaces are managed by + NetworkManager. If set to false, then + any interface listed in + /etc/network/interfaces will be ignored + by NetworkManager. Remember that NetworkManager controls the + default route, so because the interface is ignored, + NetworkManager may assign the default route to some other + interface. + + The default value is false. + + + + + + + + + <literal>logging</literal> section + This section controls NetworkManager's logging. Any + settings here are overridden by the + and command-line options. + + + + + level + The default logging verbosity level. + One of ERR, + WARN, INFO, + DEBUG, TRACE. The ERR + level logs only critical errors. WARN logs warnings that may + reflect operation. INFO logs various informational messages that + are useful for tracking state and operations. DEBUG enables + verbose logging for debugging purposes. TRACE enables even more + verbose logging then DEBUG level. Subsequent levels also log + all messages from earlier levels; thus setting the log level + to INFO also logs error and warning messages. + + + domains + The following log domains are available: + PLATFORM, RFKILL, ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP, + WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT, + AGENTS, SETTINGS, SUSPEND, CORE, DEVICE, OLPC, WIMAX, + INFINIBAND, FIREWALL, ADSL, BOND, VLAN, BRIDGE, DBUS_PROPS, + TEAM, CONCHECK, DCB, DISPATCH. + In addition, these special domains can be used: NONE, + ALL, DEFAULT, DHCP, IP. + You can specify per-domain log level overrides by + adding a colon and a log level to any domain. E.g., + "WIFI:DEBUG". + + + Domain descriptions: + + PLATFORM : OS (platform) operations + RFKILL : RFKill subsystem operations + ETHER : Ethernet device operations + WIFI : Wi-Fi device operations + BT : Bluetooth operations + MB : Mobile broadband operations + DHCP4 : DHCP for IPv4 + DHCP6 : DHCP for IPv6 + PPP : Point-to-point protocol operations + WIFI_SCAN : Wi-Fi scanning operations + IP4 : IPv4-related operations + IP6 : IPv6-related operations + AUTOIP4 : AutoIP (avahi) operations + DNS : Domain Name System related operations + VPN : Virtual Private Network connections and operations + SHARING : Connection sharing + SUPPLICANT : WPA supplicant related operations + AGENTS : Secret agents operations and communication + SETTINGS : Settings/config service operations + SUSPEND : Suspend/resume + CORE : Core daemon and policy operations + DEVICE : Activation and general interface operations + OLPC : OLPC Mesh device operations + WIMAX : WiMAX device operations + INFINIBAND : InfiniBand device operations + FIREWALL : FirewallD related operations + ADSL : ADSL device operations + BOND : Bonding operations + VLAN : VLAN operations + BRIDGE : Bridging operations + DBUS_PROPS : D-Bus property changes + TEAM : Teaming operations + CONCHECK : Connectivity check + DCB : Data Center Bridging (DCB) operations + DISPATCH : Dispatcher scripts + + NONE : when given by itself logging is disabled + ALL : all log domains + DEFAULT : default log domains + DHCP : shortcut for "DHCP4,DHCP6" + IP : shortcut for "IP4,IP6" + + HW : deprecated alias for "PLATFORM" + + + + + + + + + <literal>connectivity</literal> section + This section controls NetworkManager's optional connectivity + checking functionality. This allows NetworkManager to detect + whether or not the system can actually access the internet or + whether it is behind a captive portal. + + + + + uri + The URI of a web page to periodically + request when connectivity is being checked. This page + should return the header "X-NetworkManager-Status" with a + value of "online". Alternatively, it's body content should + be set to "NetworkManager is online". The body content + check can be controlled by the response + option. If this option is blank or missing, connectivity + checking is disabled. + + + + interval + Specified in seconds; controls how often + connectivity is checked when a network connection exists. If + set to 0 connectivity checking is disabled. If missing, the + default is 300 seconds. + + + response + If set controls what body content + NetworkManager checks for when requesting the URI for + connectivity checking. If missing, defaults to + "NetworkManager is online" + + + + + + + Plugins + + + + keyfile + + + The keyfile plugin is the generic + plugin that supports all the connection types and + capabilities that NetworkManager has. It writes files out + in an .ini-style format in + /etc/NetworkManager/system-connections. + + + The stored connection file may contain passwords and + private keys, so it will be made readable only to root, + and the plugin will ignore files that are readable or + writeable by any user or group other than root. + + + This plugin is always active, and will automatically be + used to store any connections that aren't supported by any + other active plugin. + + + + + ifcfg-rh + + + This plugin is used on the Fedora and Red Hat Enterprise + Linux distributions to read and write configuration from + the standard + /etc/sysconfig/network-scripts/ifcfg-* + files. It currently supports reading Ethernet, Wi-Fi, + InfiniBand, VLAN, Bond, Bridge, and Team connections. + + + + + + ifcfg-suse + + + This plugin is only provided for simple backward + compatibility with SUSE and OpenSUSE configuration. Most + setups should be using the keyfile + plugin instead. The ifcfg-suse plugin + supports reading Ethernet and Wi-Fi connections, but does + not support saving any connection types. + + + + + + ifupdown + + + This plugin is used on the Debian and Ubuntu + distributions, and reads Ethernet and Wi-Fi connections + from /etc/network/interfaces. + + + This plugin is read-only; any connections (of any type) + added from within NetworkManager when you are using this + plugin will be saved using the keyfile + plugin instead. + + + + + + ibft + + + This plugin allows to read iBFT configuration (iSCSI Boot Firmware Table). + The configuration is read using /sbin/iscsiadm. Users are expected to + configure iBFT connections via the firmware interfaces. + + + + + + + + + See Also + + NetworkManager8, + nmcli1, + nmcli-examples5, + nm-online1, + nm-settings5, + nm-applet1, + nm-connection-editor1 + + + diff --git a/man/nm-settings-ifcfg-rh.5 b/man/nm-settings-ifcfg-rh.5 new file mode 100644 index 00000000..6dea364c --- /dev/null +++ b/man/nm-settings-ifcfg-rh.5 @@ -0,0 +1,2325 @@ +'\" t +.\" Title: nm-settings-ifcfg-rh +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.78.1 +.\" Date: 19 December 2014 +.\" Manual: Configuration +.\" Source: NetworkManager 1.0.0 +.\" Language: English +.\" +.TH "NM\-SETTINGS\-IFCFG\" "5" "" "NetworkManager 1\&.0\&.0" "Configuration" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nm-settings-ifcfg-rh \- Description of \fIifcfg\-rh\fR settings plugin +.SH "DESCRIPTION" +.PP +NetworkManager is based on the concept of connection profiles that contain network configuration (see +\fBnm-settings\fR(5) +for details)\&. The profiles can be stored in various formats\&. NetworkManager uses plugins for reading and writing the data\&. The plugins can be configured in +\fBNetworkManager.conf\fR(5)\&. +.PP +The +\fIifcfg\-rh\fR +plugin is used on the Fedora and Red Hat Enterprise Linux distributions to read/write configuration from/to the standard +/etc/sysconfig/network\-scripts/ifcfg\-* +files\&. Each NetworkManager connection maps to one +ifcfg\-* +file, with possible usage of +keys\-* +for passwords, +route\-* +for static IPv4 routes and +route6\-* +for static IPv6 routes\&. The plugin currently supports reading and writing Ethernet, Wi\-Fi, InfiniBand, VLAN, Bond, Bridge, and Team connections\&. Unsupported connection types (such as WWAN, PPPoE, VPN, or ADSL are handled by +\fIkeyfile\fR +plugin (\fBnm-settings-keyfile\fR(5))\&. The main reason for using +\fIifcfg\-rh\fR +plugin is the compatibility with legacy configurations for +\fIifup\fR +and +\fIifdown\fR +(initscripts)\&. +.SH "FILE FORMAT" +.PP +The +\fIifcfg\-rh\fR +config format is a simple text file containing VARIABLE="value" lines\&. The format is described in +sysconfig\&.txt +of +\fIinitscripts\fR +package\&. Note that the configuration files may be sourced by +\fIinitscripts\fR, so they must be valid shell scripts\&. That means, for instance, that +# +character can be used for comments, strings with spaces must be quoted, special characters must be escaped, etc\&. +.PP +Users can create or modify the +\fIifcfg\-rh\fR +connection files manually, even if that is not the recommended way of managing the profiles\&. However, if they choose to do that, they must inform NetworkManager about their changes (see +\fImonitor\-connection\-file\fR +in +\fBnm-settings\fR(5), and +\fInmcli con (re)load\fR)\&. +.PP +\fBSome ifcfg-rh configuration examples:\fR. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSimple DHCP ethernet configuration:\fR +NAME=ethernet +UUID=1c4ddf70\-01bf\-46d6\-b04f\-47e842bd98da +TYPE=Ethernet +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +ONBOOT=yes + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBSimple ethernet configuration with static IP:\fR +TYPE=Ethernet +BOOTPROTO=none +IPADDR=10\&.1\&.0\&.25 +PREFIX=24 +GATEWAY=10\&.1\&.0\&.1 +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes +IPV6_FAILURE_FATAL=no +NAME=ethernet\-em2 +UUID=51bb3904\-c0fc\-4dfe\-83b2\-0a71e7928c13 +DEVICE=em2 +ONBOOT=yes + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBWPA2 Enterprise WLAN (TTLS with inner MSCHAPV2 authentication):\fR +ESSID="CompanyWLAN" +MODE=Managed +KEY_MGMT=WPA\-EAP +TYPE=Wireless +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY=joe +IEEE_8021X_PASSWORD_FLAGS=ask +IEEE_8021X_INNER_AUTH_METHODS=MSCHAPV2 +IEEE_8021X_CA_CERT=/home/joe/\&.cert/company\&.crt +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=no +NAME=MyCompany +UUID=f79848ff\-11a6\-4810\-9e1a\-99039dea84c4 +ONBOOT=yes + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBBridge and bridge port configuration:\fR +ifcfg\-bridge: ifcfg\-bridge\-port: +NAME=bridge NAME=bridge007\-port\-eth0 +UUID=4be99ce0\-c5b2\-4764\-8b77\-ec226e440125 UUID=3ad56c4a\-47e1\-419b\-b0d4\-8ad86eb967a3 +DEVICE=bridge007 DEVICE=eth0 +STP=yes ONBOOT=yes +TYPE=Bridge TYPE=Ethernet +BRIDGING_OPTS=priority=32768 BRIDGE=bridge007 +ONBOOT=yes +BOOTPROTO=dhcp + + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBBonding configuration:\fR +ifcfg\-BOND: ifcfg\-BOND\-slave: +NAME=BOND NAME=BOND\-slave +UUID=b41888aa\-924c\-450c\-b0f8\-85a4f0a51b4a UUID=9bb048e4\-286a\-4cc3\-b104\-007dbd20decb +DEVICE=bond100 DEVICE=eth0 +BONDING_OPTS="mode=balance\-rr miimon=100" ONBOOT=yes +TYPE=Bond TYPE=Ethernet +BONDING_MASTER=yes MASTER=bond100 +ONBOOT=yes SLAVE=yes +BOOTPROTO=dhcp + + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBTeam and team port configuration:\fR +ifcfg\-my_team0: +DEVICE=team0 +TEAM_CONFIG="{ \e"device\e": \e"team0\e", \e"runner\e": {\e"name\e": \e"roundrobin\e"}, \e"ports\e": {\e"eth1\e": {}, \e"eth2\e": {}} }" +DEVICETYPE=Team +BOOTPROTO=dhcp +NAME=team0\-profile +UUID=1d3460a0\-7b37\-457f\-a300\-fe8d92da4807 +ONBOOT=yes + +ifcfg\-my_team0_slave1: +NAME=team0\-slave1 +UUID=d5aed298\-c567\-4cc1\-b808\-6d38ecef9e64 +DEVICE=eth1 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + +ifcfg\-my_team0_slave2: +NAME=team0\-slave2 +UUID=94e75f4e\-e5ad\-401c\-8962\-31e0ae5d2215 +DEVICE=eth2 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + +.fi +.if n \{\ +.RE +.\} + +The UUID values in the config files must be unique\&. You can use +\fIuuidgen\fR +command line tool to generate such values\&. Alternatively, you can leave out UUID entirely\&. In that case NetworkManager will generate a UUID based on the file name\&. +.SH "DIFFERENCES AGAINST INITSCRIPTS" +.PP +The main differences of NetworkManager ifcfg\-rh plugin and traditional initscripts are: +.PP +\fBNM_CONTROLLED=yes|no\fR +.RS 4 +NM_CONTROLLED is NetworkManager\-specific variable used by NetworkManager for determining whether the device of the +\fIifcfg\fR +file should be managed\&. NM_CONTROLLED=yes is supposed if the variable is not present in the file\&. Note that if you have more +\fIifcfg\fR +files for a single device, NM_CONTROLLED=no in one of the files will cause the device not to be managed\&. The profile may not even be the active one\&. +.RE +.PP +\fBNew variables\fR +.RS 4 +NetworkManager has introduced some new variable, not present in initscripts, to be able to store data for its new features\&. The variables are marked as extensions in the tables bellows\&. +.RE +.PP +\fBSemantic change of variables\fR +.RS 4 +NetworkManager had to slightly change the semantic for a few variables\&. +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +PEERDNS +\- initscripts interpret PEERDNS=no to mean "never touch resolv\&.conf"\&. NetworkManager interprets it to say "never add automatic (DHCP, PPP, VPN, etc\&.) nameservers to resolv\&.conf"\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +ONBOOT +\- initscripts use ONBOOT=yes to mark the devices that are to be activated during boot\&. NetworkManager extents this to also mean that this profile can be used for auto\-connecting at any time\&. +.RE +.RE +.PP +See the next section for detailed mapping of NetworkManager properties and +\fIifcfg\-rh\fR +variables\&. Variable names, format and usage differences in NetworkManager and initscripts are documented in the tables bellow\&. +.SH "DETAILS" +.PP +\fIifcfg\-rh\fR +plugin variables marked with +\fI(+)\fR +are NetworkManager specific extensions not understood by traditional initscripts\&. +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&1.\ \&802-1x setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +eap +T}:T{ +IEEE_8021X_EAP_METHODS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +EAP method for 802\&.1X authentication\&.\fB + +Example: \fRIEEE_8021X_EAP_METHODS=PEAP\fB + +Allowed values: \fR"LEAP", "PWD", "TLS", "PEAP", "TTLS", "FAST" +T} +T{ +identity +T}:T{ +IEEE_8021X_IDENTITY\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Identity for EAP authentication methods\&.\fB + +Example: \fRIEEE_8021X_IDENTITY=itsme +T} +T{ +anonymous\-identity +T}:T{ +IEEE_8021X_ANON_IDENTITY\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Anonymous identity for EAP authentication methods\&. +T} +T{ +pac\-file +T}:T{ +IEEE_8021X_PAC_FILE\fI(+)\fR +T}:T{ +\ \& +T}:T{ +File with PAC (Protected Access Credential) for EAP\-FAST\&.\fB + +Example: \fRIEEE_8021X_PAC_FILE=/home/joe/my\-fast\&.pac +T} +T{ +ca\-cert +T}:T{ +IEEE_8021X_CA_CERT\fI(+)\fR +T}:T{ +\ \& +T}:T{ +CA certificate for EAP\&.\fB + +Example: \fRIEEE_8021X_CA_CERT=/home/joe/cacert\&.crt +T} +T{ +ca\-path +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +T{ +subject\-match +T}:T{ +IEEE_8021X_SUBJECT_MATCH\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Substring to match subject of server certificate against\&.\fB + +Example: \fRIEEE_8021X_SUBJECT_MATCH="Red Hat" +T} +T{ +altubject\-matches +T}:T{ +IEEE_8021X_AlTSUBJECT_MATCHES\fI(+)\fR +T}:T{ +\ \& +T}:T{ +List of strings to be matched against the altSubjectName\&.\fB + +Example: \fRIEEE_8021X_ALTSUBJECT_MATCHES="s1\&.domain\&.cc" +T} +T{ +client\-cert +T}:T{ +IEEE_8021X_CLIENT_CERT\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Client certificate for EAP\&.\fB + +Example: \fRIEEE_8021X_CLIENT_CERT=/home/joe/mycert\&.crt +T} +T{ +phase1\-peapver +T}:T{ +IEEE_8021X_PEAP_VERSION\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Use to force a specific PEAP version\&.\fB + +Allowed values: \fR0, 1 +T} +T{ +phase1\-peaplabel +T}:T{ +IEEE_8021X_PEAP_FORCE_NEW_LABEL\fI(+)\fR +T}:T{ +no +T}:T{ +Use to force the new PEAP label during key derivation\&.\fB + +Allowed values: \fRyes, no +T} +T{ +phase1\-fast\-provisioning +T}:T{ +IEEE_8021X_FAST_PROVISIONING\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Enable in\-line provisioning of EAP\-FAST credentials\&.\fB + +Example: \fRIEEE_8021X_FAST_PROVISIONING="allow\-auth allow\-unauth"\fB + +Allowed values: \fRspace\-separated list of these values [allow\-auth, allow\-unauth] +T} +T{ +phase2\-auth +T}:T{ +IEEE_8021X_INNER_AUTH_METHODS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Inner non\-EAP authentication methods\&. IEEE_8021X_INNER_AUTH_METHODS can contain values both for \*(Aqphase2\-auth\*(Aq and \*(Aqphase2\-autheap\*(Aq properties\&.\fB + +Example: \fRIEEE_8021X_INNER_AUTH_METHODS=PAP\fB + +Allowed values: \fR"PAP", "CHAP", "MSCHAP", "MSCHAPV2", "GTC", "OTP", "MD5" and "TLS" +T} +T{ +phase2\-autheap +T}:T{ +IEEE_8021X_INNER_AUTH_METHODS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Inner EAP\-based authentication methods\&. Note that IEEE_8021X_INNER_AUTH_METHODS is also used for \*(Aqphase2\-auth\*(Aq values\&.\fB + +Example: \fRIEEE_8021X_INNER_AUTH_METHODS="MSCHAPV2 EAP\-TLS"\fB + +Allowed values: \fR"EAP\-MD5", "EAP\-MSCHAPV2", "EAP\-GTC", "EAP\-OTP" and "EAP\-TLS" +T} +T{ +phase2\-subject\-match +T}:T{ +IEEE_8021X_PHASE2_SUBJECT_MATCH\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Substring to match subject of server certificate against\&.\fB + +Example: \fRIEEE_8021X_PHASE2_SUBJECT_MATCH="Red Hat" +T} +T{ +phase2\-altsubject\-matches +T}:T{ +IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES\fI(+)\fR +T}:T{ +\ \& +T}:T{ +\ \& +T} +T{ +phase2\-client\-cert +T}:T{ +IEEE_8021X_INNER_CLIENT_CERT\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Client certificate for inner EAP method\&.\fB + +Example: \fRIEEE_8021X_INNER_CLIENT_CERT=/home/joe/mycert\&.crt +T} +T{ +password +T}:T{ +IEEE_8021X_PASSWORD\fI(+)\fR +T}:T{ +\ \& +T}:T{ +UTF\-8 encoded password used for EAP\&. It can also go to "key\-" lookaside file, or it can be owned by a secret agent\&. +T} +T{ +password\-flags +T}:T{ +IEEE_8021X_PASSWORD_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for IEEE_8021X_PASSWORD password\&. (see the section called \(lqSecret flags\(rq for _FLAGS values) +T} +T{ +password\-raw +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +T{ +password\-raw\-flags +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +T{ +private\-key +T}:T{ +IEEE_8021X_PRIVATE_KEY\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Private key for EAP\-TLS\&.\fB + +Example: \fRIEEE_8021X_PRIVATE_KEY=/home/joe/mykey\&.p12 +T} +T{ +private\-key\-password +T}:T{ +IEEE_8021X_PRIVATE_KEY_PASSWORD\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password for IEEE_8021X_PRIVATE_KEY\&. It can also go to "key\-" lookaside file, or it can be owned by a secret agent\&. +T} +T{ +private\-key\-password\-flags +T}:T{ +IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for IEEE_8021X_PRIVATE_KEY_PASSWORD password\&. (see the section called \(lqSecret flags\(rq for _FLAGS values) +T} +T{ +phase2\-private\-key +T}:T{ +IEEE_8021X_INNER_PRIVATE_KEY\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Private key for inner authentication method for EAP\-TLS\&. +T} +T{ +phase2\-private\-key\-password +T}:T{ +IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password for IEEE_8021X_INNER_PRIVATE_KEY\&. It can also go to "key\-" lookaside file, or it can be owned by a secret agent\&. +T} +T{ +phase2\-private\-key\-password\-flags +T}:T{ +IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD password\&. (see the section called \(lqSecret flags\(rq for _FLAGS values) +T} +T{ +pin +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +T{ +pin\-flags +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +T{ +system\-ca\-certs +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not handled by ifcfg\-rh plugin\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&2.\ \&bond setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l. +T{ +options +T}:T{ +BONDING_OPTS +T}:T{ +\ \& +T}:T{ +Bonding options\&.\fB + +Example: \fRBONDING_OPTS="miimon=100 mode=broadcast" +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&3.\ \&bridge-port setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l. +T{ +priority +T}:T{ +BRIDGING_OPTS: priority= +T}:T{ +32 +T}:T{ +STP priority\&.\fB + +Allowed values: \fR0 \- 63 +T} +T{ +path\-cost +T}:T{ +BRIDGING_OPTS: path_cost= +T}:T{ +100 +T}:T{ +STP cost\&.\fB + +Allowed values: \fR1 \- 65535 +T} +T{ +hairpin\-mode +T}:T{ +BRIDGING_OPTS: hairpin_mode= +T}:T{ +yes +T}:T{ +Hairpin mode of the bridge port\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&4.\ \&bridge setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +mac\-address +T}:T{ +MACADDR\fI(+)\fR +T}:T{ +\ \& +T}:T{ +MAC address of the bridge\&. Note that this requires a recent kernel support, originally introduced in 3\&.15 upstream kernel) MACADDR for bridges is an NM extension\&. +T} +T{ +stp +T}:T{ +STP +T}:T{ +no +T}:T{ +Span tree protocol participation\&. +T} +T{ +priority +T}:T{ +BRIDGING_OPTS: priority= +T}:T{ +32768 +T}:T{ +STP priority\&.\fB + +Allowed values: \fR0 \- 32768 +T} +T{ +forward\-delay +T}:T{ +DELAY +T}:T{ +15 +T}:T{ +STP forwarding delay\&.\fB + +Allowed values: \fR2 \- 30 +T} +T{ +hello\-time +T}:T{ +BRIDGING_OPTS: hello_time= +T}:T{ +2 +T}:T{ +STP hello time\&.\fB + +Allowed values: \fR1 \- 10 +T} +T{ +max\-age +T}:T{ +BRIDGING_OPTS: max_age= +T}:T{ +20 +T}:T{ +STP maximum message age\&.\fB + +Allowed values: \fR6 \- 40 +T} +T{ +ageing\-time +T}:T{ +BRIDGING_OPTS: ageing_time= +T}:T{ +300 +T}:T{ +Ethernet MAC ageing time\&.\fB + +Allowed values: \fR0 \- 1000000 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&5.\ \&connection setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +id +T}:T{ +NAME\fI(+)\fR +T}:T{ +\ \& +T}:T{ +User friendly name for the connection profile\&. +T} +T{ +uuid +T}:T{ +UUID\fI(+)\fR +T}:T{ +\ \& +T}:T{ +UUID for the connection profile\&. When missing, NetworkManager creates the UUID itself (by hashing the file)\&. +T} +T{ +interface\-name +T}:T{ +DEVICE +T}:T{ +\ \& +T}:T{ +Interface name of the device this profile is bound to\&. The variable can be left out when the profile should apply for more devices\&. Note that DEVICE can be required for some connection types\&. +T} +T{ +type +T}:T{ +TYPE (DEVICETYPE, DEVICE) +T}:T{ +\ \& +T}:T{ +Base type of the connection\&. DEVICETYPE is used for teaming connections\&.\fB + +Example: \fRTYPE=Ethernet; TYPE=Bond; TYPE=Bridge; DEVICETYPE=TeamPort\fB + +Allowed values: \fREthernet, Wireless, InfiniBand, Bridge, Bond, Vlan, Team, TeamPort +T} +T{ +permissions +T}:T{ +USERS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +USERS restrict the access for this conenction to certain users only\&.\fB + +Example: \fRUSERS="joe bob" +T} +T{ +autoconnect +T}:T{ +ONBOOT +T}:T{ +yes +T}:T{ +Whether the connection should be autoconnected (not only while booting)\&. +T} +T{ +autoconnect\-priority +T}:T{ +AUTOCONNECT_PRIORITY\fI(+)\fR +T}:T{ +0 +T}:T{ +Connection priority for automatic activation\&. Connections with higher numbers are preferred when selecting profiles for automatic activation\&.\fB + +Example: \fRAUTOCONNECT_PRIORITY=20\fB + +Allowed values: \fR\-999 to 999 +T} +T{ +zone +T}:T{ +ZONE\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Trust level of this connection\&. The string is usually used for a firewall\&.\fB + +Example: \fRZONE=Work +T} +T{ +master +T}:T{ +MASTER, TEAM_MASTER, BRIDGE +T}:T{ +\ \& +T}:T{ +Reference to master connection\&. The variable used depends on the connection type\&. +T} +T{ +slave\-type +T}:T{ +MASTER, TEAM_MASTER, DEVICETYPE, BRIDGE +T}:T{ +\ \& +T}:T{ +Slave type doesn\*(Aqt map directly to a variable, but it is recognized using different variables\&. MASTER for bonding, TEAM_MASTER and DEVICETYPE for teaming, BRIDGE for bridging\&. +T} +T{ +secondaries +T}:T{ +SECONDARY_UUIDS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +UUID of VPN connections that should be activated together with this connection\&. +T} +T{ +gateway\-ping\-timeout +T}:T{ +GATEWAY_PING_TIMEOUT\fI(+)\fR +T}:T{ +0 +T}:T{ +If greater than zero, the IP connectivity will be checked by pinging the gateway and waiting for the specified timeout (in seconds)\&.\fB + +Example: \fRGATEWAY_PING_TIMEOUT=5 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&6.\ \&dcb setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +app\-fcoe\-flags +T}:T{ +DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING +T}:T{ +no +T}:T{ +FCOE flags\&.\fB + +Example: \fRDCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes +T} +T{ +app\-fcoe\-priority +T}:T{ +DCB_APP_FCOE_PRIORITY +T}:T{ +\ \& +T}:T{ +Priority of FCoE frames\&.\fB + +Allowed values: \fR0 \- 7 +T} +T{ +app\-fcoe\-mode +T}:T{ +DCB_APP_FCOE_MODE +T}:T{ +fabric +T}:T{ +FCoE controller mode\&.\fB + +Allowed values: \fRfabric, vn2vn +T} +T{ +app\-iscsi\-flags +T}:T{ +DCB_APP_ISCSI_ENABLE, DCB_APP_ISCSI_ADVERTISE, DCB_APP_ISCSI_WILLING +T}:T{ +no +T}:T{ +iSCSI flags\&. +T} +T{ +app\-iscsi\-priority +T}:T{ +DCB_APP_ISCSI_PRIORITY +T}:T{ +\ \& +T}:T{ +Priority of iSCSI frames\&.\fB + +Allowed values: \fR0 \- 7 +T} +T{ +app\-fip\-flags +T}:T{ +DCB_APP_FIP_ENABLE, DCB_APP_FIP_ADVERTISE, DCB_APP_FIP_WILLING +T}:T{ +no +T}:T{ +FIP flags\&. +T} +T{ +app\-fip\-priority +T}:T{ +DCB_APP_FIP_PRIORITY +T}:T{ +\ \& +T}:T{ +Priority of FIP frames\&.\fB + +Allowed values: \fR0 \- 7 +T} +T{ +priority\-flow\-control\-flags +T}:T{ +DCB_PFC_ENABLE, DCB_PFC_ADVERTISE, DCB_PFC_WILLING +T}:T{ +no +T}:T{ +Priority flow control flags\&. +T} +T{ +priority\-flow\-control +T}:T{ +DCB_PFC_UP +T}:T{ +\ \& +T}:T{ +Priority flow control values\&. String of 8 "0" and "1", where "0"\&. means "do not transmit priority pause", "1" means "transmit pause"\&.\fB + +Example: \fRDCB_PFC_UP=01101110 +T} +T{ +priority\-group\-flags +T}:T{ +DCB_PG_ENABLE, DCB_PG_ADVERTISE, DCB_PG_WILLING +T}:T{ +no +T}:T{ +Priority groups flags\&. +T} +T{ +priority\-group\-id +T}:T{ +DCB_PG_ID +T}:T{ +\ \& +T}:T{ +Priority groups values\&. String of eight priorities (0 \- 7) or "f" (unrestricted)\&.\fB + +Example: \fRDCB_PG_ID=1205f173 +T} +T{ +priority\-group\-bandwidth +T}:T{ +DCB_PG_PCT +T}:T{ +\ \& +T}:T{ +Priority groups values\&. Eight bandwidths (in percent), separated with commas\&.\fB + +Example: \fRDCB_PG_PCT=10,5,10,15,10,10,10,30 +T} +T{ +priority\-bandwidth +T}:T{ +DCB_PG_UPPCT +T}:T{ +\ \& +T}:T{ +Priority values\&. Eight bandwidths (in percent), separated with commas\&. The sum of the numbers must be 100\&.\fB + +Example: \fRDCB_PG_UPPCT=7,13,10,10,15,15,10,20 +T} +T{ +priority\-strict\-bandwidth +T}:T{ +DCB_PG_STRICT +T}:T{ +\ \& +T}:T{ +Priority values\&. String of eight "0" or "1", where "0" means "may not utilize all bandwidth", "1" means "may utilize all bandwidth"\&.\fB + +Example: \fRDCB_PG_STRICT=01101110 +T} +T{ +priority\-traffic\-class +T}:T{ +DCB_PG_UP2TC +T}:T{ +\ \& +T}:T{ +Priority values\&. String of eight trafic class values (0 \- 7)\&.\fB + +Example: \fRDCB_PG_UP2TC=01623701 +T} +.TE +.sp 1 +.PP +All DCB related configuration is a NetworkManager extention\&. DCB=yes must be used explicitly to enable DCB so that the rest of the DCB_* variables can apply\&. +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&7.\ \&infiniband setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +mac\-address +T}:T{ +HWADDR +T}:T{ +\ \& +T}:T{ +IBoIP 20\-byte hardware address of the device (in traditional hex\-digits\-and\-colons notation)\&.\fB + +Example: \fRHWADDR=01:02:03:04:05:06:07:08:09:0A:01:02:03:04:05:06:07:08:09:11 +T} +T{ +mtu +T}:T{ +MTU +T}:T{ +\ \& +T}:T{ +MTU of the interface\&. +T} +T{ +transport\-mode +T}:T{ +CONNECTED_MODE +T}:T{ +CONNECTED_MODE=no +T}:T{ +CONNECTED_MODE=yes for "connected" mode, CONNECTED_MODE=no for "datagram" mode +T} +T{ +p\-key +T}:T{ +PKEY_ID (and PKEY=yes) +T}:T{ +PKEY=no +T}:T{ +InfiniBand P_Key\&. The value can be a hex number prefixed with "0x" or a decimal number\&. When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified\&.\fB + +Example: \fRPKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0\&.8002 +T} +T{ +parent +T}:T{ +PHYSDEV (PKEY=yes) +T}:T{ +PKEY=no +T}:T{ +InfiniBand parent device\&.\fB + +Example: \fRPHYSDEV=ib0 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&8.\ \&ipv4 setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +method +T}:T{ +BOOTPROTO +T}:T{ +none +T}:T{ +Method used for IPv4 protocol configuration\&.\fB + +Allowed values: \fRnone, dhcp (bootp), static, ibft, autoip, shared +T} +T{ +dns +T}:T{ +DNS1, DNS2, \&.\&.\&. +T}:T{ +\ \& +T}:T{ +List of DNS servers\&. Even if NetworkManager supports many DNS servers, initscripts and resolver only care about the first three, usually\&.\fB + +Example: \fRDNS1=1\&.2\&.3\&.4 DNS2=10\&.0\&.0\&.254 DNS3=8\&.8\&.8\&.8 +T} +T{ +dns\-search +T}:T{ +DOMAIN +T}:T{ +\ \& +T}:T{ +List of DNS search domains\&. +T} +T{ +addresses +T}:T{ +IPADDR, PREFIX, IPADDR1, PREFIX1, \&.\&.\&. +T}:T{ +\ \& +T}:T{ +List of static IP addresses\&.\fB + +Example: \fRIPADDR=10\&.5\&.5\&.23 PREFIX=24 IPADDR1=1\&.1\&.1\&.2 PREFIX1=16 +T} +T{ +gateway +T}:T{ +GATEWAY +T}:T{ +\ \& +T}:T{ +Gateway IP address\&.\fB + +Example: \fRGATEWAY=10\&.5\&.5\&.1 +T} +T{ +routes +T}:T{ +ADDRESS1, NETMASK1, GATEWAY1, METRIC1, \&.\&.\&. +T}:T{ +\ \& +T}:T{ +List of static routes\&. They are not stored in ifcfg\-* file, but in route\-* file instead\&. +T} +T{ +ignore\-auto\-routes +T}:T{ +PEERROUTES\fI(+)\fR +T}:T{ +yes +T}:T{ +PEERROUTES has the opposite meaning as \*(Aqignore\-auto\-routes\*(Aq property\&. +T} +T{ +ignore\-auto\-dns +T}:T{ +PEERDNS +T}:T{ +yes +T}:T{ +PEERDNS has the opposite meaning as \*(Aqignore\-auto\-dns\*(Aq property\&. +T} +T{ +dhcp\-send\-hostname +T}:T{ +DHCP_SEND_HOSTNAME\fI(+)\fR +T}:T{ +yes +T}:T{ +Whether DHCP_HOSTNAME should be sent to the DHCP server\&. +T} +T{ +dhcp\-hostname +T}:T{ +DHCP_HOSTNAME +T}:T{ +\ \& +T}:T{ +Hostname to send to the DHCP server\&. +T} +T{ +never\-default +T}:T{ +DEFROUTE (GATEWAYDEV in /etc/sysconfig/network) +T}:T{ +yes +T}:T{ +DEFROUTE=no tells NetworkManager that this connection should not be assigned the default route\&. DEFROUTE has the opposite meaning as \*(Aqnever\-default\*(Aq property\&. +T} +T{ +may\-fail +T}:T{ +IPV4_FAILURE_FATAL\fI(+)\fR +T}:T{ +no +T}:T{ +IPV4_FAILURE_FATAL has the opposite meaning as \*(Aqmay\-fail\*(Aq property\&. +T} +T{ +dhcp\-client\-id +T}:T{ +DHCP_CLIENT_ID\fI(+)\fR +T}:T{ +\ \& +T}:T{ +A string sent to the DHCP server to identify the local machine\&.\fB + +Example: \fRDHCP_CLIENT_ID=ax\-srv\-1 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&9.\ \&ipv6 setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +method +T}:T{ +IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C +T}:T{ +IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no +T}:T{ +Method used for IPv6 protocol configuration\&. ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yes +T} +T{ +dns +T}:T{ +DNS1, DNS2, \&.\&.\&. +T}:T{ +\ \& +T}:T{ +List of DNS servers\&. NetworkManager uses the variables both for IPv4 and IPv6\&. +T} +T{ +dns\-search +T}:T{ +DOMAIN +T}:T{ +\ \& +T}:T{ +List of DNS search domains\&. +T} +T{ +addresses +T}:T{ +IPV6ADDR, IPV6ADDR_SECONDARIES +T}:T{ +\ \& +T}:T{ +List of static IP addresses\&.\fB + +Example: \fRIPV6ADDR=ab12:9876::1 IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3" +T} +T{ +gateway +T}:T{ +IPV6_DEFAULTGW +T}:T{ +\ \& +T}:T{ +Gateway IP address\&.\fB + +Example: \fRIPV6_DEFAULTGW=abbe::1 +T} +T{ +routes +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +List of static routes\&. They are not stored in ifcfg\-* file, but in route6\-* file instead in the form of command line for \*(Aqip route add\*(Aq\&. +T} +T{ +ignore\-auto\-routes +T}:T{ +IPV6_PEERROUTES\fI(+)\fR +T}:T{ +yes +T}:T{ +IPV6_PEERROUTES has the opposite meaning as \*(Aqignore\-auto\-routes\*(Aq property\&. +T} +T{ +ignore\-auto\-dns +T}:T{ +IPV6_PEERDNS\fI(+)\fR +T}:T{ +yes +T}:T{ +IPV6_PEERDNS has the opposite meaning as \*(Aqignore\-auto\-dns\*(Aq property\&. +T} +T{ +dhcp\-hostname +T}:T{ +DHCP_HOSTNAME +T}:T{ +\ \& +T}:T{ +Hostname to send the DHCP server\&. +T} +T{ +never\-default +T}:T{ +IPV6_DEFROUTE\fI(+)\fR, (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network) +T}:T{ +IPV6_DEFROUTE=yes (when no variable specified) +T}:T{ +IPV6_DEFROUTE=no tells NetworkManager that this connection should not be assigned the default IPv6 route\&. IPV6_DEFROUTE has the opposite meaning as \*(Aqnever\-default\*(Aq property\&. +T} +T{ +may\-fail +T}:T{ +IPV6_FAILURE_FATAL\fI(+)\fR +T}:T{ +no +T}:T{ +IPV6_FAILURE_FATAL has the opposite meaning as \*(Aqmay\-fail\*(Aq property\&. +T} +T{ +ip6\-privacy +T}:T{ +IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP\fI(+)\fR +T}:T{ +no +T}:T{ +Configure IPv6 Privacy Extensions for SLAAC (RFC4941)\&.\fB + +Example: \fRIPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes\fB + +Allowed values: \fRIPV6_PRIVACY: no, yes (rfc3041 or rfc4941); IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&10.\ \&team-port setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l. +T{ +config +T}:T{ +TEAM_PORT_CONFIG +T}:T{ +\ \& +T}:T{ +Team port configuration in JSON\&. See man teamd\&.conf for details\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&11.\ \&team setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l. +T{ +config +T}:T{ +TEAM_CONFIG +T}:T{ +\ \& +T}:T{ +Team configuration in JSON\&. See man teamd\&.conf for details\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&12.\ \&vlan setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +parent +T}:T{ +DEVICE or PHYSDEV +T}:T{ +\ \& +T}:T{ +Parent interface of the VLAN\&. +T} +T{ +id +T}:T{ +VLAN_ID or DEVICE +T}:T{ +\ \& +T}:T{ +VLAN identifier\&. +T} +T{ +flags +T}:T{ +VLAN_FLAGS, REORDER_HDR +T}:T{ +\ \& +T}:T{ +Parent interface of the VLAN\&.\fB + +Allowed values: \fR"GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDR +T} +T{ +ingress\-property\-map +T}:T{ +VLAN_INGRESS_PRIORITY_MAP +T}:T{ +\ \& +T}:T{ +Ingress priority mapping\&.\fB + +Example: \fRVLAN_INGRESS_PRIORITY_MAP=4:2,3:5 +T} +T{ +egress\-property\-map +T}:T{ +VLAN_EGRESS_PRIORITY_MAP +T}:T{ +\ \& +T}:T{ +Egress priority mapping\&.\fB + +Example: \fRVLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7 +T} +T{ +interface\-name +T}:T{ +PHYSDEV and VLAN_ID, or DEVICE +T}:T{ +\ \& +T}:T{ +VLAN interface name\&. If all variables are set, parent device from PHYSDEV takes precedence over DEVICE, but VLAN id from DEVICE takes precedence over VLAN_ID\&.\fB + +Example: \fRPHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0\&.12 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&13.\ \&802-3-ethernet setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +port +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not saved by the plugin\&. +T} +T{ +speed +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not saved by the plugin\&. +T} +T{ +duplex +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not saved by the plugin\&. +T} +T{ +auto\-negotiate +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +The property is not saved by the plugin\&. +T} +T{ +mac\-address +T}:T{ +HWADDR +T}:T{ +\ \& +T}:T{ +Hardware address of the device in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:14:5A:05)\&. +T} +T{ +cloned\-mac\-address +T}:T{ +MACADDR +T}:T{ +\ \& +T}:T{ +Cloned (spoofed) MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:14:5A:99)\&. +T} +T{ +mac\-address\-blacklist +T}:T{ +HWADDR_BLACKLIST\fI(+)\fR +T}:T{ +\ \& +T}:T{ +It denies usage of the connection for any device whose address is listed\&.\fB + +Example: \fRHWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55" +T} +T{ +mtu +T}:T{ +MTU +T}:T{ +\ \& +T}:T{ +MTU of the interface\&. +T} +T{ +s390\-subchannels +T}:T{ +SUBCHANNELS +T}:T{ +\ \& +T}:T{ +Subchannels for IBM S390 hosts\&.\fB + +Example: \fRSUBCHANNELS=0\&.0\&.b00a,0\&.0\&.b00b,0\&.0\&.b00c +T} +T{ +s390\-nettype +T}:T{ +NETTYPE +T}:T{ +\ \& +T}:T{ +Network type of the S390 host\&.\fB + +Example: \fRNETTYPE=qeth\fB + +Allowed values: \fR"qeth", "lcs" or "ctc" +T} +T{ +s390\-options +T}:T{ +OPTIONS and PORTNAME, CTCPROTO, +T}:T{ +\ \& +T}:T{ +S390 device options\&. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&14.\ \&802-11-wireless-security setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +key\-mgmt +T}:T{ +KEY_MGMT\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Key management menthod\&.\fB + +Allowed values: \fRIEEE8021X, WPA\-PSK, WPA\-EAP +T} +T{ +wep\-tx\-keyidx +T}:T{ +DEFAULTKEY +T}:T{ +1 +T}:T{ +Index of active WEP key\&.\fB + +Allowed values: \fR1, 2, 3, 4 +T} +T{ +auth\-alg +T}:T{ +SECURITYMODE\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Authentication algorithm for WEP\&.\fB + +Allowed values: \fRrestricted, open, leap +T} +T{ +proto +T}:T{ +WPA_ALLOW_WPA\fI(+)\fR, WPA_ALLOW_WPA2\fI(+)\fR +T}:T{ +no +T}:T{ +Allowed WPA protocols, WPA and WPA2 (RSN)\&.\fB + +Allowed values: \fRyes, no +T} +T{ +pairwise +T}:T{ +CIPHER_PAIRWISE\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Restrict pairwise encryption algorithms, specified as a space separated list\&.\fB + +Allowed values: \fRCCMP, TKIP +T} +T{ +group +T}:T{ +CIPHER_GROUP\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Restrict group/broadcast encryption algorithms, specified as a space separated list\&.\fB + +Allowed values: \fRCCMP, TKIP, WEP40, WEP104 +T} +T{ +leap\-username +T}:T{ +IEEE_8021X_IDENTITY\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Login name for LEAP\&. +T} +T{ +wep\-key0 +T}:T{ +KEY1, KEY_PASSPHRASE1\fI(+)\fR +T}:T{ +\ \& +T}:T{ +The first WEP key (used in most networks)\&. See also DEFAULTKEY for key index\&. +T} +T{ +wep\-key1 +T}:T{ +KEY2, KEY_PASSPHRASE2\fI(+)\fR +T}:T{ +\ \& +T}:T{ +WEP key with index 1\&. See also DEFAULTKEY for key index\&. +T} +T{ +wep\-key2 +T}:T{ +KEY3, KEY_PASSPHRASE3\fI(+)\fR +T}:T{ +\ \& +T}:T{ +WEP key with index 2\&. See also DEFAULTKEY for key index\&. +T} +T{ +wep\-key3 +T}:T{ +KEY4, KEY_PASSPHRASE4\fI(+)\fR +T}:T{ +\ \& +T}:T{ +WEP key with index 3\&. See also DEFAULTKEY for key index\&. +T} +T{ +wep\-key\-flags +T}:T{ +WEP_KEY_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for KEY, KEY_PASSPHRASE password\&. (see the section called \(lqSecret flags\(rq for _FLAGS values) +T} +T{ +psk +T}:T{ +WPA_PSK +T}:T{ +\ \& +T}:T{ +Pre\-Shared\-Key for WPA networks\&. +T} +T{ +psk\-flags +T}:T{ +WPA_PSK_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for WPA_PSK_FLAGS\&. (see the section called \(lqSecret flags\(rq for _FLAGS values)\fB + +Example: \fRWPA_PSK_FLAGS=user +T} +T{ +leap\-password +T}:T{ +IEEE_8021X_PASSWORD\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password for LEAP\&. It can also go to "key\-" lookaside file, or it can be owned by a secret agent\&. +T} +T{ +leap\-password\-flags +T}:T{ +IEEE_8021X_PASSWORD_FLAGS\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Password flags for IEEE_8021X_PASSWORD_FLAGS\&. (see the section called \(lqSecret flags\(rq for _FLAGS values) +T} +T{ +wep\-key\-type +T}:T{ +KEY or KEY_PASSPHRASE\fI(+)\fR +T}:T{ +\ \& +T}:T{ +KEY is used for "key" type (10 or 26 hexadecimal characters, or 5 or 13 character string prefixed with "s:")\&. KEY_PASSPHRASE is used for WEP passphrases\&.\fB + +Example: \fRKEY1=s:ahoj, KEY1=0a1c45bc02, KEY_PASSPHRASE1=mysupersecretkey +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&15.\ \&802-11-wireless setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Ifcfg\-rh Variable +T}:T{ +Default +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l +l l l l. +T{ +ssid +T}:T{ +ESSID +T}:T{ +\ \& +T}:T{ +SSID of Wi\-Fi network\&.\fB + +Example: \fRESSID="Quick Net" +T} +T{ +mode +T}:T{ +MODE +T}:T{ +\ \& +T}:T{ +Wi\-Fi network mode\&.\fB + +Allowed values: \fRAd\-Hoc, Managed (Auto) [case insensitive] +T} +T{ +band +T}:T{ +BAND\fI(+)\fR +T}:T{ +\ \& +T}:T{ +BAND alone is honored, but CHANNEL overrides BAND since it implies a band\&.\fB + +Example: \fRBAND=bg\fB + +Allowed values: \fRa, bg +T} +T{ +channel +T}:T{ +CHANNEL +T}:T{ +\ \& +T}:T{ +Channel used for the Wi\-Fi communication\&. Channels greater than 14 mean "a" band, otherwise the band is "bg"\&.\fB + +Example: \fRCHANNEL=6 +T} +T{ +bssid +T}:T{ +BSSID\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Restricts association only to a single AP\&.\fB + +Example: \fRBSSID=00:1E:BD:64:83:21 +T} +T{ +rate +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +This property is not handled by ifcfg\-rh plugin\&. +T} +T{ +tx\-power +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +This property is not handled by ifcfg\-rh plugin\&. +T} +T{ +mac\-address +T}:T{ +HWADDR +T}:T{ +\ \& +T}:T{ +Hardware address of the device in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:14:5A:05)\&. +T} +T{ +cloned\-mac\-address +T}:T{ +MACADDR +T}:T{ +\ \& +T}:T{ +Cloned (spoofed) MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:14:5A:99)\&. +T} +T{ +mac\-address\-blacklist +T}:T{ +HWADDR_BLACKLIST\fI(+)\fR +T}:T{ +\ \& +T}:T{ +It denies usage of the connection for any device whose address is listed\&. +T} +T{ +seen\-bssids +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +This property is not handled by ifcfg\-rh plugin\&. +T} +T{ +mtu +T}:T{ +MTU +T}:T{ +\ \& +T}:T{ +MTU of the wireless interface\&. +T} +T{ +hidden +T}:T{ +SSID_HIDDEN\fI(+)\fR +T}:T{ +\ \& +T}:T{ +Whether the network hides the SSID\&. +T} +T{ +security +T}:T{ +(none) +T}:T{ +\ \& +T}:T{ +This property is deprecated and not handled by ifcfg\-rh\-plugin\&. +T} +.TE +.sp 1 +.PP +The following settings are not supported by +\fIifcfg\-rh\fR +plugin: +.PP +adsl, bluetooth, ppp, pppoe, serial, generic, gsm, cdma, 802\-11\-olpc\-mesh, wimax, vpn +.SS "Secret flags" +.PP +Each secret property in a NetworkManager setting has an associated +\fIflags\fR +property that describes how to handle that secret\&. In the +\fIfcfg\-rh\fR +plugin variables for secret flags have a +\fI_FLAGS\fR +suffix\&. The variables contain one or more of the folowing values (space separated)\&. Missing (or empty) *_FLAGS variable means that the password is owned by NetworkManager\&. +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +user +\- a user\-session secret agent is responsible for providing and storing this secret; when it is required, agents will be asked to provide it\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +ask +\- the associated password is not saved but it will be requested from the user each time it is required\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +unused +\- in some situations it cannot be automatically determined that a secret is required or not\&. This flag hints that the secret is not required and should not be requested from the user\&. +.RE +.SH "AUTHOR" +.PP +NetworkManager developers +.SH "FILES" +.PP +/etc/sysconfig/network\-scripts/ifcfg\-* +.PP +/etc/sysconfig/network\-scripts/keys\-* +.PP +/etc/sysconfig/network\-scripts/route\-* +.PP +/etc/sysconfig/network\-scripts/route6\-* +.PP +/usr/share/doc/initscripts/sysconfig\&.txt +.SH "SEE ALSO" +.PP +https://developer\&.gnome\&.org/NetworkManager/unstable/ref\-settings\&.html +.PP +nm\-settings(5), nm\-settings\-keyfile(5), NetworkManager(8), NetworkManager\&.conf(5), nmcli(1), nmcli\-examples(5) diff --git a/man/nm-settings-ifcfg-rh.xml b/man/nm-settings-ifcfg-rh.xml new file mode 100644 index 00000000..e578442a --- /dev/null +++ b/man/nm-settings-ifcfg-rh.xml @@ -0,0 +1,335 @@ + + +19 December 2014nm-settings-ifcfg-rh5NetworkManagerConfiguration1.0.0nm-settings-ifcfg-rhDescription of ifcfg-rh settings pluginDESCRIPTION + NetworkManager is based on the concept of connection profiles that contain + network configuration (see nm-settings5 for details). The profiles can be + stored in various formats. NetworkManager uses plugins for reading and writing + the data. The plugins can be configured in NetworkManager.conf5. + + The ifcfg-rh plugin is used on the Fedora and Red Hat + Enterprise Linux distributions to read/write configuration from/to + the standard /etc/sysconfig/network-scripts/ifcfg-* files. + Each NetworkManager connection maps to one ifcfg-* file, with + possible usage of keys-* for passwords, route-* + for static IPv4 routes and route6-* for static IPv6 routes. + The plugin currently supports reading and writing Ethernet, Wi-Fi, InfiniBand, + VLAN, Bond, Bridge, and Team connections. Unsupported connection types (such as + WWAN, PPPoE, VPN, or ADSL are handled by keyfile plugin + (nm-settings-keyfile5). + The main reason for using ifcfg-rh plugin is the compatibility + with legacy configurations for ifup and ifdown + (initscripts). + File Format + The ifcfg-rh config format is a simple text file containing + VARIABLE="value" lines. The format is described in sysconfig.txt + of initscripts package. Note that the configuration files + may be sourced by initscripts, so they must be valid shell + scripts. That means, for instance, that # character can be used + for comments, strings with spaces must be quoted, special characters must be escaped, + etc. + + Users can create or modify the ifcfg-rh connection files + manually, even if that is not the recommended way of managing the profiles. + However, if they choose to do that, they must inform NetworkManager about + their changes (see monitor-connection-file in + nm-settings5, and nmcli con (re)load). + Some <emphasis>ifcfg-rh</emphasis> configuration examples:Simple DHCP ethernet configuration: +NAME=ethernet +UUID=1c4ddf70-01bf-46d6-b04f-47e842bd98da +TYPE=Ethernet +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +ONBOOT=yes + Simple ethernet configuration with static IP: +TYPE=Ethernet +BOOTPROTO=none +IPADDR=10.1.0.25 +PREFIX=24 +GATEWAY=10.1.0.1 +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes +IPV6_FAILURE_FATAL=no +NAME=ethernet-em2 +UUID=51bb3904-c0fc-4dfe-83b2-0a71e7928c13 +DEVICE=em2 +ONBOOT=yes + WPA2 Enterprise WLAN (TTLS with inner MSCHAPV2 authentication): +ESSID="CompanyWLAN" +MODE=Managed +KEY_MGMT=WPA-EAP +TYPE=Wireless +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY=joe +IEEE_8021X_PASSWORD_FLAGS=ask +IEEE_8021X_INNER_AUTH_METHODS=MSCHAPV2 +IEEE_8021X_CA_CERT=/home/joe/.cert/company.crt +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=no +NAME=MyCompany +UUID=f79848ff-11a6-4810-9e1a-99039dea84c4 +ONBOOT=yes + Bridge and bridge port configuration: +ifcfg-bridge: ifcfg-bridge-port: +NAME=bridge NAME=bridge007-port-eth0 +UUID=4be99ce0-c5b2-4764-8b77-ec226e440125 UUID=3ad56c4a-47e1-419b-b0d4-8ad86eb967a3 +DEVICE=bridge007 DEVICE=eth0 +STP=yes ONBOOT=yes +TYPE=Bridge TYPE=Ethernet +BRIDGING_OPTS=priority=32768 BRIDGE=bridge007 +ONBOOT=yes +BOOTPROTO=dhcp + + Bonding configuration: +ifcfg-BOND: ifcfg-BOND-slave: +NAME=BOND NAME=BOND-slave +UUID=b41888aa-924c-450c-b0f8-85a4f0a51b4a UUID=9bb048e4-286a-4cc3-b104-007dbd20decb +DEVICE=bond100 DEVICE=eth0 +BONDING_OPTS="mode=balance-rr miimon=100" ONBOOT=yes +TYPE=Bond TYPE=Ethernet +BONDING_MASTER=yes MASTER=bond100 +ONBOOT=yes SLAVE=yes +BOOTPROTO=dhcp + + Team and team port configuration: +ifcfg-my_team0: +DEVICE=team0 +TEAM_CONFIG="{ \"device\": \"team0\", \"runner\": {\"name\": \"roundrobin\"}, \"ports\": {\"eth1\": {}, \"eth2\": {}} }" +DEVICETYPE=Team +BOOTPROTO=dhcp +NAME=team0-profile +UUID=1d3460a0-7b37-457f-a300-fe8d92da4807 +ONBOOT=yes + +ifcfg-my_team0_slave1: +NAME=team0-slave1 +UUID=d5aed298-c567-4cc1-b808-6d38ecef9e64 +DEVICE=eth1 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + +ifcfg-my_team0_slave2: +NAME=team0-slave2 +UUID=94e75f4e-e5ad-401c-8962-31e0ae5d2215 +DEVICE=eth2 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + + The UUID values in the config files must be unique. You can use uuidgen + command line tool to generate such values. Alternatively, you can leave out UUID + entirely. In that case NetworkManager will generate a UUID based on the file name. + Differences against initscripts + The main differences of NetworkManager ifcfg-rh plugin and traditional + initscripts are: + NM_CONTROLLED=yes|no + NM_CONTROLLED is NetworkManager-specific variable used by NetworkManager + for determining whether the device of the ifcfg file + should be managed. NM_CONTROLLED=yes is supposed if the variable is not + present in the file. + Note that if you have more ifcfg files for a single + device, NM_CONTROLLED=no in one of the files will cause the device not + to be managed. The profile may not even be the active one. + New variables + NetworkManager has introduced some new variable, not present in initscripts, + to be able to store data for its new features. The variables are marked + as extensions in the tables bellows. + Semantic change of variables + NetworkManager had to slightly change the semantic for a few variables. + PEERDNS - + initscripts interpret PEERDNS=no to mean "never touch resolv.conf". + NetworkManager interprets it to say "never add automatic (DHCP, PPP, VPN, etc.) + nameservers to resolv.conf".ONBOOT - + initscripts use ONBOOT=yes to mark the devices that are to be activated + during boot. NetworkManager extents this to also mean that this profile + can be used for auto-connecting at any time. + See the next section for detailed mapping of NetworkManager properties and + ifcfg-rh variables. Variable names, format and usage + differences in NetworkManager and initscripts are documented in the tables bellow. + DETAILSifcfg-rh plugin variables marked with (+) + are NetworkManager specific extensions not understood by traditional initscripts. + 802-1x settingPropertyIfcfg-rh VariableDefaultDescriptioneapIEEE_8021X_EAP_METHODS(+)EAP method for 802.1X authentication. + +Example: IEEE_8021X_EAP_METHODS=PEAP + +Allowed values: "LEAP", "PWD", "TLS", "PEAP", "TTLS", "FAST"identityIEEE_8021X_IDENTITY(+)Identity for EAP authentication methods. + +Example: IEEE_8021X_IDENTITY=itsmeanonymous-identityIEEE_8021X_ANON_IDENTITY(+)Anonymous identity for EAP authentication methods.pac-fileIEEE_8021X_PAC_FILE(+)File with PAC (Protected Access Credential) for EAP-FAST. + +Example: IEEE_8021X_PAC_FILE=/home/joe/my-fast.pacca-certIEEE_8021X_CA_CERT(+)CA certificate for EAP. + +Example: IEEE_8021X_CA_CERT=/home/joe/cacert.crtca-path(none)The property is not handled by ifcfg-rh plugin.subject-matchIEEE_8021X_SUBJECT_MATCH(+)Substring to match subject of server certificate against. + +Example: IEEE_8021X_SUBJECT_MATCH="Red Hat"altubject-matchesIEEE_8021X_AlTSUBJECT_MATCHES(+)List of strings to be matched against the altSubjectName. + +Example: IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc"client-certIEEE_8021X_CLIENT_CERT(+)Client certificate for EAP. + +Example: IEEE_8021X_CLIENT_CERT=/home/joe/mycert.crtphase1-peapverIEEE_8021X_PEAP_VERSION(+)Use to force a specific PEAP version. + +Allowed values: 0, 1phase1-peaplabelIEEE_8021X_PEAP_FORCE_NEW_LABEL(+)noUse to force the new PEAP label during key derivation. + +Allowed values: yes, nophase1-fast-provisioningIEEE_8021X_FAST_PROVISIONING(+)Enable in-line provisioning of EAP-FAST credentials. + +Example: IEEE_8021X_FAST_PROVISIONING="allow-auth allow-unauth" + +Allowed values: space-separated list of these values [allow-auth, allow-unauth]phase2-authIEEE_8021X_INNER_AUTH_METHODS(+)Inner non-EAP authentication methods. IEEE_8021X_INNER_AUTH_METHODS can contain values both for 'phase2-auth' and 'phase2-autheap' properties. + +Example: IEEE_8021X_INNER_AUTH_METHODS=PAP + +Allowed values: "PAP", "CHAP", "MSCHAP", "MSCHAPV2", "GTC", "OTP", "MD5" and "TLS"phase2-autheapIEEE_8021X_INNER_AUTH_METHODS(+)Inner EAP-based authentication methods. Note that IEEE_8021X_INNER_AUTH_METHODS is also used for 'phase2-auth' values. + +Example: IEEE_8021X_INNER_AUTH_METHODS="MSCHAPV2 EAP-TLS" + +Allowed values: "EAP-MD5", "EAP-MSCHAPV2", "EAP-GTC", "EAP-OTP" and "EAP-TLS"phase2-subject-matchIEEE_8021X_PHASE2_SUBJECT_MATCH(+)Substring to match subject of server certificate against. + +Example: IEEE_8021X_PHASE2_SUBJECT_MATCH="Red Hat"phase2-altsubject-matchesIEEE_8021X_PHASE2_ALTSUBJECT_MATCHES(+)phase2-client-certIEEE_8021X_INNER_CLIENT_CERT(+)Client certificate for inner EAP method. + +Example: IEEE_8021X_INNER_CLIENT_CERT=/home/joe/mycert.crtpasswordIEEE_8021X_PASSWORD(+)UTF-8 encoded password used for EAP. It can also go to "key-" lookaside file, or it can be owned by a secret agent.password-flagsIEEE_8021X_PASSWORD_FLAGS(+)Password flags for IEEE_8021X_PASSWORD password. (see for _FLAGS values)password-raw(none)The property is not handled by ifcfg-rh plugin.password-raw-flags(none)The property is not handled by ifcfg-rh plugin.private-keyIEEE_8021X_PRIVATE_KEY(+)Private key for EAP-TLS. + +Example: IEEE_8021X_PRIVATE_KEY=/home/joe/mykey.p12private-key-passwordIEEE_8021X_PRIVATE_KEY_PASSWORD(+)Password for IEEE_8021X_PRIVATE_KEY. It can also go to "key-" lookaside file, or it can be owned by a secret agent.private-key-password-flagsIEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS(+)Password flags for IEEE_8021X_PRIVATE_KEY_PASSWORD password. (see for _FLAGS values)phase2-private-keyIEEE_8021X_INNER_PRIVATE_KEY(+)Private key for inner authentication method for EAP-TLS.phase2-private-key-passwordIEEE_8021X_INNER_PRIVATE_KEY_PASSWORD(+)Password for IEEE_8021X_INNER_PRIVATE_KEY. It can also go to "key-" lookaside file, or it can be owned by a secret agent.phase2-private-key-password-flagsIEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS(+)Password flags for IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD password. (see for _FLAGS values)pin(none)The property is not handled by ifcfg-rh plugin.pin-flags(none)The property is not handled by ifcfg-rh plugin.system-ca-certs(none)The property is not handled by ifcfg-rh plugin.
bond settingPropertyIfcfg-rh VariableDefaultDescriptionoptionsBONDING_OPTSBonding options. + +Example: BONDING_OPTS="miimon=100 mode=broadcast"
bridge-port settingPropertyIfcfg-rh VariableDefaultDescriptionpriorityBRIDGING_OPTS: priority=32STP priority. + +Allowed values: 0 - 63path-costBRIDGING_OPTS: path_cost=100STP cost. + +Allowed values: 1 - 65535hairpin-modeBRIDGING_OPTS: hairpin_mode=yesHairpin mode of the bridge port.
bridge settingPropertyIfcfg-rh VariableDefaultDescriptionmac-addressMACADDR(+)MAC address of the bridge. Note that this requires a recent kernel support, originally introduced in 3.15 upstream kernel) MACADDR for bridges is an NM extension.stpSTPnoSpan tree protocol participation.priorityBRIDGING_OPTS: priority=32768STP priority. + +Allowed values: 0 - 32768forward-delayDELAY15STP forwarding delay. + +Allowed values: 2 - 30hello-timeBRIDGING_OPTS: hello_time=2STP hello time. + +Allowed values: 1 - 10max-ageBRIDGING_OPTS: max_age=20STP maximum message age. + +Allowed values: 6 - 40ageing-timeBRIDGING_OPTS: ageing_time=300Ethernet MAC ageing time. + +Allowed values: 0 - 1000000
connection settingPropertyIfcfg-rh VariableDefaultDescriptionidNAME(+)User friendly name for the connection profile.uuidUUID(+)UUID for the connection profile. When missing, NetworkManager creates the UUID itself (by hashing the file).interface-nameDEVICEInterface name of the device this profile is bound to. The variable can be left out when the profile should apply for more devices. Note that DEVICE can be required for some connection types.typeTYPE (DEVICETYPE, DEVICE)Base type of the connection. DEVICETYPE is used for teaming connections. + +Example: TYPE=Ethernet; TYPE=Bond; TYPE=Bridge; DEVICETYPE=TeamPort + +Allowed values: Ethernet, Wireless, InfiniBand, Bridge, Bond, Vlan, Team, TeamPortpermissionsUSERS(+)USERS restrict the access for this conenction to certain users only. + +Example: USERS="joe bob"autoconnectONBOOTyesWhether the connection should be autoconnected (not only while booting).autoconnect-priorityAUTOCONNECT_PRIORITY(+)0Connection priority for automatic activation. Connections with higher numbers are preferred when selecting profiles for automatic activation. + +Example: AUTOCONNECT_PRIORITY=20 + +Allowed values: -999 to 999zoneZONE(+)Trust level of this connection. The string is usually used for a firewall. + +Example: ZONE=WorkmasterMASTER, TEAM_MASTER, BRIDGEReference to master connection. The variable used depends on the connection type.slave-typeMASTER, TEAM_MASTER, DEVICETYPE, BRIDGESlave type doesn't map directly to a variable, but it is recognized using different variables. MASTER for bonding, TEAM_MASTER and DEVICETYPE for teaming, BRIDGE for bridging.secondariesSECONDARY_UUIDS(+)UUID of VPN connections that should be activated together with this connection.gateway-ping-timeoutGATEWAY_PING_TIMEOUT(+)0If greater than zero, the IP connectivity will be checked by pinging the gateway and waiting for the specified timeout (in seconds). + +Example: GATEWAY_PING_TIMEOUT=5
dcb settingPropertyIfcfg-rh VariableDefaultDescriptionapp-fcoe-flagsDCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLINGnoFCOE flags. + +Example: DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yesapp-fcoe-priorityDCB_APP_FCOE_PRIORITYPriority of FCoE frames. + +Allowed values: 0 - 7app-fcoe-modeDCB_APP_FCOE_MODEfabricFCoE controller mode. + +Allowed values: fabric, vn2vnapp-iscsi-flagsDCB_APP_ISCSI_ENABLE, DCB_APP_ISCSI_ADVERTISE, DCB_APP_ISCSI_WILLINGnoiSCSI flags.app-iscsi-priorityDCB_APP_ISCSI_PRIORITYPriority of iSCSI frames. + +Allowed values: 0 - 7app-fip-flagsDCB_APP_FIP_ENABLE, DCB_APP_FIP_ADVERTISE, DCB_APP_FIP_WILLINGnoFIP flags.app-fip-priorityDCB_APP_FIP_PRIORITYPriority of FIP frames. + +Allowed values: 0 - 7priority-flow-control-flagsDCB_PFC_ENABLE, DCB_PFC_ADVERTISE, DCB_PFC_WILLINGnoPriority flow control flags.priority-flow-controlDCB_PFC_UPPriority flow control values. String of 8 "0" and "1", where "0". means "do not transmit priority pause", "1" means "transmit pause". + +Example: DCB_PFC_UP=01101110priority-group-flagsDCB_PG_ENABLE, DCB_PG_ADVERTISE, DCB_PG_WILLINGnoPriority groups flags.priority-group-idDCB_PG_IDPriority groups values. String of eight priorities (0 - 7) or "f" (unrestricted). + +Example: DCB_PG_ID=1205f173priority-group-bandwidthDCB_PG_PCTPriority groups values. Eight bandwidths (in percent), separated with commas. + +Example: DCB_PG_PCT=10,5,10,15,10,10,10,30priority-bandwidthDCB_PG_UPPCTPriority values. Eight bandwidths (in percent), separated with commas. The sum of the numbers must be 100. + +Example: DCB_PG_UPPCT=7,13,10,10,15,15,10,20priority-strict-bandwidthDCB_PG_STRICTPriority values. String of eight "0" or "1", where "0" means "may not utilize all bandwidth", "1" means "may utilize all bandwidth". + +Example: DCB_PG_STRICT=01101110priority-traffic-classDCB_PG_UP2TCPriority values. String of eight trafic class values (0 - 7). + +Example: DCB_PG_UP2TC=01623701
+ All DCB related configuration is a NetworkManager extention. DCB=yes must be + used explicitly to enable DCB so that the rest of the DCB_* variables can apply. + infiniband settingPropertyIfcfg-rh VariableDefaultDescriptionmac-addressHWADDRIBoIP 20-byte hardware address of the device (in traditional hex-digits-and-colons notation). + +Example: HWADDR=01:02:03:04:05:06:07:08:09:0A:01:02:03:04:05:06:07:08:09:11mtuMTUMTU of the interface.transport-modeCONNECTED_MODECONNECTED_MODE=noCONNECTED_MODE=yes for "connected" mode, CONNECTED_MODE=no for "datagram" modep-keyPKEY_ID (and PKEY=yes)PKEY=noInfiniBand P_Key. The value can be a hex number prefixed with "0x" or a decimal number. When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified. + +Example: PKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0.8002parentPHYSDEV (PKEY=yes)PKEY=noInfiniBand parent device. + +Example: PHYSDEV=ib0
ipv4 settingPropertyIfcfg-rh VariableDefaultDescriptionmethodBOOTPROTOnoneMethod used for IPv4 protocol configuration. + +Allowed values: none, dhcp (bootp), static, ibft, autoip, shareddnsDNS1, DNS2, ...List of DNS servers. Even if NetworkManager supports many DNS servers, initscripts and resolver only care about the first three, usually. + +Example: DNS1=1.2.3.4 DNS2=10.0.0.254 DNS3=8.8.8.8dns-searchDOMAINList of DNS search domains.addressesIPADDR, PREFIX, IPADDR1, PREFIX1, ...List of static IP addresses. + +Example: IPADDR=10.5.5.23 PREFIX=24 IPADDR1=1.1.1.2 PREFIX1=16gatewayGATEWAYGateway IP address. + +Example: GATEWAY=10.5.5.1routesADDRESS1, NETMASK1, GATEWAY1, METRIC1, ...List of static routes. They are not stored in ifcfg-* file, but in route-* file instead.ignore-auto-routesPEERROUTES(+)yesPEERROUTES has the opposite meaning as 'ignore-auto-routes' property.ignore-auto-dnsPEERDNSyesPEERDNS has the opposite meaning as 'ignore-auto-dns' property.dhcp-send-hostnameDHCP_SEND_HOSTNAME(+)yesWhether DHCP_HOSTNAME should be sent to the DHCP server.dhcp-hostnameDHCP_HOSTNAMEHostname to send to the DHCP server.never-defaultDEFROUTE (GATEWAYDEV in /etc/sysconfig/network)yesDEFROUTE=no tells NetworkManager that this connection should not be assigned the default route. DEFROUTE has the opposite meaning as 'never-default' property.may-failIPV4_FAILURE_FATAL(+)noIPV4_FAILURE_FATAL has the opposite meaning as 'may-fail' property.dhcp-client-idDHCP_CLIENT_ID(+)A string sent to the DHCP server to identify the local machine. + +Example: DHCP_CLIENT_ID=ax-srv-1
ipv6 settingPropertyIfcfg-rh VariableDefaultDescriptionmethodIPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6CIPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=noMethod used for IPv6 protocol configuration. ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yesdnsDNS1, DNS2, ...List of DNS servers. NetworkManager uses the variables both for IPv4 and IPv6.dns-searchDOMAINList of DNS search domains.addressesIPV6ADDR, IPV6ADDR_SECONDARIESList of static IP addresses. + +Example: IPV6ADDR=ab12:9876::1 IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3"gatewayIPV6_DEFAULTGWGateway IP address. + +Example: IPV6_DEFAULTGW=abbe::1routes(none)List of static routes. They are not stored in ifcfg-* file, but in route6-* file instead in the form of command line for 'ip route add'.ignore-auto-routesIPV6_PEERROUTES(+)yesIPV6_PEERROUTES has the opposite meaning as 'ignore-auto-routes' property.ignore-auto-dnsIPV6_PEERDNS(+)yesIPV6_PEERDNS has the opposite meaning as 'ignore-auto-dns' property.dhcp-hostnameDHCP_HOSTNAMEHostname to send the DHCP server.never-defaultIPV6_DEFROUTE(+), (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network)IPV6_DEFROUTE=yes (when no variable specified)IPV6_DEFROUTE=no tells NetworkManager that this connection should not be assigned the default IPv6 route. IPV6_DEFROUTE has the opposite meaning as 'never-default' property.may-failIPV6_FAILURE_FATAL(+)noIPV6_FAILURE_FATAL has the opposite meaning as 'may-fail' property.ip6-privacyIPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+)noConfigure IPv6 Privacy Extensions for SLAAC (RFC4941). + +Example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes + +Allowed values: IPV6_PRIVACY: no, yes (rfc3041 or rfc4941); IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no
team-port settingPropertyIfcfg-rh VariableDefaultDescriptionconfigTEAM_PORT_CONFIGTeam port configuration in JSON. See man teamd.conf for details.
team settingPropertyIfcfg-rh VariableDefaultDescriptionconfigTEAM_CONFIGTeam configuration in JSON. See man teamd.conf for details.
vlan settingPropertyIfcfg-rh VariableDefaultDescriptionparentDEVICE or PHYSDEVParent interface of the VLAN.idVLAN_ID or DEVICEVLAN identifier.flagsVLAN_FLAGS, REORDER_HDRParent interface of the VLAN. + +Allowed values: "GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDRingress-property-mapVLAN_INGRESS_PRIORITY_MAPIngress priority mapping. + +Example: VLAN_INGRESS_PRIORITY_MAP=4:2,3:5egress-property-mapVLAN_EGRESS_PRIORITY_MAPEgress priority mapping. + +Example: VLAN_EGRESS_PRIORITY_MAP=5:4,4:1,3:7interface-namePHYSDEV and VLAN_ID, or DEVICEVLAN interface name. If all variables are set, parent device from PHYSDEV takes precedence over DEVICE, but VLAN id from DEVICE takes precedence over VLAN_ID. + +Example: PHYSDEV=eth0, VLAN_ID=12; or DEVICE=eth0.12
802-3-ethernet settingPropertyIfcfg-rh VariableDefaultDescriptionport(none)The property is not saved by the plugin.speed(none)The property is not saved by the plugin.duplex(none)The property is not saved by the plugin.auto-negotiate(none)The property is not saved by the plugin.mac-addressHWADDRHardware address of the device in traditional hex-digits-and-colons notation (e.g. 00:22:68:14:5A:05).cloned-mac-addressMACADDRCloned (spoofed) MAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:14:5A:99).mac-address-blacklistHWADDR_BLACKLIST(+)It denies usage of the connection for any device whose address is listed. + +Example: HWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55"mtuMTUMTU of the interface.s390-subchannelsSUBCHANNELSSubchannels for IBM S390 hosts. + +Example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00cs390-nettypeNETTYPENetwork type of the S390 host. + +Example: NETTYPE=qeth + +Allowed values: "qeth", "lcs" or "ctc"s390-optionsOPTIONS and PORTNAME, CTCPROTO,S390 device options. All options go to OPTIONS, except for "portname" and "ctcprot" that have their own variables.
802-11-wireless-security settingPropertyIfcfg-rh VariableDefaultDescriptionkey-mgmtKEY_MGMT(+)Key management menthod. + +Allowed values: IEEE8021X, WPA-PSK, WPA-EAPwep-tx-keyidxDEFAULTKEY1Index of active WEP key. + +Allowed values: 1, 2, 3, 4auth-algSECURITYMODE(+)Authentication algorithm for WEP. + +Allowed values: restricted, open, leapprotoWPA_ALLOW_WPA(+), WPA_ALLOW_WPA2(+)noAllowed WPA protocols, WPA and WPA2 (RSN). + +Allowed values: yes, nopairwiseCIPHER_PAIRWISE(+)Restrict pairwise encryption algorithms, specified as a space separated list. + +Allowed values: CCMP, TKIPgroupCIPHER_GROUP(+)Restrict group/broadcast encryption algorithms, specified as a space separated list. + +Allowed values: CCMP, TKIP, WEP40, WEP104leap-usernameIEEE_8021X_IDENTITY(+)Login name for LEAP.wep-key0KEY1, KEY_PASSPHRASE1(+)The first WEP key (used in most networks). See also DEFAULTKEY for key index.wep-key1KEY2, KEY_PASSPHRASE2(+)WEP key with index 1. See also DEFAULTKEY for key index.wep-key2KEY3, KEY_PASSPHRASE3(+)WEP key with index 2. See also DEFAULTKEY for key index.wep-key3KEY4, KEY_PASSPHRASE4(+)WEP key with index 3. See also DEFAULTKEY for key index.wep-key-flagsWEP_KEY_FLAGS(+)Password flags for KEY<i>, KEY_PASSPHRASE<i> password. (see for _FLAGS values)pskWPA_PSKPre-Shared-Key for WPA networks.psk-flagsWPA_PSK_FLAGS(+)Password flags for WPA_PSK_FLAGS. (see for _FLAGS values) + +Example: WPA_PSK_FLAGS=userleap-passwordIEEE_8021X_PASSWORD(+)Password for LEAP. It can also go to "key-" lookaside file, or it can be owned by a secret agent.leap-password-flagsIEEE_8021X_PASSWORD_FLAGS(+)Password flags for IEEE_8021X_PASSWORD_FLAGS. (see for _FLAGS values)wep-key-typeKEY<i> or KEY_PASSPHRASE<i>(+)KEY is used for "key" type (10 or 26 hexadecimal characters, or 5 or 13 character string prefixed with "s:"). KEY_PASSPHRASE is used for WEP passphrases. + +Example: KEY1=s:ahoj, KEY1=0a1c45bc02, KEY_PASSPHRASE1=mysupersecretkey
802-11-wireless settingPropertyIfcfg-rh VariableDefaultDescriptionssidESSIDSSID of Wi-Fi network. + +Example: ESSID="Quick Net"modeMODEWi-Fi network mode. + +Allowed values: Ad-Hoc, Managed (Auto) [case insensitive]bandBAND(+)BAND alone is honored, but CHANNEL overrides BAND since it implies a band. + +Example: BAND=bg + +Allowed values: a, bgchannelCHANNELChannel used for the Wi-Fi communication. Channels greater than 14 mean "a" band, otherwise the band is "bg". + +Example: CHANNEL=6bssidBSSID(+)Restricts association only to a single AP. + +Example: BSSID=00:1E:BD:64:83:21rate(none)This property is not handled by ifcfg-rh plugin.tx-power(none)This property is not handled by ifcfg-rh plugin.mac-addressHWADDRHardware address of the device in traditional hex-digits-and-colons notation (e.g. 00:22:68:14:5A:05).cloned-mac-addressMACADDRCloned (spoofed) MAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:14:5A:99).mac-address-blacklistHWADDR_BLACKLIST(+)It denies usage of the connection for any device whose address is listed.seen-bssids(none)This property is not handled by ifcfg-rh plugin.mtuMTUMTU of the wireless interface.hiddenSSID_HIDDEN(+)Whether the network hides the SSID.security(none)This property is deprecated and not handled by ifcfg-rh-plugin.
The following settings are not supported by ifcfg-rh plugin:adsl, bluetooth, ppp, pppoe, serial, generic, gsm, cdma, 802-11-olpc-mesh, wimax, vpnSecret flags + Each secret property in a NetworkManager setting has an associated + flags property that describes how to handle that secret. + In the fcfg-rh plugin variables for secret flags have a + _FLAGS suffix. The variables contain one or more of the + folowing values (space separated). Missing (or empty) *_FLAGS variable means + that the password is owned by NetworkManager. + user - a user-session secret agent is responsible for providing + and storing this secret; when it is required, agents will be asked to provide it.ask - the associated password is not saved but it will be + requested from the user each time it is required.unused - in some situations it cannot be automatically determined + that a secret is required or not. This flag hints that the secret is not required and should + not be requested from the user.
AUTHORNetworkManager developersFILES/etc/sysconfig/network-scripts/ifcfg-*/etc/sysconfig/network-scripts/keys-*/etc/sysconfig/network-scripts/route-*/etc/sysconfig/network-scripts/route6-*/usr/share/doc/initscripts/sysconfig.txtSEE ALSOhttps://developer.gnome.org/NetworkManager/unstable/ref-settings.htmlnm-settings(5), nm-settings-keyfile(5), NetworkManager(8), NetworkManager.conf(5), nmcli(1), nmcli-examples(5)
diff --git a/man/nm-settings-ifcfg-rh.xsl b/man/nm-settings-ifcfg-rh.xsl new file mode 100644 index 00000000..f76dee75 --- /dev/null +++ b/man/nm-settings-ifcfg-rh.xsl @@ -0,0 +1,405 @@ + + + + + + + + + + + + + + + + + + + nm-settings-ifcfg-rh + 5 + NetworkManager + Configuration + + + + nm-settings-ifcfg-rh + Description of ifcfg-rh settings plugin + + + DESCRIPTION + + NetworkManager is based on the concept of connection profiles that contain + network configuration (see nm-settings + 5 for details). The profiles can be + stored in various formats. NetworkManager uses plugins for reading and writing + the data. The plugins can be configured in + NetworkManager.conf5. + + + The ifcfg-rh plugin is used on the Fedora and Red Hat + Enterprise Linux distributions to read/write configuration from/to + the standard /etc/sysconfig/network-scripts/ifcfg-* files. + Each NetworkManager connection maps to one ifcfg-* file, with + possible usage of keys-* for passwords, route-* + for static IPv4 routes and route6-* for static IPv6 routes. + The plugin currently supports reading and writing Ethernet, Wi-Fi, InfiniBand, + VLAN, Bond, Bridge, and Team connections. Unsupported connection types (such as + WWAN, PPPoE, VPN, or ADSL are handled by keyfile plugin + (nm-settings-keyfile5). + The main reason for using ifcfg-rh plugin is the compatibility + with legacy configurations for ifup and ifdown + (initscripts). + + + + File Format + + The ifcfg-rh config format is a simple text file containing + VARIABLE="value" lines. The format is described in sysconfig.txt + of initscripts package. Note that the configuration files + may be sourced by initscripts, so they must be valid shell + scripts. That means, for instance, that # character can be used + for comments, strings with spaces must be quoted, special characters must be escaped, + etc. + + + Users can create or modify the ifcfg-rh connection files + manually, even if that is not the recommended way of managing the profiles. + However, if they choose to do that, they must inform NetworkManager about + their changes (see monitor-connection-file in + nm-settings5 + , and nmcli con (re)load). + + + Some <emphasis>ifcfg-rh</emphasis> configuration examples: + + + Simple DHCP ethernet configuration: +NAME=ethernet +UUID=1c4ddf70-01bf-46d6-b04f-47e842bd98da +TYPE=Ethernet +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +ONBOOT=yes + + + + + Simple ethernet configuration with static IP: +TYPE=Ethernet +BOOTPROTO=none +IPADDR=10.1.0.25 +PREFIX=24 +GATEWAY=10.1.0.1 +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes +IPV6_FAILURE_FATAL=no +NAME=ethernet-em2 +UUID=51bb3904-c0fc-4dfe-83b2-0a71e7928c13 +DEVICE=em2 +ONBOOT=yes + + + + + WPA2 Enterprise WLAN (TTLS with inner MSCHAPV2 authentication): +ESSID="CompanyWLAN" +MODE=Managed +KEY_MGMT=WPA-EAP +TYPE=Wireless +IEEE_8021X_EAP_METHODS=TTLS +IEEE_8021X_IDENTITY=joe +IEEE_8021X_PASSWORD_FLAGS=ask +IEEE_8021X_INNER_AUTH_METHODS=MSCHAPV2 +IEEE_8021X_CA_CERT=/home/joe/.cert/company.crt +BOOTPROTO=dhcp +DEFROUTE=yes +PEERDNS=yes +PEERROUTES=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=no +NAME=MyCompany +UUID=f79848ff-11a6-4810-9e1a-99039dea84c4 +ONBOOT=yes + + + + + Bridge and bridge port configuration: +ifcfg-bridge: ifcfg-bridge-port: +NAME=bridge NAME=bridge007-port-eth0 +UUID=4be99ce0-c5b2-4764-8b77-ec226e440125 UUID=3ad56c4a-47e1-419b-b0d4-8ad86eb967a3 +DEVICE=bridge007 DEVICE=eth0 +STP=yes ONBOOT=yes +TYPE=Bridge TYPE=Ethernet +BRIDGING_OPTS=priority=32768 BRIDGE=bridge007 +ONBOOT=yes +BOOTPROTO=dhcp + + + + + + Bonding configuration: +ifcfg-BOND: ifcfg-BOND-slave: +NAME=BOND NAME=BOND-slave +UUID=b41888aa-924c-450c-b0f8-85a4f0a51b4a UUID=9bb048e4-286a-4cc3-b104-007dbd20decb +DEVICE=bond100 DEVICE=eth0 +BONDING_OPTS="mode=balance-rr miimon=100" ONBOOT=yes +TYPE=Bond TYPE=Ethernet +BONDING_MASTER=yes MASTER=bond100 +ONBOOT=yes SLAVE=yes +BOOTPROTO=dhcp + + + + + + Team and team port configuration: +ifcfg-my_team0: +DEVICE=team0 +TEAM_CONFIG="{ \"device\": \"team0\", \"runner\": {\"name\": \"roundrobin\"}, \"ports\": {\"eth1\": {}, \"eth2\": {}} }" +DEVICETYPE=Team +BOOTPROTO=dhcp +NAME=team0-profile +UUID=1d3460a0-7b37-457f-a300-fe8d92da4807 +ONBOOT=yes + +ifcfg-my_team0_slave1: +NAME=team0-slave1 +UUID=d5aed298-c567-4cc1-b808-6d38ecef9e64 +DEVICE=eth1 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + +ifcfg-my_team0_slave2: +NAME=team0-slave2 +UUID=94e75f4e-e5ad-401c-8962-31e0ae5d2215 +DEVICE=eth2 +ONBOOT=yes +TEAM_MASTER=team0 +DEVICETYPE=TeamPort + + + + The UUID values in the config files must be unique. You can use uuidgen + command line tool to generate such values. Alternatively, you can leave out UUID + entirely. In that case NetworkManager will generate a UUID based on the file name. + + + + + + Differences against initscripts + + The main differences of NetworkManager ifcfg-rh plugin and traditional + initscripts are: + + + NM_CONTROLLED=yes|no + + NM_CONTROLLED is NetworkManager-specific variable used by NetworkManager + for determining whether the device of the ifcfg file + should be managed. NM_CONTROLLED=yes is supposed if the variable is not + present in the file. + Note that if you have more ifcfg files for a single + device, NM_CONTROLLED=no in one of the files will cause the device not + to be managed. The profile may not even be the active one. + + + + New variables + + NetworkManager has introduced some new variable, not present in initscripts, + to be able to store data for its new features. The variables are marked + as extensions in the tables bellows. + + + + Semantic change of variables + + NetworkManager had to slightly change the semantic for a few variables. + + + PEERDNS - + initscripts interpret PEERDNS=no to mean "never touch resolv.conf". + NetworkManager interprets it to say "never add automatic (DHCP, PPP, VPN, etc.) + nameservers to resolv.conf". + + + ONBOOT - + initscripts use ONBOOT=yes to mark the devices that are to be activated + during boot. NetworkManager extents this to also mean that this profile + can be used for auto-connecting at any time. + + + + + + + + See the next section for detailed mapping of NetworkManager properties and + ifcfg-rh variables. Variable names, format and usage + differences in NetworkManager and initscripts are documented in the tables bellow. + + + + + DETAILS + + ifcfg-rh plugin variables marked with (+) + are NetworkManager specific extensions not understood by traditional initscripts. + + + + Secret flags + + Each secret property in a NetworkManager setting has an associated + flags property that describes how to handle that secret. + In the fcfg-rh plugin variables for secret flags have a + _FLAGS suffix. The variables contain one or more of the + folowing values (space separated). Missing (or empty) *_FLAGS variable means + that the password is owned by NetworkManager. + + + + user - a user-session secret agent is responsible for providing + and storing this secret; when it is required, agents will be asked to provide it. + + + ask - the associated password is not saved but it will be + requested from the user each time it is required. + + + unused - in some situations it cannot be automatically determined + that a secret is required or not. This flag hints that the secret is not required and should + not be requested from the user. + + + + + + + AUTHOR + + + NetworkManager developers + + + + + FILES + /etc/sysconfig/network-scripts/ifcfg-* + /etc/sysconfig/network-scripts/keys-* + /etc/sysconfig/network-scripts/route-* + /etc/sysconfig/network-scripts/route6-* + /usr/share/doc/initscripts/sysconfig.txt + + + SEE ALSO + https://developer.gnome.org/NetworkManager/unstable/ref-settings.html + nm-settings(5), nm-settings-keyfile(5), NetworkManager(8), NetworkManager.conf(5), nmcli(1), nmcli-examples(5) + + + + + + + + + + <xsl:value-of select="@name"/> setting + + + + Property + Ifcfg-rh Variable + Default + Description + + + + + + +
+
+ + + + All DCB related configuration is a NetworkManager extention. DCB=yes must be + used explicitly to enable DCB so that the rest of the DCB_* variables can apply. + + + + + The following settings are not supported by ifcfg-rh plugin: + + +
+ + + + + + + + + + + + + + + + (see for _FLAGS values) + + + + +Example: + + + + +Allowed values: + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/man/nm-settings-keyfile.5 b/man/nm-settings-keyfile.5 new file mode 100644 index 00000000..53e9165f --- /dev/null +++ b/man/nm-settings-keyfile.5 @@ -0,0 +1,698 @@ +'\" t +.\" Title: nm-settings-keyfile +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.78.1 +.\" Date: 19 December 2014 +.\" Manual: Configuration +.\" Source: NetworkManager 1.0.0 +.\" Language: English +.\" +.TH "NM\-SETTINGS\-KEYFIL" "5" "" "NetworkManager 1\&.0\&.0" "Configuration" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nm-settings-keyfile \- Description of \fIkeyfile\fR settings plugin +.SH "DESCRIPTION" +.PP +NetworkManager is based on the concept of connection profiles that contain network configuration (see +\fBnm-settings\fR(5) +for details)\&. The profiles can be stored in various formats\&. NetworkManager uses plugins for reading and writing the data\&. The plugins can be configured in +\fBNetworkManager.conf\fR(5)\&. +.PP +The +\fIkeyfile\fR +plugin is the generic plugin that supports all the connection types and capabilities that NetworkManager has\&. It writes files out in a \&.ini\-style format in +/etc/NetworkManager/system\-connections/\&. This plugin is always enabled and will automatically be used to store any connections that are not supported by any other active plugin\&. For security, it will ignore files that are readable or writeable by any user or group other than \*(Aqroot\*(Aq since private keys and passphrases may be stored in plaintext inside the file\&. +.SH "FILE FORMAT" +.PP +The +\fIkeyfile\fR +config format is a simple \&.ini\-style format\&. It consists of sections (groups) of key\-value pairs\&. Each section corresponds to a setting name as described in the settings specification (\fBnm-settings\fR(5))\&. Each configuration key/value pair in the section is one of the properties listed in the settings specification\&. The majority of properties of the specification is written in the same format into the +\fIkeyfile\fR +too\&. However some values are inconvenient for people to use\&. These are stored in the files in more readable ways\&. These properties are described bellow\&. An example could be IP addresses that are not written as integer arrays, but more reasonably as "1\&.2\&.3\&.4/12 1\&.2\&.3\&.254"\&. More information of the generic key file format can be found at +\m[blue]\fBGLib key file format\fR\m[]\&\s-2\u[1]\d\s+2 +(Lines beginning with a \*(Aq#\*(Aq are comments, lists are separated by character +; +etc\&.)\&. +.PP +Users can create or modify the +\fIkeyfile\fR +connection files manually, even if that is not the recommended way of managing the profiles\&. However, if they choose to do that, they must inform NetworkManager about their changes (see +\fImonitor\-connection\-file\fR +in +\fBnm-settings\fR(5) +and +\fInmcli con (re)load\fR)\&. +.PP +\fBExamples of keyfile configuration\fR. +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBA sample configuration for an ethernet network:\fR +[connection] +id=Main eth0 +uuid=27afa607\-ee36\-43f0\-b8c3\-9d245cdc4bb3 +type=802\-3\-ethernet +autoconnect=true + +[ipv4] +method=auto + +[802\-3\-ethernet] +mac\-address=00:23:5a:47:1f:71 + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBA sample configuration for WPA\-EAP (PEAP with MSCHAPv2) and always\-ask secret:\fR +[connection] +id=CompanyWIFI +uuid=cdac6154\-a33b\-4b15\-9904\-666772cfa5ee +type=wifi +autoconnect=false + +[wifi] +ssid=CorpWLAN +mode=infrastructure +security=802\-11\-wireless\-security + +[wifi\-security] +key\-mgmt=wpa\-eap + +[ipv4] +method=auto + +[ipv6] +method=auto + +[802\-1x] +eap=peap; +identity=joe +ca\-cert=/home/joe/\&.cert/corp\&.crt +phase1\-peapver=1 +phase2\-auth=mschapv2 +password\-flags=2 + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBA sample configuration for openvpn:\fR +[connection] +id=RedHat\-openvpn +uuid=7f9b3356\-b210\-4c0e\-8123\-bd116c9c280f +type=vpn +timestamp=1385401165 + +[vpn] +service\-type=org\&.freedesktop\&.NetworkManager\&.openvpn +connection\-type=password +password\-flags=3 +remote=ovpn\&.my\-company\&.com +cipher=AES\-256\-CBC +reneg\-seconds=0 +port=443 +username=joe +ca=/etc/openvpn/ISCA\&.pem +tls\-remote=ovpn\&.my\-company\&.com + +[ipv6] +method=auto + +[ipv4] +method=auto +ignore\-auto\-dns=true +never\-default=true + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBA sample configuration for a bridge and a bridge port:\fR +[connection] [connection] +id=MainBridge id=br\-port\-1 +uuid=171ae855\-a0ab\-42b6\-bd0c\-60f5812eea9d uuid=d6e8ae98\-71f8\-4b3d\-9d2d\-2e26048fe794 +interface\-name=MainBridge interface\-name=em1 +type=bridge type=ethernet + master=MainBridge +[bridge] slave\-type=bridge +interface\-name=MainBridge + +.fi +.if n \{\ +.RE +.\} + +.sp +.if n \{\ +.RS 4 +.\} +.nf +\fBA sample configuration for a VLAN:\fR +[connection] +id=VLAN for building 4A +uuid=8ce1c9e0\-ce7a\-4d2c\-aa28\-077dda09dd7e +interface\-name=VLAN\-4A +type=vlan + +[vlan] +interface\-name=VLAN\-4A +parent=eth0 +id=4 + +.fi +.if n \{\ +.RE +.\} +.SH "DETAILS" +.PP +\fIkeyfile\fR +plugin variables for the majority of NetworkManager properties have one\-to\-one mapping\&. It means a NetworkManager property is stored in the keyfile as a variable of the same name and in the same format\&. There are several exceptions to this rule, mainly for making keyfile syntax easier for humans\&. The exceptions handled specially by +\fIkeyfile\fR +plugin are listed bellow\&. Refer to +\fBnm-settings\fR(5) +for all available settings and properties and their description\&. +.PP +\fBName aliases\fR. Some of the NetworkManager setting names are somewhat hard to type or remember\&. Therefore +\fIkeyfile\fR +introduces aliases that can be used instead of the names\&. +.RS 4 +\fIsetting name keyfile alias\fR +.RE +.RS 4 +802\-3\-ethernet = ethernet +.RE +.RS 4 +802\-11\-wireless = wifi +.RE +.RS 4 +802\-11\-wireless\-security = wifi\-security +.RE +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&1.\ \&bridge setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l. +T{ +mac\-address +T}:T{ +mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +MAC address in traditional hex\-digits\-and\-colons notation, or semicolon separated list of 6 decimal bytes (obsolete)\fB + +Example: \fRmac\-address=00:22:68:12:79:A2 mac\-address=0;34;104;18;121;162; +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&2.\ \&infiniband setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l. +T{ +mac\-address +T}:T{ +mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +MAC address in traditional hex\-digits\-and\-colons notation, or or semicolon separated list of 20 decimal bytes (obsolete)\fB + +Example: \fRmac\-address= 80:00:00:6d:fe:80:00:00:00:00:00:00:00:02:55:00:70:33:cf:01 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&3.\ \&ipv4 setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l. +T{ +dns +T}:T{ +dns +T}:T{ +list of DNS IP addresses +T}:T{ +List of DNS servers\&.\fB + +Example: \fRdns=1\&.2\&.3\&.4;8\&.8\&.8\&.8;8\&.8\&.4\&.4; +T} +T{ +addresses +T}:T{ +address1, address2, \&.\&.\&. +T}:T{ +address/plen +T}:T{ +List of static IP addresses\&.\fB + +Example: \fRaddress1=192\&.168\&.100\&.100/24 address2=10\&.1\&.1\&.5/24 +T} +T{ +gateway +T}:T{ +gateway +T}:T{ +string +T}:T{ +Gateway IP addresses as a string\&.\fB + +Example: \fRgateway=192\&.168\&.100\&.1 +T} +T{ +routes +T}:T{ +route1, route2, \&.\&.\&. +T}:T{ +route/plen[,gateway,metric] +T}:T{ +List of IP routes\&.\fB + +Example: \fRroute1=8\&.8\&.8\&.0/24,10\&.1\&.1\&.1,77 route2=7\&.7\&.0\&.0/16 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&4.\ \&ipv6 setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l. +T{ +dns +T}:T{ +dns +T}:T{ +list of DNS IP addresses +T}:T{ +List of DNS servers\&.\fB + +Example: \fRdns=2001:4860:4860::8888;2001:4860:4860::8844; +T} +T{ +addresses +T}:T{ +address1, address2, \&.\&.\&. +T}:T{ +address/plen +T}:T{ +List of static IP addresses\&.\fB + +Example: \fRaddress1=abbe::cafe/96 address2=2001::1234 +T} +T{ +gateway +T}:T{ +gateway +T}:T{ +string +T}:T{ +Gateway IP addresses as a string\&.\fB + +Example: \fRgateway=abbe::1 +T} +T{ +routes +T}:T{ +route1, route2, \&.\&.\&. +T}:T{ +route/plen[,gateway,metric] +T}:T{ +List of IP routes\&.\fB + +Example: \fRroute1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&5.\ \&serial setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l. +T{ +parity +T}:T{ +parity +T}:T{ +\*(Aqe\*(Aq, \*(Aqo\*(Aq, or \*(Aqn\*(Aq +T}:T{ +The connection parity; even, odd, or none\&. Note that older versions of NetworkManager stored this as an integer: 69 (\*(AqE\*(Aq) for even, 111 (\*(Aqo\*(Aq) for odd, or 110 (\*(Aqn\*(Aq) for none\&.\fB + +Example: \fRparity=n +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&6.\ \&vpn setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l +l l l l. +T{ +data +T}:T{ +separate variables named after keys of the dictionary +T}:T{ +\ \& +T}:T{ +The keys of the data dictionary are used as variable names directly under [vpn] section\&.\fB + +Example: \fRremote=ovpn\&.corp\&.com cipher=AES\-256\-CBC username=joe +T} +T{ +secrets +T}:T{ +separate variables named after keys of the dictionary +T}:T{ +\ \& +T}:T{ +The keys of the secrets dictionary are used as variable names directly under [vpn\-secrets] section\&.\fB + +Example: \fRpassword=Popocatepetl +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&7.\ \&802-3-ethernet setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l. +T{ +mac\-address +T}:T{ +mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) (e\&.g\&. 0;34;104;18;121;162) +T} +T{ +cloned\-mac\-address +T}:T{ +cloned\-mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +Cloned MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) (e\&.g\&. 0;34;104;18;121;178)\&. +T} +T{ +mac\-address\-blacklist +T}:T{ +mac\-address\-blacklist +T}:T{ +list of MACs (separated with semicolons) +T}:T{ +MAC address blacklist\&.\fB + +Example: \fRmac\-address\-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&8.\ \&802-11-wireless setting (section) +.TS +allbox tab(:); +lB lB lB lB. +T{ +Property +T}:T{ +Keyfile Variable +T}:T{ +Format +T}:T{ +Description +T} +.T& +l l l l +l l l l +l l l l +l l l l. +T{ +ssid +T}:T{ +ssid +T}:T{ +string (or decimal\-byte list \- obsolete) +T}:T{ +SSID of Wi\-Fi network\&.\fB + +Example: \fRssid=Quick Net +T} +T{ +mac\-address +T}:T{ +mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) (e\&.g\&. 0;34;104;18;121;162)\&. +T} +T{ +cloned\-mac\-address +T}:T{ +cloned\-mac\-address +T}:T{ +ususal hex\-digits\-and\-colons notation +T}:T{ +Cloned MAC address in traditional hex\-digits\-and\-colons notation (e\&.g\&. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) (e\&.g\&. 0;34;104;18;121;178)\&. +T} +T{ +mac\-address\-blacklist +T}:T{ +mac\-address\-blacklist +T}:T{ +list of MACs (separated with semicolons) +T}:T{ +MAC address blacklist\&.\fB + +Example: \fRmac\-address\-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 +T} +.TE +.sp 1 +.SS "Secret flags" +.PP +Each secret property in a NetworkManager setting has an associated +\fIflags\fR +property that describes how to handle that secret\&. In the +\fIkeyfile\fR +plugin, the value of +\fI\-flags\fR +variable is a decimal number (0 \- 7) defined as a sum of the following values: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +0 \- (NM owned) \- the system is responsible for providing and storing this secret\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +1 \- (agent\-owned) \- a user\-session secret agent is responsible for providing and storing this secret; when it is required, agents will be asked to provide it\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +2 \- (not\-saved) \- this secret should not be saved but should be requested from the user each time it is required\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +4 \- (not\-required) \- in some situations it cannot be automatically determined that a secret is required or not\&. This flag hints that the secret is not required and should not be requested from the user\&. +.RE +.SH "AUTHOR" +.PP +NetworkManager developers +.SH "FILES" +.PP +/etc/NetworkManager/system\-connections/* +.SH "SEE ALSO" +.PP +https://developer\&.gnome\&.org/NetworkManager/unstable/ref\-settings\&.html +.PP +nm\-settings(5), nm\-settings\-ifcfg\-rh(5), NetworkManager(8), NetworkManager\&.conf(5), nmcli(1), nmcli\-examples(5) +.SH "NOTES" +.IP " 1." 4 +GLib key file format +.RS 4 +\%https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html#glib-Key-value-file-parser.description +.RE diff --git a/man/nm-settings-keyfile.xml b/man/nm-settings-keyfile.xml new file mode 100644 index 00000000..45bc472b --- /dev/null +++ b/man/nm-settings-keyfile.xml @@ -0,0 +1,233 @@ + + +19 December 2014nm-settings-keyfile5NetworkManagerConfiguration1.0.0nm-settings-keyfileDescription of keyfile settings pluginDESCRIPTION + NetworkManager is based on the concept of connection profiles that contain + network configuration (see nm-settings5 for details). The profiles can be + stored in various formats. NetworkManager uses plugins for reading and writing + the data. The plugins can be configured in NetworkManager.conf5. + + The keyfile plugin is the generic plugin that supports all + the connection types and capabilities that NetworkManager has. It writes files + out in a .ini-style format in /etc/NetworkManager/system-connections/. + This plugin is always enabled and will automatically be used to store + any connections that are not supported by any other active plugin. + For security, it will ignore files that are readable or writeable by any user + or group other than 'root' since private keys and passphrases may be stored + in plaintext inside the file. + File Format + The keyfile config format is a simple .ini-style + format. It consists of sections (groups) of key-value pairs. Each section + corresponds to a setting name as described in the settings specification + (nm-settings5). Each configuration key/value + pair in the section is one of the properties listed in the settings + specification. The majority of properties of the specification is written + in the same format into the keyfile too. However + some values are inconvenient for people to use. These are stored in the + files in more readable ways. These properties are described bellow. + An example could be IP addresses that are not written as integer arrays, + but more reasonably as "1.2.3.4/12 1.2.3.254". + More information of the generic key file format can be found at + + GLib key file format (Lines beginning with a '#' are comments, + lists are separated by character ; etc.). + + Users can create or modify the keyfile connection files + manually, even if that is not the recommended way of managing the profiles. + However, if they choose to do that, they must inform NetworkManager about + their changes (see monitor-connection-file in + nm-settings5 and nmcli con (re)load). + Examples of <emphasis>keyfile</emphasis> configurationA sample configuration for an ethernet network: +[connection] +id=Main eth0 +uuid=27afa607-ee36-43f0-b8c3-9d245cdc4bb3 +type=802-3-ethernet +autoconnect=true + +[ipv4] +method=auto + +[802-3-ethernet] +mac-address=00:23:5a:47:1f:71 + A sample configuration for WPA-EAP (PEAP with MSCHAPv2) and always-ask secret: +[connection] +id=CompanyWIFI +uuid=cdac6154-a33b-4b15-9904-666772cfa5ee +type=wifi +autoconnect=false + +[wifi] +ssid=CorpWLAN +mode=infrastructure +security=802-11-wireless-security + +[wifi-security] +key-mgmt=wpa-eap + +[ipv4] +method=auto + +[ipv6] +method=auto + +[802-1x] +eap=peap; +identity=joe +ca-cert=/home/joe/.cert/corp.crt +phase1-peapver=1 +phase2-auth=mschapv2 +password-flags=2 + A sample configuration for openvpn: +[connection] +id=RedHat-openvpn +uuid=7f9b3356-b210-4c0e-8123-bd116c9c280f +type=vpn +timestamp=1385401165 + +[vpn] +service-type=org.freedesktop.NetworkManager.openvpn +connection-type=password +password-flags=3 +remote=ovpn.my-company.com +cipher=AES-256-CBC +reneg-seconds=0 +port=443 +username=joe +ca=/etc/openvpn/ISCA.pem +tls-remote=ovpn.my-company.com + +[ipv6] +method=auto + +[ipv4] +method=auto +ignore-auto-dns=true +never-default=true + A sample configuration for a bridge and a bridge port: +[connection] [connection] +id=MainBridge id=br-port-1 +uuid=171ae855-a0ab-42b6-bd0c-60f5812eea9d uuid=d6e8ae98-71f8-4b3d-9d2d-2e26048fe794 +interface-name=MainBridge interface-name=em1 +type=bridge type=ethernet + master=MainBridge +[bridge] slave-type=bridge +interface-name=MainBridge + A sample configuration for a VLAN: +[connection] +id=VLAN for building 4A +uuid=8ce1c9e0-ce7a-4d2c-aa28-077dda09dd7e +interface-name=VLAN-4A +type=vlan + +[vlan] +interface-name=VLAN-4A +parent=eth0 +id=4 + DETAILSkeyfile plugin variables for the majority of NetworkManager + properties have one-to-one mapping. It means a NetworkManager property is stored + in the keyfile as a variable of the same name and in the same format. + There are several exceptions to this rule, mainly for making keyfile syntax easier + for humans. The exceptions handled specially by keyfile + plugin are listed bellow. Refer to + nm-settings5 + for all available settings and properties and their description. + Name aliases + Some of the NetworkManager setting names are somewhat hard to type or remember. Therefore + keyfile introduces aliases that can be used instead of the names. + setting name keyfile alias802-3-ethernet = ethernet802-11-wireless = wifi802-11-wireless-security = wifi-security + + + + + +bridge setting (section)PropertyKeyfile VariableFormatDescription +mac-addressmac-addressususal hex-digits-and-colons notationMAC address in traditional hex-digits-and-colons notation, or semicolon separated list of 6 decimal bytes (obsolete) + +Example: mac-address=00:22:68:12:79:A2 mac-address=0;34;104;18;121;162; +
+ + + + + +infiniband setting (section)PropertyKeyfile VariableFormatDescription +mac-addressmac-addressususal hex-digits-and-colons notationMAC address in traditional hex-digits-and-colons notation, or or semicolon separated list of 20 decimal bytes (obsolete) + +Example: mac-address= 80:00:00:6d:fe:80:00:00:00:00:00:00:00:02:55:00:70:33:cf:01 +
+ +ipv4 setting (section)PropertyKeyfile VariableFormatDescription +dnsdnslist of DNS IP addressesList of DNS servers. + +Example: dns=1.2.3.4;8.8.8.8;8.8.4.4; +addressesaddress1, address2, ...address/plenList of static IP addresses. + +Example: address1=192.168.100.100/24 address2=10.1.1.5/24 +gatewaygatewaystringGateway IP addresses as a string. + +Example: gateway=192.168.100.1 +routesroute1, route2, ...route/plen[,gateway,metric]List of IP routes. + +Example: route1=8.8.8.0/24,10.1.1.1,77 route2=7.7.0.0/16 +
+ipv6 setting (section)PropertyKeyfile VariableFormatDescription +dnsdnslist of DNS IP addressesList of DNS servers. + +Example: dns=2001:4860:4860::8888;2001:4860:4860::8844; +addressesaddress1, address2, ...address/plenList of static IP addresses. + +Example: address1=abbe::cafe/96 address2=2001::1234 +gatewaygatewaystringGateway IP addresses as a string. + +Example: gateway=abbe::1 +routesroute1, route2, ...route/plen[,gateway,metric]List of IP routes. + +Example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403 +
+ + + +serial setting (section)PropertyKeyfile VariableFormatDescription +parityparity'e', 'o', or 'n'The connection parity; even, odd, or none. Note that older versions of NetworkManager stored this as an integer: 69 ('E') for even, 111 ('o') for odd, or 110 ('n') for none. + +Example: parity=n +
+ + + +vpn setting (section)PropertyKeyfile VariableFormatDescription +dataseparate variables named after keys of the dictionaryThe keys of the data dictionary are used as variable names directly under [vpn] section. + +Example: remote=ovpn.corp.com cipher=AES-256-CBC username=joe +secretsseparate variables named after keys of the dictionaryThe keys of the secrets dictionary are used as variable names directly under [vpn-secrets] section. + +Example: password=Popocatepetl +
+ +802-3-ethernet setting (section)PropertyKeyfile VariableFormatDescription +mac-addressmac-addressususal hex-digits-and-colons notationMAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) (e.g. 0;34;104;18;121;162) +cloned-mac-addresscloned-mac-addressususal hex-digits-and-colons notationCloned MAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) (e.g. 0;34;104;18;121;178). +mac-address-blacklistmac-address-blacklistlist of MACs (separated with semicolons)MAC address blacklist. + +Example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 +
+ +802-11-wireless setting (section)PropertyKeyfile VariableFormatDescription +ssidssidstring (or decimal-byte list - obsolete)SSID of Wi-Fi network. + +Example: ssid=Quick Net +mac-addressmac-addressususal hex-digits-and-colons notationMAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) (e.g. 0;34;104;18;121;162). +cloned-mac-addresscloned-mac-addressususal hex-digits-and-colons notationCloned MAC address in traditional hex-digits-and-colons notation (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) (e.g. 0;34;104;18;121;178). +mac-address-blacklistmac-address-blacklistlist of MACs (separated with semicolons)MAC address blacklist. + +Example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 +
+Secret flags + Each secret property in a NetworkManager setting has an associated flags + property that describes how to handle that secret. In the keyfile plugin, + the value of -flags variable is a decimal number (0 - 7) defined as a sum + of the following values: + 0 - (NM owned) - the system is responsible for providing and storing this secret.1 - (agent-owned) - a user-session secret agent is responsible for providing + and storing this secret; when it is required, agents will be asked to provide it.2 - (not-saved) - this secret should not be saved but should be requested + from the user each time it is required.4 - (not-required) - in some situations it cannot be automatically determined + that a secret is required or not. This flag hints that the secret is not required + and should not be requested from the user.
AUTHORNetworkManager developersFILES/etc/NetworkManager/system-connections/*SEE ALSOhttps://developer.gnome.org/NetworkManager/unstable/ref-settings.htmlnm-settings(5), nm-settings-ifcfg-rh(5), NetworkManager(8), NetworkManager.conf(5), nmcli(1), nmcli-examples(5)
diff --git a/man/nm-settings-keyfile.xsl b/man/nm-settings-keyfile.xsl new file mode 100644 index 00000000..b6e01a23 --- /dev/null +++ b/man/nm-settings-keyfile.xsl @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + nm-settings-keyfile + 5 + NetworkManager + Configuration + + + + nm-settings-keyfile + Description of keyfile settings plugin + + + DESCRIPTION + + NetworkManager is based on the concept of connection profiles that contain + network configuration (see nm-settings + 5 for details). The profiles can be + stored in various formats. NetworkManager uses plugins for reading and writing + the data. The plugins can be configured in + NetworkManager.conf5. + + + The keyfile plugin is the generic plugin that supports all + the connection types and capabilities that NetworkManager has. It writes files + out in a .ini-style format in /etc/NetworkManager/system-connections/. + This plugin is always enabled and will automatically be used to store + any connections that are not supported by any other active plugin. + For security, it will ignore files that are readable or writeable by any user + or group other than 'root' since private keys and passphrases may be stored + in plaintext inside the file. + + + + File Format + + The keyfile config format is a simple .ini-style + format. It consists of sections (groups) of key-value pairs. Each section + corresponds to a setting name as described in the settings specification + (nm-settings + 5). Each configuration key/value + pair in the section is one of the properties listed in the settings + specification. The majority of properties of the specification is written + in the same format into the keyfile too. However + some values are inconvenient for people to use. These are stored in the + files in more readable ways. These properties are described bellow. + An example could be IP addresses that are not written as integer arrays, + but more reasonably as "1.2.3.4/12 1.2.3.254". + More information of the generic key file format can be found at + + GLib key file format (Lines beginning with a '#' are comments, + lists are separated by character ; etc.). + + + Users can create or modify the keyfile connection files + manually, even if that is not the recommended way of managing the profiles. + However, if they choose to do that, they must inform NetworkManager about + their changes (see monitor-connection-file in + nm-settings5 + and nmcli con (re)load). + + + Examples of <emphasis>keyfile</emphasis> configuration + + + A sample configuration for an ethernet network: +[connection] +id=Main eth0 +uuid=27afa607-ee36-43f0-b8c3-9d245cdc4bb3 +type=802-3-ethernet +autoconnect=true + +[ipv4] +method=auto + +[802-3-ethernet] +mac-address=00:23:5a:47:1f:71 + + + + + A sample configuration for WPA-EAP (PEAP with MSCHAPv2) and always-ask secret: +[connection] +id=CompanyWIFI +uuid=cdac6154-a33b-4b15-9904-666772cfa5ee +type=wifi +autoconnect=false + +[wifi] +ssid=CorpWLAN +mode=infrastructure +security=802-11-wireless-security + +[wifi-security] +key-mgmt=wpa-eap + +[ipv4] +method=auto + +[ipv6] +method=auto + +[802-1x] +eap=peap; +identity=joe +ca-cert=/home/joe/.cert/corp.crt +phase1-peapver=1 +phase2-auth=mschapv2 +password-flags=2 + + + + + A sample configuration for openvpn: +[connection] +id=RedHat-openvpn +uuid=7f9b3356-b210-4c0e-8123-bd116c9c280f +type=vpn +timestamp=1385401165 + +[vpn] +service-type=org.freedesktop.NetworkManager.openvpn +connection-type=password +password-flags=3 +remote=ovpn.my-company.com +cipher=AES-256-CBC +reneg-seconds=0 +port=443 +username=joe +ca=/etc/openvpn/ISCA.pem +tls-remote=ovpn.my-company.com + +[ipv6] +method=auto + +[ipv4] +method=auto +ignore-auto-dns=true +never-default=true + + + + + A sample configuration for a bridge and a bridge port: +[connection] [connection] +id=MainBridge id=br-port-1 +uuid=171ae855-a0ab-42b6-bd0c-60f5812eea9d uuid=d6e8ae98-71f8-4b3d-9d2d-2e26048fe794 +interface-name=MainBridge interface-name=em1 +type=bridge type=ethernet + master=MainBridge +[bridge] slave-type=bridge +interface-name=MainBridge + + + + + A sample configuration for a VLAN: +[connection] +id=VLAN for building 4A +uuid=8ce1c9e0-ce7a-4d2c-aa28-077dda09dd7e +interface-name=VLAN-4A +type=vlan + +[vlan] +interface-name=VLAN-4A +parent=eth0 +id=4 + + + + + + + DETAILS + + keyfile plugin variables for the majority of NetworkManager + properties have one-to-one mapping. It means a NetworkManager property is stored + in the keyfile as a variable of the same name and in the same format. + There are several exceptions to this rule, mainly for making keyfile syntax easier + for humans. The exceptions handled specially by keyfile + plugin are listed bellow. Refer to + nm-settings5 + for all available settings and properties and their description. + + Name aliases + + Some of the NetworkManager setting names are somewhat hard to type or remember. Therefore + keyfile introduces aliases that can be used instead of the names. + + + setting name keyfile alias + 802-3-ethernet = ethernet + 802-11-wireless = wifi + 802-11-wireless-security = wifi-security + + + + + + Secret flags + + Each secret property in a NetworkManager setting has an associated flags + property that describes how to handle that secret. In the keyfile plugin, + the value of -flags variable is a decimal number (0 - 7) defined as a sum + of the following values: + + + + 0 - (NM owned) - the system is responsible for providing and storing this secret. + + + 1 - (agent-owned) - a user-session secret agent is responsible for providing + and storing this secret; when it is required, agents will be asked to provide it. + + + 2 - (not-saved) - this secret should not be saved but should be requested + from the user each time it is required. + + + 4 - (not-required) - in some situations it cannot be automatically determined + that a secret is required or not. This flag hints that the secret is not required + and should not be requested from the user. + + + + + + + AUTHOR + + + NetworkManager developers + + + + + FILES + /etc/NetworkManager/system-connections/* + + + SEE ALSO + https://developer.gnome.org/NetworkManager/unstable/ref-settings.html + nm-settings(5), nm-settings-ifcfg-rh(5), NetworkManager(8), NetworkManager.conf(5), nmcli(1), nmcli-examples(5) + + + + + + + + + <xsl:value-of select="@name"/> setting (section) + + + + Property + Keyfile Variable + Format + Description + + + + + + +
+
+
+ + + + + + + + + + + +Example: + + + + +Allowed values: + + + + + +
diff --git a/man/nm-settings.5 b/man/nm-settings.5 index 6f6aaf8e..0a90098a 100644 --- a/man/nm-settings.5 +++ b/man/nm-settings.5 @@ -2,12 +2,12 @@ .\" Title: nm-settings .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 03 July 2014 +.\" Date: 19 December 2014 .\" Manual: Configuration -.\" Source: NetworkManager 0.9.10.0 +.\" Source: NetworkManager 1.0.0 .\" Language: English .\" -.TH "NM\-SETTINGS" "5" "" "NetworkManager 0\&.9\&.10\&.0" "Configuration" +.TH "NM\-SETTINGS" "5" "" "NetworkManager 1\&.0\&.0" "Configuration" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -111,112 +111,121 @@ l l l l l l l l l l l l. T{ -name +altsubject\-matches T}:T{ -string +array of string T}:T{ -802\-1x +[] T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +List of strings to be matched against the altSubjectName of the certificate presented by the authentication server\&. If the list is empty, no verification of the server certificate\*(Aqs altSubjectName is performed\&. T} T{ -eap +anonymous\-identity T}:T{ -array of string +string T}:T{ \ \& T}:T{ -The allowed EAP method to be used when authenticating to the network with 802\&.1x\&. Valid methods are: \*(Aqleap\*(Aq, \*(Aqmd5\*(Aq, \*(Aqtls\*(Aq, \*(Aqpeap\*(Aq, \*(Aqttls\*(Aq, \*(Aqpwd\*(Aq, and \*(Aqfast\*(Aq\&. Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations\&. +Anonymous identity string for EAP authentication methods\&. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP\-TTLS\&. T} T{ -identity +ca\-cert T}:T{ -string +byte array T}:T{ \ \& T}:T{ -Identity string for EAP authentication methods\&. Often the user\*(Aqs user or login name\&. +Contains the CA certificate if used by the EAP method specified in the "eap" property\&. Certificate data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte\&. This property can be unset even if the EAP method supports CA certificates, but this allows man\-in\-the\-middle attacks and is NOT recommended\&. T} T{ -anonymous\-identity +ca\-path T}:T{ string T}:T{ \ \& T}:T{ -Anonymous identity string for EAP authentication methods\&. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP\-TTLS\&. +UTF\-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca\-cert" property\&. T} T{ -pac\-file +client\-cert T}:T{ -string +byte array T}:T{ \ \& T}:T{ -UTF\-8 encoded file path containing PAC for EAP\-FAST\&. +Contains the client certificate if used by the EAP method specified in the "eap" property\&. Certificate data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte\&. T} T{ -ca\-cert +eap T}:T{ -byte array +array of string T}:T{ [] T}:T{ -Contains the CA certificate if used by the EAP method specified in the \*(Aqeap\*(Aq property\&. Certificate data is specified using a \*(Aqscheme\*(Aq; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. This property can be unset even if the EAP method supports CA certificates, but this allows man\-in\-the\-middle attacks and is NOT recommended\&. +The allowed EAP method to be used when authenticating to the network with 802\&.1x\&. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", and "fast"\&. Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations\&. T} T{ -ca\-path +identity T}:T{ string T}:T{ \ \& T}:T{ -UTF\-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the \*(Aqca\-cert\*(Aq property\&. +Identity string for EAP authentication methods\&. Often the user\*(Aqs user or login name\&. +T} +T{ +name +T}:T{ +string +T}:T{ +802\-1x +T}:T{ +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -subject\-match +pac\-file T}:T{ string T}:T{ \ \& T}:T{ -Substring to be matched against the subject of the certificate presented by the authentication server\&. When unset, no verification of the authentication server certificate\*(Aqs subject is performed\&. +UTF\-8 encoded file path containing PAC for EAP\-FAST\&. T} T{ -altsubject\-matches +password T}:T{ -array of string +string T}:T{ \ \& T}:T{ -List of strings to be matched against the altSubjectName of the certificate presented by the authentication server\&. If the list is empty, no verification of the server certificate\*(Aqs altSubjectName is performed\&. +UTF\-8 encoded password used for EAP authentication methods\&. If both the "password" property and the "password\-raw" property are specified, "password" is preferred\&. T} T{ -client\-cert +password\-flags T}:T{ -byte array +NMSettingSecretFlags (uint32) T}:T{ -[] +\ \& T}:T{ -Contains the client certificate if used by the EAP method specified in the \*(Aqeap\*(Aq property\&. Certificate data is specified using a \*(Aqscheme\*(Aq; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. +Flags indicating how to handle the "password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -phase1\-peapver +password\-raw T}:T{ -string +byte array T}:T{ \ \& T}:T{ -Forces which PEAP version is used when PEAP is set as the EAP method in \*(Aqeap\*(Aq property\&. When unset, the version reported by the server will be used\&. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version\&. To do so, this property may be set to \*(Aq0\*(Aq or \*(Aq1\*(Aq to force that specific PEAP version\&. +Password used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF\-8 to be used\&. If both the "password" property and the "password\-raw" property are specified, "password" is preferred\&. T} T{ -phase1\-peaplabel +password\-raw\-flags T}:T{ -string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -Forces use of the new PEAP label during key derivation\&. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1\&. Set to \*(Aq1\*(Aq to force use of the new PEAP label\&. See the wpa_supplicant documentation for more details\&. +Flags indicating how to handle the "password\-raw" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ phase1\-fast\-provisioning @@ -225,178 +234,169 @@ string T}:T{ \ \& T}:T{ -Enables or disables in\-line provisioning of EAP\-FAST credentials when FAST is specified as the EAP method in the #NMSetting8021x:eap property\&. Allowed values are \*(Aq0\*(Aq (disabled), \*(Aq1\*(Aq (allow unauthenticated provisioning), \*(Aq2\*(Aq (allow authenticated provisioning), and \*(Aq3\*(Aq (allow both authenticated and unauthenticated provisioning)\&. See the wpa_supplicant documentation for more details\&. +Enables or disables in\-line provisioning of EAP\-FAST credentials when FAST is specified as the EAP method in the "eap" property\&. Recognized values are "0" (disabled), "1" (allow unauthenticated provisioning), "2" (allow authenticated provisioning), and "3" (allow both authenticated and unauthenticated provisioning)\&. See the wpa_supplicant documentation for more details\&. T} T{ -phase2\-auth +phase1\-peaplabel T}:T{ string T}:T{ \ \& T}:T{ -Specifies the allowed \*(Aqphase 2\*(Aq inner non\-EAP authentication methods when an EAP method that uses an inner TLS tunnel is specified in the \*(Aqeap\*(Aq property\&. Recognized non\-EAP phase2 methods are \*(Aqpap\*(Aq, \*(Aqchap\*(Aq, \*(Aqmschap\*(Aq, \*(Aqmschapv2\*(Aq, \*(Aqgtc\*(Aq, \*(Aqotp\*(Aq, \*(Aqmd5\*(Aq, and \*(Aqtls\*(Aq\&. Each \*(Aqphase 2\*(Aq inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details\&. +Forces use of the new PEAP label during key derivation\&. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1\&. Set to "1" to force use of the new PEAP label\&. See the wpa_supplicant documentation for more details\&. T} T{ -phase2\-autheap +phase1\-peapver T}:T{ string T}:T{ \ \& T}:T{ -Specifies the allowed \*(Aqphase 2\*(Aq inner EAP\-based authentication methods when an EAP method that uses an inner TLS tunnel is specified in the \*(Aqeap\*(Aq property\&. Recognized EAP\-based \*(Aqphase 2\*(Aq methods are \*(Aqmd5\*(Aq, \*(Aqmschapv2\*(Aq, \*(Aqotp\*(Aq, \*(Aqgtc\*(Aq, and \*(Aqtls\*(Aq\&. Each \*(Aqphase 2\*(Aq inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details\&. +Forces which PEAP version is used when PEAP is set as the EAP method in the "eap" property\&. When unset, the version reported by the server will be used\&. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version\&. To do so, this property may be set to "0" or "1" to force that specific PEAP version\&. T} T{ -phase2\-ca\-cert +phase2\-altsubject\-matches T}:T{ -byte array +array of string T}:T{ [] T}:T{ -Contains the \*(Aqphase 2\*(Aq CA certificate if used by the EAP method specified in the \*(Aqphase2\-auth\*(Aq or \*(Aqphase2\-autheap\*(Aq properties\&. Certificate data is specified using a \*(Aqscheme\*(Aq; two are currentlysupported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. This property can be unset even if the EAP method supports CA certificates, but this allows man\-in\-the\-middle attacks and is NOT recommended\&. +List of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner "phase 2" authentication\&. If the list is empty, no verification of the server certificate\*(Aqs altSubjectName is performed\&. T} T{ -phase2\-ca\-path +phase2\-auth T}:T{ string T}:T{ \ \& T}:T{ -UTF\-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the \*(Aqphase2\-ca\-cert\*(Aq property\&. +Specifies the allowed "phase 2" inner non\-EAP authentication methods when an EAP method that uses an inner TLS tunnel is specified in the "eap" property\&. Recognized non\-EAP "phase 2" methods are "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", and "tls"\&. Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details\&. T} T{ -phase2\-subject\-match +phase2\-autheap T}:T{ string T}:T{ \ \& T}:T{ -Substring to be matched against the subject of the certificate presented by the authentication server during the inner \*(Aqphase2\*(Aq authentication\&. When unset, no verification of the authentication server certificate\*(Aqs subject is performed\&. +Specifies the allowed "phase 2" inner EAP\-based authentication methods when an EAP method that uses an inner TLS tunnel is specified in the "eap" property\&. Recognized EAP\-based "phase 2" methods are "md5", "mschapv2", "otp", "gtc", and "tls"\&. Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details\&. T} T{ -phase2\-altsubject\-matches +phase2\-ca\-cert T}:T{ -array of string +byte array T}:T{ \ \& T}:T{ -List of strings to be matched against List of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner \*(Aqphase 2\*(Aq authentication\&. If the list is empty, no verification of the server certificate\*(Aqs altSubjectName is performed\&. +Contains the "phase 2" CA certificate if used by the EAP method specified in the "phase2\-auth" or "phase2\-autheap" properties\&. Certificate data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte\&. This property can be unset even if the EAP method supports CA certificates, but this allows man\-in\-the\-middle attacks and is NOT recommended\&. T} T{ -phase2\-client\-cert +phase2\-ca\-path T}:T{ -byte array +string T}:T{ -[] +\ \& T}:T{ -Contains the \*(Aqphase 2\*(Aq client certificate if used by the EAP method specified in the \*(Aqphase2\-auth\*(Aq or \*(Aqphase2\-autheap\*(Aq properties\&. Certificate data is specified using a \*(Aqscheme\*(Aq; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. +UTF\-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2\-ca\-cert" property\&. T} T{ -password +phase2\-client\-cert T}:T{ -string +byte array T}:T{ \ \& T}:T{ -UTF\-8 encoded password used for EAP authentication methods\&. +Contains the "phase 2" client certificate if used by the EAP method specified in the "phase2\-auth" or "phase2\-autheap" properties\&. Certificate data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme (which is backwards compatible with NM 0\&.7\&.x) this property should be set to the certificate\*(Aqs DER encoded data\&. When using the path scheme, this property should be set to the full UTF\-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte\&. This property can be unset even if the EAP method supports CA certificates, but this allows man\-in\-the\-middle attacks and is NOT recommended\&. T} T{ -password\-flags +phase2\-private\-key T}:T{ -uint32 +byte array T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the 802\&.1x password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Contains the "phase 2" inner private key when the "phase2\-auth" or "phase2\-autheap" property is set to "tls"\&. Key data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme and private keys, this property should be set to the key\*(Aqs encrypted PEM encoded data\&. When using private keys with the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte\&. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "phase2\-private\-key\-password" property must be set to password used to decrypt the PKCS#12 certificate and key\&. When using PKCS#12 files and the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string "file://" and and ending with a terminating NUL byte, and as with the blob scheme the "phase2\-private\-key\-password" property must be set to the password used to decode the PKCS#12 private key and certificate\&. T} T{ -password\-raw +phase2\-private\-key\-password T}:T{ -byte array +string T}:T{ -[] +\ \& T}:T{ -Password used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF\-8 to be used\&. If both \*(Aqpassword\*(Aq and \*(Aqpassword\-raw\*(Aq are given, \*(Aqpassword\*(Aq is preferred\&. +The password used to decrypt the "phase 2" private key specified in the "phase2\-private\-key" property when the private key either uses the path scheme, or is a PKCS#12 format key\&. T} T{ -password\-raw\-flags +phase2\-private\-key\-password\-flags T}:T{ -uint32 +NMSettingSecretFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the 802\&.1x password byte array\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Flags indicating how to handle the "phase2\-private\-key\-password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -private\-key +phase2\-subject\-match T}:T{ -byte array +string T}:T{ -[] +\ \& T}:T{ -Contains the private key when the \*(Aqeap\*(Aq property is set to \*(Aqtls\*(Aq\&. Key data is specified using a \*(Aqscheme\*(Aq; two are currently supported: blob and path\&. When using the blob scheme and private keys, this property should be set to the key\*(Aqs encrypted PEM encoded data\&. When using private keys with the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \*(Aqprivate\-key\-password\*(Aq property must be set to password used to decrypt the PKCS#12 certificate and key\&. When using PKCS#12 files and the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string \*(Aqfile://\*(Aq and and ending with a terminating NULL byte, and as with the blob scheme the \*(Aqprivate\-key\-password\*(Aq property must be set to the password used to decode the PKCS#12 private key and certificate\&. +Substring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication\&. When unset, no verification of the authentication server certificate\*(Aqs subject is performed\&. T} T{ -private\-key\-password +pin T}:T{ string T}:T{ \ \& T}:T{ -The password used to decrypt the private key specified in the \*(Aqprivate\-key\*(Aq property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key\&. +PIN used for EAP authentication methods\&. T} T{ -private\-key\-password\-flags +pin\-flags T}:T{ -uint32 +NMSettingSecretFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the 802\&.1x private key password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Flags indicating how to handle the "pin" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -phase2\-private\-key +private\-key T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -Contains the \*(Aqphase 2\*(Aq inner private key when the \*(Aqphase2\-auth\*(Aq or \*(Aqphase2\-autheap\*(Aq property is set to \*(Aqtls\*(Aq\&. Key data is specified using a \*(Aqscheme\*(Aq; two are currently supported: blob and path\&. When using the blob scheme and private keys, this property should be set to the key\*(Aqs encrypted PEM encoded data\&. When using private keys with the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string \*(Aqfile://\*(Aq and ending with a terminating NULL byte\&. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \*(Aqphase2\-private\-key\-password\*(Aq property must be set to password used to decrypt the PKCS#12 certificate and key\&. When using PKCS#12 files and the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string \*(Aqfile://\*(Aq and and ending with a terminating NULL byte, and as with the blob scheme the \*(Aqphase2\-private\-key\-password\*(Aq property must be set to the password used to decode the PKCS#12 private key and certificate\&. +Contains the private key when the "eap" property is set to "tls"\&. Key data is specified using a "scheme"; two are currently supported: blob and path\&. When using the blob scheme and private keys, this property should be set to the key\*(Aqs encrypted PEM encoded data\&. When using private keys with the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte\&. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "private\-key\-password" property must be set to password used to decrypt the PKCS#12 certificate and key\&. When using PKCS#12 files and the path scheme, this property should be set to the full UTF\-8 encoded path of the key, prefixed with the string "file://" and and ending with a terminating NUL byte, and as with the blob scheme the "private\-key\-password" property must be set to the password used to decode the PKCS#12 private key and certificate\&. WARNING: "private\-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users\&. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data\&. T} T{ -phase2\-private\-key\-password +private\-key\-password T}:T{ string T}:T{ \ \& T}:T{ -The password used to decrypt the \*(Aqphase 2\*(Aq private key specified in the \*(Aqprivate\-key\*(Aq property when the phase2 private key either uses the path scheme, or if the phase2 private key is a PKCS#12 format key\&. +The password used to decrypt the private key specified in the "private\-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key\&. T} T{ -phase2\-private\-key\-password\-flags +private\-key\-password\-flags T}:T{ -uint32 +NMSettingSecretFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the 802\&.1x phase2 private key password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Flags indicating how to handle the "private\-key\-password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -pin +subject\-match T}:T{ string T}:T{ \ \& T}:T{ -PIN used for EAP authentication methods\&. -T} -T{ -pin\-flags -T}:T{ -uint32 -T}:T{ -0 -T}:T{ -Flags indicating how to handle the 802\&.1x PIN\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Substring to be matched against the subject of the certificate presented by the authentication server\&. When unset, no verification of the authentication server certificate\*(Aqs subject is performed\&. T} T{ system\-ca\-certs @@ -405,7 +405,7 @@ boolean T}:T{ FALSE T}:T{ -When TRUE, overrides \*(Aqca\-path\*(Aq and \*(Aqphase2\-ca\-path\*(Aq properties using the system CA directory specified at configure time with the \-\-system\-ca\-path switch\&. The certificates in this directory are added to the verification chain in addition to any certificates specified by the \*(Aqca\-cert\*(Aq and \*(Aqphase2\-ca\-cert\*(Aq properties\&. +When TRUE, overrides the "ca\-path" and "phase2\-ca\-path" properties using the system CA directory specified at configure time with the \-\-system\-ca\-path switch\&. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca\-cert" and "phase2\-ca\-cert" properties\&. T} .TE .sp 1 @@ -437,22 +437,22 @@ l l l l l l l l l l l l. T{ -name +encapsulation T}:T{ string T}:T{ -adsl +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Encapsulation of ADSL connection\&. Can be "vcmux" or "llc"\&. T} T{ -username +name T}:T{ string T}:T{ -\ \& +adsl T}:T{ -Username used to authenticate with the pppoa service\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ password @@ -461,16 +461,16 @@ string T}:T{ \ \& T}:T{ -Password used to authenticate with the pppoa service\&. +Password used to authenticate with the ADSL service\&. T} T{ password\-flags T}:T{ -uint32 +NMSettingSecretFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the ADSL password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Flags indicating how to handle the "password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ protocol @@ -479,34 +479,34 @@ string T}:T{ \ \& T}:T{ -ADSL connection protocol\&. +ADSL connection protocol\&. Can be "pppoa", "pppoe" or "ipoatm"\&. T} T{ -encapsulation +username T}:T{ string T}:T{ \ \& T}:T{ -Encapsulation of ADSL connection +Username used to authenticate with the ADSL service\&. T} T{ -vpi +vci T}:T{ uint32 T}:T{ 0 T}:T{ -VPI of ADSL connection +VCI of ADSL connection T} T{ -vci +vpi T}:T{ uint32 T}:T{ 0 T}:T{ -VCI of ADSL connection +VPI of ADSL connection T} .TE .sp 1 @@ -533,22 +533,22 @@ l l l l l l l l l l l l. T{ -name +bdaddr T}:T{ -string +byte array T}:T{ -bluetooth +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The Bluetooth address of the device\&. T} T{ -bdaddr +name T}:T{ -byte array +string T}:T{ -[] +bluetooth T}:T{ -The Bluetooth address of the device +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ type @@ -557,7 +557,7 @@ string T}:T{ \ \& T}:T{ -Either \*(Aqdun\*(Aq for Dial\-Up Networking connections or \*(Aqpanu\*(Aq for Personal Area Networking connections\&. +Either "dun" for Dial\-Up Networking connections or "panu" for Personal Area Networking connections to devices supporting the NAP profile\&. T} .TE .sp 1 @@ -584,31 +584,31 @@ l l l l l l l l l l l l. T{ -name +interface\-name T}:T{ string T}:T{ -bond +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Deprecated in favor of connection\&.interface\-name, but can be used for backward\-compatibility with older daemons, to set the bond\*(Aqs interface name\&. T} T{ -interface\-name +name T}:T{ string T}:T{ -\ \& +bond T}:T{ -The name of the virtual in\-kernel bonding network interface +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ options T}:T{ -dict of (string::string) +dict of string to string T}:T{ \ \& T}:T{ -Dictionary of key/value pairs of bonding options\&. Both keys and values must be strings\&. Option names must contain only alphanumeric characters (ie, [a\-zA\-Z0\-9])\&. +Dictionary of key/value pairs of bonding options\&. Both keys and values must be strings\&. Option names must contain only alphanumeric characters (ie, [a\-zA\-Z0\-9])\&. T} .TE .sp 1 @@ -641,85 +641,85 @@ l l l l l l l l l l l l. T{ -name +ageing\-time T}:T{ -string +uint32 T}:T{ -bridge +300 T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The Ethernet MAC address aging time, in seconds\&. T} T{ -interface\-name +forward\-delay T}:T{ -string +uint32 T}:T{ -\ \& +15 T}:T{ -The name of the virtual in\-kernel bridging network interface +The Spanning Tree Protocol (STP) forwarding delay, in seconds\&. T} T{ -mac\-address +hello\-time T}:T{ -byte array +uint32 T}:T{ -[] +2 T}:T{ -The MAC address of the bridge +The Spanning Tree Protocol (STP) hello time, in seconds\&. T} T{ -stp +interface\-name T}:T{ -boolean +string T}:T{ -TRUE +\ \& T}:T{ -Controls whether Spanning Tree Protocol (STP) is enabled for this bridge\&. +Deprecated in favor of connection\&.interface\-name, but can be used for backward\-compatibility with older daemons, to set the bridge\*(Aqs interface name\&. T} T{ -priority +mac\-address T}:T{ -uint32 +byte array T}:T{ -32768 +\ \& T}:T{ -Sets the Spanning Tree Protocol (STP) priority for this bridge\&. Lower values are \*(Aqbetter\*(Aq; the lowest priority bridge will be elected the root bridge\&. +If specified, the MAC address of bridge\&. When creating a new bridge, this MAC address will be set\&. When matching an existing (outside NetworkManager created) bridge, this MAC address must match\&. T} T{ -forward\-delay +max\-age T}:T{ uint32 T}:T{ -15 +20 T}:T{ -The Spanning Tree Protocol (STP) forwarding delay, in seconds\&. +The Spanning Tree Protocol (STP) maximum message age, in seconds\&. T} T{ -hello\-time +name T}:T{ -uint32 +string T}:T{ -2 +bridge T}:T{ -The Spanning Tree Protocol (STP) hello time, in seconds\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -max\-age +priority T}:T{ uint32 T}:T{ -20 +32768 T}:T{ -The Spanning Tree Protocol (STP) maximum message age, in seconds\&. +Sets the Spanning Tree Protocol (STP) priority for this bridge\&. Lower values are "better"; the lowest priority bridge will be elected the root bridge\&. T} T{ -ageing\-time +stp T}:T{ -uint32 +boolean T}:T{ -300 +TRUE T}:T{ -The Ethernet MAC address aging time, in seconds\&. +Controls whether Spanning Tree Protocol (STP) is enabled for this bridge\&. T} .TE .sp 1 @@ -747,22 +747,22 @@ l l l l l l l l l l l l. T{ -name +hairpin\-mode T}:T{ -string +boolean T}:T{ -bridge\-port +FALSE T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Enables or disabled "hairpin mode" for the port, which allows frames to be sent back out through the port the frame was received on\&. T} T{ -priority +name T}:T{ -uint32 +string T}:T{ -32 +bridge\-port T}:T{ -The Spanning Tree Protocol (STP) priority of this bridge port +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ path\-cost @@ -774,13 +774,13 @@ T}:T{ The Spanning Tree Protocol (STP) port cost for destinations via this port\&. T} T{ -hairpin\-mode +priority T}:T{ -boolean +uint32 T}:T{ -FALSE +32 T}:T{ -Enables or disabled \*(Aqhairpin mode\*(Aq for the port, which allows frames to be sent back out through the port the frame was received on\&. +The Spanning Tree Protocol (STP) priority of this bridge port\&. T} .TE .sp 1 @@ -815,7 +815,7 @@ string T}:T{ cdma T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ number @@ -824,34 +824,34 @@ string T}:T{ \ \& T}:T{ -Number to dial when establishing a PPP data session with the CDMA\-based mobile broadband network\&. If not specified, the default number (#777) is used when required\&. +The number to dial to establish the connection to the CDMA\-based mobile broadband network, if any\&. If not specified, the default number (#777) is used when required\&. T} T{ -username +password T}:T{ string T}:T{ \ \& T}:T{ -Username used to authenticate with the network, if required\&. Note that many providers do not require a username or accept any username\&. +The password used to authenticate with the network, if required\&. Many providers do not require a password, or accept any password\&. But if a password is required, it is specified here\&. T} T{ -password +password\-flags T}:T{ -string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -Password used to authenticate with the network, if required\&. Note that many providers do not require a password or accept any password\&. +Flags indicating how to handle the "password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -password\-flags +username T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the CDMA password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +The username used to authenticate with the network, if required\&. Many providers do not require a username, or accept any username\&. But if a username is required, it is specified here\&. T} .TE .sp 1 @@ -887,78 +887,79 @@ l l l l l l l l l l l l l l l l +l l l l l l l l. T{ -name +autoconnect T}:T{ -string +boolean T}:T{ -connection +TRUE T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Whether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available\&. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection\&. T} T{ -id +autoconnect\-priority T}:T{ -string +int32 T}:T{ -\ \& +0 T}:T{ -User\-readable connection identifier/name\&. Must be one or more characters and may change over the lifetime of the connection if the user decides to rename it\&. +The autoconnect priority\&. If the connection is set to autoconnect, connections with higher priority will be preferred\&. Defaults to 0\&. The higher number means higher priority\&. T} T{ -uuid +gateway\-ping\-timeout T}:T{ -string +uint32 T}:T{ -\ \& +0 T}:T{ -Universally unique connection identifier\&. Must be in the format \*(Aq2815492f\-7e56\-435e\-b2e9\-246bd7cdc664\*(Aq (ie, contains only hexadecimal characters and \*(Aq\-\*(Aq)\&. The UUID should be assigned when the connection is created and never changed as long as the connection still applies to the same network\&. For example, it should not be changed when the user changes the connection\*(Aqs \*(Aqid\*(Aq, but should be recreated when the Wi\-Fi SSID, mobile broadband network provider, or the connection type changes\&. +If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping\&. T} T{ -interface\-name +id T}:T{ string T}:T{ \ \& T}:T{ -Interface name this connection is bound to\&. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings)\&. For connection types where interface names cannot easily be made persistent (e\&.g\&. mobile broadband or USB Ethernet), this property should not be used\&. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface\&. +A human readable unique identifier for the connection, like "Work Wi\-Fi" or "T\-Mobile 3G"\&. T} T{ -type +interface\-name T}:T{ string T}:T{ \ \& T}:T{ -Base type of the connection\&. For hardware\-dependent connections, should contain the setting name of the hardware\-type specific setting (ie, \*(Aq802\-3\-ethernet\*(Aq or \*(Aq802\-11\-wireless\*(Aq or \*(Aqbluetooth\*(Aq, etc), and for non\-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, \*(Aqvpn\*(Aq or \*(Aqbridge\*(Aq, etc)\&. +The name of the network interface this connection is bound to\&. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings)\&. For software devices this specifies the name of the created device\&. For connection types where interface names cannot easily be made persistent (e\&.g\&. mobile broadband or USB Ethernet), this property should not be used\&. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface\&. T} T{ -permissions +master T}:T{ -array of string +string T}:T{ \ \& T}:T{ -An array of strings defining what access a given user has to this connection\&. If this is NULL or empty, all users are allowed to access this connection\&. Otherwise a user is allowed to access this connection if and only if they are in this array\&. Each entry is of the form "[type]:[id]:[reserved]", for example: "user:dcbw:blah" At this time only the \*(Aquser\*(Aq [type] is allowed\&. Any other values are ignored and reserved for future use\&. [id] is the username that this permission refers to, which may not contain the \*(Aq:\*(Aq character\&. Any [reserved] information (if present) must be ignored and is reserved for future use\&. All of [type], [id], and [reserved] must be valid UTF\-8\&. +Interface name of the master device or UUID of the master connection\&. T} T{ -autoconnect +name T}:T{ -boolean +string T}:T{ -TRUE +connection T}:T{ -If TRUE, NetworkManager will activate this connection when its network resources are available\&. If FALSE, the connection must be manually activated by the user or some other mechanism\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -timestamp +permissions T}:T{ -uint64 +array of string T}:T{ -0 +[] T}:T{ -Timestamp (in seconds since the Unix Epoch) that the connection was last successfully activated\&. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp\&. The property is only meant for reading (changes to this property will not be preserved)\&. +An array of strings defining what access a given user has to this connection\&. If this is NULL or empty, all users are allowed to access this connection\&. Otherwise a user is allowed to access this connection if and only if they are in this list\&. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah"\&. At this time only the "user" [type] is allowed\&. Any other values are ignored and reserved for future use\&. [id] is the username that this permission refers to, which may not contain the ":" character\&. Any [reserved] information present must be ignored and is reserved for future use\&. All of [type], [id], and [reserved] must be valid UTF\-8\&. T} T{ read\-only @@ -967,52 +968,61 @@ boolean T}:T{ FALSE T}:T{ -If TRUE, the connection is read\-only and cannot be changed by the user or any other mechanism\&. This is normally set for system connections whose plugin cannot yet write updated connections back out\&. +FALSE if the connection can be modified using the provided settings service\*(Aqs D\-Bus interface with the right privileges, or TRUE if the connection is read\-only and cannot be modified\&. T} T{ -zone +secondaries T}:T{ -string +array of string T}:T{ -\ \& +[] T}:T{ -The trust level of a the connection\&.Free form case\-insensitive string (for example "Home", "Work", "Public")\&. NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall\&. +List of connection UUIDs that should be activated when the base connection itself is activated\&. Currently only VPN connections are supported\&. T} T{ -master +slave\-type T}:T{ string T}:T{ \ \& T}:T{ -Interface name of the master device or UUID of the master connection +Setting name of the device type of this slave\*(Aqs master connection (eg, "bond"), or NULL if this connection is not a slave\&. T} T{ -slave\-type +timestamp +T}:T{ +uint64 +T}:T{ +0 +T}:T{ +The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated\&. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp\&. The property is only meant for reading (changes to this property will not be preserved)\&. +T} +T{ +type T}:T{ string T}:T{ \ \& T}:T{ -Setting name describing the type of slave this connection is (ie, \*(Aqbond\*(Aq) or NULL if this connection is not a slave\&. +Base type of the connection\&. For hardware\-dependent connections, should contain the setting name of the hardware\-type specific setting (ie, "802\-3\-ethernet" or "802\-11\-wireless" or "bluetooth", etc), and for non\-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc)\&. T} T{ -secondaries +uuid T}:T{ -array of string +string T}:T{ \ \& T}:T{ -List of connection UUIDs that should be activated when the base connection itself is activated\&. Currently only VPN connections are supported\&. +A universally unique identifier for the connection, for example generated with libuuid\&. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network\&. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re\-created when the Wi\-Fi SSID, mobile broadband network provider, or "type" property changes\&. The UUID must be in the format "2815492f\-7e56\-435e\-b2e9\-246bd7cdc664" (ie, contains only hexadecimal characters and "\-")\&. T} T{ -gateway\-ping\-timeout +zone T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping\&. +The trust level of a the connection\&. Free form case\-insensitive string (for example "Home", "Work", "Public")\&. NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall\&. T} .TE .sp 1 @@ -1052,22 +1062,22 @@ l l l l l l l l l l l l. T{ -name +app\-fcoe\-flags T}:T{ -string +NMSettingDcbFlags (uint32) T}:T{ -dcb +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Specifies the NMSettingDcbFlags for the DCB FCoE application\&. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)\&. T} T{ -app\-fcoe\-flags +app\-fcoe\-mode T}:T{ -uint32 +string T}:T{ -0 +"fabric" T}:T{ -Specifies the flags for the DCB FCoE application\&. Flags may be any combination of 0x1 (enable), 0x2 (advertise), and 0x4 (willing)\&. (see the section called \(lqSecret flag types:\(rq for flag values) +The FCoE controller mode; either "fabric" (default) or "vn2vn"\&. T} T{ app\-fcoe\-priority @@ -1076,88 +1086,79 @@ int32 T}:T{ \-1 T}:T{ -The highest User Priority (0 \- 7) which FCoE frames should use, or \-1 for default priority\&. Only used when the \*(Aqapp\-fcoe\-flags\*(Aq property includes the \*(Aqenabled\*(Aq flag\&. -T} -T{ -app\-fcoe\-mode -T}:T{ -string -T}:T{ -"fabric" -T}:T{ -The FCoe controller mode; either \*(Aqfabric\*(Aq (default) or \*(Aqvn2vn\*(Aq\&. +The highest User Priority (0 \- 7) which FCoE frames should use, or \-1 for default priority\&. Only used when the "app\-fcoe\-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag\&. T} T{ -app\-iscsi\-flags +app\-fip\-flags T}:T{ -uint32 +NMSettingDcbFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Specifies the flags for the DCB iSCSI application\&. Flags may be any combination of 0x1 (enable), 0x2 (advertise), and 0x4 (willing)\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Specifies the NMSettingDcbFlags for the DCB FIP application\&. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)\&. T} T{ -app\-iscsi\-priority +app\-fip\-priority T}:T{ int32 T}:T{ \-1 T}:T{ -The highest User Priority (0 \- 7) which iSCSI frames should use, or \-1 for default priority\&. Only used when the \*(Aqapp\-iscsi\-flags\*(Aq property includes the \*(Aqenabled\*(Aq flag\&. +The highest User Priority (0 \- 7) which FIP frames should use, or \-1 for default priority\&. Only used when the "app\-fip\-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag\&. T} T{ -app\-fip\-flags +app\-iscsi\-flags T}:T{ -uint32 +NMSettingDcbFlags (uint32) T}:T{ -0 +\ \& T}:T{ -Specifies the flags for the DCB FIP application\&. Flags may be any combination of 0x1 (enable), 0x2 (advertise), and 0x4 (willing)\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Specifies the NMSettingDcbFlags for the DCB iSCSI application\&. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)\&. T} T{ -app\-fip\-priority +app\-iscsi\-priority T}:T{ int32 T}:T{ \-1 T}:T{ -The highest User Priority (0 \- 7) which FIP frames should use, or \-1 for default priority\&. Only used when the \*(Aqapp\-fip\-flags\*(Aq property includes the \*(Aqenabled\*(Aq flag\&. +The highest User Priority (0 \- 7) which iSCSI frames should use, or \-1 for default priority\&. Only used when the "app\-iscsi\-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag\&. T} T{ -priority\-flow\-control\-flags +name T}:T{ -uint32 +string T}:T{ -0 +dcb T}:T{ -Specifies the flags for DCB Priority Flow Control\&. Flags may be any combination of 0x1 (enable), 0x2 (advertise), and 0x4 (willing)\&. (see the section called \(lqSecret flag types:\(rq for flag values) +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -priority\-flow\-control +priority\-bandwidth T}:T{ array of uint32 T}:T{ \ \& T}:T{ -An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates whether or not the corresponding priority should transmit priority pause\&. Allowed values are 0 (do not transmit pause) and 1 (transmit pause)\&. +An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates the percentage of bandwidth of the priority\*(Aqs assigned group that the priority may use\&. The sum of all percentages for priorities which belong to the same group must total 100 percent\&. T} T{ -priority\-group\-flags +priority\-flow\-control T}:T{ -uint32 +array of uint32 T}:T{ -0 +\ \& T}:T{ -Specifies the flags for DCB Priority Groups\&. Flags may be any combination of 0x1 (enable), 0x2 (advertise), and 0x4 (willing)\&. (see the section called \(lqSecret flag types:\(rq for flag values) +An array of 8 boolean values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates whether or not the corresponding priority should transmit priority pause\&. T} T{ -priority\-group\-id +priority\-flow\-control\-flags T}:T{ -array of uint32 +NMSettingDcbFlags (uint32) T}:T{ \ \& T}:T{ -An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates the Priority Group ID\&. Allowed Priority Group ID values are 0 \- 7 or 15 for the unrestricted group\&. +Specifies the NMSettingDcbFlags for DCB Priority Flow Control (PFC)\&. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)\&. T} T{ priority\-group\-bandwidth @@ -1169,13 +1170,22 @@ T}:T{ An array of 8 uint values, where the array index corresponds to the Priority Group ID (0 \- 7) and the value indicates the percentage of link bandwidth allocated to that group\&. Allowed values are 0 \- 100, and the sum of all values must total 100 percent\&. T} T{ -priority\-bandwidth +priority\-group\-flags +T}:T{ +NMSettingDcbFlags (uint32) +T}:T{ +\ \& +T}:T{ +Specifies the NMSettingDcbFlags for DCB Priority Groups\&. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4)\&. +T} +T{ +priority\-group\-id T}:T{ array of uint32 T}:T{ \ \& T}:T{ -An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates the percentage of bandwidth of the priority\*(Aqs assigned group that the priority may use\&. The sum of all percentages for priorities which belong to the same group must total 100 percent\&. +An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates the Priority Group ID\&. Allowed Priority Group ID values are 0 \- 7 or 15 for the unrestricted group\&. T} T{ priority\-strict\-bandwidth @@ -1184,7 +1194,7 @@ array of uint32 T}:T{ \ \& T}:T{ -An array of 8 uint values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group\&. Allowed values are 0 (the priority may not utilize all bandwidth) or 1 (the priority may utilize all bandwidth)\&. +An array of 8 boolean values, where the array index corresponds to the User Priority (0 \- 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group\&. T} T{ priority\-traffic\-class @@ -1202,7 +1212,38 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&10.\ \&gsm setting +.B Table\ \&10.\ \&generic setting +.TS +allbox tab(:); +lB lB lB lB. +T{ +Key Name +T}:T{ +Value Type +T}:T{ +Default Value +T}:T{ +Value Description +T} +.T& +l l l l. +T{ +name +T}:T{ +string +T}:T{ +generic +T}:T{ +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. +T} +.TE +.sp 1 +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&11.\ \&gsm setting .TS allbox tab(:); lB lB lB lB. @@ -1216,8 +1257,6 @@ T}:T{ Value Description T} .T& -l l l l -l l l l l l l l l l l l l l l l @@ -1229,76 +1268,67 @@ l l l l l l l l l l l l. T{ -name +apn T}:T{ string T}:T{ -gsm +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM\-based network\&. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider\-specific walled\-garden, so it is important to use the correct APN for the user\*(Aqs mobile broadband plan\&. The APN may only be composed of the characters a\-z, 0\-9, \&., and \- per GSM 03\&.60 Section 14\&.9\&. T} T{ -number +home\-only T}:T{ -string +boolean T}:T{ -\ \& +FALSE T}:T{ -Number to dial when establishing a PPP data session with the GSM\-based mobile broadband network\&. Many modems do not require PPP for connections to the mobile network and thus this property should be left blank, which allows NetworkManager to select the appropriate settings automatically\&. +When TRUE, only connections to the home network will be allowed\&. Connections to roaming networks will not be made\&. T} T{ -username +name T}:T{ string T}:T{ -\ \& +gsm T}:T{ -Username used to authenticate with the network, if required\&. Note that many providers do not require a username or accept any username\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -password +network\-id T}:T{ string T}:T{ \ \& T}:T{ -Password used to authenticate with the network, if required\&. Note that many providers do not require a password or accept any password\&. -T} -T{ -password\-flags -T}:T{ -uint32 -T}:T{ -0 -T}:T{ -Flags indicating how to handle the GSM password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +The Network ID (GSM LAI format, ie MCC\-MNC) to force specific network registration\&. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network\&. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible\&. T} T{ -apn +number T}:T{ string T}:T{ \ \& T}:T{ -The GPRS Access Point Name specifying the APN used when establishing a data session with the GSM\-based network\&. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider\-specific walled\-garden, so it is important to use the correct APN for the user\*(Aqs mobile broadband plan\&. The APN may only be composed of the characters a\-z, 0\-9, \&., and \- per GSM 03\&.60 Section 14\&.9\&. +Number to dial when establishing a PPP data session with the GSM\-based mobile broadband network\&. Many modems do not require PPP for connections to the mobile network and thus this property should be left blank, which allows NetworkManager to select the appropriate settings automatically\&. T} T{ -network\-id +password T}:T{ string T}:T{ \ \& T}:T{ -The Network ID (GSM LAI format, ie MCC\-MNC) to force specific network registration\&. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network\&. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible\&. +The password used to authenticate with the network, if required\&. Many providers do not require a password, or accept any password\&. But if a password is required, it is specified here\&. T} T{ -network\-type +password\-flags T}:T{ -int32 +NMSettingSecretFlags (uint32) T}:T{ -\-1 +\ \& T}:T{ -Network preference to force the device to only use specific network technologies\&. The permitted values are: \-1: any, 0: 3G only, 1: GPRS/EDGE only, 2: prefer 3G, 3: prefer 2G, 4: prefer 4G/LTE, 5: 4G/LTE only\&. Notes: This property is deprecated and NetworkManager from 0\&.9\&.10 onwards doesn\*(Aqt use this property when talking to ModemManager\&.Also, not all devices allow network preference control\&. +Flags indicating how to handle the "password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ pin @@ -1312,29 +1342,20 @@ T} T{ pin\-flags T}:T{ -uint32 -T}:T{ -0 -T}:T{ -Flags indicating how to handle the GSM SIM PIN\&. (see the section called \(lqSecret flag types:\(rq for flag values) -T} -T{ -allowed\-bands -T}:T{ -uint32 +NMSettingSecretFlags (uint32) T}:T{ -1 +\ \& T}:T{ -Bitfield of allowed frequency bands\&.Notes: This property is deprecated and NetworkManager from 0\&.9\&.10 onwards doesn\*(Aqt use this property when talking to ModemManager\&.Also, not all devices allow frequency band control\&. +Flags indicating how to handle the "pin" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -home\-only +username T}:T{ -boolean +string T}:T{ -FALSE +\ \& T}:T{ -When TRUE, only connections to the home network will be allowed\&. Connections to roaming networks will not be made\&. +The username used to authenticate with the network, if required\&. Many providers do not require a username, or accept any username\&. But if a username is required, it is specified here\&. T} .TE .sp 1 @@ -1343,7 +1364,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&11.\ \&infiniband setting +.B Table\ \&12.\ \&infiniband setting .TS allbox tab(:); lB lB lB lB. @@ -1364,22 +1385,13 @@ l l l l l l l l l l l l. T{ -name -T}:T{ -string -T}:T{ -infiniband -T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. -T} -T{ mac\-address T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. +If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. T} T{ mtu @@ -1391,13 +1403,13 @@ T}:T{ If non\-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames\&. T} T{ -transport\-mode +name T}:T{ string T}:T{ -\ \& +infiniband T}:T{ -The IPoIB transport mode\&. Either \*(Aqdatagram\*(Aq or \*(Aqconnected\*(Aq\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ p\-key @@ -1406,7 +1418,7 @@ int32 T}:T{ \-1 T}:T{ -The InfiniBand P_Key\&. Either \-1 for the default, or a 16\-bit unsigned integer\&. +The InfiniBand P_Key to use for this device\&. A value of \-1 means to use the default P_Key (aka "the P_Key at index 0")\&. Otherwise it is a 16\-bit unsigned integer, whose high bit is set if it is a "full membership" P_Key\&. T} T{ parent @@ -1415,7 +1427,16 @@ string T}:T{ \ \& T}:T{ -The interface name of the parent device, or NULL +The interface name of the parent device of this device\&. Normally NULL, but if the "p_key" property is set, then you must specify the base device by setting either this property or "mac\-address"\&. +T} +T{ +transport\-mode +T}:T{ +string +T}:T{ +\ \& +T}:T{ +The IP\-over\-InfiniBand transport mode\&. Either "datagram" or "connected"\&. T} .TE .sp 1 @@ -1424,7 +1445,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&12.\ \&ipv4 setting +.B Table\ \&13.\ \&ipv4 setting .TS allbox tab(:); lB lB lB lB. @@ -1451,78 +1472,81 @@ l l l l l l l l l l l l l l l l +l l l l +l l l l +l l l l l l l l. T{ -name +address\-data T}:T{ -string +array of vardict T}:T{ -ipv4 +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Array of IPv4 addresses\&. Each address dictionary contains at least \*(Aqaddress\*(Aq and \*(Aqprefix\*(Aq entries, containing the IP address as a string, and the prefix length as a uint32\&. Additional attributes may also exist on some addresses\&. T} T{ -method +addresses T}:T{ -string +array of array of uint32 T}:T{ \ \& T}:T{ -IPv4 configuration method\&. If \*(Aqauto\*(Aq is specified then the appropriate automatic method (DHCP, PPP, etc) is used for the interface and most other properties can be left unset\&. If \*(Aqlink\-local\*(Aq is specified, then a link\-local address in the 169\&.254/16 range will be assigned to the interface\&. If \*(Aqmanual\*(Aq is specified, static IP addressing is used and at least one IP address must be given in the \*(Aqaddresses\*(Aq property\&. If \*(Aqshared\*(Aq is specified (indicating that this connection will provide network access to other computers) then the interface is assigned an address in the 10\&.42\&.x\&.1/24 range and a DHCP and forwarding DNS server are started, and the interface is NAT\-ed to the current default network connection\&. \*(Aqdisabled\*(Aq means IPv4 will not be used on this connection\&. This property must be set\&. +Deprecated in favor of the \*(Aqaddress\-data\*(Aq and \*(Aqgateway\*(Aq properties, but this can be used for backward\-compatibility with older daemons\&. Note that if you send this property the daemon will ignore \*(Aqaddress\-data\*(Aq and \*(Aqgateway\*(Aq\&. Array of IPv4 address structures\&. Each IPv4 address structure is composed of 3 32\-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 \- 32), and last the IPv4 gateway (network byte order)\&. The gateway may be left as 0 if no gateway exists for that subnet\&. T} T{ -dns +dhcp\-client\-id T}:T{ -array of uint32 +string T}:T{ \ \& T}:T{ -List of DNS servers (network byte order)\&. For the \*(Aqauto\*(Aq method, these DNS servers are appended to those (if any) returned by automatic configuration\&. DNS servers cannot be used with the \*(Aqshared\*(Aq, \*(Aqlink\-local\*(Aq, or \*(Aqdisabled\*(Aq methods as there is no upstream network\&. In all other methods, these DNS servers are used as the only DNS servers for this connection\&. +A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options\&. T} T{ -dns\-search +dhcp\-hostname T}:T{ -array of string +string T}:T{ \ \& T}:T{ -List of DNS search domains\&. For the \*(Aqauto\*(Aq method, these search domains are appended to those returned by automatic configuration\&. Search domains cannot be used with the \*(Aqshared\*(Aq, \*(Aqlink\-local\*(Aq, or \*(Aqdisabled\*(Aq methods as there is no upstream network\&. In all other methods, these search domains are used as the only search domains for this connection\&. +If the "dhcp\-send\-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease\&. T} T{ -addresses +dhcp\-send\-hostname T}:T{ -array of array of uint32 +boolean T}:T{ -\ \& +TRUE T}:T{ -Array of IPv4 address structures\&. Each IPv4 address structure is composed of 3 32\-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 \- 32), and last the IPv4 gateway (network byte order)\&. The gateway may be left as 0 if no gateway exists for that subnet\&. For the \*(Aqauto\*(Aq method, given IP addresses are appended to those returned by automatic configuration\&. Addresses cannot be used with the \*(Aqshared\*(Aq, \*(Aqlink\-local\*(Aq, or \*(Aqdisabled\*(Aq methods as addressing is either automatic or disabled with these methods\&. +If TRUE, a hostname is sent to the DHCP server when acquiring a lease\&. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer\&. If the "dhcp\-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent\&. T} T{ -address\-labels +dns T}:T{ -array of string +array of uint32 T}:T{ -\ \& +[] T}:T{ -Internal use only +Array of IP addresses of DNS servers (as network\-byte\-order integers) T} T{ -routes +dns\-search T}:T{ -array of array of uint32 +array of string T}:T{ -\ \& +[] T}:T{ -Array of IPv4 route structures\&. Each IPv4 route structure is composed of 4 32\-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 \- 32), the third being the next\-hop (network byte order) if any, and the fourth being the route metric\&. For the \*(Aqauto\*(Aq method, given IP routes are appended to those returned by automatic configuration\&. Routes cannot be used with the \*(Aqshared\*(Aq, \*(Aqlink\-local\*(Aq, or \*(Aqdisabled\*(Aq, methods as there is no upstream network\&. +Array of DNS search domains\&. T} T{ -ignore\-auto\-routes +gateway T}:T{ -boolean +string T}:T{ -FALSE +\ \& T}:T{ -When the method is set to \*(Aqauto\*(Aq and this property to TRUE, automatically configured routes are ignored and only routes specified in the \*(Aqroutes\*(Aq property, if any, are used\&. +The gateway associated with this configuration\&. This is only meaningful if "addresses" is also set\&. T} T{ ignore\-auto\-dns @@ -1531,34 +1555,43 @@ boolean T}:T{ FALSE T}:T{ -When the method is set to \*(Aqauto\*(Aq and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \*(Aqdns\*(Aq and \*(Aqdns\-search\*(Aq properties, if any, are used\&. +When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns\-search" properties, if any, are used\&. T} T{ -dhcp\-client\-id +ignore\-auto\-routes T}:T{ -string +boolean T}:T{ -\ \& +FALSE T}:T{ -A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options\&. +When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used\&. T} T{ -dhcp\-send\-hostname +may\-fail T}:T{ boolean T}:T{ TRUE T}:T{ -If TRUE, a hostname is sent to the DHCP server when acquiring a lease\&. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer\&. If the \*(Aqdhcp\-hostname\*(Aq property is empty and this property is TRUE, the current persistent hostname of the computer is sent\&. +If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out\&. Note that at least one IP configuration must succeed or overall network configuration will still fail\&. For example, in IPv6\-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully\&. T} T{ -dhcp\-hostname +method T}:T{ string T}:T{ \ \& T}:T{ -If the \*(Aqdhcp\-send\-hostname\*(Aq property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease\&. +IP configuration method\&. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link\-local"\&. See the subclass\-specific documentation for other values\&. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration\&. The "ignore\-auto\-routes" and "ignore\-auto\-dns" properties modify this behavior\&. For methods that imply no upstream network, such as "shared" or "link\-local", these properties must be empty\&. +T} +T{ +name +T}:T{ +string +T}:T{ +ipv4 +T}:T{ +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ never\-default @@ -1567,16 +1600,34 @@ boolean T}:T{ FALSE T}:T{ -If TRUE, this connection will never be the default IPv4 connection, meaning it will never be assigned the default route by NetworkManager\&. +If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager\&. T} T{ -may\-fail +route\-data T}:T{ -boolean +array of vardict T}:T{ -TRUE +\ \& T}:T{ -If TRUE, allow overall network configuration to proceed even if IPv4 configuration times out\&. Note that at least one IP configuration must succeed or overall network configuration will still fail\&. For example, in IPv6\-only networks, setting this property to TRUE allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully\&. +Array of IPv4 routes\&. Each route dictionary contains at least \*(Aqdest\*(Aq and \*(Aqprefix\*(Aq entries, containing the destination IP address as a string, and the prefix length as a uint32\&. Most routes will also have a \*(Aqgateway\*(Aq entry, containing the gateway IP address as a string\&. If the route has a \*(Aqmetric\*(Aq entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device)\&. Additional attributes may also exist on some routes\&. +T} +T{ +route\-metric +T}:T{ +int64 +T}:T{ +\-1 +T}:T{ +The default metric for routes that don\*(Aqt explicitly specify a metric\&. The default value \-1 means that the metric is choosen automatically based on the device type\&. The metric applies to dynamic routes, manual (static) routes that don\*(Aqt have an explicit metric setting, address prefix routes, and the default route\&. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default)\&. Hence, setting this property to zero effectively mean setting it to 1024\&. For IPv4, zero is a regular value for the metric\&. +T} +T{ +routes +T}:T{ +array of array of uint32 +T}:T{ +\ \& +T}:T{ +Deprecated in favor of the \*(Aqroute\-data\*(Aq property, but this can be used for backward\-compatibility with older daemons\&. Note that if you send this property the daemon will ignore \*(Aqroute\-data\*(Aq\&. Array of IPv4 route structures\&. Each IPv4 route structure is composed of 4 32\-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 \- 32), the third being the next\-hop (network byte order) if any, and the fourth being the route metric\&. If the metric is 0, NM will choose an appropriate default metric for the device\&. (There is no way to explicitly specify an actual metric of 0 with this property\&.) T} .TE .sp 1 @@ -1585,7 +1636,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&13.\ \&ipv6 setting +.B Table\ \&14.\ \&ipv6 setting .TS allbox tab(:); lB lB lB lB. @@ -1610,24 +1661,29 @@ l l l l l l l l l l l l l l l l +l l l l +l l l l +l l l l +l l l l +l l l l l l l l. T{ -name +address\-data T}:T{ -string +array of vardict T}:T{ -ipv6 +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Array of IPv6 addresses\&. Each address dictionary contains at least \*(Aqaddress\*(Aq and \*(Aqprefix\*(Aq entries, containing the IP address as a string, and the prefix length as a uint32\&. Additional attributes may also exist on some addresses\&. T} T{ -method +addresses T}:T{ -string +array of legacy IPv6 address struct (a(ayuay)) T}:T{ \ \& T}:T{ -IPv6 configuration method\&. If \*(Aqauto\*(Aq is specified then the appropriate automatic method (PPP, router advertisement, etc) is used for the device and most other properties can be left unset\&. To force the use of DHCP only, specify \*(Aqdhcp\*(Aq; this method is only valid for Ethernet\-based hardware\&. If \*(Aqlink\-local\*(Aq is specified, then an IPv6 link\-local address will be assigned to the interface\&. If \*(Aqmanual\*(Aq is specified, static IP addressing is used and at least one IP address must be given in the \*(Aqaddresses\*(Aq property\&. If \*(Aqignore\*(Aq is specified, IPv6 configuration is not done\&. This property must be set\&. Note: the \*(Aqshared\*(Aq method is not yet supported\&. +Deprecated in favor of the \*(Aqaddress\-data\*(Aq and \*(Aqgateway\*(Aq properties, but this can be used for backward\-compatibility with older daemons\&. Note that if you send this property the daemon will ignore \*(Aqaddress\-data\*(Aq and \*(Aqgateway\*(Aq\&. Array of IPv6 address structures\&. Each IPv6 address structure is composed of an IPv6 address, a prefix length (1 \- 128), and an IPv6 gateway address\&. The gateway may be zeroed out if no gateway exists for that subnet\&. T} T{ dhcp\-hostname @@ -1636,43 +1692,52 @@ string T}:T{ \ \& T}:T{ -The specified name will be sent to the DHCP server when acquiring a lease\&. +If the "dhcp\-send\-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease\&. +T} +T{ +dhcp\-send\-hostname +T}:T{ +boolean +T}:T{ +TRUE +T}:T{ +If TRUE, a hostname is sent to the DHCP server when acquiring a lease\&. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer\&. If the "dhcp\-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent\&. T} T{ dns T}:T{ array of byte array T}:T{ -\ \& +[] T}:T{ -Array of DNS servers, where each member of the array is a byte array containing the IPv6 address of the DNS server (in network byte order)\&. For the \*(Aqauto\*(Aq method, these DNS servers are appended to those (if any) returned by automatic configuration\&. DNS servers cannot be used with the \*(Aqshared\*(Aq or \*(Aqlink\-local\*(Aq methods as there is no usptream network\&. In all other methods, these DNS servers are used as the only DNS servers for this connection\&. +Array of IP addresses of DNS servers (in network byte order) T} T{ dns\-search T}:T{ array of string T}:T{ -\ \& +[] T}:T{ -List of DNS search domains\&. For the \*(Aqauto\*(Aq method, these search domains are appended to those returned by automatic configuration\&. Search domains cannot be used with the \*(Aqshared\*(Aq or \*(Aqlink\-local\*(Aq methods as there is no upstream network\&. In all other methods, these search domains are used as the only search domains for this connection\&. +Array of DNS search domains\&. T} T{ -addresses +gateway T}:T{ -array of (byte array, uint32, byte array) +string T}:T{ \ \& T}:T{ -Array of IPv6 address structures\&. Each IPv6 address structure is composed of 3 members, the first being a byte array containing the IPv6 address (network byte order), the second a 32\-bit integer containing the IPv6 address prefix, and the third a byte array containing the IPv6 address (network byte order) of the gateway associated with this address, if any\&. If no gateway is given, the third element should be given as all zeros\&. For the \*(Aqauto\*(Aq method, given IP addresses are appended to those returned by automatic configuration\&. Addresses cannot be used with the \*(Aqshared\*(Aq or \*(Aqlink\-local\*(Aq methods as the interface is automatically assigned an address with these methods\&. +The gateway associated with this configuration\&. This is only meaningful if "addresses" is also set\&. T} T{ -routes +ignore\-auto\-dns T}:T{ -array of (byte array, uint32, byte array, uint32) +boolean T}:T{ -\ \& +FALSE T}:T{ -Array of IPv6 route structures\&. Each IPv6 route structure is composed of 4 members; the first being the destination IPv6 network or address (network byte order) as a byte array, the second the destination network or address IPv6 prefix, the third being the next\-hop IPv6 address (network byte order) if any, and the fourth being the route metric\&. For the \*(Aqauto\*(Aq method, given IP routes are appended to those returned by automatic configuration\&. Routes cannot be used with the \*(Aqshared\*(Aq or \*(Aqlink\-local\*(Aq methods because there is no upstream network\&. +When "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns\-search" properties, if any, are used\&. T} T{ ignore\-auto\-routes @@ -1681,16 +1746,43 @@ boolean T}:T{ FALSE T}:T{ -When the method is set to \*(Aqauto\*(Aq or \*(Aqdhcp\*(Aq and this property is set to TRUE, automatically configured routes are ignored and only routes specified in the \*(Aqroutes\*(Aq property, if any, are used\&. +When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used\&. T} T{ -ignore\-auto\-dns +ip6\-privacy +T}:T{ +NMSettingIP6ConfigPrivacy (int32) +T}:T{ +\ \& +T}:T{ +Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941\&. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI\-64\&. This enhances privacy, but could cause problems in some applications, on the other hand\&. The permitted values are: 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses)\&. +T} +T{ +may\-fail T}:T{ boolean T}:T{ -FALSE +TRUE +T}:T{ +If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out\&. Note that at least one IP configuration must succeed or overall network configuration will still fail\&. For example, in IPv6\-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully\&. +T} +T{ +method +T}:T{ +string +T}:T{ +\ \& +T}:T{ +IP configuration method\&. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link\-local"\&. See the subclass\-specific documentation for other values\&. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration\&. The "ignore\-auto\-routes" and "ignore\-auto\-dns" properties modify this behavior\&. For methods that imply no upstream network, such as "shared" or "link\-local", these properties must be empty\&. +T} +T{ +name +T}:T{ +string +T}:T{ +ipv6 T}:T{ -When the method is set to \*(Aqauto\*(Aq or \*(Aqdhcp\*(Aq and this property is set to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \*(Aqdns\*(Aq and \*(Aqdns\-search\*(Aq properties, if any, are used\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ never\-default @@ -1699,25 +1791,34 @@ boolean T}:T{ FALSE T}:T{ -If TRUE, this connection will never be the default IPv6 connection, meaning it will never be assigned the default IPv6 route by NetworkManager\&. +If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager\&. T} T{ -may\-fail +route\-data T}:T{ -boolean +array of vardict T}:T{ -TRUE +\ \& T}:T{ -If TRUE, allow overall network configuration to proceed even if IPv6 configuration times out\&. Note that at least one IP configuration must succeed or overall network configuration will still fail\&. For example, in IPv4\-only networks, setting this property to TRUE allows the overall network configuration to succeed if IPv6 configuration fails but IPv4 configuration completes successfully\&. +Array of IPv6 routes\&. Each route dictionary contains at least \*(Aqdest\*(Aq and \*(Aqprefix\*(Aq entries, containing the destination IP address as a string, and the prefix length as a uint32\&. Most routes will also have a \*(Aqnext\-hop\*(Aq entry, containing the next hop IP address as a string\&. If the route has a \*(Aqmetric\*(Aq entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device)\&. Additional attributes may also exist on some routes\&. T} T{ -ip6\-privacy +route\-metric T}:T{ -int32 +int64 T}:T{ \-1 T}:T{ -Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941\&. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI\-64\&. This enhances privacy, but could cause problems in some applications, on the other hand\&. The permitted values are: 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses)\&. +The default metric for routes that don\*(Aqt explicitly specify a metric\&. The default value \-1 means that the metric is choosen automatically based on the device type\&. The metric applies to dynamic routes, manual (static) routes that don\*(Aqt have an explicit metric setting, address prefix routes, and the default route\&. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default)\&. Hence, setting this property to zero effectively mean setting it to 1024\&. For IPv4, zero is a regular value for the metric\&. +T} +T{ +routes +T}:T{ +array of legacy IPv6 route struct (a(ayuayu)) +T}:T{ +\ \& +T}:T{ +Deprecated in favor of the \*(Aqroute\-data\*(Aq property, but this can be used for backward\-compatibility with older daemons\&. Note that if you send this property the daemon will ignore \*(Aqroute\-data\*(Aq\&. Array of IPv6 route structures\&. Each IPv6 route structure is composed of an IPv6 address, a prefix length (1 \- 128), an IPv6 next hop address (which may be zeroed out if there is no next hop), and a metric\&. If the metric is 0, NM will choose an appropriate default metric for the device\&. T} .TE .sp 1 @@ -1726,7 +1827,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&14.\ \&802-11-olpc-mesh setting +.B Table\ \&15.\ \&802-11-olpc-mesh setting .TS allbox tab(:); lB lB lB lB. @@ -1745,40 +1846,40 @@ l l l l l l l l l l l l. T{ -name +channel T}:T{ -string +uint32 T}:T{ -802\-11\-olpc\-mesh +0 T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +Channel on which the mesh network to join is located\&. T} T{ -ssid +dhcp\-anycast\-address T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -SSID of the mesh network to join\&. +Anycast DHCP MAC address used when requesting an IP address via DHCP\&. The specific anycast address used determines which DHCP server class answers the request\&. T} T{ -channel +name T}:T{ -uint32 +string T}:T{ -0 +802\-11\-olpc\-mesh T}:T{ -Channel on which the mesh network to join is located\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -dhcp\-anycast\-address +ssid T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -Anycast DHCP MAC address used when requesting an IP address via DHCP\&. The specific anycast address used determines which DHCP server class answers the the request\&. +SSID of the mesh network to join\&. T} .TE .sp 1 @@ -1787,7 +1888,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&15.\ \&ppp setting +.B Table\ \&16.\ \&ppp setting .TS allbox tab(:); lB lB lB lB. @@ -1821,175 +1922,175 @@ l l l l l l l l l l l l. T{ -name +baud T}:T{ -string +uint32 T}:T{ -ppp +0 T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +If non\-zero, instruct pppd to set the serial port to the specified baudrate\&. This value should normally be left as 0 to automatically choose the speed\&. T} T{ -noauth +crtscts T}:T{ boolean T}:T{ -TRUE +FALSE T}:T{ -If TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client\&. If FALSE, require authentication from the remote side\&. In almost all cases, this should be TRUE\&. +If TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals\&. This value should normally be set to FALSE\&. T} T{ -refuse\-eap +lcp\-echo\-failure T}:T{ -boolean +uint32 T}:T{ -FALSE +0 T}:T{ -If TRUE, the EAP authentication method will not be used\&. +If non\-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo\-requests go unanswered by the peer\&. The "lcp\-echo\-interval" property must also be set to a non\-zero value if this property is used\&. T} T{ -refuse\-pap +lcp\-echo\-interval T}:T{ -boolean +uint32 T}:T{ -FALSE +0 T}:T{ -If TRUE, the PAP authentication method will not be used\&. +If non\-zero, instruct pppd to send an LCP echo\-request frame to the peer every n seconds (where n is the specified value)\&. Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this\&. T} T{ -refuse\-chap +mppe\-stateful T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, the CHAP authentication method will not be used\&. +If TRUE, stateful MPPE is used\&. See pppd documentation for more information on stateful MPPE\&. T} T{ -refuse\-mschap +mru T}:T{ -boolean +uint32 T}:T{ -FALSE +0 T}:T{ -If TRUE, the MSCHAP authentication method will not be used\&. +If non\-zero, instruct pppd to request that the peer send packets no larger than the specified size\&. If non\-zero, the MRU should be between 128 and 16384\&. T} T{ -refuse\-mschapv2 +mtu T}:T{ -boolean +uint32 T}:T{ -FALSE +0 T}:T{ -If TRUE, the MSCHAPv2 authentication method will not be used\&. +If non\-zero, instruct pppd to send packets no larger than the specified size\&. T} T{ -nobsdcomp +name T}:T{ -boolean +string T}:T{ -FALSE +ppp T}:T{ -If TRUE, BSD compression will not be requested\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -nodeflate +no\-vj\-comp T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, \*(Aqdeflate\*(Aq compression will not be requested\&. +If TRUE, Van Jacobsen TCP header compression will not be requested\&. T} T{ -no\-vj\-comp +noauth T}:T{ boolean T}:T{ -FALSE +TRUE T}:T{ -If TRUE, Van Jacobsen TCP header compression will not be requested\&. +If TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client\&. If FALSE, require authentication from the remote side\&. In almost all cases, this should be TRUE\&. T} T{ -require\-mppe +nobsdcomp T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, MPPE (Microsoft Point\-to\-Point Encrpytion) will be required for the PPP session\&. If either 64\-bit or 128\-bit MPPE is not available the session will fail\&. Note that MPPE is not used on mobile broadband connections\&. +If TRUE, BSD compression will not be requested\&. T} T{ -require\-mppe\-128 +nodeflate T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, 128\-bit MPPE (Microsoft Point\-to\-Point Encrpytion) will be required for the PPP session, and the \*(Aqrequire\-mppe\*(Aq property must also be set to TRUE\&. If 128\-bit MPPE is not available the session will fail\&. +If TRUE, "deflate" compression will not be requested\&. T} T{ -mppe\-stateful +refuse\-chap T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, stateful MPPE is used\&. See pppd documentation for more information on stateful MPPE\&. +If TRUE, the CHAP authentication method will not be used\&. T} T{ -crtscts +refuse\-eap T}:T{ boolean T}:T{ FALSE T}:T{ -If TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals\&. This value should normally be set to FALSE\&. +If TRUE, the EAP authentication method will not be used\&. T} T{ -baud +refuse\-mschap T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -If non\-zero, instruct pppd to set the serial port to the specified baudrate\&. This value should normally be left as 0 to automatically choose the speed\&. +If TRUE, the MSCHAP authentication method will not be used\&. T} T{ -mru +refuse\-mschapv2 T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -If non\-zero, instruct pppd to request that the peer send packets no larger than the specified size\&. If non\-zero, the MRU should be between 128 and 16384\&. +If TRUE, the MSCHAPv2 authentication method will not be used\&. T} T{ -mtu +refuse\-pap T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -If non\-zero, instruct pppd to send packets no larger than the specified size\&. +If TRUE, the PAP authentication method will not be used\&. T} T{ -lcp\-echo\-failure +require\-mppe T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -If non\-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo\-requests go unanswered by the peer\&. The \*(Aqlcp\-echo\-interval\*(Aq property must also be set to a non\-zero value if this property is used\&. +If TRUE, MPPE (Microsoft Point\-to\-Point Encrpytion) will be required for the PPP session\&. If either 64\-bit or 128\-bit MPPE is not available the session will fail\&. Note that MPPE is not used on mobile broadband connections\&. T} T{ -lcp\-echo\-interval +require\-mppe\-128 T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -If non\-zero, instruct pppd to send an LCP echo\-request frame to the peer every n seconds (where n is the specified value)\&. Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this\&. +If TRUE, 128\-bit MPPE (Microsoft Point\-to\-Point Encrpytion) will be required for the PPP session, and the "require\-mppe" property must also be set to TRUE\&. If 128\-bit MPPE is not available the session will fail\&. T} .TE .sp 1 @@ -1998,7 +2099,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&16.\ \&pppoe setting +.B Table\ \&17.\ \&pppoe setting .TS allbox tab(:); lB lB lB lB. @@ -2024,43 +2125,43 @@ string T}:T{ pppoe T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -service +password T}:T{ string T}:T{ \ \& T}:T{ -If specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service\&. For most providers, this should be left blank\&. It is only required if there are multiple access concentrators or a specific service is known to be required\&. +Password used to authenticate with the PPPoE service\&. T} T{ -username +password\-flags T}:T{ -string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -Username used to authenticate with the PPPoE service\&. +Flags indicating how to handle the "password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -password +service T}:T{ string T}:T{ \ \& T}:T{ -Password used to authenticate with the PPPoE service\&. +If specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service\&. For most providers, this should be left blank\&. It is only required if there are multiple access concentrators or a specific service is known to be required\&. T} T{ -password\-flags +username T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the PPPoE password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Username used to authenticate with the PPPoE service\&. T} .TE .sp 1 @@ -2069,7 +2170,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&17.\ \&serial setting +.B Table\ \&18.\ \&serial setting .TS allbox tab(:); lB lB lB lB. @@ -2090,15 +2191,6 @@ l l l l l l l l l l l l. T{ -name -T}:T{ -string -T}:T{ -serial -T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. -T} -T{ baud T}:T{ uint32 @@ -2114,25 +2206,25 @@ uint32 T}:T{ 8 T}:T{ -Byte\-width of the serial communication\&. The 8 in \*(Aq8n1\*(Aq for example\&. +Byte\-width of the serial communication\&. The 8 in "8n1" for example\&. T} T{ -parity +name T}:T{ -gchar +string T}:T{ -110 +serial T}:T{ -Parity setting of the serial port\&. Either \*(AqE\*(Aq for even parity, \*(Aqo\*(Aq for odd parity, or \*(Aqn\*(Aq for no parity\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -stopbits +parity T}:T{ -uint32 +byte T}:T{ -1 +\ \& T}:T{ -Number of stop bits for communication on the serial port\&. Either 1 or 2\&. The 1 in \*(Aq8n1\*(Aq for example\&. +The connection parity: 69 (ASCII \*(AqE\*(Aq) for even parity, 111 (ASCII \*(Aqo\*(Aq) for odd, 110 (ASCII \*(Aqn\*(Aq) for none\&. T} T{ send\-delay @@ -2143,6 +2235,15 @@ T}:T{ T}:T{ Time to delay between each byte sent to the modem, in microseconds\&. T} +T{ +stopbits +T}:T{ +uint32 +T}:T{ +1 +T}:T{ +Number of stop bits for communication on the serial port\&. Either 1 or 2\&. The 1 in "8n1" for example\&. +T} .TE .sp 1 .sp @@ -2150,7 +2251,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&18.\ \&team setting +.B Table\ \&19.\ \&team setting .TS allbox tab(:); lB lB lB lB. @@ -2168,13 +2269,13 @@ l l l l l l l l l l l l. T{ -name +config T}:T{ string T}:T{ -team +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The JSON configuration for the team network interface\&. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd\&. If not specified, the default configuration is used\&. See man teamd\&.conf for the format details\&. T} T{ interface\-name @@ -2183,16 +2284,16 @@ string T}:T{ \ \& T}:T{ -The name of the virtual in\-kernel team network interface +Deprecated in favor of connection\&.interface\-name, but can be used for backward\-compatibility with older daemons, to set the team\*(Aqs interface name\&. T} T{ -config +name T}:T{ string T}:T{ -\ \& +team T}:T{ -JSON configuration for the team network interface\&. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd\&. If not specified, the default configuration is used\&. See man teamd\&.conf for the format details\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} .TE .sp 1 @@ -2201,7 +2302,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&19.\ \&team-port setting +.B Table\ \&20.\ \&team-port setting .TS allbox tab(:); lB lB lB lB. @@ -2218,22 +2319,22 @@ T} l l l l l l l l. T{ -name +config T}:T{ string T}:T{ -team\-port +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The JSON configuration for the team port\&. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd\&. If not specified, the default configuration is used\&. See man teamd\&.conf for the format details\&. T} T{ -config +name T}:T{ string T}:T{ -\ \& +team\-port T}:T{ -JSON configuration for the team port\&. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd\&. If not specified, the dafault configuration is used\&. See man teamd\&.conf for the format details\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} .TE .sp 1 @@ -2242,7 +2343,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&20.\ \&vlan setting +.B Table\ \&21.\ \&vlan setting .TS allbox tab(:); lB lB lB lB. @@ -2264,67 +2365,67 @@ l l l l l l l l l l l l. T{ -name +egress\-priority\-map T}:T{ -string +array of string T}:T{ -vlan +[] T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +For outgoing packets, a list of mappings from Linux SKB priorities to 802\&.1p priorities\&. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"\&. T} T{ -interface\-name +flags T}:T{ -string +NMVlanFlags (uint32) T}:T{ \ \& T}:T{ -If given, specifies the kernel name of the VLAN interface\&. If not given, a default name will be constructed from the interface described by the parent interface and the \*(Aqid\*(Aq property, ex \*(Aqeth2\&.1\*(Aq\&. The parent interface may be given by the \*(Aqparent\*(Aq property or by the \*(Aqmac\-address\*(Aq property of a \*(Aqwired\*(Aq setting\&. +One or more flags which control the behavior and features of the VLAN interface\&. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device\*(Aqs operating state)\&. T} T{ -parent +id T}:T{ -string +uint32 T}:T{ -\ \& +0 T}:T{ -If given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created\&. If this property is not specified, the connection must contain a \*(Aqwired\*(Aq setting with a \*(Aqmac\-address\*(Aq property\&. +The VLAN identifier that the interface created by this connection should be assigned\&. T} T{ -id +ingress\-priority\-map T}:T{ -uint32 +array of string T}:T{ -0 +[] T}:T{ -The VLAN indentifier the interface created by this connection should be assigned\&. +For incoming packets, a list of mappings from 802\&.1p priorities to Linux SKB priorities\&. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3"\&. T} T{ -flags +interface\-name T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -One or more flags which control the behavior and features of the VLAN interface\&. Flags include reordering of output packet headers (0x01), use of the GVRP protocol (0x02), and loose binding of the interface to its master device\*(Aqs operating state (0x04)\&. +Deprecated in favor of connection\&.interface\-name, but can be used for backward\-compatibility with older daemons, to set the vlan\*(Aqs interface name\&. T} T{ -ingress\-priority\-map +name T}:T{ -array of string +string T}:T{ -\ \& +vlan T}:T{ -For incoming packets, a list of mappings from 802\&.1p priorities to Linux SKB priorities\&. The mapping is given in the format \*(Aqfrom:to\*(Aq where both \*(Aqfrom\*(Aq and \*(Aqto\*(Aq are unsigned integers, ie \*(Aq7:3\*(Aq\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -egress\-priority\-map +parent T}:T{ -array of string +string T}:T{ \ \& T}:T{ -For outgoing packets, a list of mappings from Linux SKB priorities to 802\&.1p priorities\&. The mapping is given in the format \*(Aqfrom:to\*(Aq where both \*(Aqfrom\*(Aq and \*(Aqto\*(Aq are unsigned integers, ie \*(Aq7:3\*(Aq\&. +If given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created\&. If this property is not specified, the connection must contain an "802\-3\-ethernet" setting with a "mac\-address" property\&. T} .TE .sp 1 @@ -2333,7 +2434,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&21.\ \&vpn setting +.B Table\ \&22.\ \&vpn setting .TS allbox tab(:); lB lB lB lB. @@ -2351,51 +2452,61 @@ l l l l l l l l l l l l l l l l +l l l l l l l l. T{ +data +T}:T{ +dict of string to string +T}:T{ +\ \& +T}:T{ +Dictionary of key/value pairs of VPN plugin specific data\&. Both keys and values must be strings\&. +T} +T{ name T}:T{ string T}:T{ vpn T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -service\-type +persistent T}:T{ -string +boolean T}:T{ -\ \& +FALSE T}:T{ -D\-Bus service name of the VPN plugin that this setting uses to connect to its network\&. i\&.e\&. org\&.freedesktop\&.NetworkManager\&.vpnc for the vpnc plugin\&. +If the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected\&. T} T{ -user\-name +secrets T}:T{ -string +dict of string to string T}:T{ \ \& T}:T{ -If the VPN connection requires a user name for authentication, that name should be provided here\&. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty\&. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection\&. +Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys\&. Both keys and values must be strings\&. T} T{ -data +service\-type T}:T{ -dict of (string::string) +string T}:T{ \ \& T}:T{ -Dictionary of key/value pairs of VPN plugin specific data\&. Both keys and values must be strings\&. +D\-Bus service name of the VPN plugin that this setting uses to connect to its network\&. i\&.e\&. org\&.freedesktop\&.NetworkManager\&.vpnc for the vpnc plugin\&. T} T{ -secrets +user\-name T}:T{ -dict of (string::string) +string T}:T{ \ \& T}:T{ -Dictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys\&. Both keys and values must be strings\&. +If the VPN connection requires a user name for authentication, that name should be provided here\&. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty\&. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection\&. T} .TE .sp 1 @@ -2404,7 +2515,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&22.\ \&wimax setting +.B Table\ \&23.\ \&wimax setting .TS allbox tab(:); lB lB lB lB. @@ -2422,13 +2533,22 @@ l l l l l l l l l l l l. T{ +mac\-address +T}:T{ +byte array +T}:T{ +\ \& +T}:T{ +If specified, this connection will only apply to the WiMAX device whose MAC address matches\&. This property does not change the MAC address of the device (known as MAC spoofing)\&. +T} +T{ name T}:T{ string T}:T{ wimax T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ network\-name @@ -2439,15 +2559,6 @@ T}:T{ T}:T{ Network Service Provider (NSP) name of the WiMAX network this connection should use\&. T} -T{ -mac\-address -T}:T{ -byte array -T}:T{ -[] -T}:T{ -If specified, this connection will only apply to the WiMAX device whose MAC address matches\&. This property does not change the MAC address of the device (known as MAC spoofing)\&. -T} .TE .sp 1 .sp @@ -2455,7 +2566,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&23.\ \&802-3-ethernet setting +.B Table\ \&24.\ \&802-3-ethernet setting .TS allbox tab(:); lB lB lB lB. @@ -2482,31 +2593,22 @@ l l l l l l l l l l l l. T{ -name +auto\-negotiate T}:T{ -string +boolean T}:T{ -802\-3\-ethernet +TRUE T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +If TRUE, allow auto\-negotiation of port speed and duplex mode\&. If FALSE, do not allow auto\-negotiation, in which case the "speed" and "duplex" properties should be set\&. T} T{ -port +cloned\-mac\-address T}:T{ -string +byte array T}:T{ \ \& T}:T{ -Specific port type to use if multiple the device supports multiple attachment methods\&. One of \*(Aqtp\*(Aq (Twisted Pair), \*(Aqaui\*(Aq (Attachment Unit Interface), \*(Aqbnc\*(Aq (Thin Ethernet) or \*(Aqmii\*(Aq (Media Independent Interface\&. If the device supports only one port type, this setting is ignored\&. -T} -T{ -speed -T}:T{ -uint32 -T}:T{ -0 -T}:T{ -If non\-zero, request that the device use only the specified speed\&. In Mbit/s, ie 100 == 100Mbit/s\&. +If specified, request that the device use this MAC address instead of its permanent MAC address\&. This is known as MAC cloning or spoofing\&. T} T{ duplex @@ -2515,41 +2617,23 @@ string T}:T{ \ \& T}:T{ -If specified, request that the device only use the specified duplex mode\&. Either \*(Aqhalf\*(Aq or \*(Aqfull\*(Aq\&. -T} -T{ -auto\-negotiate -T}:T{ -boolean -T}:T{ -TRUE -T}:T{ -If TRUE, allow auto\-negotiation of port speed and duplex mode\&. If FALSE, do not allow auto\-negotiation,in which case the \*(Aqspeed\*(Aq and \*(Aqduplex\*(Aq properties should be set\&. +If specified, request that the device only use the specified duplex mode\&. Either "half" or "full"\&. T} T{ mac\-address T}:T{ byte array T}:T{ -[] -T}:T{ -If specified, this connection will only apply to the Ethernet device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. -T} -T{ -cloned\-mac\-address -T}:T{ -byte array -T}:T{ -[] +\ \& T}:T{ -If specified, request that the device use this MAC address instead of its permanent MAC address\&. This is known as MAC cloning or spoofing\&. +If specified, this connection will only apply to the Ethernet device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. T} T{ mac\-address\-blacklist T}:T{ array of string T}:T{ -\ \& +[] T}:T{ If specified, this connection will never apply to the Ethernet device whose permanent MAC address matches an address in the list\&. Each MAC address is in the standard hex\-digits\-and\-colons notation (00:11:22:33:44:55)\&. T} @@ -2563,13 +2647,22 @@ T}:T{ If non\-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames\&. T} T{ -s390\-subchannels +name T}:T{ -array of string +string +T}:T{ +802\-3\-ethernet +T}:T{ +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. +T} +T{ +port +T}:T{ +string T}:T{ \ \& T}:T{ -Identifies specific subchannels that this network device uses for communcation with z/VM or s390 host\&. Like the \*(Aqmac\-address\*(Aq property for non\-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels\&. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (\&.) character\&. +Specific port type to use if multiple the device supports multiple attachment methods\&. One of "tp" (Twisted Pair), "aui" (Attachment Unit Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface\&. If the device supports only one port type, this setting is ignored\&. T} T{ s390\-nettype @@ -2578,16 +2671,34 @@ string T}:T{ \ \& T}:T{ -s390 network device type; one of \*(Aqqeth\*(Aq, \*(Aqlcs\*(Aq, or \*(Aqctc\*(Aq, representing the different types of virtual network devices available on s390 systems\&. +s390 network device type; one of "qeth", "lcs", or "ctc", representing the different types of virtual network devices available on s390 systems\&. T} T{ s390\-options T}:T{ -dict of (string::string) +dict of string to string T}:T{ \ \& T}:T{ -Dictionary of key/value pairs of s390\-specific device options\&. Both keys and values must be strings\&. Allowed keys include \*(Aqportno\*(Aq, \*(Aqlayer2\*(Aq, \*(Aqportname\*(Aq, \*(Aqprotocol\*(Aq, among others\&. +Dictionary of key/value pairs of s390\-specific device options\&. Both keys and values must be strings\&. Allowed keys include "portno", "layer2", "portname", "protocol", among others\&. Key names must contain only alphanumeric characters (ie, [a\-zA\-Z0\-9])\&. +T} +T{ +s390\-subchannels +T}:T{ +array of string +T}:T{ +[] +T}:T{ +Identifies specific subchannels that this network device uses for communication with z/VM or s390 host\&. Like the "mac\-address" property for non\-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels\&. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (\&.) character\&. +T} +T{ +speed +T}:T{ +uint32 +T}:T{ +0 +T}:T{ +If non\-zero, request that the device use only the specified speed\&. In Mbit/s, ie 100 == 100Mbit/s\&. T} .TE .sp 1 @@ -2596,7 +2707,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&24.\ \&802-11-wireless setting +.B Table\ \&25.\ \&802-11-wireless setting .TS allbox tab(:); lB lB lB lB. @@ -2626,139 +2737,139 @@ l l l l l l l l l l l l. T{ -name +band T}:T{ string T}:T{ -802\-11\-wireless +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +802\&.11 frequency band of the network\&. One of "a" for 5GHz 802\&.11a or "bg" for 2\&.4GHz 802\&.11\&. This will lock associations to the Wi\-Fi network to the specific band, i\&.e\&. if "a" is specified, the device will not associate with the same network in the 2\&.4GHz band even if the network\*(Aqs settings are compatible\&. This setting depends on specific driver capability and may not work with all drivers\&. T} T{ -ssid +bssid T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -SSID of the Wi\-Fi network\&. Must be specified\&. +If specified, directs the device to only associate with the given access point\&. This capability is highly driver dependent and not supported by all devices\&. Note: this property does not control the BSSID used when creating an Ad\-Hoc network and is unlikely to in the future\&. T} T{ -mode +channel T}:T{ -string +uint32 T}:T{ -\ \& +0 T}:T{ -Wi\-Fi network mode; one of \*(Aqinfrastructure\*(Aq, \*(Aqadhoc\*(Aq or \*(Aqap\*(Aq\&. If blank, infrastructure is assumed\&. +Wireless channel to use for the Wi\-Fi connection\&. The device will only join (or create for Ad\-Hoc networks) a Wi\-Fi network on the specified channel\&. Because channel numbers overlap between bands, this property also requires the "band" property to be set\&. T} T{ -band +cloned\-mac\-address T}:T{ -string +byte array T}:T{ \ \& T}:T{ -802\&.11 frequency band of the network\&. One of \*(Aqa\*(Aq for 5GHz 802\&.11a or \*(Aqbg\*(Aq for 2\&.4GHz 802\&.11\&. This will lock associations to the Wi\-Fi network to the specific band, i\&.e\&. if \*(Aqa\*(Aq is specified, the device will not associate with the same network in the 2\&.4GHz band even if the network\*(Aqs settings are compatible\&. This setting depends on specific driver capability and may not work with all drivers\&. +If specified, request that the Wi\-Fi device use this MAC address instead of its permanent MAC address\&. This is known as MAC cloning or spoofing\&. T} T{ -channel +hidden T}:T{ -uint32 +boolean T}:T{ -0 +FALSE T}:T{ -Wireless channel to use for the Wi\-Fi connection\&. The device will only join (or create for Ad\-Hoc networks) a Wi\-Fi network on the specified channel\&. Because channel numbers overlap between bands, this property also requires the \*(Aqband\*(Aq property to be set\&. +If TRUE, indicates this network is a non\-broadcasting network that hides its SSID\&. In this case various workarounds may take place, such as probe\-scanning the SSID for more reliable network discovery\&. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution\&. T} T{ -bssid +mac\-address T}:T{ byte array T}:T{ -[] +\ \& T}:T{ -If specified, directs the device to only associate with the given access point\&. This capability is highly driver dependent and not supported by all devices\&. Note: this property does not control the BSSID used when creating an Ad\-Hoc network and is unlikely to in the future\&. +If specified, this connection will only apply to the Wi\-Fi device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. T} T{ -rate +mac\-address\-blacklist T}:T{ -uint32 +array of string T}:T{ -0 +[] T}:T{ -If non\-zero, directs the device to only use the specified bitrate for communication with the access point\&. Units are in Kb/s, ie 5500 = 5\&.5 Mbit/s\&. This property is highly driver dependent and not all devices support setting a static bitrate\&. +A list of permanent MAC addresses of Wi\-Fi devices to which this connection should never apply\&. Each MAC address should be given in the standard hex\-digits\-and\-colons notation (eg "00:11:22:33:44:55")\&. T} T{ -tx\-power +mode T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -If non\-zero, directs the device to use the specified transmit power\&. Units are dBm\&. This property is highly driver dependent and not all devices support setting a static transmit power\&. +Wi\-Fi network mode; one of "infrastructure", "adhoc" or "ap"\&. If blank, infrastructure is assumed\&. T} T{ -mac\-address +mtu T}:T{ -byte array +uint32 T}:T{ -[] +0 T}:T{ -If specified, this connection will only apply to the Wi\-Fi device whose permanent MAC address matches\&. This property does not change the MAC address of the device (i\&.e\&. MAC spoofing)\&. +If non\-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames\&. T} T{ -cloned\-mac\-address +name T}:T{ -byte array +string T}:T{ -[] +802\-11\-wireless T}:T{ -If specified, request that the Wi\-Fi device use this MAC address instead of its permanent MAC address\&. This is known as MAC cloning or spoofing\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -mac\-address\-blacklist +rate T}:T{ -array of string +uint32 T}:T{ -\ \& +0 T}:T{ -A list of permanent MAC addresses of Wi\-Fi devices to which this connection should never apply\&. Each MAC address should be given in the standard hex\-digits\-and\-colons notation (eg \*(Aq00:11:22:33:44:55\*(Aq)\&. +If non\-zero, directs the device to only use the specified bitrate for communication with the access point\&. Units are in Kb/s, ie 5500 = 5\&.5 Mbit/s\&. This property is highly driver dependent and not all devices support setting a static bitrate\&. T} T{ -mtu +security T}:T{ -uint32 +None T}:T{ -0 +\ \& T}:T{ -If non\-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames\&. +This property is deprecated, but can be set to the value \*(Aq802\-11\-wireless\-security\*(Aq when a wireless security setting is also present in the connection dictionary, for compatibility with very old NetworkManager daemons\&. T} T{ seen\-bssids T}:T{ array of string T}:T{ -\ \& +[] T}:T{ -A list of BSSIDs (each BSSID formatted as a MAC address like 00:11:22:33:44:55\*(Aq) that have been detected as part of the Wi\-Fi network\&. NetworkManager internally tracks previously seen BSSIDs\&. The property is only meant for reading and reflects the BSSID list of NetworkManager\&. The changes you make to this property will not be preserved\&. +A list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi\-Fi network\&. NetworkManager internally tracks previously seen BSSIDs\&. The property is only meant for reading and reflects the BSSID list of NetworkManager\&. The changes you make to this property will not be preserved\&. T} T{ -security +ssid T}:T{ -string +byte array T}:T{ \ \& T}:T{ -If the wireless connection has any security restrictions, like 802\&.1x, WEP, or WPA, set this property to \*(Aq802\-11\-wireless\-security\*(Aq and ensure the connection contains a valid 802\-11\-wireless\-security setting\&. +SSID of the Wi\-Fi network\&. Must be specified\&. T} T{ -hidden +tx\-power T}:T{ -boolean +uint32 T}:T{ -FALSE +0 T}:T{ -If TRUE, indicates this network is a non\-broadcasting network that hides its SSID\&. In this case various workarounds may take place, such as probe\-scanning the SSID for more reliable network discovery\&. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution\&. +If non\-zero, directs the device to use the specified transmit power\&. Units are dBm\&. This property is highly driver dependent and not all devices support setting a static transmit power\&. T} .TE .sp 1 @@ -2767,7 +2878,7 @@ T} .nr an-no-space-flag 1 .nr an-break-flag 1 .br -.B Table\ \&25.\ \&802-11-wireless-security setting +.B Table\ \&26.\ \&802-11-wireless-security setting .TS allbox tab(:); lB lB lB lB. @@ -2800,166 +2911,166 @@ l l l l l l l l l l l l. T{ -name +auth\-alg T}:T{ string T}:T{ -802\-11\-wireless\-security +\ \& T}:T{ -The setting\*(Aqs name; these names are defined by the specification and cannot be changed after the object has been created\&. Each setting class has a name, and all objects of that class share the same name\&. +When WEP is used (ie, key\-mgmt = "none" or "ieee8021x") indicate the 802\&.11 authentication algorithm required by the AP here\&. One of "open" for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP\&. When using Cisco LEAP (ie, key\-mgmt = "ieee8021x" and auth\-alg = "leap") the "leap\-username" and "leap\-password" properties must be specified\&. T} T{ -key\-mgmt +group T}:T{ -string +array of string T}:T{ -\ \& +[] T}:T{ -Key management used for the connection\&. One of \*(Aqnone\*(Aq (WEP), \*(Aqieee8021x\*(Aq (Dynamic WEP), \*(Aqwpa\-none\*(Aq (WPA\-PSK Ad\-Hoc), \*(Aqwpa\-psk\*(Aq (infrastructure WPA\-PSK), or \*(Aqwpa\-eap\*(Aq (WPA\-Enterprise)\&. This property must be set for any Wi\-Fi connection that uses security\&. +A list of group/broadcast encryption algorithms which prevents connections to Wi\-Fi networks that do not utilize one of the algorithms in the list\&. For maximum compatibility leave this property empty\&. Each list element may be one of "wep40", "wep104", "tkip", or "ccmp"\&. T} T{ -wep\-tx\-keyidx +key\-mgmt T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -When static WEP is used (ie, key\-mgmt = \*(Aqnone\*(Aq) and a non\-default WEP key index is used by the AP, put that WEP key index here\&. Valid values are 0 (default key) through 3\&. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 \- 4\&. +Key management used for the connection\&. One of "none" (WEP), "ieee8021x" (Dynamic WEP), "wpa\-none" (Ad\-Hoc WPA\-PSK), "wpa\-psk" (infrastructure WPA\-PSK), or "wpa\-eap" (WPA\-Enterprise)\&. This property must be set for any Wi\-Fi connection that uses security\&. T} T{ -auth\-alg +leap\-password T}:T{ string T}:T{ \ \& T}:T{ -When WEP is used (ie, key\-mgmt = \*(Aqnone\*(Aq or \*(Aqieee8021x\*(Aq) indicate the 802\&.11 authentication algorithm required by the AP here\&. One of \*(Aqopen\*(Aq for Open System, \*(Aqshared\*(Aq for Shared Key, or \*(Aqleap\*(Aq for Cisco LEAP\&. When using Cisco LEAP (ie, key\-mgmt = \*(Aqieee8021x\*(Aq and auth\-alg = \*(Aqleap\*(Aq) the \*(Aqleap\-username\*(Aq and \*(Aqleap\-password\*(Aq properties must be specified\&. +The login password for legacy LEAP connections (ie, key\-mgmt = "ieee8021x" and auth\-alg = "leap")\&. T} T{ -proto +leap\-password\-flags T}:T{ -array of string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -List of strings specifying the allowed WPA protocol versions to use\&. Each element may be one \*(Aqwpa\*(Aq (allow WPA) or \*(Aqrsn\*(Aq (allow WPA2/RSN)\&. If not specified, both WPA and RSN connections are allowed\&. +Flags indicating how to handle the "leap\-password" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -pairwise +leap\-username T}:T{ -array of string +string T}:T{ \ \& T}:T{ -A list of pairwise encryption algorithms which prevents connections to Wi\-Fi networks that do not utilize one of the algorithms in the list\&. For maximum compatibility leave this property empty\&. Each list element may be one of \*(Aqtkip\*(Aq or \*(Aqccmp\*(Aq\&. +The login username for legacy LEAP connections (ie, key\-mgmt = "ieee8021x" and auth\-alg = "leap")\&. T} T{ -group +name T}:T{ -array of string +string T}:T{ -\ \& +802\-11\-wireless\-security T}:T{ -A list of group/broadcast encryption algorithms which prevents connections to Wi\-Fi networks that do not utilize one of the algorithms in the list\&. For maximum compatibility leave this property empty\&. Each list element may be one of \*(Aqwep40\*(Aq, \*(Aqwep104\*(Aq, \*(Aqtkip\*(Aq, or \*(Aqccmp\*(Aq\&. +The setting\*(Aqs name, which uniquely identifies the setting within the connection\&. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"\&. T} T{ -leap\-username +pairwise T}:T{ -string +array of string T}:T{ -\ \& +[] T}:T{ -The login username for legacy LEAP connections (ie, key\-mgmt = \*(Aqieee8021x\*(Aq and auth\-alg = \*(Aqleap\*(Aq)\&. +A list of pairwise encryption algorithms which prevents connections to Wi\-Fi networks that do not utilize one of the algorithms in the list\&. For maximum compatibility leave this property empty\&. Each list element may be one of "tkip" or "ccmp"\&. T} T{ -wep\-key0 +proto T}:T{ -string +array of string T}:T{ -\ \& +[] T}:T{ -Index 0 WEP key\&. This is the WEP key used in most networks\&. See the \*(Aqwep\-key\-type\*(Aq property for a description of how this key is interpreted\&. +List of strings specifying the allowed WPA protocol versions to use\&. Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN)\&. If not specified, both WPA and RSN connections are allowed\&. T} T{ -wep\-key1 +psk T}:T{ string T}:T{ \ \& T}:T{ -Index 1 WEP key\&. This WEP index is not used by most networks\&. See the \*(Aqwep\-key\-type\*(Aq property for a description of how this key is interpreted\&. +Pre\-Shared\-Key for WPA networks\&. If the key is 64\-characters long, it must contain only hexadecimal characters and is interpreted as a hexadecimal WPA key\&. Otherwise, the key must be between 8 and 63 ASCII characters (as specified in the 802\&.11i standard) and is interpreted as a WPA passphrase, and is hashed to derive the actual WPA\-PSK used when connecting to the Wi\-Fi network\&. T} T{ -wep\-key2 +psk\-flags T}:T{ -string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -Index 2 WEP key\&. This WEP index is not used by most networks\&. See the \*(Aqwep\-key\-type\*(Aq property for a description of how this key is interpreted\&. +Flags indicating how to handle the "psk" property\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -wep\-key3 +wep\-key\-flags T}:T{ -string +NMSettingSecretFlags (uint32) T}:T{ \ \& T}:T{ -Index 3 WEP key\&. This WEP index is not used by most networks\&. See the \*(Aqwep\-key\-type\*(Aq property for a description of how this key is interpreted\&. +Flags indicating how to handle the "wep\-key0", "wep\-key1", "wep\-key2", and "wep\-key3" properties\&. (see the section called \(lqSecret flag types:\(rq for flag values) T} T{ -wep\-key\-flags +wep\-key\-type T}:T{ -uint32 +NMWepKeyType (uint32) T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the WEP keys\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Controls the interpretation of WEP keys\&. Allowed values are NM_WEP_KEY_TYPE_KEY (1), in which case the key is either a 10\- or 26\-character hexadecimal string, or a 5\- or 13\-character ASCII password; or NM_WEP_KEY_TYPE_PASSPHRASE (2), in which case the passphrase is provided as a string and will be hashed using the de\-facto MD5 method to derive the actual WEP key\&. T} T{ -wep\-key\-type +wep\-key0 T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -Controls the interpretation of WEP keys\&. Allowed values are 1 (interpret WEP keys as hexadecimal or ASCII keys) or 2 (interpret WEP keys as WEP Passphrases)\&. If set to 1 and the keys are hexadecimal, they must be either 10 or 26 characters in length\&. If set to 1 and the keys are ASCII keys, they must be either 5 or 13 characters in length\&. If set to 2, the passphrase is hashed using the de\-facto MD5 method to derive the actual WEP key\&. +Index 0 WEP key\&. This is the WEP key used in most networks\&. See the "wep\-key\-type" property for a description of how this key is interpreted\&. T} T{ -psk +wep\-key1 T}:T{ string T}:T{ \ \& T}:T{ -Pre\-Shared\-Key for WPA networks\&. If the key is 64\-characters long, it must contain only hexadecimal characters and is interpreted as a hexadecimal WPA key\&. Otherwise, the key must be between 8 and 63 ASCII characters (as specified in the 802\&.11i standard) and is interpreted as a WPA passphrase, and is hashed to derive the actual WPA\-PSK used when connecting to the Wi\-Fi network\&. +Index 1 WEP key\&. This WEP index is not used by most networks\&. See the "wep\-key\-type" property for a description of how this key is interpreted\&. T} T{ -psk\-flags +wep\-key2 T}:T{ -uint32 +string T}:T{ -0 +\ \& T}:T{ -Flags indicating how to handle the WPA PSK key\&. (see the section called \(lqSecret flag types:\(rq for flag values) +Index 2 WEP key\&. This WEP index is not used by most networks\&. See the "wep\-key\-type" property for a description of how this key is interpreted\&. T} T{ -leap\-password +wep\-key3 T}:T{ string T}:T{ \ \& T}:T{ -The login password for legacy LEAP connections (ie, key\-mgmt = \*(Aqieee8021x\*(Aq and auth\-alg = \*(Aqleap\*(Aq)\&. +Index 3 WEP key\&. This WEP index is not used by most networks\&. See the "wep\-key\-type" property for a description of how this key is interpreted\&. T} T{ -leap\-password\-flags +wep\-tx\-keyidx T}:T{ uint32 T}:T{ 0 T}:T{ -Flags indicating how to handle the LEAP password\&. (see the section called \(lqSecret flag types:\(rq for flag values) +When static WEP is used (ie, key\-mgmt = "none") and a non\-default WEP key index is used by the AP, put that WEP key index here\&. Valid values are 0 (default key) through 3\&. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 \- 4\&. T} .TE .sp 1 @@ -3024,6 +3135,6 @@ NetworkManager developers or distro plugin\-specific location .SH "SEE ALSO" .PP -https://live\&.gnome\&.org/NetworkManagerConfiguration +https://wiki\&.gnome\&.org/Projects/NetworkManager/ConfigurationSpecification .PP NetworkManager(8), nmcli(1), nmcli\-examples(5), NetworkManager\&.conf(5) diff --git a/man/nm-settings.xml b/man/nm-settings.xml new file mode 100644 index 00000000..7c3dd96a --- /dev/null +++ b/man/nm-settings.xml @@ -0,0 +1,343 @@ + + +19 December 2014nm-settings5NetworkManagerConfiguration1.0.0nm-settingsDescription of settings and properties of NetworkManager connection profilesDESCRIPTION + NetworkManager is based on a concept of connection profiles, sometimes referred to as + connections only. These connection profiles contain a network configuration. When + NetworkManager activates a connection profile on a network device the configuration will + be applied and an active network connection will be established. Users are free to create + as many connection profiles as they see fit. Thus they are flexible in having various network + configurations for different networking needs. The connection profiles are handled by + NetworkManager via settings service and are exported on D-Bus + (/org/freedesktop/NetworkManager/Settings/<num> objects). + The conceptual objects can be described as follows: + Connection (profile) + A specific, encapsulated, independent group of settings describing + all the configuration required to connect to a specific network. + It is referred to by a unique identifier called the UUID. A connection + is tied to a one specific device type, but not necessarily a specific + hardware device. It is composed of one or more Settings + objects. + Setting + A group of related key/value pairs describing a specific piece of a + Connection (profile). Settings keys and allowed values are + described in the tables below. Keys are also reffered to as properties. + Developers can find the setting objects and their properties in the libnm-util + sources. Look for the class_init functions near the bottom of + each setting source file. + + The settings and properties shown in tables below list all available connection + configuration options. However, note that not all settings are applicable to all + connection types. NetworkManager provides a command-line tool nmcli + that allows direct configuration of the settings and properties according to a connection + profile type. nmcli connection editor has also a built-in + describe command that can display description of particular settings + and properties of this page. + + 802-1x settingKey NameValue TypeDefault ValueValue Description + altsubject-matchesarray of string[]List of strings to be matched against the altSubjectName of the certificate presented by the authentication server. If the list is empty, no verification of the server certificate's altSubjectName is performed. + anonymous-identitystringAnonymous identity string for EAP authentication methods. Used as the unencrypted identity with EAP types that support different tunneled identity like EAP-TTLS. + ca-certbyte arrayContains the CA certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. + ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca-cert" property. + client-certbyte arrayContains the client certificate if used by the EAP method specified in the "eap" property. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. + eaparray of string[]The allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd", and "fast". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations. + identitystringIdentity string for EAP authentication methods. Often the user's user or login name. + namestring802-1xThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + pac-filestringUTF-8 encoded file path containing PAC for EAP-FAST. + passwordstringUTF-8 encoded password used for EAP authentication methods. If both the "password" property and the "password-raw" property are specified, "password" is preferred. + password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values) + password-rawbyte arrayPassword used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF-8 to be used. If both the "password" property and the "password-raw" property are specified, "password" is preferred. + password-raw-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password-raw" property. (see for flag values) + phase1-fast-provisioningstringEnables or disables in-line provisioning of EAP-FAST credentials when FAST is specified as the EAP method in the "eap" property. Recognized values are "0" (disabled), "1" (allow unauthenticated provisioning), "2" (allow authenticated provisioning), and "3" (allow both authenticated and unauthenticated provisioning). See the wpa_supplicant documentation for more details. + phase1-peaplabelstringForces use of the new PEAP label during key derivation. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1. Set to "1" to force use of the new PEAP label. See the wpa_supplicant documentation for more details. + phase1-peapverstringForces which PEAP version is used when PEAP is set as the EAP method in the "eap" property. When unset, the version reported by the server will be used. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version. To do so, this property may be set to "0" or "1" to force that specific PEAP version. + phase2-altsubject-matchesarray of string[]List of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner "phase 2" authentication. If the list is empty, no verification of the server certificate's altSubjectName is performed. + phase2-authstringSpecifies the allowed "phase 2" inner non-EAP authentication methods when an EAP method that uses an inner TLS tunnel is specified in the "eap" property. Recognized non-EAP "phase 2" methods are "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details. + phase2-autheapstringSpecifies the allowed "phase 2" inner EAP-based authentication methods when an EAP method that uses an inner TLS tunnel is specified in the "eap" property. Recognized EAP-based "phase 2" methods are "md5", "mschapv2", "otp", "gtc", and "tls". Each "phase 2" inner method requires specific parameters for successful authentication; see the wpa_supplicant documentation for more details. + phase2-ca-certbyte arrayContains the "phase 2" CA certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. + phase2-ca-pathstringUTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2-ca-cert" property. + phase2-client-certbyte arrayContains the "phase 2" client certificate if used by the EAP method specified in the "phase2-auth" or "phase2-autheap" properties. Certificate data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string "file://" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended. + phase2-private-keybyte arrayContains the "phase 2" inner private key when the "phase2-auth" or "phase2-autheap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "phase2-private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and and ending with a terminating NUL byte, and as with the blob scheme the "phase2-private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. + phase2-private-key-passwordstringThe password used to decrypt the "phase 2" private key specified in the "phase2-private-key" property when the private key either uses the path scheme, or is a PKCS#12 format key. + phase2-private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "phase2-private-key-password" property. (see for flag values) + phase2-subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed. + pinstringPIN used for EAP authentication methods. + pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values) + private-keybyte arrayContains the private key when the "eap" property is set to "tls". Key data is specified using a "scheme"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the "private-key-password" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string "file://" and and ending with a terminating NUL byte, and as with the blob scheme the "private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: "private-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data. + private-key-passwordstringThe password used to decrypt the private key specified in the "private-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key. + private-key-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "private-key-password" property. (see for flag values) + subject-matchstringSubstring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. + system-ca-certsbooleanFALSEWhen TRUE, overrides the "ca-path" and "phase2-ca-path" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca-cert" and "phase2-ca-cert" properties. +
+ adsl settingKey NameValue TypeDefault ValueValue Description + encapsulationstringEncapsulation of ADSL connection. Can be "vcmux" or "llc". + namestringadslThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + passwordstringPassword used to authenticate with the ADSL service. + password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values) + protocolstringADSL connection protocol. Can be "pppoa", "pppoe" or "ipoatm". + usernamestringUsername used to authenticate with the ADSL service. + vciuint320VCI of ADSL connection + vpiuint320VPI of ADSL connection +
+ bluetooth settingKey NameValue TypeDefault ValueValue Description + bdaddrbyte arrayThe Bluetooth address of the device. + namestringbluetoothThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + typestringEither "dun" for Dial-Up Networking connections or "panu" for Personal Area Networking connections to devices supporting the NAP profile. +
+ bond settingKey NameValue TypeDefault ValueValue Description + interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bond's interface name. + namestringbondThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + optionsdict of string to stringDictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]). +
+ bridge settingKey NameValue TypeDefault ValueValue Description + ageing-timeuint32300The Ethernet MAC address aging time, in seconds. + forward-delayuint3215The Spanning Tree Protocol (STP) forwarding delay, in seconds. + hello-timeuint322The Spanning Tree Protocol (STP) hello time, in seconds. + interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the bridge's interface name. + mac-addressbyte arrayIf specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. When matching an existing (outside NetworkManager created) bridge, this MAC address must match. + max-ageuint3220The Spanning Tree Protocol (STP) maximum message age, in seconds. + namestringbridgeThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + priorityuint3232768Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are "better"; the lowest priority bridge will be elected the root bridge. + stpbooleanTRUEControls whether Spanning Tree Protocol (STP) is enabled for this bridge. +
+ bridge-port settingKey NameValue TypeDefault ValueValue Description + hairpin-modebooleanFALSEEnables or disabled "hairpin mode" for the port, which allows frames to be sent back out through the port the frame was received on. + namestringbridge-portThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + path-costuint32100The Spanning Tree Protocol (STP) port cost for destinations via this port. + priorityuint3232The Spanning Tree Protocol (STP) priority of this bridge port. +
+ cdma settingKey NameValue TypeDefault ValueValue Description + namestringcdmaThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + numberstringThe number to dial to establish the connection to the CDMA-based mobile broadband network, if any. If not specified, the default number (#777) is used when required. + passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here. + password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values) + usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here. +
+ connection settingKey NameValue TypeDefault ValueValue Description + autoconnectbooleanTRUEWhether or not the connection should be automatically connected by NetworkManager when the resources for the connection are available. TRUE to automatically activate the connection, FALSE to require manual intervention to activate the connection. + autoconnect-priorityint320The autoconnect priority. If the connection is set to autoconnect, connections with higher priority will be preferred. Defaults to 0. The higher number means higher priority. + gateway-ping-timeoutuint320If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping. + idstringA human readable unique identifier for the connection, like "Work Wi-Fi" or "T-Mobile 3G". + interface-namestringThe name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface. + masterstringInterface name of the master device or UUID of the master connection. + namestringconnectionThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + permissionsarray of string[]An array of strings defining what access a given user has to this connection. If this is NULL or empty, all users are allowed to access this connection. Otherwise a user is allowed to access this connection if and only if they are in this list. Each entry is of the form "[type]:[id]:[reserved]"; for example, "user:dcbw:blah". At this time only the "user" [type] is allowed. Any other values are ignored and reserved for future use. [id] is the username that this permission refers to, which may not contain the ":" character. Any [reserved] information present must be ignored and is reserved for future use. All of [type], [id], and [reserved] must be valid UTF-8. + read-onlybooleanFALSEFALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified. + secondariesarray of string[]List of connection UUIDs that should be activated when the base connection itself is activated. Currently only VPN connections are supported. + slave-typestringSetting name of the device type of this slave's master connection (eg, "bond"), or NULL if this connection is not a slave. + timestampuint640The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved). + typestringBase type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc). + uuidstringA universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the "id" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or "type" property changes. The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664" (ie, contains only hexadecimal characters and "-"). + zonestringThe trust level of a the connection. Free form case-insensitive string (for example "Home", "Work", "Public"). NULL or unspecified zone means the connection will be placed in the default zone as defined by the firewall. +
+ dcb settingKey NameValue TypeDefault ValueValue Description + app-fcoe-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FCoE application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4). + app-fcoe-modestring"fabric"The FCoE controller mode; either "fabric" (default) or "vn2vn". + app-fcoe-priorityint32-1The highest User Priority (0 - 7) which FCoE frames should use, or -1 for default priority. Only used when the "app-fcoe-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag. + app-fip-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB FIP application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4). + app-fip-priorityint32-1The highest User Priority (0 - 7) which FIP frames should use, or -1 for default priority. Only used when the "app-fip-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag. + app-iscsi-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for the DCB iSCSI application. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4). + app-iscsi-priorityint32-1The highest User Priority (0 - 7) which iSCSI frames should use, or -1 for default priority. Only used when the "app-iscsi-flags" property includes the NM_SETTING_DCB_FLAG_ENABLE (0x1) flag. + namestringdcbThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + priority-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the percentage of bandwidth of the priority's assigned group that the priority may use. The sum of all percentages for priorities which belong to the same group must total 100 percent. + priority-flow-controlarray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the corresponding priority should transmit priority pause. + priority-flow-control-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Flow Control (PFC). Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4). + priority-group-bandwidtharray of uint32An array of 8 uint values, where the array index corresponds to the Priority Group ID (0 - 7) and the value indicates the percentage of link bandwidth allocated to that group. Allowed values are 0 - 100, and the sum of all values must total 100 percent. + priority-group-flagsNMSettingDcbFlags (uint32)Specifies the NMSettingDcbFlags for DCB Priority Groups. Flags may be any combination of NM_SETTING_DCB_FLAG_ENABLE (0x1), NM_SETTING_DCB_FLAG_ADVERTISE (0x2), and NM_SETTING_DCB_FLAG_WILLING (0x4). + priority-group-idarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the Priority Group ID. Allowed Priority Group ID values are 0 - 7 or 15 for the unrestricted group. + priority-strict-bandwidtharray of uint32An array of 8 boolean values, where the array index corresponds to the User Priority (0 - 7) and the value indicates whether or not the priority may use all of the bandwidth allocated to its assigned group. + priority-traffic-classarray of uint32An array of 8 uint values, where the array index corresponds to the User Priority (0 - 7) and the value indicates the traffic class (0 - 7) to which the priority is mapped. +
+ generic settingKey NameValue TypeDefault ValueValue Description + namestringgenericThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". +
+ gsm settingKey NameValue TypeDefault ValueValue Description + apnstringThe GPRS Access Point Name specifying the APN used when establishing a data session with the GSM-based network. The APN often determines how the user will be billed for their network usage and whether the user has access to the Internet or just a provider-specific walled-garden, so it is important to use the correct APN for the user's mobile broadband plan. The APN may only be composed of the characters a-z, 0-9, ., and - per GSM 03.60 Section 14.9. + home-onlybooleanFALSEWhen TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made. + namestringgsmThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + network-idstringThe Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible. + numberstringNumber to dial when establishing a PPP data session with the GSM-based mobile broadband network. Many modems do not require PPP for connections to the mobile network and thus this property should be left blank, which allows NetworkManager to select the appropriate settings automatically. + passwordstringThe password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here. + password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values) + pinstringIf the SIM is locked with a PIN it must be unlocked before any other operations are requested. Specify the PIN here to allow operation of the device. + pin-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "pin" property. (see for flag values) + usernamestringThe username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here. +
+ infiniband settingKey NameValue TypeDefault ValueValue Description + mac-addressbyte arrayIf specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing). + mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames. + namestringinfinibandThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + p-keyint32-1The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka "the P_Key at index 0"). Otherwise it is a 16-bit unsigned integer, whose high bit is set if it is a "full membership" P_Key. + parentstringThe interface name of the parent device of this device. Normally NULL, but if the "p_key" property is set, then you must specify the base device by setting either this property or "mac-address". + transport-modestringThe IP-over-InfiniBand transport mode. Either "datagram" or "connected". +
+ ipv4 settingKey NameValue TypeDefault ValueValue Description + address-dataarray of vardictArray of IPv4 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses. + addressesarray of array of uint32Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv4 address structures. Each IPv4 address structure is composed of 3 32-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 - 32), and last the IPv4 gateway (network byte order). The gateway may be left as 0 if no gateway exists for that subnet. + dhcp-client-idstringA string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. + dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. + dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. + dnsarray of uint32[]Array of IP addresses of DNS servers (as network-byte-order integers) + dns-searcharray of string[]Array of DNS search domains. + gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. + ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used. + ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used. + may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully. + methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. + namestringipv4The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager. + route-dataarray of vardictArray of IPv4 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'gateway' entry, containing the gateway IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes. + route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric. + routesarray of array of uint32Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv4 route structures. Each IPv4 route structure is composed of 4 32-bit values; the first being the destination IPv4 network or address (network byte order), the second the destination network or address prefix (1 - 32), the third being the next-hop (network byte order) if any, and the fourth being the route metric. If the metric is 0, NM will choose an appropriate default metric for the device. (There is no way to explicitly specify an actual metric of 0 with this property.) +
+ ipv6 settingKey NameValue TypeDefault ValueValue Description + address-dataarray of vardictArray of IPv6 addresses. Each address dictionary contains at least 'address' and 'prefix' entries, containing the IP address as a string, and the prefix length as a uint32. Additional attributes may also exist on some addresses. + addressesarray of legacy IPv6 address struct (a(ayuay))Deprecated in favor of the 'address-data' and 'gateway' properties, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'address-data' and 'gateway'. Array of IPv6 address structures. Each IPv6 address structure is composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 gateway address. The gateway may be zeroed out if no gateway exists for that subnet. + dhcp-hostnamestringIf the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. + dhcp-send-hostnamebooleanTRUEIf TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. + dnsarray of byte array[]Array of IP addresses of DNS servers (in network byte order) + dns-searcharray of string[]Array of DNS search domains. + gatewaystringThe gateway associated with this configuration. This is only meaningful if "addresses" is also set. + ignore-auto-dnsbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the "dns" and "dns-search" properties, if any, are used. + ignore-auto-routesbooleanFALSEWhen "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used. + ip6-privacyNMSettingIP6ConfigPrivacy (int32)Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). + may-failbooleanTRUEIf TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully. + methodstringIP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. + namestringipv6The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + never-defaultbooleanFALSEIf TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager. + route-dataarray of vardictArray of IPv6 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes. + route-metricint64-1The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric. + routesarray of legacy IPv6 route struct (a(ayuayu))Deprecated in favor of the 'route-data' property, but this can be used for backward-compatibility with older daemons. Note that if you send this property the daemon will ignore 'route-data'. Array of IPv6 route structures. Each IPv6 route structure is composed of an IPv6 address, a prefix length (1 - 128), an IPv6 next hop address (which may be zeroed out if there is no next hop), and a metric. If the metric is 0, NM will choose an appropriate default metric for the device. +
+ 802-11-olpc-mesh settingKey NameValue TypeDefault ValueValue Description + channeluint320Channel on which the mesh network to join is located. + dhcp-anycast-addressbyte arrayAnycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request. + namestring802-11-olpc-meshThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + ssidbyte arraySSID of the mesh network to join. +
+ ppp settingKey NameValue TypeDefault ValueValue Description + bauduint320If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed. + crtsctsbooleanFALSEIf TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE. + lcp-echo-failureuint320If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The "lcp-echo-interval" property must also be set to a non-zero value if this property is used. + lcp-echo-intervaluint320If non-zero, instruct pppd to send an LCP echo-request frame to the peer every n seconds (where n is the specified value). Note that some PPP peers will respond to echo requests and some will not, and it is not possible to autodetect this. + mppe-statefulbooleanFALSEIf TRUE, stateful MPPE is used. See pppd documentation for more information on stateful MPPE. + mruuint320If non-zero, instruct pppd to request that the peer send packets no larger than the specified size. If non-zero, the MRU should be between 128 and 16384. + mtuuint320If non-zero, instruct pppd to send packets no larger than the specified size. + namestringpppThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + no-vj-compbooleanFALSEIf TRUE, Van Jacobsen TCP header compression will not be requested. + noauthbooleanTRUEIf TRUE, do not require the other side (usually the PPP server) to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE. + nobsdcompbooleanFALSEIf TRUE, BSD compression will not be requested. + nodeflatebooleanFALSEIf TRUE, "deflate" compression will not be requested. + refuse-chapbooleanFALSEIf TRUE, the CHAP authentication method will not be used. + refuse-eapbooleanFALSEIf TRUE, the EAP authentication method will not be used. + refuse-mschapbooleanFALSEIf TRUE, the MSCHAP authentication method will not be used. + refuse-mschapv2booleanFALSEIf TRUE, the MSCHAPv2 authentication method will not be used. + refuse-papbooleanFALSEIf TRUE, the PAP authentication method will not be used. + require-mppebooleanFALSEIf TRUE, MPPE (Microsoft Point-to-Point Encrpytion) will be required for the PPP session. If either 64-bit or 128-bit MPPE is not available the session will fail. Note that MPPE is not used on mobile broadband connections. + require-mppe-128booleanFALSEIf TRUE, 128-bit MPPE (Microsoft Point-to-Point Encrpytion) will be required for the PPP session, and the "require-mppe" property must also be set to TRUE. If 128-bit MPPE is not available the session will fail. +
+ pppoe settingKey NameValue TypeDefault ValueValue Description + namestringpppoeThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + passwordstringPassword used to authenticate with the PPPoE service. + password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "password" property. (see for flag values) + servicestringIf specified, instruct PPPoE to only initiate sessions with access concentrators that provide the specified service. For most providers, this should be left blank. It is only required if there are multiple access concentrators or a specific service is known to be required. + usernamestringUsername used to authenticate with the PPPoE service. +
+ serial settingKey NameValue TypeDefault ValueValue Description + bauduint3257600Speed to use for communication over the serial port. Note that this value usually has no effect for mobile broadband modems as they generally ignore speed settings and use the highest available speed. + bitsuint328Byte-width of the serial communication. The 8 in "8n1" for example. + namestringserialThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + paritybyteThe connection parity: 69 (ASCII 'E') for even parity, 111 (ASCII 'o') for odd, 110 (ASCII 'n') for none. + send-delayuint640Time to delay between each byte sent to the modem, in microseconds. + stopbitsuint321Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in "8n1" for example. +
+ team settingKey NameValue TypeDefault ValueValue Description + configstringThe JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details. + interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the team's interface name. + namestringteamThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". +
+ team-port settingKey NameValue TypeDefault ValueValue Description + configstringThe JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details. + namestringteam-portThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". +
+ vlan settingKey NameValue TypeDefault ValueValue Description + egress-priority-maparray of string[]For outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3". + flagsNMVlanFlags (uint32)One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). + iduint320The VLAN identifier that the interface created by this connection should be assigned. + ingress-priority-maparray of string[]For incoming packets, a list of mappings from 802.1p priorities to Linux SKB priorities. The mapping is given in the format "from:to" where both "from" and "to" are unsigned integers, ie "7:3". + interface-namestringDeprecated in favor of connection.interface-name, but can be used for backward-compatibility with older daemons, to set the vlan's interface name. + namestringvlanThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + parentstringIf given, specifies the parent interface name or parent connection UUID from which this VLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property. +
+ vpn settingKey NameValue TypeDefault ValueValue Description + datadict of string to stringDictionary of key/value pairs of VPN plugin specific data. Both keys and values must be strings. + namestringvpnThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + persistentbooleanFALSEIf the VPN service supports persistence, and this property is TRUE, the VPN will attempt to stay connected across link changes and outages, until explicitly disconnected. + secretsdict of string to stringDictionary of key/value pairs of VPN plugin specific secrets like passwords or private keys. Both keys and values must be strings. + service-typestringD-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin. + user-namestringIf the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection. +
+ wimax settingKey NameValue TypeDefault ValueValue Description + mac-addressbyte arrayIf specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). + namestringwimaxThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + network-namestringNetwork Service Provider (NSP) name of the WiMAX network this connection should use. +
+ 802-3-ethernet settingKey NameValue TypeDefault ValueValue Description + auto-negotiatebooleanTRUEIf TRUE, allow auto-negotiation of port speed and duplex mode. If FALSE, do not allow auto-negotiation, in which case the "speed" and "duplex" properties should be set. + cloned-mac-addressbyte arrayIf specified, request that the device use this MAC address instead of its permanent MAC address. This is known as MAC cloning or spoofing. + duplexstringIf specified, request that the device only use the specified duplex mode. Either "half" or "full". + mac-addressbyte arrayIf specified, this connection will only apply to the Ethernet device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing). + mac-address-blacklistarray of string[]If specified, this connection will never apply to the Ethernet device whose permanent MAC address matches an address in the list. Each MAC address is in the standard hex-digits-and-colons notation (00:11:22:33:44:55). + mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames. + namestring802-3-ethernetThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + portstringSpecific port type to use if multiple the device supports multiple attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface. If the device supports only one port type, this setting is ignored. + s390-nettypestrings390 network device type; one of "qeth", "lcs", or "ctc", representing the different types of virtual network devices available on s390 systems. + s390-optionsdict of string to stringDictionary of key/value pairs of s390-specific device options. Both keys and values must be strings. Allowed keys include "portno", "layer2", "portname", "protocol", among others. Key names must contain only alphanumeric characters (ie, [a-zA-Z0-9]). + s390-subchannelsarray of string[]Identifies specific subchannels that this network device uses for communication with z/VM or s390 host. Like the "mac-address" property for non-z/VM devices, this property can be used to ensure this connection only applies to the network device that uses these subchannels. The list should contain exactly 3 strings, and each string may only be composed of hexadecimal characters and the period (.) character. + speeduint320If non-zero, request that the device use only the specified speed. In Mbit/s, ie 100 == 100Mbit/s. +
+ 802-11-wireless settingKey NameValue TypeDefault ValueValue Description + bandstring802.11 frequency band of the network. One of "a" for 5GHz 802.11a or "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if "a" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers. + bssidbyte arrayIf specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future. + channeluint320Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the "band" property to be set. + cloned-mac-addressbyte arrayIf specified, request that the Wi-Fi device use this MAC address instead of its permanent MAC address. This is known as MAC cloning or spoofing. + hiddenbooleanFALSEIf TRUE, indicates this network is a non-broadcasting network that hides its SSID. In this case various workarounds may take place, such as probe-scanning the SSID for more reliable network discovery. However, these workarounds expose inherent insecurities with hidden SSID networks, and thus hidden SSID networks should be used with caution. + mac-addressbyte arrayIf specified, this connection will only apply to the Wi-Fi device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing). + mac-address-blacklistarray of string[]A list of permanent MAC addresses of Wi-Fi devices to which this connection should never apply. Each MAC address should be given in the standard hex-digits-and-colons notation (eg "00:11:22:33:44:55"). + modestringWi-Fi network mode; one of "infrastructure", "adhoc" or "ap". If blank, infrastructure is assumed. + mtuuint320If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple Ethernet frames. + namestring802-11-wirelessThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + rateuint320If non-zero, directs the device to only use the specified bitrate for communication with the access point. Units are in Kb/s, ie 5500 = 5.5 Mbit/s. This property is highly driver dependent and not all devices support setting a static bitrate. + securityNoneThis property is deprecated, but can be set to the value '802-11-wireless-security' when a wireless security setting is also present in the connection dictionary, for compatibility with very old NetworkManager daemons. + seen-bssidsarray of string[]A list of BSSIDs (each BSSID formatted as a MAC address like "00:11:22:33:44:55") that have been detected as part of the Wi-Fi network. NetworkManager internally tracks previously seen BSSIDs. The property is only meant for reading and reflects the BSSID list of NetworkManager. The changes you make to this property will not be preserved. + ssidbyte arraySSID of the Wi-Fi network. Must be specified. + tx-poweruint320If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power. +
+ 802-11-wireless-security settingKey NameValue TypeDefault ValueValue Description + auth-algstringWhen WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the 802.11 authentication algorithm required by the AP here. One of "open" for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the "leap-username" and "leap-password" properties must be specified. + grouparray of string[]A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "wep40", "wep104", "tkip", or "ccmp". + key-mgmtstringKey management used for the connection. One of "none" (WEP), "ieee8021x" (Dynamic WEP), "wpa-none" (Ad-Hoc WPA-PSK), "wpa-psk" (infrastructure WPA-PSK), or "wpa-eap" (WPA-Enterprise). This property must be set for any Wi-Fi connection that uses security. + leap-passwordstringThe login password for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap"). + leap-password-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "leap-password" property. (see for flag values) + leap-usernamestringThe login username for legacy LEAP connections (ie, key-mgmt = "ieee8021x" and auth-alg = "leap"). + namestring802-11-wireless-securityThe setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired". + pairwisearray of string[]A list of pairwise encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of "tkip" or "ccmp". + protoarray of string[]List of strings specifying the allowed WPA protocol versions to use. Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN). If not specified, both WPA and RSN connections are allowed. + pskstringPre-Shared-Key for WPA networks. If the key is 64-characters long, it must contain only hexadecimal characters and is interpreted as a hexadecimal WPA key. Otherwise, the key must be between 8 and 63 ASCII characters (as specified in the 802.11i standard) and is interpreted as a WPA passphrase, and is hashed to derive the actual WPA-PSK used when connecting to the Wi-Fi network. + psk-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "psk" property. (see for flag values) + wep-key-flagsNMSettingSecretFlags (uint32)Flags indicating how to handle the "wep-key0", "wep-key1", "wep-key2", and "wep-key3" properties. (see for flag values) + wep-key-typeNMWepKeyType (uint32)Controls the interpretation of WEP keys. Allowed values are NM_WEP_KEY_TYPE_KEY (1), in which case the key is either a 10- or 26-character hexadecimal string, or a 5- or 13-character ASCII password; or NM_WEP_KEY_TYPE_PASSPHRASE (2), in which case the passphrase is provided as a string and will be hashed using the de-facto MD5 method to derive the actual WEP key. + wep-key0stringIndex 0 WEP key. This is the WEP key used in most networks. See the "wep-key-type" property for a description of how this key is interpreted. + wep-key1stringIndex 1 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted. + wep-key2stringIndex 2 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted. + wep-key3stringIndex 3 WEP key. This WEP index is not used by most networks. See the "wep-key-type" property for a description of how this key is interpreted. + wep-tx-keyidxuint320When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key index is used by the AP, put that WEP key index here. Valid values are 0 (default key) through 3. Note that some consumer access points (like the Linksys WRT54G) number the keys 1 - 4. +
+Secret flag types: + Each secret property in a setting has an associated flags property + that describes how to handle that secret. The flags property is a bitfield + that contains zero or more of the following values logically OR-ed together. + 0x0 (none) - the system is responsible for providing and storing this secret.0x1 (agent-owned) - a user-session secret agent is responsible for providing and storing + this secret; when it is required, agents will be asked to provide it.0x2 (not-saved) - this secret should not be saved but should be requested from the user + each time it is required. This flag should be used for One-Time-Pad secrets, PIN codes from hardware tokens, + or if the user simply does not want to save the secret.0x4 (not-required) - in some situations it cannot be automatically determined that a secret + is required or not. This flag hints that the secret is not required and should not be requested from the user.
AUTHORNetworkManager developersFILES/etc/NetworkManager/system-connectionsor distro plugin-specific locationSEE ALSOhttps://wiki.gnome.org/Projects/NetworkManager/ConfigurationSpecificationNetworkManager(8), nmcli(1), nmcli-examples(5), NetworkManager.conf(5)
diff --git a/man/nm-settings.xsl b/man/nm-settings.xsl new file mode 100644 index 00000000..24e41535 --- /dev/null +++ b/man/nm-settings.xsl @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + nm-settings + 5 + NetworkManager + Configuration + + + + nm-settings + Description of settings and properties of NetworkManager connection profiles + + + DESCRIPTION + + NetworkManager is based on a concept of connection profiles, sometimes referred to as + connections only. These connection profiles contain a network configuration. When + NetworkManager activates a connection profile on a network device the configuration will + be applied and an active network connection will be established. Users are free to create + as many connection profiles as they see fit. Thus they are flexible in having various network + configurations for different networking needs. The connection profiles are handled by + NetworkManager via settings service and are exported on D-Bus + (/org/freedesktop/NetworkManager/Settings/<num> objects). + The conceptual objects can be described as follows: + + + Connection (profile) + + + A specific, encapsulated, independent group of settings describing + all the configuration required to connect to a specific network. + It is referred to by a unique identifier called the UUID. A connection + is tied to a one specific device type, but not necessarily a specific + hardware device. It is composed of one or more Settings + objects. + + + + + + + Setting + + + A group of related key/value pairs describing a specific piece of a + Connection (profile). Settings keys and allowed values are + described in the tables below. Keys are also reffered to as properties. + Developers can find the setting objects and their properties in the libnm-util + sources. Look for the class_init functions near the bottom of + each setting source file. + + + + + + + The settings and properties shown in tables below list all available connection + configuration options. However, note that not all settings are applicable to all + connection types. NetworkManager provides a command-line tool nmcli + that allows direct configuration of the settings and properties according to a connection + profile type. nmcli connection editor has also a built-in + describe command that can display description of particular settings + and properties of this page. + + + + + + Secret flag types: + + Each secret property in a setting has an associated flags property + that describes how to handle that secret. The flags property is a bitfield + that contains zero or more of the following values logically OR-ed together. + + + + 0x0 (none) - the system is responsible for providing and storing this secret. + + + 0x1 (agent-owned) - a user-session secret agent is responsible for providing and storing + this secret; when it is required, agents will be asked to provide it. + + + 0x2 (not-saved) - this secret should not be saved but should be requested from the user + each time it is required. This flag should be used for One-Time-Pad secrets, PIN codes from hardware tokens, + or if the user simply does not want to save the secret. + + + 0x4 (not-required) - in some situations it cannot be automatically determined that a secret + is required or not. This flag hints that the secret is not required and should not be requested from the user. + + + + + + AUTHOR + + + NetworkManager developers + + + + + FILES + /etc/NetworkManager/system-connections + or distro plugin-specific location + + + SEE ALSO + https://wiki.gnome.org/Projects/NetworkManager/ConfigurationSpecification + NetworkManager(8), nmcli(1), nmcli-examples(5), NetworkManager.conf(5) + + + + + + + <xsl:value-of select="@name"/> setting + + + + Key Name + Value Type + Default Value + Value Description + + + + + + +
+
+ + + + + + + + (see for flag values) + + + +
diff --git a/man/nmcli-examples.5 b/man/nmcli-examples.5 index 7145d682..23045ecd 100644 --- a/man/nmcli-examples.5 +++ b/man/nmcli-examples.5 @@ -2,12 +2,12 @@ .\" Title: nmcli-examples .\" Author: .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 16 June 2014 +.\" Date: 19 November 2014 .\" Manual: Examples -.\" Source: NetworkManager 0.9.10 +.\" Source: NetworkManager 1.0 .\" Language: English .\" -.TH "NMCLI\-EXAMPLES" "5" "" "NetworkManager 0\&.9\&.10" "Examples" +.TH "NMCLI\-EXAMPLES" "5" "" "NetworkManager 1\&.0" "Examples" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -121,6 +121,7 @@ GENERAL\&.STATE: 100 (connected) GENERAL\&.REASON: 0 (No reason given) GENERAL\&.UDI: /sys/devices/pci0000:00/0000:00:1c\&.1/0000:03:00\&.0/net/wlan0 GENERAL\&.IP\-IFACE: wlan0 +GENERAL\&.IS\-SOFTWARE: no GENERAL\&.NM\-MANAGED: yes GENERAL\&.AUTOCONNECT: yes GENERAL\&.FIRMWARE\-MISSING: no @@ -350,6 +351,7 @@ interface, the second to \fB $ nmcli con add con\-name my\-con\-em1 ifname em1 type ethernet ip4 192\&.168\&.100\&.100/24 gw4 192\&.168\&.100\&.1 ip4 1\&.2\&.3\&.4 ip6 abbe::cafe $ nmcli con mod my\-con\-em1 ipv4\&.dns "8\&.8\&.8\&.8 8\&.8\&.4\&.4" +$ nmcli con mod my\-con\-em1 +ipv4\&.dns 1\&.2\&.3\&.4 $ nmcli con mod my\-con\-em1 ipv6\&.dns "2001:4860:4860::8888 2001:4860:4860::8844" $ nmcli \-p con show my\-con\-em1 \fR @@ -362,7 +364,7 @@ $ nmcli \-p con show my\-con\-em1 The first command adds an Ethernet connection profile named \fImy\-con\-em1\fR that is bound to interface name -\fIem1\fR\&. The profile is configured with static IP addresses\&. Three addresses are added, two IPv4 addresses and one IPv6\&. The first IP 192\&.168\&.100\&.100 has a prefix of 24 (netmask equivalent of 255\&.255\&.255\&.0)\&. Gateway entry for the first IP address will become the default route if this profile is activated on em1 interface (and there is no connection with higher priority)\&. The second two addresses don\*(Aqt specify a prefix, so a default prefix will be used, i\&.e\&. 32 for IPv4 and 128 for IPv6\&. The second and third commands modify DNS parameters of the new connection profile\&. The last +\fIem1\fR\&. The profile is configured with static IP addresses\&. Three addresses are added, two IPv4 addresses and one IPv6\&. The first IP 192\&.168\&.100\&.100 has a prefix of 24 (netmask equivalent of 255\&.255\&.255\&.0)\&. Gateway entry will become the default route if this profile is activated on em1 interface (and there is no connection with higher priority)\&. The next two addresses do not specify a prefix, so a default prefix will be used, i\&.e\&. 32 for IPv4 and 128 for IPv6\&. The second, third and fourth commands modify DNS parameters of the new connection profile\&. The last \fIcon show\fR command displays the profile so that all parameters can be reviewed\&. .PP @@ -469,6 +471,7 @@ connection\&.uuid: de89cdeb\-a3e1\-4d53\-8fa0\-c22546c775 connection\&.interface\-name: \-\- connection\&.type: 802\-3\-ethernet connection\&.autoconnect: yes +connection\&.autoconnect\-priority: 0 connection\&.timestamp: 0 connection\&.read\-only: no connection\&.permissions: @@ -494,7 +497,9 @@ ipv4\&.method: auto ipv4\&.dns: ipv4\&.dns\-search: ipv4\&.addresses: +ipv4\&.gateway: \-\- ipv4\&.routes: +ipv4\&.route\-metric: \-1 ipv4\&.ignore\-auto\-routes: no ipv4\&.ignore\-auto\-dns: no ipv4\&.dhcp\-client\-id: \-\- @@ -507,7 +512,9 @@ ipv6\&.method: auto ipv6\&.dns: ipv6\&.dns\-search: ipv6\&.addresses: +ipv6\&.gateway: \-\- ipv6\&.routes: +ipv6\&.route\-metric: \-1 ipv6\&.ignore\-auto\-routes: no ipv6\&.ignore\-auto\-dns: no ipv6\&.never\-default: no @@ -524,22 +531,23 @@ nmcli ipv4\&.addresses> desc === [addresses] === [NM property description] -Array of IPv4 address structures\&. Each IPv4 address structure is composed of 3 32\-bit values; the first being the IPv4 address (network byte order), the second the prefix (1 \- 32), and last the IPv4 gateway (network byte order)\&. The gateway may be left as 0 if no gateway exists for that subnet\&. For the \*(Aqauto\*(Aq method, given IP addresses are appended to those returned by automatic configuration\&. Addresses cannot be used with the \*(Aqshared\*(Aq, \*(Aqlink\-local\*(Aq, or \*(Aqdisabled\*(Aq methods as addressing is either automatic or disabled with these methods\&. +Array of IP addresses\&. [nmcli specific description] Enter a list of IPv4 addresses formatted as: - ip[/prefix] [gateway], ip[/prefix] [gateway],\&.\&.\&. + ip[/prefix], ip[/prefix],\&.\&.\&. Missing prefix is regarded as prefix of 32\&. -Example: 192\&.168\&.1\&.5/24 192\&.168\&.1\&.1, 10\&.0\&.0\&.11/24 +Example: 192\&.168\&.1\&.5/24, 10\&.0\&.0\&.11/24 -nmcli ipv4\&.addresses> set 192\&.168\&.1\&.100/24 192\&.168\&.1\&.1 +nmcli ipv4\&.addresses> set 192\&.168\&.1\&.100/24 Do you also want to set \*(Aqipv4\&.method\*(Aq to \*(Aqmanual\*(Aq? [yes]: yes nmcli ipv4\&.addresses> nmcli ipv4\&.addresses> print -addresses: { ip = 192\&.168\&.1\&.100/24, gw = 192\&.168\&.1\&.1 } +addresses: 192\&.168\&.1\&.100/24 nmcli ipv4\&.addresses> back nmcli ipv4> b +nmcli> set ipv4\&.gateway 192\&.168\&.1\&.1 nmcli> verify Verify connection: OK nmcli> print @@ -551,6 +559,7 @@ connection\&.uuid: de89cdeb\-a3e1\-4d53\-8fa0\-c22546c775 connection\&.interface\-name: \-\- connection\&.type: 802\-3\-ethernet connection\&.autoconnect: yes +connection\&.autoconnect\-priority: 0 connection\&.timestamp: 0 connection\&.read\-only: no connection\&.permissions: @@ -575,8 +584,10 @@ connection\&.gateway\-ping\-timeout: 0 ipv4\&.method: manual ipv4\&.dns: ipv4\&.dns\-search: -ipv4\&.addresses: { ip = 192\&.168\&.1\&.100/24, gw = 192\&.168\&.1\&.1 } +ipv4\&.addresses: 192\&.168\&.1\&.100/24 +ipv4\&.gateway: 192\&.168\&.1\&.1 ipv4\&.routes: +ipv4\&.route\-metric: \-1 ipv4\&.ignore\-auto\-routes: no ipv4\&.ignore\-auto\-dns: no ipv4\&.dhcp\-client\-id: \-\- @@ -590,6 +601,7 @@ ipv6\&.dns: ipv6\&.dns\-search: ipv6\&.addresses: ipv6\&.routes: +ipv6\&.route\-metric: \-1 ipv6\&.ignore\-auto\-routes: no ipv6\&.ignore\-auto\-dns: no ipv6\&.never\-default: no @@ -607,6 +619,7 @@ connection\&.uuid: de89cdeb\-a3e1\-4d53\-8fa0\-c22546c775 connection\&.interface\-name: \-\- connection\&.type: 802\-3\-ethernet connection\&.autoconnect: yes +connection\&.autoconnect\-priority: 0 connection\&.timestamp: 0 connection\&.read\-only: no connection\&.permissions: @@ -629,10 +642,12 @@ connection\&.gateway\-ping\-timeout: 0 802\-3\-ethernet\&.s390\-options: \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- ipv4\&.method: manual -ipv4\&.dns: 8\&.8\&.8\&.8, 8\&.8\&.4\&.4 +ipv4\&.dns: 8\&.8\&.8\&.8,8\&.8\&.4\&.4 ipv4\&.dns\-search: -ipv4\&.addresses: { ip = 192\&.168\&.1\&.100/24, gw = 192\&.168\&.1\&.1 } +ipv4\&.addresses: 192\&.168\&.1\&.100/24 +ipv4\&.gateway: 192\&.168\&.1\&.1 ipv4\&.routes: +ipv4\&.route\-metric: \-1 ipv4\&.ignore\-auto\-routes: no ipv4\&.ignore\-auto\-dns: no ipv4\&.dhcp\-client\-id: \-\- @@ -645,7 +660,9 @@ ipv6\&.method: auto ipv6\&.dns: ipv6\&.dns\-search: ipv6\&.addresses: +ipv6\&.gateway: \-\- ipv6\&.routes: +ipv6\&.route\-metric: \-1 ipv6\&.ignore\-auto\-routes: no ipv6\&.ignore\-auto\-dns: no ipv6\&.never\-default: no @@ -664,7 +681,7 @@ nmcli> quit .RE .\} .PP -Example session in the nmcli interactive connection editor\&. The scenario creates an Ethernet connection (configuration) with static addressing (IPs and DNS)\&. +Example session in the nmcli interactive connection editor\&. The scenario creates an Ethernet connection profile with static addressing (IPs and DNS)\&. .SH "SEE ALSO" .PP \fBnmcli\fR(1), diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 08f07b4a..c9a69cb9 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -19,9 +19,9 @@ .\" with this manual; if not, write to the Free Software Foundation, Inc., .\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. .\" -.\" Copyright (C) 2010 - 2014 Red Hat, Inc. +.\" Copyright 2010 - 2014 Red Hat, Inc. .\" -.TH NMCLI "1" "28 February 2014" +.TH NMCLI "1" "3 December 2014" .SH NAME nmcli \- command\(hyline tool for controlling NetworkManager @@ -33,7 +33,7 @@ nmcli \- command\(hyline tool for controlling NetworkManager .sp .IR OBJECT " := { " -.BR general " | " networking " | " radio " | " connection " | " device +.BR general " | " networking " | " radio " | " connection " | " device " | " agent .RI " }" .sp @@ -131,6 +131,8 @@ incompatible versions may produce incorrect results. .B \-a, \-\-ask When using this option \fInmcli\fP will stop and ask for any missing required arguments, so do not use this option for non-interactive purposes like scripts. +This option controls, for example, whether you will be prompted for a password +if it is required for connecting to a network. .TP .B \-w, \-\-wait This option sets a timeout period for which \fInmcli\fP will wait for \fINetworkManager\fP @@ -287,12 +289,12 @@ active if a device is using that connection profile. Without a parameter, all profiles are listed. When --active option is specified, only the active profiles are shown. .TP -.B show [--active] [ id | uuid | path | apath ] ... +.B show [--active] [--show-secrets] [ id | uuid | path | apath ] ... .br Show details for specified connections. By default, both static configuration and active connection data are displayed. When --active option is specified, -only the active profiles are taken into -account. +only the active profiles are taken into account. When --show-secrets option is +specified, secrets associated with the profile will be revealed too. \fIid\fP, \fIuuid\fP, \fIpath\fP and \fIapath\fP keywords can be used if \fI\fP is ambiguous. .RS @@ -327,10 +329,10 @@ When no command is given to the \fIconnection\fP object, the default action is 'nmcli connection show'. .RE .TP -.B up [ id | uuid | path ] [ifname ] [ap ] [nsp ] +.B up [ id | uuid | path ] [ifname ] [ap ] [nsp ] [passwd ] .RE .RS -.B up ifname [ap ] [nsp ] +.B up ifname [ap ] [nsp ] [passwd ] .RS .br Activate a connection. The connection is identified by its name, UUID or D-Bus @@ -355,18 +357,38 @@ Available options are: \(en BSSID of the AP which the command should connect to (for Wi\(hyFi connections) .IP \fInsp\fP 13 \(en NSP (Network Service Provider) which the command should connect to (for WiMAX connections) +.IP \fIpasswd-file\fP 13 +\(en some networks may require credentials during activation. You can give these +credentials using this option. +Each line of the file should contain one password in the form of +.br +\fBsetting_name.property_name:the password\fP +.br +For example, for WPA Wi-Fi with PSK, the line would be +.br +\fI802-11-wireless-security.psk:secret12345\fP +.br +For 802.1X password, the line would be +.br +\fI802-1x.password:my 1X password\fP +.br +nmcli also accepts "wifi-sec" and "wifi" strings instead of "802-11-wireless-security". +When NetworkManager requires a password and it is not given, nmcli will ask for it +when run with --ask. If --ask was not passed, NetworkManager can ask another secret +agent that may be running (typically a GUI secret agent, such as nm-applet or +gnome-shell). .RE .RE .TP -.B down [ id | uuid | path | apath ] +.B down [ id | uuid | path | apath ] ... .br Deactivate a connection from a device without preventing the device from -further auto-activation. +further auto-activation. Multiple connections can be passed to the command. .sp -Be aware that this command deactivates the specified active connection. The device +Be aware that this command deactivates the specified active connection, but the device on which the connection was active, is still ready to connect and will perform auto-activation by looking for a suitable connection that has the 'autoconnect' -flag set. This includes the just deactivated connection, so if the connection is set +flag set. This includes the just deactivated connection. So if the connection is set to auto-connect, it will be automatically started on the disconnected device again. .br In most cases you may want to use \fIdevice disconnect\fP command instead. @@ -418,6 +440,8 @@ Note: use quotes around \fB*\fP to suppress shell expansion. \(en MAC address of the device this connection is locked to .IP "\fI[cloned-mac ]\fP" 42 \(en cloned MAC +.IP "\fI[mode infrastructure|ap|adhoc]\fP" 42 +\(en Wi-Fi network mode. If blank, \fIinfrastructure\fP is assumed. .IP "\fI[mtu ]\fP" 42 \(en MTU .RE @@ -683,7 +707,7 @@ of its latest state. .B device - show and manage network interfaces .br .TP -.SS \fICOMMAND\fP := { status | show | connect | disconnect | wifi | wimax } +.SS \fICOMMAND\fP := { status | show | connect | disconnect | delete | wifi | wimax } .sp .RS .TP @@ -713,6 +737,14 @@ connections without user/manual intervention. .br If '--wait' option is not specified, the default timeout will be 10 seconds. .TP +.B delete +.br +Delete a device. The command removes the interface from the system. Note that +this only works for software devices like bonds, bridges, teams, etc. +Hardware devices (like Ethernet) cannot be deleted by the command. +.br +If '--wait' option is not specified, the default timeout will be 10 seconds. +.TP .B wifi [list [ifname ] [bssid ]] .br List available Wi\(hyFi access points. The \fIifname\fP and \fIbssid\fP options @@ -761,6 +793,39 @@ This command does not show the APs, use 'nmcli device wifi list' for that. List available WiMAX NSP. The \fIifname\fP and \fInsp\fP options can be used to list networks for a particular interface or with a specific NSP, respectively. +.RE + +.TP +.B agent \- run nmcli as a NetworkManager secret agent, or polkit agent +.br +.TP +.SS \fICOMMAND\fP := { secret | polkit | all } +.sp +.RS +.TP +.B secret +.br +Register nmcli as a NetworkManager secret agent and listen for secret requests. +You do usually not need this command, because nmcli can handle secrets when +connecting to networks. However, you may find the command useful when you use +another tool for activating connections and you do not have a secret agent +available (like nm-applet). +.TP +.B polkit +.br +Register nmcli as a polkit agent for the user session and listen for +authorization requests. You do not usually need this command, because nmcli can +handle polkit actions related to NetworkManager operations (when run with +--ask). However, you may find the command useful when you want to run a simple +text based polkit agent and you do not have an agent of a desktop environment. +Note that running this command makes nmcli handle all polkit requests, not only +NetworkManager related ones, because only one polkit agent can run for the +session. +.TP +.B all +.br +Runs nmcli as both NetworkManager secret and a polkit agent. +.RE .SH ENVIRONMENT VARIABLES \fInmcli\fP's behavior is affected by the following environment variables. @@ -851,6 +916,11 @@ shows all connection profile names and their auto-connect property. .IP shows details for "My default em1" connection profile. +.IP "\fB\f(CWnmcli connection show --show-secrets \(dq\&My Home WiFi\(dq\&\fP\fP" +.IP +shows details for "My Home WiFi" connection profile with all passwords. +Without \fI--show-secrets\fP option, secrets would not be displayed. + .IP "\fB\f(CWnmcli \-f active connection show \(dq\&My default em1\(dq\&\fP\fP" .IP shows details for "My default em1" active connection, like IP, DHCP diff --git a/man/nmtui.1.in b/man/nmtui.1.in new file mode 100644 index 00000000..32b76954 --- /dev/null +++ b/man/nmtui.1.in @@ -0,0 +1,66 @@ +.\" nmtui (1) manual page +.\" +.\" This is free documentation; 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. +.\" +.\" The GNU General Public License's references to "object code" +.\" and "executables" are to be interpreted as the output of any +.\" document formatting or typesetting system, including +.\" intermediate and printed output. +.\" +.\" This manual 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 Licence along +.\" with this manual; if not, write to the Free Software Foundation, Inc., +.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +.\" +.\" Copyright 2014 Red Hat, Inc. +.\" +.TH NMTUI "1" "6 November 2014" + +.SH NAME +nmtui \- Text User Interface for controlling NetworkManager +.SH SYNOPSIS +.B nmtui +.RI " [ " edit " | " connect " | " hostname " ] [ ... ] " +.P +.B nmtui\-edit +.RI " [ " connection-id " | " connection-name " ] " +.P +.B nmtui\-connect +.RI " [ " connection-name " | " connection-uuid " | " device-name " | " Wi-Fi-SSID " ] " +.P +.B nmtui\-hostname + +.SH DESCRIPTION +.B nmtui +is a curses\(hybased TUI application for interacting with \fINetworkManager\fP. +.P +When starting \fInmtui\fP, the user is prompted to choose the activity to perform +unless it was specified as the first argument. +.P +The supported activities are: +.IP \(em 4 +\fIedit\fP: show a connection editor that supports adding, modifying, viewing and deleting +connections. It provides similar functionality as \fInm\-connection\-editor\fP. +.IP \(em 4 +\fIconnect\fP: show a list of available connections, with the option to activate or deactivate +them. It provides similar functionality as \fInm\-applet\fP. +.IP \(em 4 +\fIhostname\fP: set the system hostname. + +.P +Corresponding to above activities, \fInmtui\fP also comes with binaries named +\fInmtui\-edit\fP, \fInmtui\-connect\fP, and \fInmtui-hostname\fP to skip the selection +of the activities. + +.SH SEE ALSO +.BR NetworkManager(8), +.BR nmcli(1). +.BR nm\-applet(1). +.BR nm\-connection\-editor(1). diff --git a/po/POTFILES.in b/po/POTFILES.in index 6368a9f5..926dd6c3 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,19 +1,86 @@ [encoding: UTF-8] # List of source files containing translatable strings. # Please keep this file sorted alphabetically. -cli/src/common.c -cli/src/connections.c -cli/src/devices.c -cli/src/network-manager.c -cli/src/nmcli.c -cli/src/settings.c -cli/src/utils.c +clients/cli/agent.c +clients/cli/common.c +clients/cli/connections.c +clients/cli/devices.c +clients/cli/general.c +clients/cli/nmcli.c +clients/cli/polkit-agent.c +clients/cli/settings.c +clients/cli/utils.c +clients/common/nm-polkit-listener.c +clients/common/nm-secret-agent-simple.c +clients/nm-online.c +clients/tui/newt/nmt-newt-utils.c +clients/tui/nm-editor-utils.c +clients/tui/nmt-connect-connection-list.c +clients/tui/nmt-device-entry.c +clients/tui/nmt-edit-connection-list.c +clients/tui/nmt-editor-section.c +clients/tui/nmt-editor.c +clients/tui/nmt-mtu-entry.c +clients/tui/nmt-page-bond.c +clients/tui/nmt-page-bridge-port.c +clients/tui/nmt-page-bridge.c +clients/tui/nmt-page-dsl.c +clients/tui/nmt-page-ethernet.c +clients/tui/nmt-page-infiniband.c +clients/tui/nmt-page-ip4.c +clients/tui/nmt-page-ip6.c +clients/tui/nmt-page-ppp.c +clients/tui/nmt-page-team-port.c +clients/tui/nmt-page-team.c +clients/tui/nmt-page-vlan.c +clients/tui/nmt-page-wifi.c +clients/tui/nmt-password-dialog.c +clients/tui/nmt-password-fields.c +clients/tui/nmt-route-editor.c +clients/tui/nmt-route-table.c +clients/tui/nmt-slave-list.c +clients/tui/nmt-widget-list.c +clients/tui/nmtui-connect.c +clients/tui/nmtui-edit.c +clients/tui/nmtui-hostname.c +clients/tui/nmtui.c +libnm-core/crypto.c +libnm-core/crypto_gnutls.c +libnm-core/crypto_nss.c +libnm-core/nm-connection.c +libnm-core/nm-setting-8021x.c +libnm-core/nm-setting-adsl.c +libnm-core/nm-setting-bluetooth.c +libnm-core/nm-setting-bond.c +libnm-core/nm-setting-bridge-port.c +libnm-core/nm-setting-bridge.c +libnm-core/nm-setting-cdma.c +libnm-core/nm-setting-connection.c +libnm-core/nm-setting-dcb.c +libnm-core/nm-setting-gsm.c +libnm-core/nm-setting-infiniband.c +libnm-core/nm-setting-ip-config.c +libnm-core/nm-setting-ip4-config.c +libnm-core/nm-setting-ip6-config.c +libnm-core/nm-setting-olpc-mesh.c +libnm-core/nm-setting-ppp.c +libnm-core/nm-setting-pppoe.c +libnm-core/nm-setting-team-port.c +libnm-core/nm-setting-vlan.c +libnm-core/nm-setting-vpn.c +libnm-core/nm-setting-wimax.c +libnm-core/nm-setting-wired.c +libnm-core/nm-setting-wireless-security.c +libnm-core/nm-setting-wireless.c +libnm-core/nm-setting.c +libnm-core/nm-utils.c libnm-glib/nm-device.c libnm-glib/nm-remote-connection.c libnm-util/crypto.c libnm-util/crypto_gnutls.c libnm-util/crypto_nss.c libnm-util/nm-connection.c +libnm-util/nm-setting.c libnm-util/nm-setting-8021x.c libnm-util/nm-setting-adsl.c libnm-util/nm-setting-bluetooth.c @@ -38,59 +105,52 @@ libnm-util/nm-setting-wired.c libnm-util/nm-setting-wireless-security.c libnm-util/nm-setting-wireless.c libnm-util/nm-utils.c +libnm/nm-device-adsl.c +libnm/nm-device-bond.c +libnm/nm-device-bridge.c +libnm/nm-device-bt.c +libnm/nm-device-ethernet.c +libnm/nm-device-generic.c +libnm/nm-device-infiniband.c +libnm/nm-device-modem.c +libnm/nm-device-olpc-mesh.c +libnm/nm-device-team.c +libnm/nm-device-vlan.c +libnm/nm-device-wifi.c +libnm/nm-device-wimax.c +libnm/nm-device.c +libnm/nm-manager.c +libnm/nm-object.c +libnm/nm-remote-connection.c +libnm/nm-remote-settings.c +libnm/nm-vpn-plugin-old.c policy/org.freedesktop.NetworkManager.policy.in.in +src/NetworkManagerUtils.c src/main.c +src/main-utils.c src/dhcp-manager/nm-dhcp-dhclient.c src/dhcp-manager/nm-dhcp-dhclient-utils.c src/dhcp-manager/nm-dhcp-manager.c src/dns-manager/nm-dns-manager.c -src/logging/nm-logging.c -src/config/nm-config.c src/devices/adsl/nm-device-adsl.c src/devices/bluetooth/nm-bluez-device.c src/devices/bluetooth/nm-device-bt.c src/devices/nm-device-bond.c src/devices/nm-device-bridge.c src/devices/nm-device-ethernet.c +src/devices/nm-device-ethernet-utils.c src/devices/nm-device-infiniband.c -src/devices/nm-device-team.c src/devices/nm-device-vlan.c +src/devices/team/nm-device-team.c src/devices/wifi/nm-device-olpc-mesh.c +src/devices/wifi/nm-device-wifi.c +src/devices/wifi/nm-wifi-ap-utils.c +src/devices/wimax/nm-device-wimax.c src/devices/wwan/nm-modem-broadband.c -src/devices/wwan/nm-modem-old.c +src/nm-config.c +src/nm-iface-helper.c +src/nm-logging.c src/nm-manager.c src/nm-sleep-monitor-systemd.c +src/settings/plugins/ibft/plugin.c src/settings/plugins/ifcfg-rh/reader.c -src/settings/nm-settings-utils.c -test/nm-online.c -tui/newt/nmt-newt-utils.c -tui/nm-editor-utils.c -tui/nmt-connect-connection-list.c -tui/nmt-device-entry.c -tui/nmt-edit-connection-list.c -tui/nmt-editor.c -tui/nmt-mtu-entry.c -tui/nmt-page-bond.c -tui/nmt-page-bridge-port.c -tui/nmt-page-bridge.c -tui/nmt-page-ethernet.c -tui/nmt-page-infiniband.c -tui/nmt-page-ip4.c -tui/nmt-page-ip6.c -tui/nmt-page-main.c -tui/nmt-page-team-port.c -tui/nmt-page-team.c -tui/nmt-page-vlan.c -tui/nmt-page-wifi.c -tui/nmt-password-dialog.c -tui/nmt-password-fields.c -tui/nmt-route-editor.c -tui/nmt-route-table.c -tui/nmt-secret-agent.c -tui/nmt-slave-list.c -tui/nmt-widget-list.c -tui/nmtui-connect.c -tui/nmtui-edit.c -tui/nmtui-hostname.c -tui/nmtui.c - diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 461200fa..f611e4ce 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,7 +1,8 @@ +clients/tui/vpn-helpers.c examples/python/NetworkManager.py examples/python/systray/eggtrayicon.c policy/org.freedesktop.NetworkManager.policy.in vpn-daemons/openvpn vpn-daemons/pptp vpn-daemons/vpnc -tui/vpn-helpers.c +contrib/fedora/rpm/ diff --git a/po/as.po b/po/as.po index dac6acc5..dbe4a16c 100644 --- a/po/as.po +++ b/po/as.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" -"product=NetworkManager&keywords=I18N+L10N&component=general\n" -"POT-Creation-Date: 2014-01-30 15:24+0000\n" -"PO-Revision-Date: 2014-02-06 17:17+0630\n" +"product=NetworkManager&keywords=I18N+L10N&component=Translations\n" +"POT-Creation-Date: 2014-10-06 22:25+0000\n" +"PO-Revision-Date: 2014-10-07 22:48+0530\n" "Last-Translator: Nilamdyuti Goswami \n" "Language-Team: Assamese \n" "Language: as\n" @@ -19,434 +19,473 @@ msgstr "" "X-Generator: Lokalize 1.5\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../cli/src/common.c:34 ../cli/src/common.c:46 ../cli/src/common.c:54 -#: ../cli/src/common.c:65 ../cli/src/connections.c:179 -#: ../cli/src/connections.c:201 +#: ../clients/cli/common.c:38 ../clients/cli/common.c:50 +#: ../clients/cli/common.c:58 ../clients/cli/common.c:69 +#: ../clients/cli/connections.c:169 ../clients/cli/connections.c:191 msgid "GROUP" msgstr "দল" #. 0 -#: ../cli/src/common.c:35 ../cli/src/common.c:55 +#: ../clients/cli/common.c:39 ../clients/cli/common.c:59 msgid "ADDRESS" msgstr "ঠিকনা" #. 1 -#: ../cli/src/common.c:36 ../cli/src/common.c:56 +#: ../clients/cli/common.c:40 ../clients/cli/common.c:60 msgid "ROUTE" msgstr "পথ" #. 2 -#: ../cli/src/common.c:37 ../cli/src/common.c:57 +#: ../clients/cli/common.c:41 ../clients/cli/common.c:61 msgid "DNS" msgstr "DNS" #. 3 -#: ../cli/src/common.c:38 ../cli/src/common.c:58 +#: ../clients/cli/common.c:42 ../clients/cli/common.c:62 msgid "DOMAIN" msgstr "ডমেইন" #. 4 -#: ../cli/src/common.c:39 +#: ../clients/cli/common.c:43 msgid "WINS" msgstr "WINS" #. 0 -#: ../cli/src/common.c:47 ../cli/src/common.c:66 +#: ../clients/cli/common.c:51 ../clients/cli/common.c:70 msgid "OPTION" msgstr "বিকল্প" -#: ../cli/src/common.c:404 ../cli/src/settings.c:2808 +#: ../clients/cli/common.c:377 ../clients/cli/settings.c:3055 +#: ../clients/cli/settings.c:3074 #, c-format msgid "invalid IPv4 address '%s'" msgstr "অবৈধ IPv4 ঠিকনা '%s'" -#: ../cli/src/common.c:412 +#: ../clients/cli/common.c:385 #, c-format msgid "invalid prefix '%s'; <1-32> allowed" msgstr "অবৈধ উপসৰ্গ '%s'; <1-32> অনুমোদিত" -#: ../cli/src/common.c:419 ../cli/src/common.c:472 +#: ../clients/cli/common.c:392 ../clients/cli/common.c:445 #, c-format msgid "invalid gateway '%s'" msgstr "অবৈধ গেইটৱে '%s'" -#: ../cli/src/common.c:457 ../cli/src/settings.c:3054 +#: ../clients/cli/common.c:430 ../clients/cli/settings.c:3401 +#: ../clients/cli/settings.c:3420 #, c-format msgid "invalid IPv6 address '%s'" msgstr "অবৈধ IPv6 ঠিকনা '%s'" -#: ../cli/src/common.c:465 +#: ../clients/cli/common.c:438 #, c-format msgid "invalid prefix '%s'; <1-128> allowed" msgstr "অবৈধ উপসৰ্গ '%s'; <1-128> অনুমোদিত" -#: ../cli/src/common.c:512 +#: ../clients/cli/common.c:521 #, c-format -msgid "invalid IPv4 route '%s'" -msgstr "অবৈধ IPv4 পথ '%s'" +msgid "invalid route destination address '%s'" +msgstr "অবৈধ পথ গন্তব্য ঠিকনা '%s'" -#: ../cli/src/common.c:520 +#: ../clients/cli/common.c:528 #, c-format -msgid "invalid prefix '%s'; <0-32> allowed" -msgstr "অবৈধ উপসৰ্গ '%s'; <0-32> অনুমোদিত" +msgid "invalid prefix '%s'; <1-%d> allowed" +msgstr "অবৈধ উপসৰ্গ '%s'; <1-%d> অনুমোদিত" -#: ../cli/src/common.c:527 ../cli/src/common.c:590 +#: ../clients/cli/common.c:538 #, c-format msgid "invalid next hop address '%s'" msgstr "অবৈধ পৰৱৰ্তী হপ ঠিকনা '%s'" -#: ../cli/src/common.c:534 ../cli/src/common.c:598 +#: ../clients/cli/common.c:543 #, c-format -msgid "invalid metric '%s'" -msgstr "অবৈধ মেট্ৰিক '%s'" +msgid "" +"the second component of route ('%s') is neither a next hop address nor a " +"metric" +msgstr "পথ ('%s') ৰ দ্বিতীয় উপাদান এটা পৰৱৰ্তী হপ ঠিকনা অথবা এটা মেট্ৰিক নহয়" -#: ../cli/src/common.c:575 +#: ../clients/cli/common.c:553 #, c-format -msgid "invalid IPv6 route '%s'" -msgstr "অবৈধ IPv6 পথ '%s'" +msgid "invalid metric '%s'" +msgstr "অবৈধ মেট্ৰিক '%s'" -#: ../cli/src/common.c:583 -#, c-format -msgid "invalid prefix '%s'; <0-128> allowed" -msgstr "অবৈধ উপসৰ্গ '%s'; <0-128> অনুমোদিত" +#: ../clients/cli/common.c:562 +msgid "default route cannot be added (NetworkManager handles it by itself)" +msgstr "অবিকল্পিত পথ যোগ কৰিব নোৱাৰি (NetworkManager এ নিজেই কৰি লয়)" -#: ../cli/src/common.c:619 +#: ../clients/cli/common.c:650 msgid "unmanaged" msgstr "অব্যৱস্থাপিত" -#: ../cli/src/common.c:621 +#: ../clients/cli/common.c:652 msgid "unavailable" msgstr "উপলব্ধ নাই" -#: ../cli/src/common.c:623 ../cli/src/network-manager.c:276 +#: ../clients/cli/common.c:654 ../clients/cli/general.c:259 msgid "disconnected" msgstr "বিচ্ছিন্নিত" -#: ../cli/src/common.c:625 +#: ../clients/cli/common.c:656 msgid "connecting (prepare)" msgstr "সংযোগ কৰা হৈছে (প্ৰস্তুত হওক)" -#: ../cli/src/common.c:627 +#: ../clients/cli/common.c:658 msgid "connecting (configuring)" msgstr "সংযোগ কৰা (সংৰূপণ কৰা)" -#: ../cli/src/common.c:629 +#: ../clients/cli/common.c:660 msgid "connecting (need authentication)" msgstr "সংযোগ কৰা (প্ৰমাণীকৰণৰ প্ৰয়োজন)" -#: ../cli/src/common.c:631 +#: ../clients/cli/common.c:662 msgid "connecting (getting IP configuration)" msgstr "সংযোগ কৰা (IP সংৰূপ প্ৰাপ্ত কৰা)" -#: ../cli/src/common.c:633 +#: ../clients/cli/common.c:664 msgid "connecting (checking IP connectivity)" -msgstr "সংযোগ কৰা (IP সংযোগ নীৰিক্ষণ কৰা)" +msgstr "সংযোগ কৰা (IP সংযোগ নিৰীক্ষণ কৰা)" -#: ../cli/src/common.c:635 +#: ../clients/cli/common.c:666 msgid "connecting (starting secondary connections)" msgstr "সংযোগ কৰা (দ্বিতীয় সংযোগসমূহ আৰম্ভ কৰা)" -#: ../cli/src/common.c:637 ../cli/src/network-manager.c:272 +#: ../clients/cli/common.c:668 ../clients/cli/general.c:255 msgid "connected" msgstr "সংযুক্ত" -#: ../cli/src/common.c:639 ../cli/src/connections.c:528 +#: ../clients/cli/common.c:670 ../clients/cli/connections.c:533 msgid "deactivating" msgstr "নিষ্ক্ৰিয় কৰা হৈছে" -#: ../cli/src/common.c:641 +#: ../clients/cli/common.c:672 msgid "connection failed" msgstr "সংযোগ ব্যৰ্থ" -#: ../cli/src/common.c:643 ../cli/src/connections.c:533 -#: ../cli/src/connections.c:556 ../cli/src/connections.c:1669 -#: ../cli/src/devices.c:829 ../cli/src/devices.c:2263 -#: ../cli/src/network-manager.c:279 ../cli/src/network-manager.c:297 -#: ../cli/src/network-manager.c:360 ../cli/src/network-manager.c:363 -#: ../cli/src/network-manager.c:373 ../cli/src/network-manager.c:375 -#: ../cli/src/network-manager.c:432 ../cli/src/network-manager.c:448 -#: ../cli/src/settings.c:732 ../cli/src/settings.c:760 -#: ../cli/src/settings.c:822 ../cli/src/settings.c:1137 -#: ../cli/src/utils.c:1114 ../src/main.c:470 ../src/main.c:498 +#: ../clients/cli/common.c:674 ../clients/cli/connections.c:538 +#: ../clients/cli/connections.c:561 ../clients/cli/connections.c:1622 +#: ../clients/cli/devices.c:889 ../clients/cli/general.c:262 +#: ../clients/cli/general.c:280 ../clients/cli/general.c:410 +#: ../clients/cli/general.c:426 ../clients/cli/settings.c:702 +#: ../clients/cli/settings.c:764 ../clients/cli/settings.c:1056 +#: ../clients/cli/utils.c:1123 ../src/main.c:505 ../src/main.c:533 msgid "unknown" msgstr "অজ্ঞাত" -#: ../cli/src/common.c:652 +#: ../clients/cli/common.c:683 msgid "No reason given" msgstr "কোনো কাৰণ দিয়া হোৱা নাই" -#: ../cli/src/common.c:655 ../cli/src/connections.c:2467 +#: ../clients/cli/common.c:686 ../clients/cli/connections.c:2392 #, c-format msgid "Unknown error" msgstr "অজ্ঞাত ত্ৰুটি" -#: ../cli/src/common.c:658 +#: ../clients/cli/common.c:689 msgid "Device is now managed" msgstr "ডিভাইচ এতিয়া ব্যৱস্থাপিত" -#: ../cli/src/common.c:661 +#: ../clients/cli/common.c:692 msgid "Device is now unmanaged" msgstr "ডিভাইচ এতিয়া ব্যৱস্থাপিত নহয়" -#: ../cli/src/common.c:664 +#: ../clients/cli/common.c:695 msgid "The device could not be readied for configuration" msgstr "ডিভাইচক সংৰূপণৰ বাবে পঢ়িব নোৱাৰি" -#: ../cli/src/common.c:667 +#: ../clients/cli/common.c:698 msgid "" "IP configuration could not be reserved (no available address, timeout, etc.)" msgstr "IP সংৰূপ সংৰক্ষণ কৰিব নোৱাৰি (কোনো ঠিকনা, সময়অন্ত, ইত্যাদী উপলব্ধ নাই)" -#: ../cli/src/common.c:670 +#: ../clients/cli/common.c:701 msgid "The IP configuration is no longer valid" msgstr "IP সংৰূপ আৰু বৈধ নহয়" -#: ../cli/src/common.c:673 +#: ../clients/cli/common.c:704 msgid "Secrets were required, but not provided" msgstr "গোপনসমূহৰ প্ৰয়োজন আছিল, কিন্তু প্ৰদান কৰা হোৱা নাছিল" -#: ../cli/src/common.c:676 +#: ../clients/cli/common.c:707 msgid "802.1X supplicant disconnected" msgstr "802.1X চাপ্লিকেণ্ট বিচ্ছিন্নিত" -#: ../cli/src/common.c:679 +#: ../clients/cli/common.c:710 msgid "802.1X supplicant configuration failed" msgstr "802.1X চাপ্লিকেণ্ট সংৰূপ ব্যৰ্থ হল" -#: ../cli/src/common.c:682 +#: ../clients/cli/common.c:713 msgid "802.1X supplicant failed" msgstr "802.1X চাপ্লিকেণ্ট ব্যৰ্থ হল" -#: ../cli/src/common.c:685 +#: ../clients/cli/common.c:716 msgid "802.1X supplicant took too long to authenticate" msgstr "802.1X চাপ্লিকেণ্ট প্ৰমাণীত হবলে বহু সময় ললে" -#: ../cli/src/common.c:688 +#: ../clients/cli/common.c:719 msgid "PPP service failed to start" msgstr "PPP সেৱা আৰম্ভ হবলে ব্যৰ্থ হল" -#: ../cli/src/common.c:691 +#: ../clients/cli/common.c:722 msgid "PPP service disconnected" msgstr "PPP সেৱা বিচ্ছিন্নিত হল" -#: ../cli/src/common.c:694 +#: ../clients/cli/common.c:725 msgid "PPP failed" msgstr "PPP ব্যৰ্থ হল" -#: ../cli/src/common.c:697 +#: ../clients/cli/common.c:728 msgid "DHCP client failed to start" -msgstr "DHCP ক্লাএন্ট আৰম্ভ হবলে ব্যৰ্থ হল" +msgstr "DHCP ক্লাএণ্ট আৰম্ভ হবলে ব্যৰ্থ হল" -#: ../cli/src/common.c:700 +#: ../clients/cli/common.c:731 msgid "DHCP client error" -msgstr "DHCP ক্লাএন্ট ত্ৰুটি" +msgstr "DHCP ক্লাএণ্ট ত্ৰুটি" -#: ../cli/src/common.c:703 +#: ../clients/cli/common.c:734 msgid "DHCP client failed" -msgstr "DHCP ক্লাএন্ট ব্যৰ্থ হল" +msgstr "DHCP ক্লাএণ্ট ব্যৰ্থ হল" -#: ../cli/src/common.c:706 +#: ../clients/cli/common.c:737 msgid "Shared connection service failed to start" msgstr "অংশীদাৰী সংযোগ সেৱা আৰম্ভ হবলে ব্যৰ্থ হল" -#: ../cli/src/common.c:709 +#: ../clients/cli/common.c:740 msgid "Shared connection service failed" msgstr "অংশীদাৰী সংযোগ সেৱা ব্যৰ্থ হল" -#: ../cli/src/common.c:712 +#: ../clients/cli/common.c:743 msgid "AutoIP service failed to start" msgstr "AutoIP সেৱা আৰম্ভ হবলে ব্যৰ্থ হল" -#: ../cli/src/common.c:715 +#: ../clients/cli/common.c:746 msgid "AutoIP service error" msgstr "AutoIP সেৱা ত্ৰুটি" -#: ../cli/src/common.c:718 +#: ../clients/cli/common.c:749 msgid "AutoIP service failed" msgstr "AutoIP সেৱা ব্যৰ্থ হল" -#: ../cli/src/common.c:721 +#: ../clients/cli/common.c:752 msgid "The line is busy" msgstr "শাৰী ব্যস্থ" -#: ../cli/src/common.c:724 +#: ../clients/cli/common.c:755 msgid "No dial tone" msgstr "কোনো ডায়েল শব্দ নাই" -#: ../cli/src/common.c:727 +#: ../clients/cli/common.c:758 msgid "No carrier could be established" msgstr "কোনো বাহক স্থাপন কৰিব পৰা নগল" -#: ../cli/src/common.c:730 +#: ../clients/cli/common.c:761 msgid "The dialing request timed out" msgstr "ডায়লিং অনুৰোধৰ সময় অন্ত হল" -#: ../cli/src/common.c:733 +#: ../clients/cli/common.c:764 msgid "The dialing attempt failed" msgstr "ডায়লিং চেষ্টা ব্যৰ্থ হল" -#: ../cli/src/common.c:736 +#: ../clients/cli/common.c:767 msgid "Modem initialization failed" msgstr "মডেম আৰম্ভকৰণ ব্যৰ্থ হল" -#: ../cli/src/common.c:739 +#: ../clients/cli/common.c:770 msgid "Failed to select the specified APN" msgstr "ধাৰ্য্যত APN নিৰ্বাচন কৰিবলে ব্যৰ্থ" -#: ../cli/src/common.c:742 +#: ../clients/cli/common.c:773 msgid "Not searching for networks" -msgstr "নেটৱাৰ্কসমূহ সন্ধান কৰা হোৱা নাই" +msgstr "নেটৱৰ্কসমূহ সন্ধান কৰা হোৱা নাই" -#: ../cli/src/common.c:745 +#: ../clients/cli/common.c:776 msgid "Network registration denied" -msgstr "নেটৱাৰ্ক ৰেজিষ্ট্ৰেষণ নাকচ কৰা হৈছে" +msgstr "নেটৱৰ্ক ৰেজিষ্ট্ৰেষণ নাকচ কৰা হৈছে" -#: ../cli/src/common.c:748 +#: ../clients/cli/common.c:779 msgid "Network registration timed out" -msgstr "নেটৱাৰ্ক ৰেজিষ্ট্ৰেষণৰ সময় অন্ত হল" +msgstr "নেটৱৰ্ক ৰেজিষ্ট্ৰেষণৰ সময় অন্ত হল" -#: ../cli/src/common.c:751 +#: ../clients/cli/common.c:782 msgid "Failed to register with the requested network" -msgstr "অনুৰোধ কৰা নেটৱাৰ্কৰ সৈতে ৰেজিস্টাৰ কৰিবলে ব্যৰ্থ হল" +msgstr "অনুৰোধ কৰা নেটৱৰ্কৰ সৈতে ৰেজিস্টাৰ কৰিবলে ব্যৰ্থ হল" -#: ../cli/src/common.c:754 +#: ../clients/cli/common.c:785 msgid "PIN check failed" -msgstr "PIN নীৰিক্ষণ ব্যৰ্থ হল" +msgstr "PIN নিৰীক্ষণ ব্যৰ্থ হল" -#: ../cli/src/common.c:757 +#: ../clients/cli/common.c:788 msgid "Necessary firmware for the device may be missing" -msgstr "ডিভাইচৰ বাবে প্ৰয়োজনীয় ফাৰ্মৱেৰ সন্ধানহিন হব পাৰে" +msgstr "ডিভাইচৰ বাবে প্ৰয়োজনীয় ফাৰ্মৱেৰ সন্ধানহীন হব পাৰে" -#: ../cli/src/common.c:760 +#: ../clients/cli/common.c:791 msgid "The device was removed" msgstr "ডিভাইচ আতৰোৱা হৈছিল" -#: ../cli/src/common.c:763 +#: ../clients/cli/common.c:794 msgid "NetworkManager went to sleep" msgstr "NetworkManager নিদ্ৰাত গল" -#: ../cli/src/common.c:766 +#: ../clients/cli/common.c:797 msgid "The device's active connection disappeared" msgstr "ডিভাইচৰ সক্ৰিয় সংযোগ অদৃশ্য হল" -#: ../cli/src/common.c:769 +#: ../clients/cli/common.c:800 msgid "Device disconnected by user or client" -msgstr "ডিভাইচ ব্যৱহাৰকাৰী অথবা ক্লাএন্ট দ্বাৰা বিচ্ছিন্ন কৰা হল" +msgstr "ডিভাইচ ব্যৱহাৰকাৰী অথবা ক্লাএণ্ট দ্বাৰা বিচ্ছিন্ন কৰা হল" -#: ../cli/src/common.c:772 +#: ../clients/cli/common.c:803 msgid "Carrier/link changed" msgstr "বাহক/সংযোগ পৰিৱৰ্তন হল" -#: ../cli/src/common.c:775 +#: ../clients/cli/common.c:806 msgid "The device's existing connection was assumed" msgstr "ডিভাইচৰ স্থায়ী সংযোগ ধাৰণা কৰা হৈছিল" -#: ../cli/src/common.c:778 +#: ../clients/cli/common.c:809 msgid "The supplicant is now available" -msgstr "চাপ্লিকেন্ট এতিয়া উপলব্ধ" +msgstr "চাপ্লিকেণ্ট এতিয়া উপলব্ধ" -#: ../cli/src/common.c:781 +#: ../clients/cli/common.c:812 msgid "The modem could not be found" msgstr "মডেম পোৱা নগল" -#: ../cli/src/common.c:784 +#: ../clients/cli/common.c:815 msgid "The Bluetooth connection failed or timed out" msgstr "ব্লুটুথ সংযোগ ব্যৰ্থ হল অথবা সময়অন্ত হল" -#: ../cli/src/common.c:787 +#: ../clients/cli/common.c:818 msgid "GSM Modem's SIM card not inserted" msgstr "GSM মডেমৰ SIM কাৰ্ড সুমুৱা হোৱা নাই" -#: ../cli/src/common.c:790 +#: ../clients/cli/common.c:821 msgid "GSM Modem's SIM PIN required" msgstr "GSM মডেমৰ SIM PIN ৰ প্ৰয়োজন" -#: ../cli/src/common.c:793 +#: ../clients/cli/common.c:824 msgid "GSM Modem's SIM PUK required" msgstr "GSM মডেমৰ SIM PUK ৰ প্ৰয়োজন" -#: ../cli/src/common.c:796 +#: ../clients/cli/common.c:827 msgid "GSM Modem's SIM wrong" msgstr "GSM মডেমৰ SIM ভূল" -#: ../cli/src/common.c:799 +#: ../clients/cli/common.c:830 msgid "InfiniBand device does not support connected mode" msgstr "InfiniBand ডিভাইচে সংযুক্ত অৱস্থা সমৰ্থন নকৰে" -#: ../cli/src/common.c:802 +#: ../clients/cli/common.c:833 msgid "A dependency of the connection failed" msgstr "সংযোগৰ এটা নিৰ্ভৰতা ব্যৰ্থ হল" -#: ../cli/src/common.c:805 +#: ../clients/cli/common.c:836 msgid "A problem with the RFC 2684 Ethernet over ADSL bridge" msgstr "ADSL ব্ৰিজৰে RFC 2684 ইথাৰনেটৰ সৈতে এটা সমস্যা" -#: ../cli/src/common.c:808 +#: ../clients/cli/common.c:839 msgid "ModemManager is unavailable" msgstr "ModemManager উপলব্ধ নাই" -#: ../cli/src/common.c:811 +#: ../clients/cli/common.c:842 msgid "The Wi-Fi network could not be found" -msgstr "Wi-Fi নেটৱাৰ্ক পোৱা নগল" +msgstr "Wi-Fi নেটৱৰ্ক পোৱা নগল" -#: ../cli/src/common.c:814 +#: ../clients/cli/common.c:845 msgid "A secondary connection of the base connection failed" msgstr "ভিত্তি সংযোগৰ এটা দ্বিতীয় সংযোগ ব্যৰ্থ হল" -#: ../cli/src/common.c:817 +#: ../clients/cli/common.c:848 msgid "DCB or FCoE setup failed" msgstr "DCB অথবা FCoE সংস্থাপন ব্যৰ্থ হল" -#: ../cli/src/common.c:820 +#: ../clients/cli/common.c:851 msgid "teamd control failed" msgstr "teamd নিয়ন্ত্ৰণ ব্যৰ্থ হল" +#: ../clients/cli/common.c:854 +msgid "Modem failed or no longer available" +msgstr "মডেম ব্যৰ্থ হল অথবা উপলব্ধ নহয়" + +#: ../clients/cli/common.c:857 +msgid "Modem now ready and available" +msgstr "মডেম প্ৰস্তুত আৰু উপলব্ধ" + +#: ../clients/cli/common.c:860 +msgid "SIM PIN was incorrect" +msgstr "SIM PIN ভুল আছিল" + #. TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) -#: ../cli/src/common.c:824 ../cli/src/devices.c:636 -#: ../libnm-glib/nm-device.c:1834 +#: ../clients/cli/common.c:864 ../clients/cli/devices.c:616 +#: ../libnm-glib/nm-device.c:1812 msgid "Unknown" msgstr "অজ্ঞাত" -#: ../cli/src/common.c:866 +#: ../clients/cli/common.c:906 #, c-format msgid "invalid priority map '%s'" msgstr "অবৈধ প্ৰাথমিকতা মেপ '%s'" -#: ../cli/src/common.c:873 ../cli/src/common.c:879 +#: ../clients/cli/common.c:913 ../clients/cli/common.c:919 #, c-format msgid "priority '%s' is not valid (<0-%ld>)" msgstr "প্ৰাথমিকতা '%s' বৈধ নহয় (<0-%ld>)" -#: ../cli/src/common.c:935 +#: ../clients/cli/common.c:986 #, c-format msgid "'%s' is not a valid team configuration or file name." msgstr "'%s' এটা বৈধ দল সংৰূপ অথবা ফাইল নাম নহয়।" #. define some prompts for connection editor -#: ../cli/src/connections.c:62 +#: ../clients/cli/connections.c:40 msgid "Setting name? " msgstr "সংহতিৰ নাম?" -#: ../cli/src/connections.c:63 +#: ../clients/cli/connections.c:41 msgid "Property name? " msgstr "বৈশিষ্ট্যৰ নাম?" -#: ../cli/src/connections.c:64 +#: ../clients/cli/connections.c:42 msgid "Enter connection type: " msgstr "সংযোগৰ ধৰণ সুমুৱাওক:" +#. define some other prompts +#: ../clients/cli/connections.c:45 +msgid "Connection type: " +msgstr "সংযোগৰ ধৰণ:" + +#: ../clients/cli/connections.c:46 +msgid "VPN type: " +msgstr "VPN ধৰণ:" + +#: ../clients/cli/connections.c:47 +msgid "Bond master: " +msgstr "বান্ধনী মাস্টাৰ:" + +#: ../clients/cli/connections.c:48 +msgid "Team master: " +msgstr "দলৰ গৰাকী:" + +#: ../clients/cli/connections.c:49 +msgid "Bridge master: " +msgstr "ব্ৰিজ মাস্টাৰ:" + +#: ../clients/cli/connections.c:50 +msgid "Connection (name, UUID, or path): " +msgstr "সংযোগ (নাম, UUID, অথবা পথ):" + #. 0 -#: ../cli/src/connections.c:68 ../cli/src/connections.c:180 -#: ../cli/src/devices.c:86 ../cli/src/devices.c:114 ../cli/src/devices.c:124 -#: ../cli/src/devices.c:134 ../cli/src/devices.c:143 ../cli/src/devices.c:158 -#: ../cli/src/devices.c:171 ../cli/src/devices.c:197 ../cli/src/devices.c:212 -#: ../cli/src/devices.c:221 +#: ../clients/cli/connections.c:58 ../clients/cli/connections.c:170 +#: ../clients/cli/devices.c:55 ../clients/cli/devices.c:84 +#: ../clients/cli/devices.c:94 ../clients/cli/devices.c:105 +#: ../clients/cli/devices.c:114 ../clients/cli/devices.c:129 +#: ../clients/cli/devices.c:142 ../clients/cli/devices.c:168 +#: ../clients/cli/devices.c:183 ../clients/cli/devices.c:192 +#: ../clients/cli/devices.c:201 msgid "NAME" msgstr "নাম" #. 0 #. 1 -#: ../cli/src/connections.c:69 ../cli/src/connections.c:181 +#: ../clients/cli/connections.c:59 ../clients/cli/connections.c:171 msgid "UUID" msgstr "UUID" @@ -454,29 +493,30 @@ msgstr "UUID" #. 0 #. 1 #. 2 -#: ../cli/src/connections.c:70 ../cli/src/connections.c:202 -#: ../cli/src/devices.c:72 ../cli/src/devices.c:88 ../cli/src/devices.c:200 +#: ../clients/cli/connections.c:60 ../clients/cli/connections.c:192 +#: ../clients/cli/devices.c:41 ../clients/cli/devices.c:57 +#: ../clients/cli/devices.c:171 msgid "TYPE" msgstr "ধৰণ" #. 2 -#: ../cli/src/connections.c:71 +#: ../clients/cli/connections.c:61 msgid "TIMESTAMP" msgstr "টাইমস্টাম্প" #. 3 -#: ../cli/src/connections.c:72 +#: ../clients/cli/connections.c:62 msgid "TIMESTAMP-REAL" msgstr "টাইমস্টাম্প-প্ৰকৃত" #. 4 -#. 14 -#: ../cli/src/connections.c:73 ../cli/src/devices.c:101 +#. 15 +#: ../clients/cli/connections.c:63 ../clients/cli/devices.c:71 msgid "AUTOCONNECT" msgstr "স্বসংযোগ" #. 5 -#: ../cli/src/connections.c:74 +#: ../clients/cli/connections.c:64 msgid "READONLY" msgstr "কেৱলপঢ়িবপৰা" @@ -485,16 +525,17 @@ msgstr "কেৱলপঢ়িবপৰা" #. 2 #. 15 #. 5 -#: ../cli/src/connections.c:75 ../cli/src/connections.c:188 -#: ../cli/src/devices.c:74 ../cli/src/devices.c:187 ../cli/src/devices.c:203 +#: ../clients/cli/connections.c:65 ../clients/cli/connections.c:178 +#: ../clients/cli/devices.c:43 ../clients/cli/devices.c:158 +#: ../clients/cli/devices.c:174 msgid "DBUS-PATH" msgstr "DBUS-PATH" #. 7 #. 13 #. 4 -#: ../cli/src/connections.c:76 ../cli/src/devices.c:185 -#: ../cli/src/devices.c:202 +#: ../clients/cli/connections.c:66 ../clients/cli/devices.c:156 +#: ../clients/cli/devices.c:173 msgid "ACTIVE" msgstr "সক্ৰিয়" @@ -502,8 +543,9 @@ msgstr "সক্ৰিয়" #. 0 #. 12 #. 3 -#: ../cli/src/connections.c:77 ../cli/src/devices.c:71 ../cli/src/devices.c:87 -#: ../cli/src/devices.c:184 ../cli/src/devices.c:201 +#: ../clients/cli/connections.c:67 ../clients/cli/devices.c:40 +#: ../clients/cli/devices.c:56 ../clients/cli/devices.c:155 +#: ../clients/cli/devices.c:172 msgid "DEVICE" msgstr "ডিভাইচ" @@ -512,116 +554,118 @@ msgstr "ডিভাইচ" #. 1 #. 9 #. 1 -#: ../cli/src/connections.c:78 ../cli/src/connections.c:183 -#: ../cli/src/devices.c:73 ../cli/src/devices.c:96 -#: ../cli/src/network-manager.c:39 +#: ../clients/cli/connections.c:68 ../clients/cli/connections.c:173 +#: ../clients/cli/devices.c:42 ../clients/cli/devices.c:65 +#: ../clients/cli/general.c:36 msgid "STATE" msgstr "অৱস্থা" #. 10 -#: ../cli/src/connections.c:79 +#: ../clients/cli/connections.c:69 msgid "ACTIVE-PATH" msgstr "ACTIVE-PATH" #. 2 -#: ../cli/src/connections.c:182 +#: ../clients/cli/connections.c:172 msgid "DEVICES" msgstr "ডিভাইচসমূহ" #. 4 -#: ../cli/src/connections.c:184 +#: ../clients/cli/connections.c:174 msgid "DEFAULT" msgstr "অবিকল্পিত" #. 5 -#: ../cli/src/connections.c:185 +#: ../clients/cli/connections.c:175 msgid "DEFAULT6" msgstr "DEFAULT6" #. 6 -#: ../cli/src/connections.c:186 +#: ../clients/cli/connections.c:176 msgid "SPEC-OBJECT" msgstr "SPEC-OBJECT" #. 7 #. 4 -#: ../cli/src/connections.c:187 ../cli/src/connections.c:225 -#: ../tui/nm-editor-utils.c:243 ../tui/nmt-connect-connection-list.c:342 +#. Ask for optional 'vpn' arguments. +#: ../clients/cli/connections.c:177 ../clients/cli/connections.c:215 +#: ../clients/cli/connections.c:3446 ../clients/tui/nm-editor-utils.c:234 +#: ../clients/tui/nmt-connect-connection-list.c:407 msgid "VPN" msgstr "VPN" #. 9 #. 5 -#. 18 -#: ../cli/src/connections.c:189 ../cli/src/devices.c:77 -#: ../cli/src/devices.c:105 +#. 19 +#: ../clients/cli/connections.c:179 ../clients/cli/devices.c:46 +#: ../clients/cli/devices.c:75 msgid "CON-PATH" msgstr "CON-PATH" #. 10 -#: ../cli/src/connections.c:190 +#: ../clients/cli/connections.c:180 msgid "ZONE" msgstr "অঞ্চল" #. 11 -#: ../cli/src/connections.c:191 +#: ../clients/cli/connections.c:181 msgid "MASTER-PATH" msgstr "মাস্টাৰ-পথ" #. 1 -#: ../cli/src/connections.c:203 +#: ../clients/cli/connections.c:193 msgid "USERNAME" msgstr "ব্যৱহাৰকাৰীনাম" #. 2 -#: ../cli/src/connections.c:204 +#: ../clients/cli/connections.c:194 msgid "GATEWAY" msgstr "গেইটৱে" #. 3 -#: ../cli/src/connections.c:205 +#: ../clients/cli/connections.c:195 msgid "BANNER" msgstr "বেনাৰ" #. 4 -#: ../cli/src/connections.c:206 +#: ../clients/cli/connections.c:196 msgid "VPN-STATE" msgstr "VPN-STATE" #. 5 -#: ../cli/src/connections.c:207 +#: ../clients/cli/connections.c:197 msgid "CFG" msgstr "CFG" -#: ../cli/src/connections.c:220 ../cli/src/devices.c:236 +#: ../clients/cli/connections.c:210 ../clients/cli/devices.c:216 msgid "GENERAL" msgstr "সাধাৰণ" #. 0 #. 6 -#: ../cli/src/connections.c:221 ../cli/src/devices.c:243 +#: ../clients/cli/connections.c:211 ../clients/cli/devices.c:223 msgid "IP4" msgstr "IP4" #. 1 #. 7 -#: ../cli/src/connections.c:222 ../cli/src/devices.c:244 +#: ../clients/cli/connections.c:212 ../clients/cli/devices.c:224 msgid "DHCP4" msgstr "DHCP4" #. 2 #. 8 -#: ../cli/src/connections.c:223 ../cli/src/devices.c:245 +#: ../clients/cli/connections.c:213 ../clients/cli/devices.c:225 msgid "IP6" msgstr "IP6" #. 3 #. 9 -#: ../cli/src/connections.c:224 ../cli/src/devices.c:246 +#: ../clients/cli/connections.c:214 ../clients/cli/devices.c:226 msgid "DHCP6" msgstr "DHCP6" -#: ../cli/src/connections.c:261 +#: ../clients/cli/connections.c:248 #, c-format msgid "" "Usage: nmcli connection { COMMAND | help }\n" @@ -639,7 +683,8 @@ msgid "" "\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n" "\n" -" modify [id | uuid | path] . \n" +" modify [--temporary] [id | uuid | path] ([+|-]. " +")+\n" "\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n" @@ -666,7 +711,8 @@ msgstr "" "\n" " add COMMON_OPTIONS TYPE_SPECIFIC_OPTIONS IP_OPTIONS\n" "\n" -" modify [id | uuid | path] . \n" +" modify [--temporary] [id | uuid | path] ([+|-]. " +")+\n" "\n" " edit [id | uuid | path] \n" " edit [type ] [con-name ]\n" @@ -678,7 +724,7 @@ msgstr "" " load [ ... ]\n" "\n" -#: ../cli/src/connections.c:283 +#: ../clients/cli/connections.c:269 #, c-format msgid "" "Usage: nmcli connection show { ARGUMENTS | help }\n" @@ -722,7 +768,7 @@ msgstr "" "যেতিয়া --active বিকল্প ধাৰ্য্য কৰা হয়, কেৱল সক্ৰিয় আলেখ্যসমূহ\n" "ব্যৱহাৰ কৰা হয়।\n" -#: ../cli/src/connections.c:305 +#: ../clients/cli/connections.c:290 #, c-format msgid "" "Usage: nmcli connection up { ARGUMENTS | help }\n" @@ -763,7 +809,7 @@ msgstr "" "nsp - সংযোগ কৰিবলে NSP ধাৰ্য্য কৰে (কেৱল WiMAX ৰ বাবে বৈধ)\n" "\n" -#: ../cli/src/connections.c:326 +#: ../clients/cli/connections.c:310 #, c-format msgid "" "Usage: nmcli connection down { ARGUMENTS | help }\n" @@ -785,7 +831,7 @@ msgstr "" "অথবা D-Bus পথ দ্বাৰা চিনাক্ত কৰা হয়।\n" "\n" -#: ../cli/src/connections.c:339 +#: ../clients/cli/connections.c:322 #, c-format #| msgid "" #| "Usage: nmcli connection add { ARGUMENTS | help }\n" @@ -798,6 +844,8 @@ msgstr "" #| " [con-name ]\n" #| " [autoconnect yes|no]\n" #| "\n" +#| " [save yes|no]\n" +#| "\n" #| " TYPE_SPECIFIC_OPTIONS:\n" #| " ethernet: [mac ]\n" #| " [cloned-mac ]\n" @@ -851,11 +899,11 @@ msgstr "" #| " [arp-interval ]\n" #| " [arp-ip-target ]\n" #| "\n" -#| " bond-slave: master \n" +#| " bond-slave: master \n" #| "\n" #| " team: [config |]\n" #| "\n" -#| " team-slave: master \n" +#| " team-slave: master \n" #| " [config |]\n" #| "\n" #| " bridge: [stp yes|no]\n" @@ -864,13 +912,15 @@ msgstr "" #| " [hello-time <1-10>]\n" #| " [max-age <6-40>]\n" #| " [ageing-time <0-1000000>]\n" +#| " [mac ]\n" #| "\n" -#| " bridge-slave: master \n" +#| " bridge-slave: master \n" #| " [priority <0-63>]\n" #| " [path-cost <1-65535>]\n" #| " [hairpin yes|no]\n" #| "\n" -#| " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan\n" +#| " vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|" +#| "libreswan|ssh|l2tp|iodine|...\n" #| " [user ]\n" #| "\n" #| " olpc-mesh: ssid \n" @@ -946,12 +996,13 @@ msgid "" " [updelay ]\n" " [arp-interval ]\n" " [arp-ip-target ]\n" +" [lacp-rate slow (0) | fast (1)]\n" "\n" -" bond-slave: master \n" +" bond-slave: master \n" "\n" " team: [config |]\n" "\n" -" team-slave: master \n" +" team-slave: master \n" " [config |]\n" "\n" " bridge: [stp yes|no]\n" @@ -960,13 +1011,15 @@ msgid "" " [hello-time <1-10>]\n" " [max-age <6-40>]\n" " [ageing-time <0-1000000>]\n" +" [mac ]\n" "\n" -" bridge-slave: master \n" +" bridge-slave: master \n" " [priority <0-63>]\n" " [path-cost <1-65535>]\n" " [hairpin yes|no]\n" "\n" -" vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan\n" +" vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|" +"ssh|l2tp|iodine|...\n" " [user ]\n" "\n" " olpc-mesh: ssid \n" @@ -1042,12 +1095,13 @@ msgstr "" " [updelay ]\n" " [arp-interval ]\n" " [arp-ip-target ]\n" +" [lacp-rate slow (0) | fast (1)]\n" "\n" -" bond-slave: master \n" +" bond-slave: master \n" "\n" " team: [config |]\n" "\n" -" team-slave: master \n" +" team-slave: master \n" " [config |]\n" "\n" " bridge: [stp yes|no]\n" @@ -1056,13 +1110,15 @@ msgstr "" " [hello-time <1-10>]\n" " [max-age <6-40>]\n" " [ageing-time <0-1000000>]\n" +" [mac ]\n" "\n" -" bridge-slave: master \n" +" bridge-slave: master \n" " [priority <0-63>]\n" " [path-cost <1-65535>]\n" " [hairpin yes|no]\n" "\n" -" vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan\n" +" vpn: vpn-type vpnc|openvpn|pptp|openconnect|openswan|libreswan|" +"ssh|l2tp|iodine|...\n" " [user ]\n" "\n" " olpc-mesh: ssid \n" @@ -1074,28 +1130,52 @@ msgstr "" " [ip6 ] [gw6 ]\n" "\n" -#: ../cli/src/connections.c:417 +#: ../clients/cli/connections.c:401 #, c-format msgid "" "Usage: nmcli connection modify { ARGUMENTS | help }\n" "\n" -"ARGUMENTS := [id | uuid | path] . " -"[]\n" +"ARGUMENTS := [id | uuid | path] ([+|-]. )+\n" "\n" -"Modify a single property in the connection profile.\n" -"The profile is identified by its name, UUID or D-Bus path.\n" +"Modify one or more properties of the connection profile.\n" +"The profile is identified by its name, UUID or D-Bus path. For multi-valued\n" +"properties you can use optional '+' or '-' prefix to the property name.\n" +"The '+' sign allows appending items instead of overwriting the whole value.\n" +"The '-' sign allows removing selected items instead of the whole value.\n" +"\n" +"Examples:\n" +"nmcli con mod home-wifi wifi.ssid rakosnicek\n" +"nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, " +"10.10.1.5/8\"\n" +"nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n" +"nmcli con mod em1-1 -ipv4.dns 1\n" +"nmcli con mod em1-1 -ipv6.addr \"abbe::cafe/56\"\n" +"nmcli con mod bond0 +bond.options mii=500\n" +"nmcli con mod bond0 -bond.options downdelay\n" "\n" msgstr "" -"ব্যৱহাৰ: nmcli connection modify { ARGUMENTS | help }\n" +"Usage: nmcli connection modify { ARGUMENTS | help }\n" "\n" -"ARGUMENTS := [id | uuid | path] . " -"[]\n" +"ARGUMENTS := [id | uuid | path] ([+|-]. )+\n" "\n" -"সংযোগ আলেখ্যগ এটা বৈশিষ্ট্য পৰিবৰ্তন কৰক।\n" -"আলেখ্যক তাৰ নাম, UUID অথবা D-Bus পথ দ্বাৰা চিনাক্ত কৰা হয়।\n" +"Modify one or more properties of the connection profile.\n" +"The profile is identified by its name, UUID or D-Bus path. For multi-valued\n" +"properties you can use optional '+' or '-' prefix to the property name.\n" +"The '+' sign allows appending items instead of overwriting the whole value.\n" +"The '-' sign allows removing selected items instead of the whole value.\n" +"\n" +"Examples:\n" +"nmcli con mod home-wifi wifi.ssid rakosnicek\n" +"nmcli con mod em1-1 ipv4.method manual ipv4.addr \"192.168.1.2/24, " +"10.10.1.5/8\"\n" +"nmcli con mod em1-1 +ipv4.dns 8.8.4.4\n" +"nmcli con mod em1-1 -ipv4.dns 1\n" +"nmcli con mod em1-1 -ipv6.addr \"abbe::cafe/56\"\n" +"nmcli con mod bond0 +bond.options mii=500\n" +"nmcli con mod bond0 -bond.options downdelay\n" "\n" -#: ../cli/src/connections.c:429 +#: ../clients/cli/connections.c:424 #, c-format msgid "" "Usage: nmcli connection edit { ARGUMENTS | help }\n" @@ -1122,7 +1202,7 @@ msgstr "" "এটা ভাৱবিনিময়ী সম্পাদকত এটা নতুন সংযোগ আলেখ্য যোগ কৰক।\n" "\n" -#: ../cli/src/connections.c:445 +#: ../clients/cli/connections.c:439 #, c-format msgid "" "Usage: nmcli connection delete { ARGUMENTS | help }\n" @@ -1141,7 +1221,7 @@ msgstr "" "আলেখ্যক তাৰ নাম, UUID অথবা D-Bus পথ দ্বাৰা চিনাক্ত কৰা হয়।\n" "\n" -#: ../cli/src/connections.c:457 +#: ../clients/cli/connections.c:450 #, c-format msgid "" "Usage: nmcli connection reload { help }\n" @@ -1154,7 +1234,7 @@ msgstr "" "ডিস্কৰ পৰা সকলো সংযোগ ফাইল পুনৰ লড কৰক\n" "\n" -#: ../cli/src/connections.c:466 +#: ../clients/cli/connections.c:458 #, c-format msgid "" "Usage: nmcli connection load { ARGUMENTS | help }\n" @@ -1177,335 +1257,330 @@ msgstr "" "তাৰ শেহতীয়া অৱস্থাৰ বিষয়ে জ্ঞাত।\n" "\n" -#: ../cli/src/connections.c:524 +#: ../clients/cli/connections.c:529 msgid "activating" msgstr "সক্ৰিয় কৰা হৈছে" -#: ../cli/src/connections.c:526 +#: ../clients/cli/connections.c:531 msgid "activated" msgstr "সক্ৰিয়" -#: ../cli/src/connections.c:530 +#: ../clients/cli/connections.c:535 msgid "deactivated" msgstr "নিষ্ক্ৰিয়" -#: ../cli/src/connections.c:542 +#: ../clients/cli/connections.c:547 msgid "VPN connecting (prepare)" msgstr "VPN সংযোগ কৰা হৈছে (প্ৰস্তুত হওক)" -#: ../cli/src/connections.c:544 +#: ../clients/cli/connections.c:549 msgid "VPN connecting (need authentication)" msgstr "VPN সংযোগ কৰা হৈছে (প্ৰমাণীকৰণৰ প্ৰয়োজন)" -#: ../cli/src/connections.c:546 +#: ../clients/cli/connections.c:551 msgid "VPN connecting" msgstr "VPN সংযোগ কৰা হৈছে" -#: ../cli/src/connections.c:548 +#: ../clients/cli/connections.c:553 msgid "VPN connecting (getting IP configuration)" msgstr "VPN সংযোগ কৰা (IP সংৰূপ প্ৰাপ্ত কৰা)" -#: ../cli/src/connections.c:550 +#: ../clients/cli/connections.c:555 msgid "VPN connected" msgstr "VPN সংযুক্ত" -#: ../cli/src/connections.c:552 +#: ../clients/cli/connections.c:557 msgid "VPN connection failed" msgstr "VPN সংযোগ ব্যৰ্থ হল" -#: ../cli/src/connections.c:554 +#: ../clients/cli/connections.c:559 msgid "VPN disconnected" msgstr "VPN বিচ্ছিন্নিত" -#: ../cli/src/connections.c:637 +#: ../clients/cli/connections.c:642 msgid "Connection profile details" msgstr "সংযোগ আলেখ্যৰ বিৱৰণ" -#: ../cli/src/connections.c:649 ../cli/src/connections.c:1046 +#: ../clients/cli/connections.c:654 ../clients/cli/connections.c:1006 #, c-format msgid "Error: 'connection show': %s" msgstr "ত্ৰুটি: 'connection show': %s" -#: ../cli/src/connections.c:843 +#: ../clients/cli/connections.c:798 msgid "never" msgstr "কেতিয়াও নহয়" #. "CAPABILITIES" -#: ../cli/src/connections.c:844 ../cli/src/connections.c:845 -#: ../cli/src/connections.c:847 ../cli/src/connections.c:906 -#: ../cli/src/connections.c:907 ../cli/src/connections.c:909 -#: ../cli/src/connections.c:6377 ../cli/src/connections.c:6378 -#: ../cli/src/devices.c:606 ../cli/src/devices.c:656 ../cli/src/devices.c:798 -#: ../cli/src/devices.c:799 ../cli/src/devices.c:800 ../cli/src/devices.c:833 -#: ../cli/src/devices.c:862 ../cli/src/devices.c:863 ../cli/src/devices.c:864 -#: ../cli/src/devices.c:865 ../cli/src/devices.c:866 ../cli/src/devices.c:867 -#: ../cli/src/devices.c:868 ../cli/src/network-manager.c:442 +#: ../clients/cli/connections.c:799 ../clients/cli/connections.c:800 +#: ../clients/cli/connections.c:802 ../clients/cli/connections.c:861 +#: ../clients/cli/connections.c:862 ../clients/cli/connections.c:864 +#: ../clients/cli/connections.c:2765 ../clients/cli/connections.c:6495 +#: ../clients/cli/connections.c:6496 ../clients/cli/devices.c:586 +#: ../clients/cli/devices.c:636 ../clients/cli/devices.c:857 +#: ../clients/cli/devices.c:858 ../clients/cli/devices.c:859 +#: ../clients/cli/devices.c:860 ../clients/cli/devices.c:893 +#: ../clients/cli/devices.c:895 ../clients/cli/devices.c:923 +#: ../clients/cli/devices.c:924 ../clients/cli/devices.c:925 +#: ../clients/cli/devices.c:926 ../clients/cli/devices.c:927 +#: ../clients/cli/devices.c:928 ../clients/cli/devices.c:929 +#: ../clients/cli/general.c:420 msgid "yes" msgstr "হয়" -#: ../cli/src/connections.c:844 ../cli/src/connections.c:845 -#: ../cli/src/connections.c:847 ../cli/src/connections.c:906 -#: ../cli/src/connections.c:907 ../cli/src/connections.c:909 -#: ../cli/src/connections.c:6377 ../cli/src/connections.c:6378 -#: ../cli/src/devices.c:606 ../cli/src/devices.c:656 ../cli/src/devices.c:798 -#: ../cli/src/devices.c:799 ../cli/src/devices.c:800 ../cli/src/devices.c:833 -#: ../cli/src/devices.c:862 ../cli/src/devices.c:863 ../cli/src/devices.c:864 -#: ../cli/src/devices.c:865 ../cli/src/devices.c:866 ../cli/src/devices.c:867 -#: ../cli/src/devices.c:868 ../cli/src/network-manager.c:444 +#: ../clients/cli/connections.c:799 ../clients/cli/connections.c:800 +#: ../clients/cli/connections.c:802 ../clients/cli/connections.c:861 +#: ../clients/cli/connections.c:862 ../clients/cli/connections.c:864 +#: ../clients/cli/connections.c:2766 ../clients/cli/connections.c:6495 +#: ../clients/cli/connections.c:6496 ../clients/cli/devices.c:586 +#: ../clients/cli/devices.c:636 ../clients/cli/devices.c:857 +#: ../clients/cli/devices.c:858 ../clients/cli/devices.c:859 +#: ../clients/cli/devices.c:860 ../clients/cli/devices.c:893 +#: ../clients/cli/devices.c:895 ../clients/cli/devices.c:923 +#: ../clients/cli/devices.c:924 ../clients/cli/devices.c:925 +#: ../clients/cli/devices.c:926 ../clients/cli/devices.c:927 +#: ../clients/cli/devices.c:928 ../clients/cli/devices.c:929 +#: ../clients/cli/general.c:422 msgid "no" msgstr "নহয়" -#: ../cli/src/connections.c:902 ../cli/src/connections.c:912 -#: ../cli/src/devices.c:596 +#: ../clients/cli/connections.c:857 ../clients/cli/connections.c:867 +#: ../clients/cli/devices.c:576 msgid "N/A" msgstr "অপ্ৰযোজ্য" -#: ../cli/src/connections.c:1034 +#: ../clients/cli/connections.c:994 msgid "Activate connection details" msgstr "সক্ৰিয় সংযোগৰ বিৱৰণ" -#: ../cli/src/connections.c:1267 +#: ../clients/cli/connections.c:1227 #, c-format msgid "invalid field '%s'; allowed fields: %s and %s, or %s,%s" msgstr "অবৈধ ফিল্ড '%s'; অনুমোদিত ফিল্ডসমূহ: %s আৰু %s, অথবা %s,%s" -#: ../cli/src/connections.c:1282 ../cli/src/connections.c:1290 +#: ../clients/cli/connections.c:1242 ../clients/cli/connections.c:1250 #, c-format -msgid "'%s' has to be alone'" -msgstr "'%s' অকলে থাকিব লাগিব'" - -#: ../cli/src/connections.c:1321 ../cli/src/connections.c:2047 -#: ../cli/src/connections.c:2107 ../cli/src/connections.c:7877 -#: ../cli/src/connections.c:7993 ../cli/src/connections.c:8086 -#: ../cli/src/connections.c:8114 ../cli/src/devices.c:1199 -#: ../cli/src/devices.c:1247 ../cli/src/devices.c:1405 -#: ../cli/src/devices.c:1540 ../cli/src/devices.c:1677 -#: ../cli/src/devices.c:2121 ../cli/src/devices.c:2420 -#: ../cli/src/network-manager.c:484 -#, c-format -msgid "Error: NetworkManager is not running." -msgstr "ত্ৰুটি: NetworkManager চলি থকা নাই।" +msgid "'%s' has to be alone" +msgstr "'%s' অকলে থাকিব লাগিব" #. Add headers -#: ../cli/src/connections.c:1351 +#: ../clients/cli/connections.c:1304 msgid "NetworkManager active profiles" msgstr "NetworkManager সক্ৰিয় আলেখ্যসমূহ" -#: ../cli/src/connections.c:1352 +#: ../clients/cli/connections.c:1305 msgid "NetworkManager connection profiles" msgstr "NetworkManager সংযোগ আলেখ্যসমূহ" -#: ../cli/src/connections.c:1389 ../cli/src/connections.c:1992 -#: ../cli/src/connections.c:2008 ../cli/src/connections.c:2017 -#: ../cli/src/connections.c:2027 ../cli/src/connections.c:2124 -#: ../cli/src/connections.c:7848 ../cli/src/connections.c:8024 -#: ../cli/src/devices.c:1635 ../cli/src/devices.c:1643 -#: ../cli/src/devices.c:2034 ../cli/src/devices.c:2041 -#: ../cli/src/devices.c:2055 ../cli/src/devices.c:2062 -#: ../cli/src/devices.c:2079 ../cli/src/devices.c:2087 -#: ../cli/src/devices.c:2283 ../cli/src/devices.c:2379 -#: ../cli/src/devices.c:2386 +#: ../clients/cli/connections.c:1342 ../clients/cli/connections.c:1946 +#: ../clients/cli/connections.c:1962 ../clients/cli/connections.c:1971 +#: ../clients/cli/connections.c:1981 ../clients/cli/connections.c:2060 +#: ../clients/cli/connections.c:8006 ../clients/cli/connections.c:8224 +#: ../clients/cli/devices.c:1887 ../clients/cli/devices.c:1895 +#: ../clients/cli/devices.c:2211 ../clients/cli/devices.c:2218 +#: ../clients/cli/devices.c:2232 ../clients/cli/devices.c:2239 +#: ../clients/cli/devices.c:2256 ../clients/cli/devices.c:2264 +#: ../clients/cli/devices.c:2453 ../clients/cli/devices.c:2549 +#: ../clients/cli/devices.c:2556 #, c-format msgid "Error: %s argument is missing." -msgstr "ত্ৰুটি: %s তৰ্ক সন্ধানহিন।" +msgstr "ত্ৰুটি: %s তৰ্ক সন্ধানহীন।" -#: ../cli/src/connections.c:1440 +#: ../clients/cli/connections.c:1393 #, c-format msgid "Error: %s - no such connection profile." msgstr "ত্ৰুটি: %s - এই ধৰণৰ কোনো সংযোগ আলেখ্য নাই।" -#: ../cli/src/connections.c:1456 ../cli/src/connections.c:2060 -#: ../cli/src/connections.c:8092 ../cli/src/connections.c:8133 -#: ../cli/src/connections.c:8280 ../cli/src/devices.c:2262 -#: ../cli/src/devices.c:2636 ../cli/src/network-manager.c:539 -#: ../cli/src/network-manager.c:582 ../cli/src/network-manager.c:599 -#: ../cli/src/network-manager.c:645 ../cli/src/network-manager.c:659 -#: ../cli/src/network-manager.c:776 ../cli/src/network-manager.c:820 -#: ../cli/src/network-manager.c:840 +#: ../clients/cli/connections.c:1409 ../clients/cli/connections.c:2005 +#: ../clients/cli/connections.c:8535 ../clients/cli/devices.c:2432 +#: ../clients/cli/devices.c:2897 ../clients/cli/general.c:517 +#: ../clients/cli/general.c:564 ../clients/cli/general.c:581 +#: ../clients/cli/general.c:630 ../clients/cli/general.c:644 +#: ../clients/cli/general.c:760 ../clients/cli/general.c:804 +#: ../clients/cli/general.c:824 #, c-format msgid "Error: %s." msgstr "ত্ৰুটি: %s।" -#: ../cli/src/connections.c:1551 +#: ../clients/cli/connections.c:1504 #, c-format msgid "no active connection on device '%s'" msgstr "ডিভাইচ '%s' ত কোনো সক্ৰিয় সংযোগ নাই" -#: ../cli/src/connections.c:1559 +#: ../clients/cli/connections.c:1512 msgid "no active connection or device" msgstr "কোনো সক্ৰিয় সংযোগ অথবা ডিভাইচ নাই" -#: ../cli/src/connections.c:1630 +#: ../clients/cli/connections.c:1583 #, c-format msgid "device '%s' not compatible with connection '%s'" msgstr "ডিভাইচ '%s' সংযোগ '%s' ৰ সৈতে সংগত নহয়" -#: ../cli/src/connections.c:1633 +#: ../clients/cli/connections.c:1586 #, c-format msgid "no device found for connection '%s'" msgstr "সংযোগ '%s' ৰ বাবে কোনো ডিভাইচ পোৱা নগল" -#: ../cli/src/connections.c:1645 +#: ../clients/cli/connections.c:1598 msgid "unknown reason" msgstr "অজ্ঞাত কাৰণ" -#: ../cli/src/connections.c:1647 ../cli/src/network-manager.c:288 +#: ../clients/cli/connections.c:1600 ../clients/cli/general.c:271 msgid "none" msgstr "কোনো নহয়" -#: ../cli/src/connections.c:1649 +#: ../clients/cli/connections.c:1602 msgid "the user was disconnected" msgstr "ব্যৱহাৰকাৰীজনক বিচ্ছিন্ন কৰা হৈছিল" -#: ../cli/src/connections.c:1651 +#: ../clients/cli/connections.c:1604 msgid "the base network connection was interrupted" -msgstr "ভিত্তি নেটৱাৰ্ক সংযোগ বাধাগ্ৰস্থ হৈছিল" +msgstr "ভিত্তি নেটৱৰ্ক সংযোগ বাধাগ্ৰস্থ হৈছিল" -#: ../cli/src/connections.c:1653 +#: ../clients/cli/connections.c:1606 msgid "the VPN service stopped unexpectedly" msgstr "VPN সেৱা অপ্ৰত্যাশিতভাৱে বন্ধ হল" -#: ../cli/src/connections.c:1655 +#: ../clients/cli/connections.c:1608 msgid "the VPN service returned invalid configuration" msgstr "VPN সেৱায় অবৈধ সংৰূপ ঘুৰাই দিলে" -#: ../cli/src/connections.c:1657 +#: ../clients/cli/connections.c:1610 msgid "the connection attempt timed out" msgstr "সংযোগৰ চেষ্টাৰ সময় অন্ত হল" -#: ../cli/src/connections.c:1659 +#: ../clients/cli/connections.c:1612 msgid "the VPN service did not start in time" msgstr "VPN সেৱা সময়ত আৰম্ভ নহল" -#: ../cli/src/connections.c:1661 +#: ../clients/cli/connections.c:1614 msgid "the VPN service failed to start" msgstr "VPN সেৱা আৰম্ভ হবলে ব্যৰ্থ হল" -#: ../cli/src/connections.c:1663 +#: ../clients/cli/connections.c:1616 msgid "no valid VPN secrets" msgstr "কোনো বৈধ VPN গোপন তথ্য নাই" -#: ../cli/src/connections.c:1665 +#: ../clients/cli/connections.c:1618 msgid "invalid VPN secrets" msgstr "অবৈধ VPN গোপন তথ্য" -#: ../cli/src/connections.c:1667 +#: ../clients/cli/connections.c:1620 msgid "the connection was removed" msgstr "সংযোগ আতৰোৱা হৈছিল" -#: ../cli/src/connections.c:1684 ../cli/src/connections.c:1840 -#: ../cli/src/connections.c:6280 +#: ../clients/cli/connections.c:1642 ../clients/cli/connections.c:1670 +#: ../clients/cli/connections.c:1826 ../clients/cli/connections.c:6386 #, c-format msgid "Connection successfully activated (D-Bus active path: %s)\n" msgstr "সংযোগ সফলভাৱে সক্ৰিয় কৰা হৈছিল (D-Bus সক্ৰিয় পথ: %s)\n" -#: ../cli/src/connections.c:1689 +#: ../clients/cli/connections.c:1649 +#, c-format +msgid "" +"Connection successfully activated (master waiting for slaves) (D-Bus active " +"path: %s)\n" +msgstr "" +"সংযোগ সফলভাৱে সক্ৰিয় কৰা হৈছে (মাস্টাৰে স্লেইভৰ বাবে অপেক্ষা কৰি আছে) (D-Bus " +"সক্ৰিয় পথ: %s)\n" + +#: ../clients/cli/connections.c:1653 ../clients/cli/connections.c:1676 #, c-format msgid "Error: Connection activation failed." msgstr "ত্ৰুটি: সংযোগৰ সক্ৰিয়কৰণ ব্যৰ্থ হল।" -#: ../cli/src/connections.c:1714 +#: ../clients/cli/connections.c:1720 #, c-format msgid "VPN connection successfully activated (D-Bus active path: %s)\n" msgstr "VPN সংযোগ সফলভাৱে সক্ৰিয় কৰা হল (D-Bus সক্ৰিয় পথ: %s)\n" -#: ../cli/src/connections.c:1721 +#: ../clients/cli/connections.c:1728 #, c-format msgid "Error: Connection activation failed: %s." msgstr "ত্ৰুটি: সংযোগৰ সক্ৰিয়কৰণ ব্যৰ্থ হল: %s।" -#: ../cli/src/connections.c:1739 ../cli/src/devices.c:1296 +#: ../clients/cli/connections.c:1747 ../clients/cli/devices.c:1331 #, c-format msgid "Error: Timeout %d sec expired." msgstr "ত্ৰুটি: সময়অন্ত %d sec ৰ অৱসান ঘটিল" -#: ../cli/src/connections.c:1804 -#, c-format -msgid "" -"Error: Device '%s' is waiting for slaves before proceeding with activation." -msgstr "ত্ৰুটি: ডিভাইচ '%s' এ সক্ৰিয়কৰণৰ আগত স্লেইভসমূহৰ বাবে অপেক্ষা কৰি আছে।" - -#: ../cli/src/connections.c:1824 +#: ../clients/cli/connections.c:1808 #, c-format msgid "Error: Connection activation failed: %s" msgstr "ত্ৰুটি: সংযোগৰ সক্ৰিয়কৰণ ব্যৰ্থ হল: %s" -#: ../cli/src/connections.c:1929 ../cli/src/connections.c:2061 +#: ../clients/cli/connections.c:1884 ../clients/cli/connections.c:2006 msgid "unknown error" msgstr "অজ্ঞাত ত্ৰুটি" -#: ../cli/src/connections.c:1937 +#: ../clients/cli/connections.c:1892 #, c-format msgid "unknown device '%s'." msgstr "অজ্ঞাত ডিভাইচ '%s'।" -#: ../cli/src/connections.c:1942 +#: ../clients/cli/connections.c:1897 msgid "neither a valid connection nor device given" msgstr "এটা বৈধ সংযোগ অথবা ডিভাইচ দিয়া হোৱা নাই" -#: ../cli/src/connections.c:1980 ../cli/src/connections.c:2092 -#: ../cli/src/connections.c:8000 -msgid "Connection (name, UUID, or path): " -msgstr "সংযোগ (নাম, UUID, অথবা পথ):" - -#: ../cli/src/connections.c:2036 ../cli/src/devices.c:1173 -#: ../cli/src/devices.c:1649 ../cli/src/devices.c:2098 -#: ../cli/src/devices.c:2392 +#: ../clients/cli/connections.c:1990 ../clients/cli/devices.c:1230 +#: ../clients/cli/devices.c:1901 ../clients/cli/devices.c:2275 +#: ../clients/cli/devices.c:2562 #, c-format msgid "Unknown parameter: %s\n" msgstr "অজ্ঞাত প্ৰাচল: %s\n" -#: ../cli/src/connections.c:2069 +#: ../clients/cli/connections.c:2014 msgid "preparing" msgstr "প্ৰস্তুত কৰা হৈছে" -#: ../cli/src/connections.c:2097 ../cli/src/connections.c:8005 -#: ../cli/src/connections.c:8120 +#: ../clients/cli/connections.c:2042 ../clients/cli/connections.c:8205 +#: ../clients/cli/connections.c:8320 #, c-format msgid "Error: No connection specified." msgstr "ত্ৰুটি: কোনো সংযোগ ধাৰ্য্য কৰা হোৱা নাই।" -#: ../cli/src/connections.c:2134 +#: ../clients/cli/connections.c:2070 #, c-format msgid "Error: '%s' is not an active connection." msgstr "ত্ৰুটি: '%s' এটা সক্ৰিয় সংযোগ নহয়।" -#: ../cli/src/connections.c:2446 ../cli/src/utils.c:507 +#: ../clients/cli/connections.c:2371 ../clients/cli/utils.c:517 #, c-format msgid "'%s' not among [%s]" msgstr "'%s' [%s] ত অন্তৰ্ভুক্ত নহয়" -#: ../cli/src/connections.c:2528 +#: ../clients/cli/connections.c:2450 #, c-format msgid "Error: '%s': '%s' is not a valid %s MAC address." msgstr "ত্ৰুটি: '%s': '%s' এটা বৈধ %s MAC ঠিকনা নহয়।" -#: ../cli/src/connections.c:2529 ../libnm-glib/nm-device.c:1822 -#: ../tui/nm-editor-utils.c:173 +#. Ask for optional arguments +#: ../clients/cli/connections.c:2451 ../clients/cli/connections.c:2881 +#: ../clients/tui/nm-editor-utils.c:164 ../libnm-core/nm-connection.c:1509 +#: ../libnm-glib/nm-device.c:1800 msgid "InfiniBand" msgstr "InfiniBand" -#: ../cli/src/connections.c:2529 ../libnm-glib/nm-device.c:1810 -#: ../tui/nm-editor-utils.c:156 +#: ../clients/cli/connections.c:2451 ../clients/tui/nm-editor-utils.c:147 +#: ../libnm-glib/nm-device.c:1788 msgid "Ethernet" msgstr "ইথাৰনেট" -#: ../cli/src/connections.c:2552 +#: ../clients/cli/connections.c:2471 #, c-format msgid "Error: 'mtu': '%s' is not a valid MTU." msgstr "ত্ৰুটি: 'mtu': '%s' এটা বৈধ MTU।" -#: ../cli/src/connections.c:2568 +#: ../clients/cli/connections.c:2487 #, c-format msgid "Error: 'parent': '%s' is not a valid interface name." msgstr "ত্ৰুটি: 'parent': '%s' এটা বৈধ আন্তঃপৃষ্ঠ নাম নহয়।" -#: ../cli/src/connections.c:2589 +#: ../clients/cli/connections.c:2508 #, c-format msgid "Error: 'p-key': '%s' is not a valid InfiniBand P_KEY." msgstr "ত্ৰুটি: 'p-key': '%s' এটা বৈধ InfiniBand P_KEY নহয়।" -#: ../cli/src/connections.c:2605 +#: ../clients/cli/connections.c:2537 #, c-format msgid "" "Error: 'mode': '%s' is not a valid InfiniBand transport mode [datagram, " @@ -1514,481 +1589,472 @@ msgstr "" "ত্ৰুটি: 'mode': '%s' এটা বৈধ InfiniBand পৰিবহন অৱস্থা [datagram, connected] " "নহয়।" -#: ../cli/src/connections.c:2621 +#: ../clients/cli/connections.c:2551 #, c-format msgid "Error: 'flags': '%s' is not valid; use <0-7>." msgstr "ত্ৰুটি: 'flags': '%s' বৈধ নহয়; <0-7> ব্যৱহাৰ কৰক।" -#: ../cli/src/connections.c:2643 +#: ../clients/cli/connections.c:2573 #, c-format msgid "Error: '%s': '%s' is not valid; %s " msgstr "ত্ৰুটি: '%s': '%s' বৈধ নহয়; %s " -#: ../cli/src/connections.c:2750 +#: ../clients/cli/connections.c:2756 #, c-format msgid "Error: '%s': '%s' is not valid; use <%u-%u>." msgstr "ত্ৰুটি: '%s': '%s' বৈধ নহয়; <%u-%u> ব্যৱহাৰ কৰক।" -#: ../cli/src/connections.c:2764 +#. Ask for optional arguments. +#: ../clients/cli/connections.c:2812 +#, c-format +msgid "There is %d optional argument for '%s' connection type.\n" +msgid_plural "There are %d optional arguments for '%s' connection type.\n" +msgstr[0] "%d বৈকল্পিক তৰ্ক আছে, '%s' সংযোগ ধৰণৰ বাবে।\n" +msgstr[1] "%d বৈকল্পিক তৰ্কসমূহ আছে, '%s' সংযোগ ধৰণৰ বাবে।\n" + +#: ../clients/cli/connections.c:2815 +#, c-format +msgid "Do you want to provide it? %s" +msgid_plural "Do you want to provide them? %s" +msgstr[0] "আপুনি ইয়াক প্ৰদান কৰিব খোজে নে? %s" +msgstr[1] "আপুনি ইহতক প্ৰদান কৰিব খোজে নে? %s" + +#: ../clients/cli/connections.c:2830 msgid "ethernet" msgstr "ইথাৰনেট" -#: ../cli/src/connections.c:2764 ../libnm-glib/nm-device.c:1812 -#: ../tui/nm-editor-utils.c:164 +#: ../clients/cli/connections.c:2830 ../clients/tui/nm-editor-utils.c:155 +#: ../libnm-glib/nm-device.c:1790 msgid "Wi-Fi" msgstr "Wi-Fi" -#. Ask for optional arguments -#: ../cli/src/connections.c:2767 -#, c-format -msgid "There are 3 optional arguments for '%s' connection type.\n" -msgstr "'%s' সংযোগ ধৰণৰ বাবে ৩ টা বৈকল্পিক তৰ্ক আছে।\n" - -#: ../cli/src/connections.c:2768 ../cli/src/connections.c:2822 -#: ../cli/src/connections.c:2944 ../cli/src/connections.c:2990 -#: ../cli/src/connections.c:3050 ../cli/src/connections.c:3118 -#: ../cli/src/connections.c:3281 ../cli/src/connections.c:3377 -#: ../cli/src/connections.c:3459 -msgid "Do you want to provide them? (yes/no) [yes] " -msgstr "আপুনি সিহতক প্ৰদান কৰিব খোজে নে? (হয়/নহয়) [হয়] " - -#: ../cli/src/connections.c:2776 ../cli/src/connections.c:2830 -#: ../cli/src/connections.c:2957 ../cli/src/connections.c:3058 +#: ../clients/cli/connections.c:2838 ../clients/cli/connections.c:2886 +#: ../clients/cli/connections.c:2995 ../clients/cli/connections.c:3074 msgid "MTU [auto]: " msgstr "MTU [auto]: " -#: ../cli/src/connections.c:2787 ../cli/src/connections.c:2841 -#: ../cli/src/connections.c:2920 ../cli/src/connections.c:2968 +#: ../clients/cli/connections.c:2849 ../clients/cli/connections.c:2897 +#: ../clients/cli/connections.c:2967 ../clients/cli/connections.c:3006 +#: ../clients/cli/connections.c:3378 msgid "MAC [none]: " msgstr "MAC [none]: " -#: ../cli/src/connections.c:2798 +#: ../clients/cli/connections.c:2860 msgid "Cloned MAC [none]: " msgstr "ক্লৌণ্ড MAC [none]: " -#. Ask for optional arguments -#: ../cli/src/connections.c:2821 +#: ../clients/cli/connections.c:2908 #, c-format -msgid "There are 5 optional arguments for 'InfiniBand' connection type.\n" -msgstr "'InfiniBand' সংযোগ ধৰণৰ বাবে ৫ টা বৈকল্পিক তৰ্ক আছে।\n" +msgid "Transport mode %s" +msgstr "পৰিৱহন অৱস্থা %s" -#: ../cli/src/connections.c:2852 -msgid "Transport mode (datagram or connected) [datagram]: " -msgstr "পৰিবহন অৱস্থা (datagram অথবা connected) [datagram]: " - -#: ../cli/src/connections.c:2865 +#: ../clients/cli/connections.c:2921 msgid "Parent interface [none]: " msgstr "উপধায়ক আন্তঃপৃষ্ঠ [none]: " -#: ../cli/src/connections.c:2876 +#: ../clients/cli/connections.c:2932 msgid "P_KEY [none]: " msgstr "P_KEY [none]: " -#: ../cli/src/connections.c:2886 +#: ../clients/cli/connections.c:2942 #, c-format msgid "Error: 'p-key' is mandatory when 'parent' is specified.\n" msgstr "ত্ৰুটি: 'parent' ধাৰ্য্য কৰোতে 'p-key' বাধ্যতামূলক।\n" #. Ask for optional 'wimax' arguments. -#: ../cli/src/connections.c:2911 -#, c-format -msgid "There is 1 optional argument for 'WiMax' connection type.\n" -msgstr "'WiMax' সংযোগ ধৰণৰ বাবে ১ টা বৈকল্পিক তৰ্ক আছে।\n" - -#: ../cli/src/connections.c:2912 ../cli/src/connections.c:3014 -#: ../cli/src/connections.c:3233 ../cli/src/connections.c:3435 -msgid "Do you want to provide it? (yes/no) [yes] " -msgstr "আপুনি ইয়াক প্ৰদান কৰিব বিচাৰে নে? (হয়/নহয়) [হয়] " +#: ../clients/cli/connections.c:2962 ../libnm-glib/nm-device.c:1796 +msgid "WiMAX" +msgstr "WiMAX" #. Ask for optional 'pppoe' arguments. -#: ../cli/src/connections.c:2943 -#, c-format -msgid "There are 4 optional arguments for 'PPPoE' connection type.\n" -msgstr "'PPPoE' সংযোগ ধৰণৰ বাবে ৪ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:2985 +msgid "PPPoE" +msgstr "PPPoE" -#: ../cli/src/connections.c:2951 ../cli/src/connections.c:2999 +#: ../clients/cli/connections.c:2989 ../clients/cli/connections.c:3027 msgid "Password [none]: " -msgstr "পাছৱাৰ্ড [none]: " +msgstr "পাছৱৰ্ড [none]: " -#: ../cli/src/connections.c:2953 +#: ../clients/cli/connections.c:2991 msgid "Service [none]: " msgstr "সেৱা [একো নাই]: " #. Ask for optional 'gsm' or 'cdma' arguments. -#: ../cli/src/connections.c:2989 -#, c-format -msgid "" -"There are 2 optional arguments for 'mobile broadband' connection type.\n" -msgstr "'মবাইল ব্ৰডবেণ্ড' সংযোগ ধৰণৰ বাবে ২ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:3021 +msgid "mobile broadband" +msgstr "ম'বাইল ব্ৰ'ডবেণ্ড" -#: ../cli/src/connections.c:2997 ../cli/src/connections.c:3442 +#: ../clients/cli/connections.c:3025 ../clients/cli/connections.c:3450 msgid "Username [none]: " msgstr "ব্যৱহাৰকাৰীনাম [none]: " #. Ask for optional 'bluetooth' arguments. -#: ../cli/src/connections.c:3013 -#, c-format -msgid "There is 1 optional argument for 'bluetooth' connection type.\n" -msgstr "'ব্লুটুথ' সংযোগ ধৰণৰ বাবে ১ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:3040 +msgid "bluetooth" +msgstr "ব্লুটুথ" -#: ../cli/src/connections.c:3022 -msgid "Bluetooth type (panu, dun-gsm or dun-cdma) [panu]: " -msgstr "ব্লুটুথ ধৰণ (panu, dun-gsm or dun-cdma) [panu]: " +#: ../clients/cli/connections.c:3047 +#, c-format +msgid "Bluetooth type %s" +msgstr "ব্লুটুথৰ ধৰণ %s" -#: ../cli/src/connections.c:3030 +#: ../clients/cli/connections.c:3053 #, c-format msgid "Error: 'bt-type': '%s' is not a valid bluetooth type.\n" msgstr "ত্ৰুটি: 'bt-type': '%s' এটা বৈধ ব্লুটুথ ধৰণ নহয়।\n" #. Ask for optional 'vlan' arguments. -#: ../cli/src/connections.c:3049 -#, c-format -msgid "There are 4 optional arguments for 'VLAN' connection type.\n" -msgstr "'VLAN' সংযোগ ধৰণৰ বাবে ৪ টা বৈকল্পিক তৰ্ক আছে।\n" +#. 13 +#: ../clients/cli/connections.c:3069 ../clients/cli/devices.c:230 +#: ../clients/tui/nm-editor-utils.c:218 ../clients/tui/nmt-page-vlan.c:51 +#: ../libnm-core/nm-connection.c:1507 ../libnm-glib/nm-device.c:1808 +#: ../libnm-util/nm-connection.c:1612 +msgid "VLAN" +msgstr "VLAN" -#: ../cli/src/connections.c:3069 +#: ../clients/cli/connections.c:3085 msgid "VLAN flags (<0-7>) [none]: " msgstr "VLAN ফ্লেগসমূহ (<0-7>) [none]: " -#: ../cli/src/connections.c:3080 +#: ../clients/cli/connections.c:3096 msgid "Ingress priority maps [none]: " msgstr "Ingress প্ৰাথমিকতা মেপসমূহ [none]: " -#: ../cli/src/connections.c:3091 +#: ../clients/cli/connections.c:3107 msgid "Egress priority maps [none]: " msgstr "Egress প্ৰাথমিকতা মেপসমূহ [none]: " -#. Ask for optional 'bond' arguments. -#: ../cli/src/connections.c:3117 -#, c-format -msgid "There are optional arguments for 'bond' connection type.\n" -msgstr "'বান্ধনী' সংযোগ ধৰণৰ বাবে বৈকল্পিক তৰ্কসমূহ আছে।\n" - -#: ../cli/src/connections.c:3127 +#: ../clients/cli/connections.c:3118 msgid "Bonding mode [balance-rr]: " msgstr "বান্ধনী অৱস্থা [balance-rr]: " -#: ../cli/src/connections.c:3143 +#. Ask for optional 'bond' arguments. +#: ../clients/cli/connections.c:3134 +msgid "bond" +msgstr "বান্ধনী" + +#: ../clients/cli/connections.c:3156 msgid "Bonding primary interface [none]: " msgstr "বান্ধনী প্ৰাথমিক আন্তঃপৃষ্ঠ [none]: " -#: ../cli/src/connections.c:3146 +#: ../clients/cli/connections.c:3159 #, c-format msgid "Error: 'primary': '%s' is not a valid interface name.\n" msgstr "ত্ৰুটি: 'primary': '%s' এটা বৈধ আন্তঃপৃষ্ঠ নাম নহয়। \n" -#: ../cli/src/connections.c:3154 -msgid "Bonding monitoring mode (miimon or arp) [miimon]: " -msgstr "বান্ধনী মনিটৰিং অৱস্থা (miimon অথবা arp) [miimon]: " +#: ../clients/cli/connections.c:3167 +#, c-format +msgid "Bonding monitoring mode %s" +msgstr "বান্ধনী পৰ্যবেক্ষণ অৱস্থা %s" -#: ../cli/src/connections.c:3159 +#: ../clients/cli/connections.c:3173 #, c-format msgid "Error: '%s' is not a valid monitoring mode; use '%s' or '%s'.\n" msgstr "ত্ৰুটি: '%s' এটা বৈধ মনিটৰিং অৱস্থা নহয়; '%s' অথবা '%s' ব্যৱহাৰ কৰক।\n" -#: ../cli/src/connections.c:3168 +#: ../clients/cli/connections.c:3182 msgid "Bonding miimon [100]: " msgstr "বান্ধনী miimon [100]: " -#: ../cli/src/connections.c:3171 +#: ../clients/cli/connections.c:3185 #, c-format msgid "Error: 'miimon': '%s' is not a valid number <0-%u>.\n" msgstr "ত্ৰুটি: 'miimon': '%s' এটা বৈধ সংখ্যা <0-%u> নহয়।\n" -#: ../cli/src/connections.c:3179 +#: ../clients/cli/connections.c:3193 msgid "Bonding downdelay [0]: " msgstr "বান্ধনী downdelay [0]: " -#: ../cli/src/connections.c:3182 +#: ../clients/cli/connections.c:3196 #, c-format msgid "Error: 'downdelay': '%s' is not a valid number <0-%u>.\n" msgstr "ত্ৰুটি: 'downdelay': '%s' এটা বৈধ সংখ্যা <0-%u> নহয়।\n" -#: ../cli/src/connections.c:3190 +#: ../clients/cli/connections.c:3204 msgid "Bonding updelay [0]: " msgstr "বান্ধনী updelay [0]: " -#: ../cli/src/connections.c:3193 +#: ../clients/cli/connections.c:3207 #, c-format msgid "Error: 'updelay': '%s' is not a valid number <0-%u>.\n" msgstr "ত্ৰুটি: 'updelay': '%s' এটা বৈধ সংখ্যা <0-%u> নহয়।\n" -#: ../cli/src/connections.c:3202 +#: ../clients/cli/connections.c:3216 msgid "Bonding arp-interval [0]: " msgstr "বান্ধনী arp-interval [0]: " -#: ../cli/src/connections.c:3205 +#: ../clients/cli/connections.c:3219 #, c-format msgid "Error: 'arp-interval': '%s' is not a valid number <0-%u>.\n" msgstr "ত্ৰুটি: 'arp-interval': '%s' এটা বৈধ সংখ্যা <0-%u> নহয়।\n" #. FIXME: verify the string -#: ../cli/src/connections.c:3213 +#: ../clients/cli/connections.c:3227 msgid "Bonding arp-ip-target [none]: " msgstr "বান্ধনী arp-ip-target [none]: " -#. Ask for optional 'team' arguments. -#: ../cli/src/connections.c:3232 +#: ../clients/cli/connections.c:3234 +msgid "LACP rate ('slow' or 'fast') [slow]: " +msgstr "LACP হাৰ ('slow' or 'fast') [slow]: " + +#: ../clients/cli/connections.c:3240 #, c-format -msgid "There is 1 optional argument for '%s' connection type.\n" -msgstr "'%s' সংযোগ ধৰণৰ বাবে ১ টা বৈকল্পিক তৰ্ক আছে।\n" +#| msgid "Error: 'master': '%s' is not valid UUID nor interface." +msgid "Error: 'lacp_rate': '%s' is invalid ('slow' or 'fast').\n" +msgstr "ত্ৰুটি: 'lacp_rate': '%s' অবৈধ ('slow' অথবা 'fast')।\n" -#: ../cli/src/connections.c:3241 +#: ../clients/cli/connections.c:3263 msgid "Team JSON configuration [none]: " msgstr "দল JSON সংৰূপ [একো নাই]: " -#: ../cli/src/connections.c:3260 +#: ../clients/cli/connections.c:3280 msgid "team" msgstr "দল" -#: ../cli/src/connections.c:3266 +#: ../clients/cli/connections.c:3286 msgid "team-slave" msgstr "দল-স্লেইভ" #. Ask for optional 'bridge' arguments. -#: ../cli/src/connections.c:3280 -#, c-format -msgid "There are 6 optional arguments for 'bridge' connection type.\n" -msgstr "'ব্ৰিজ' সংযোগ ধৰণৰ বাবে ৬ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:3298 +msgid "bridge" +msgstr "ব্ৰিজ" -#: ../cli/src/connections.c:3290 -msgid "Enable STP (yes/no) [yes]: " -msgstr "STP সামৰ্থবান কৰিব নে (হয়/নহয়) [হয়]: " +#: ../clients/cli/connections.c:3304 +#, c-format +msgid "Enable STP %s" +msgstr "STP %s সামৰ্থবান কৰক" -#: ../cli/src/connections.c:3294 +#: ../clients/cli/connections.c:3309 #, c-format -msgid "Error: 'stp': '%s'.\n" -msgstr "ত্ৰুটি: 'stp': '%s'।\n" +msgid "Error: 'stp': %s.\n" +msgstr "ত্ৰুটি: 'stp': %s।\n" -#: ../cli/src/connections.c:3302 -msgid "STP priority [128]: " -msgstr "STP প্ৰাথমিকতা [128]: " +#: ../clients/cli/connections.c:3317 +msgid "STP priority [32768]: " +msgstr "STP প্ৰাথমিকতা [32768]: " -#: ../cli/src/connections.c:3306 +#: ../clients/cli/connections.c:3321 #, c-format msgid "Error: 'priority': '%s' is not a valid number <0-%d>.\n" msgstr "ত্ৰুটি: 'priority': '%s' এটা বৈধ সংখ্যা <0-%d> নহয়।\n" -#: ../cli/src/connections.c:3314 +#: ../clients/cli/connections.c:3329 msgid "Forward delay [15]: " msgstr "ফৰৱাৰ্ড বিলম্ব [15]: " -#: ../cli/src/connections.c:3318 +#: ../clients/cli/connections.c:3333 #, c-format msgid "Error: 'forward-delay': '%s' is not a valid number <2-30>.\n" msgstr "ত্ৰুটি: 'forward-delay': '%s' এটা বৈধ সংখ্যা <2-30> নহয়।\n" -#: ../cli/src/connections.c:3327 +#: ../clients/cli/connections.c:3342 msgid "Hello time [2]: " msgstr "হেল্লো সময় [2]: " -#: ../cli/src/connections.c:3331 +#: ../clients/cli/connections.c:3346 #, c-format msgid "Error: 'hello-time': '%s' is not a valid number <1-10>.\n" msgstr "ত্ৰুটি: 'hello-time': '%s' এটা বৈধ সংখ্যা <1-10> নহয়।\n" -#: ../cli/src/connections.c:3339 +#: ../clients/cli/connections.c:3354 msgid "Max age [20]: " msgstr "সৰ্বাধিক বয়স [20]: " -#: ../cli/src/connections.c:3343 +#: ../clients/cli/connections.c:3358 #, c-format msgid "Error: 'max-age': '%s' is not a valid number <6-40>.\n" msgstr "ত্ৰুটি: 'max-age': '%s' এটা বৈধ সংখ্যা <6-40> নহয়।\n" -#: ../cli/src/connections.c:3351 +#: ../clients/cli/connections.c:3366 msgid "MAC address ageing time [300]: " msgstr "MAC ঠিকনা বয়স সময় [300]: " -#: ../cli/src/connections.c:3355 +#: ../clients/cli/connections.c:3370 #, c-format msgid "Error: 'ageing-time': '%s' is not a valid number <0-1000000>.\n" msgstr "ত্ৰুটি: 'ageing-time': '%s' এটা বৈধ সংখ্যা <0-1000000> নহয়।\n" #. Ask for optional 'bridge-slave' arguments. -#: ../cli/src/connections.c:3376 -#, c-format -msgid "There are 3 optional arguments for 'bridge-slave' connection type.\n" -msgstr "'bridge-slave' সংযোগ ধৰণৰ বাবে ৩ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:3397 +msgid "bridge-slave" +msgstr "ব্ৰিজ-স্লেইভ" -#: ../cli/src/connections.c:3385 +#: ../clients/cli/connections.c:3402 msgid "Bridge port priority [32]: " msgstr "ব্ৰিজ পৰ্ট প্ৰাথমিকতা [32]: " -#: ../cli/src/connections.c:3398 +#: ../clients/cli/connections.c:3415 msgid "Bridge port STP path cost [100]: " msgstr "ব্ৰিজ পৰ্ট STP পথ কস্ট [100]: " -#: ../cli/src/connections.c:3412 -msgid "Hairpin (yes/no) [yes]: " -msgstr "হেয়াৰপিন (হয়/নহয়) [হয়]: " - -#: ../cli/src/connections.c:3416 +#: ../clients/cli/connections.c:3429 #, c-format -msgid "Error: 'hairpin': '%s'.\n" -msgstr "ত্ৰুটি: 'hairpin': '%s'।\n" +msgid "Hairpin %s" +msgstr "হেয়াৰপিন %s" -#. Ask for optional 'vpn' arguments. -#: ../cli/src/connections.c:3434 +#: ../clients/cli/connections.c:3434 #, c-format -msgid "There is 1 optional argument for 'VPN' connection type.\n" -msgstr "'VPN' সংযোগ ধৰণৰ বাবে ১ টা বৈকল্পিক তৰ্ক আছে।\n" +msgid "Error: 'hairpin': %s.\n" +msgstr "ত্ৰুটি: 'hairpin': %s।\n" #. Ask for optional 'olpc' arguments. -#: ../cli/src/connections.c:3458 -#, c-format -msgid "There are 2 optional arguments for 'OLPC Mesh' connection type.\n" -msgstr "'OLPC Mesh' সংযোগ ধৰণৰ বাবে ২ টা বৈকল্পিক তৰ্ক আছে।\n" +#: ../clients/cli/connections.c:3461 ../libnm-glib/nm-device.c:1794 +msgid "OLPC Mesh" +msgstr "OLPC মেশ" -#: ../cli/src/connections.c:3467 +#: ../clients/cli/connections.c:3466 msgid "OLPC Mesh channel [1]: " msgstr "OLPC Mesh চেনেল [1]: " -#: ../cli/src/connections.c:3470 +#: ../clients/cli/connections.c:3469 #, c-format msgid "Error: 'channel': '%s' is not a valid number <1-13>.\n" msgstr "ত্ৰুটি: 'channel': '%s' এটা বৈধ সংখ্যা <1-13> নহয়।\n" -#: ../cli/src/connections.c:3478 +#: ../clients/cli/connections.c:3477 msgid "DHCP anycast MAC address [none]: " msgstr "DHCP anycast MAC ঠিকনা [none]: " -#: ../cli/src/connections.c:3526 +#: ../clients/cli/connections.c:3522 msgid "IPv4 address (IP[/plen] [gateway]) [none]: " msgstr "IPv4 ঠিকনা (IP[/plen] [gateway]) [none]: " -#: ../cli/src/connections.c:3528 +#: ../clients/cli/connections.c:3524 msgid "IPv6 address (IP[/plen] [gateway]) [none]: " msgstr "IPv6 ঠিকনা (IP[/plen] [gateway]) [none]: " -#: ../cli/src/connections.c:3546 +#: ../clients/cli/connections.c:3542 #, c-format msgid " Address successfully added: %s %s\n" msgstr " ঠিকনা সফলভাৱে যোগ কৰা হল: %s %s\n" -#: ../cli/src/connections.c:3548 +#: ../clients/cli/connections.c:3544 #, c-format msgid " Warning: address already present: %s %s\n" msgstr " সতৰ্কবাৰ্তা: ঠিকনা ইতিমধ্য উপস্থিত: %s %s\n" -#: ../cli/src/connections.c:3550 +#: ../clients/cli/connections.c:3546 #, c-format msgid " Warning: ignoring garbage at the end: '%s'\n" msgstr " ঠিকনা: অন্তত আবৰ্জনা উপেক্ষা কৰা হৈছে: '%s'\n" -#: ../cli/src/connections.c:3552 ../cli/src/connections.c:4401 -#: ../cli/src/connections.c:4456 ../cli/src/connections.c:4855 -#: ../cli/src/connections.c:4865 +#: ../clients/cli/connections.c:3548 ../clients/cli/connections.c:4379 +#: ../clients/cli/connections.c:4440 ../clients/cli/connections.c:4842 +#: ../clients/cli/connections.c:4852 msgid "Error: " msgstr "ত্ৰুটি:" #. Ask for IP addresses -#: ../cli/src/connections.c:3570 -msgid "Do you want to add IP addresses? (yes/no) [yes] " -msgstr "আপুনি IP ঠিকনা যোগ কৰিব বিচাৰে নে? (হয়/নহয়) [হয়] " +#: ../clients/cli/connections.c:3565 +#, c-format +msgid "Do you want to add IP addresses? %s" +msgstr "আপুনি IP ঠিকনাসমূহ যোগ কৰিব বিচাৰে নে? %s" -#: ../cli/src/connections.c:3576 +#: ../clients/cli/connections.c:3572 #, c-format msgid "Press to finish adding addresses.\n" msgstr "ঠিকনাসমূহ যোগ কৰা শেষ কৰিবলৈ টিপক।\n" -#: ../cli/src/connections.c:3722 +#: ../clients/cli/connections.c:3711 #, c-format msgid "Error: 'parent': not valid without 'p-key'." msgstr "ত্ৰুটি: 'parent': 'p-key' ৰ অবিহনে বৈধ নহয়।" -#: ../cli/src/connections.c:3778 ../cli/src/connections.c:4771 +#: ../clients/cli/connections.c:3763 ../clients/cli/connections.c:4761 msgid "SSID: " msgstr "SSID: " -#: ../cli/src/connections.c:3781 ../cli/src/connections.c:4774 +#: ../clients/cli/connections.c:3766 ../clients/cli/connections.c:4764 msgid "Error: 'ssid' is required." msgstr "ত্ৰুটি: 'ssid' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:3845 +#: ../clients/cli/connections.c:3823 msgid "WiMAX NSP name: " msgstr "WiMAX NSP নাম: " -#: ../cli/src/connections.c:3848 +#: ../clients/cli/connections.c:3826 msgid "Error: 'nsp' is required." msgstr "ত্ৰুটি: 'nsp' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:3903 +#: ../clients/cli/connections.c:3878 msgid "PPPoE username: " msgstr "PPPoE ব্যৱহাৰকাৰীনাম: " -#: ../cli/src/connections.c:3906 +#: ../clients/cli/connections.c:3881 msgid "Error: 'username' is required." msgstr "ত্ৰুটি: 'username' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:3977 +#: ../clients/cli/connections.c:3950 msgid "APN: " msgstr "APN: " -#: ../cli/src/connections.c:3980 +#: ../clients/cli/connections.c:3953 msgid "Error: 'apn' is required." msgstr "ত্ৰুটি: 'apn' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4039 +#: ../clients/cli/connections.c:4011 msgid "Bluetooth device address: " msgstr "ব্লুটুথ ডিভাইচ ঠিকনা:" -#: ../cli/src/connections.c:4042 +#: ../clients/cli/connections.c:4014 msgid "Error: 'addr' is required." msgstr "ত্ৰুটি: 'addr' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4085 +#: ../clients/cli/connections.c:4055 #, c-format msgid "Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]." msgstr "ত্ৰুটি: 'bt-type': '%s' বৈধ নহয়; [%s, %s (%s), %s] ব্যৱহাৰ কৰক।" -#: ../cli/src/connections.c:4130 +#: ../clients/cli/connections.c:4099 msgid "VLAN parent device or connection UUID: " msgstr "VLAN উপধায়ক ডিভাইচ অথবা সংযোগ UUID:" -#: ../cli/src/connections.c:4133 +#: ../clients/cli/connections.c:4102 msgid "Error: 'dev' is required." msgstr "ত্ৰুটি: 'dev' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4137 +#: ../clients/cli/connections.c:4106 msgid "VLAN ID <0-4095>: " msgstr "VLAN ID <0-4095>: " -#: ../cli/src/connections.c:4140 +#: ../clients/cli/connections.c:4109 msgid "Error: 'id' is required." msgstr "ত্ৰুটি: 'id' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4146 +#: ../clients/cli/connections.c:4115 #, c-format msgid "Error: 'id': '%s' is not valid; use <0-4095>." msgstr "ত্ৰুটি: 'id': '%s' বৈধ নহয়; <0-4095> ব্যৱহাৰ কৰক।" -#: ../cli/src/connections.c:4156 +#: ../clients/cli/connections.c:4125 #, c-format msgid "Error: 'dev': '%s' is neither UUID, interface name, nor MAC." msgstr "ত্ৰুটি: 'dev': '%s' UUID, আন্তঃপৃষ্ঠ না, অথবা MAC নহয়।" -#: ../cli/src/connections.c:4291 +#: ../clients/cli/connections.c:4259 #, c-format msgid "Error: 'mode': %s." msgstr "ত্ৰুটি: 'mode': %s." -#: ../cli/src/connections.c:4300 +#: ../clients/cli/connections.c:4268 #, c-format msgid "Error: 'primary': '%s' is not a valid interface name." msgstr "ত্ৰুটি: 'primary': '%s' এটা বৈধ আন্তঃপৃষ্ঠ নাম নহয়।" -#: ../cli/src/connections.c:4343 -msgid "Bond master: " -msgstr "বান্ধনী মাস্টাৰ:" - -#: ../cli/src/connections.c:4346 ../cli/src/connections.c:4438 -#: ../cli/src/connections.c:4625 +#: ../clients/cli/connections.c:4320 ../clients/cli/connections.c:4418 +#: ../clients/cli/connections.c:4620 msgid "Error: 'master' is required." msgstr "ত্ৰুটি: 'master' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4351 ../cli/src/connections.c:4448 -#: ../cli/src/connections.c:4636 +#: ../clients/cli/connections.c:4326 ../clients/cli/connections.c:4424 +#: ../clients/cli/connections.c:4626 +#, c-format +msgid "Warning: master='%s' doesn't refer to any existing profile.\n" +msgstr "সতৰ্কবাৰ্তা: মাস্টাৰ='%s' এ কোনো স্থায়ী আলেখ্যলৈ প্ৰসংগ নকৰে।\n" + +#: ../clients/cli/connections.c:4329 ../clients/cli/connections.c:4432 +#: ../clients/cli/connections.c:4629 #, c-format msgid "" "Warning: 'type' is currently ignored. We only support ethernet slaves for " @@ -1997,102 +2063,81 @@ msgstr "" "সতৰ্কবাৰ্তা: 'type' বৰ্তমানে উপেক্ষা কৰা হৈছে। আমি এতিয়াৰ বাবে কেৱল ইথাৰনেট " "স্লেইভসমূহ সমৰ্থন কৰো।\n" -#: ../cli/src/connections.c:4435 -msgid "Team master: " -msgstr "দলৰ গৰাকী:" - -#: ../cli/src/connections.c:4538 +#: ../clients/cli/connections.c:4526 #, c-format msgid "Error: 'stp': %s." msgstr "ত্ৰুটি: 'stp': %s।" -#: ../cli/src/connections.c:4622 -msgid "Bridge master: " -msgstr "ব্ৰিজ মাস্টাৰ:" - -#: ../cli/src/connections.c:4630 -#, c-format -msgid "Error: 'master': '%s' is not valid UUID nor interface." -msgstr "ত্ৰুটি: 'master': '%s' বৈধ UUID অথবা আন্তঃপষ্ঠ নহয়।" - -#: ../cli/src/connections.c:4663 +#: ../clients/cli/connections.c:4656 #, c-format msgid "Error: 'hairpin': %s." msgstr "ত্ৰুটি: 'hairpin': %s. " -#: ../cli/src/connections.c:4715 -msgid "VPN type: " -msgstr "VPN ধৰণ:" - -#: ../cli/src/connections.c:4718 +#: ../clients/cli/connections.c:4709 msgid "Error: 'vpn-type' is required." msgstr "ত্ৰুটি: 'vpn-type' প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:4729 +#: ../clients/cli/connections.c:4716 #, c-format -msgid "Error: 'vpn-type': %s." -msgstr "ত্ৰুটি: 'vpn-type': %s।" +msgid "Warning: 'vpn-type': %s not known.\n" +msgstr "ত্ৰুটি: 'vpn-type': %s জ্ঞাত নহয়।\n" -#: ../cli/src/connections.c:4787 +#: ../clients/cli/connections.c:4777 #, c-format msgid "Error: 'channel': '%s' is not valid; use <1-13>." msgstr "ত্ৰুটি: 'channel': '%s' বৈধ নহয়; <1-13> ব্যৱহাৰ কৰক।" -#: ../cli/src/connections.c:4822 +#: ../clients/cli/connections.c:4809 #, c-format msgid "Error: '%s' is not a valid connection type." msgstr "ত্ৰুটি: '%s' এটা বৈধ সংযোগ ধৰণ নহয়।" -#: ../cli/src/connections.c:4920 +#: ../clients/cli/connections.c:4911 #, c-format -msgid "Error: Failed to add '%s' connection: (%d) %s" -msgstr "ত্ৰুটি: '%s' সংযোগ যোগ কৰিবলে ব্যৰ্থ: (%d) %s" +#| msgid "Error: Failed to add '%s' connection: (%d) %s" +msgid "Error: Failed to add '%s' connection: %s" +msgstr "ত্ৰুটি: '%s' সংযোগ যোগ কৰিবলে ব্যৰ্থ: %s" -#: ../cli/src/connections.c:4924 +#: ../clients/cli/connections.c:4916 #, c-format msgid "Connection '%s' (%s) successfully added.\n" msgstr "সংযোগ '%s' (%s) সফলভাৱে যোগ কৰা হল।\n" -#: ../cli/src/connections.c:4998 -msgid "Connection type: " -msgstr "সংযোগৰ ধৰণ:" - -#: ../cli/src/connections.c:5002 +#: ../clients/cli/connections.c:5127 #, c-format msgid "Error: 'type' argument is required." msgstr "ত্ৰুটি: 'type' তৰ্ক প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:5008 +#: ../clients/cli/connections.c:5135 #, c-format msgid "Error: invalid connection type; %s." msgstr "ত্ৰুটি: অবৈধ সংযোগ ধৰণ; %s।" -#: ../cli/src/connections.c:5017 +#: ../clients/cli/connections.c:5144 #, c-format msgid "Error: 'autoconnect': %s." msgstr "ত্ৰুটি: 'autoconnect': %s।" -#: ../cli/src/connections.c:5027 +#: ../clients/cli/connections.c:5154 #, c-format -#| msgid "Error: 'stp': %s." msgid "Error: 'save': %s." msgstr "ত্ৰুটি: 'save': %s।" -#: ../cli/src/connections.c:5043 +#: ../clients/cli/connections.c:5170 msgid "Interface name [*]: " msgstr "আন্তঃপৃষ্ঠৰ নাম [*]: " -#: ../cli/src/connections.c:5048 +#: ../clients/cli/connections.c:5175 #, c-format msgid "Error: 'ifname' argument is required." msgstr "ত্ৰুটি: 'ifname' তৰ্ক প্ৰয়োজনীয়।" -#: ../cli/src/connections.c:5055 +#: ../clients/cli/connections.c:5182 #, c-format msgid "Error: 'ifname': '%s' is not a valid interface nor '*'." msgstr "ত্ৰুটি: 'ifname': '%s' অথবা '*' এটা বৈধ আন্তঃপৃষ্ঠ নহয়।" -#: ../cli/src/connections.c:5884 +#: ../clients/cli/connections.c:5970 #, c-format msgid "['%s' setting values]\n" msgstr "['%s' সংহতি মানসমূহ]\n" @@ -2100,23 +2145,8 @@ msgstr "['%s' সংহতি মানসমূহ]\n" #. TRANSLATORS: do not translate command names and keywords before :: #. * However, you should translate terms enclosed in <>. #. -#: ../cli/src/connections.c:5965 +#: ../clients/cli/connections.c:6052 #, c-format -#| msgid "" -#| "---[ Main menu ]---\n" -#| "goto [ | ] :: go to a setting or property\n" -#| "remove [.] | :: remove setting or reset property " -#| "value\n" -#| "set [. ] :: set property value\n" -#| "describe [.] :: describe property\n" -#| "print [all] :: print the connection\n" -#| "verify [all] :: verify the connection\n" -#| "save :: save the connection\n" -#| "activate [] [/|] :: activate the connection\n" -#| "back :: go one level up (back)\n" -#| "help/? [] :: print this help\n" -#| "nmcli :: nmcli configuration\n" -#| "quit :: exit nmcli\n" msgid "" "---[ Main menu ]---\n" "goto [ | ] :: go to a setting or property\n" @@ -2124,7 +2154,7 @@ msgid "" "value\n" "set [. ] :: set property value\n" "describe [.] :: describe property\n" -"print [all] :: print the connection\n" +"print [all | [.]] :: print the connection\n" "verify [all] :: verify the connection\n" "save [persistent|temporary] :: save the connection\n" "activate [] [/|] :: activate the connection\n" @@ -2134,22 +2164,21 @@ msgid "" "quit :: exit nmcli\n" msgstr "" "---[ Main menu ]---\n" -"goto [ | ] :: এটা সংহতি অথবা বৈশিষ্ট্যলৈ যাওক\n" -"remove [.] | :: সংহতি আতৰাওক অথবা বৈশিষ্ট্যৰ মান পুনৰ " -"সংহতি কৰক\n" -"set [. ] :: বৈশিষ্ট্যৰ মান সংহতি কৰক\n" -"describe [.] :: বৈশিষ্ট্যৰ বিৱৰণ দিয়ক\n" -"print [all] :: সংযোগ প্ৰিন্ট কৰক\n" -"verify [all] :: সংযোগৰ সতা সত্য নিৰূপণ কৰক\n" -"save [persistent|temporary] :: সংযোগ সংৰক্ষণ " -"কৰক\n" -"activate [] [/|] :: সংযোগ সক্ৰিয় কৰক\n" -"back :: এক স্তৰ ওপৰ যাওক (পিছলৈ)\n" -"help/? [] :: এই সহায় প্ৰিন্ট কৰক\n" -"nmcli :: nmcli সংৰূপ\n" -"quit :: nmcli প্ৰস্থান কৰক\n" - -#: ../cli/src/connections.c:5992 +"goto [ | ] :: go to a setting or property\n" +"remove [.] | :: remove setting or reset property " +"value\n" +"set [. ] :: set property value\n" +"describe [.] :: describe property\n" +"print [all | [.]] :: print the connection\n" +"verify [all] :: verify the connection\n" +"save [persistent|temporary] :: save the connection\n" +"activate [] [/|] :: activate the connection\n" +"back :: go one level up (back)\n" +"help/? [] :: print this help\n" +"nmcli :: nmcli configuration\n" +"quit :: exit nmcli\n" + +#: ../clients/cli/connections.c:6079 #, c-format msgid "" "goto [.] | :: enter setting/property for editing\n" @@ -2168,7 +2197,7 @@ msgstr "" " nmcli connection> goto secondaries\n" " nmcli> goto ipv4.addresses\n" -#: ../cli/src/connections.c:5999 +#: ../clients/cli/connections.c:6086 #, c-format msgid "" "remove [.] :: remove setting or reset property value\n" @@ -2189,7 +2218,7 @@ msgstr "" "Examples: nmcli> remove wifi-sec\n" " nmcli> remove eth.mtu\n" -#: ../cli/src/connections.c:6006 +#: ../clients/cli/connections.c:6093 #, c-format msgid "" "set [. ] :: set property value\n" @@ -2204,7 +2233,7 @@ msgstr "" "\n" "উদাহৰণ: nmcli> set con.id My connection\n" -#: ../cli/src/connections.c:6011 +#: ../clients/cli/connections.c:6098 #, c-format msgid "" "describe [.] :: describe property\n" @@ -2217,7 +2246,7 @@ msgstr "" "বৈশিষ্ট্যৰ বিৱৰণ দেখুৱায়। সকলো NM সংহতি আৰু বৈশিষ্ট্যসমূহ চাবলৈ আপুনি nm-" "settings(5) manual চাব পাৰে।\n" -#: ../cli/src/connections.c:6016 +#: ../clients/cli/connections.c:6103 #, c-format msgid "" "print [all] :: print setting or connection values\n" @@ -2226,13 +2255,13 @@ msgid "" "\n" "Example: nmcli ipv4> print all\n" msgstr "" -"print [all] :: সংহতি অথবা সংযোগৰ মান প্ৰিন্ট কৰক\n" +"print [all] :: সংহতি অথবা সংযোগৰ মান প্ৰিণ্ট কৰক\n" "\n" "বৰ্তমান বৈশিষ্ট্য অথবা সম্পূৰ্ণ সংযোগ দেখুৱায়।\n" "\n" "উদাহৰণ: nmcli ipv4> print all\n" -#: ../cli/src/connections.c:6021 +#: ../clients/cli/connections.c:6108 #, c-format msgid "" "verify [all] :: verify setting or connection validity\n" @@ -2243,7 +2272,7 @@ msgid "" "Examples: nmcli> verify\n" " nmcli bond> verify\n" msgstr "" -"verify [all] :: সংহতি অথবা সংযোগৰ বৈধতা সতা সত্য নিৰূপণ কৰক\n" +"verify [all] :: সংহতি অথবা সংযোগৰ বৈধতা সত্যাপন কৰক\n" "\n" "সংহতি অথবা সংযোগ বৈধ নে আৰু পিছত সংৰক্ষণ কৰিব পাৰি নে সতা সত্য নিৰূপন কৰে। ই " "ত্ৰুটিত অবৈধ মানসমূহৰ সূচনা দিয়ে।\n" @@ -2251,13 +2280,13 @@ msgstr "" "উদাহৰণ: nmcli> verify\n" " nmcli bond> verify\n" -#: ../cli/src/connections.c:6028 +#: ../clients/cli/connections.c:6115 #, c-format msgid "" "save [persistent|temporary] :: save the connection\n" "\n" "Sends the connection profile to NetworkManager that either will save it\n" -"pesistently, or will only keep it in memory. 'save' without an argument\n" +"persistently, or will only keep it in memory. 'save' without an argument\n" "means 'save persistent'.\n" "Note that once you save the profile persistently those settings are saved\n" "across reboot or restart. Subsequent changes can also be temporary or\n" @@ -2275,11 +2304,10 @@ msgstr "" "পুনাৰম্ভৰ\n" "পিছতো থাকিব। ক্ৰমন্বয় পৰিবৰ্তনসমূহ অস্থায়ী অথবা স্থায়ী হব পাৰে\n" "কিন্তু কোনো অস্থায়ী পৰিবৰ্তন পুনাৰম্ভৰ পিছত নাথাকিব।\n" -"যদি আপুনি স্থায়ী সংযোগ সম্পূৰ্ণভাৱে আতৰাব খোজে, " -"সংযোগ\n" +"যদি আপুনি স্থায়ী সংযোগ সম্পূৰ্ণভাৱে আতৰাব খোজে, সংযোগ\n" "আলেখ্যক মচিব লাগিব।\n" -#: ../cli/src/connections.c:6039 +#: ../clients/cli/connections.c:6126 #, c-format msgid "" "activate [] [/|] :: activate the connection\n" @@ -2300,7 +2328,7 @@ msgstr "" "/| - AP (Wi-Fi) or NSP (WiMAX) (আৰম্ভণিত / যোগ কৰক যেতিয়া " "ধাৰ্য্যত নহয়)\n" -#: ../cli/src/connections.c:6046 ../cli/src/connections.c:6196 +#: ../clients/cli/connections.c:6133 ../clients/cli/connections.c:6290 #, c-format msgid "" "back :: go to upper menu level\n" @@ -2309,7 +2337,7 @@ msgstr "" "back :: ওপৰ স্তৰ মেনুলৈ যাওক\n" "\n" -#: ../cli/src/connections.c:6049 +#: ../clients/cli/connections.c:6136 #, c-format msgid "" "help/? [] :: help for the nmcli commands\n" @@ -2318,7 +2346,7 @@ msgstr "" "help/? [] :: nmcli কমান্ডসমূহৰ বাবে সহায়\n" "\n" -#: ../cli/src/connections.c:6052 +#: ../clients/cli/connections.c:6139 #, c-format msgid "" "nmcli [ ] :: nmcli configuration\n" @@ -2361,7 +2389,7 @@ msgstr "" " nmcli> nmcli save-confirmation no\n" " nmcli> nmcli prompt-color 3\n" -#: ../cli/src/connections.c:6072 ../cli/src/connections.c:6202 +#: ../clients/cli/connections.c:6159 ../clients/cli/connections.c:6296 #, c-format msgid "" "quit :: exit nmcli\n" @@ -2374,8 +2402,8 @@ msgstr "" "এই কমান্ডে nmcli প্ৰস্থান কৰে। যেতিয়া সম্পাদন কৰি থকা সংযোগ সংৰক্ষণ কৰা নহয়, " "ব্যৱহাৰকাৰীক কাৰ্য্য সুনিশ্চিত কৰিবলৈ কোৱা হয়।\n" -#: ../cli/src/connections.c:6077 ../cli/src/connections.c:6207 -#: ../cli/src/connections.c:6581 ../cli/src/connections.c:7447 +#: ../clients/cli/connections.c:6164 ../clients/cli/connections.c:6301 +#: ../clients/cli/connections.c:6706 ../clients/cli/connections.c:7597 #, c-format msgid "Unknown command: '%s'\n" msgstr "অজ্ঞাত কমান্ড: '%s'\n" @@ -2383,7 +2411,7 @@ msgstr "অজ্ঞাত কমান্ড: '%s'\n" #. TRANSLATORS: do not translate command names and keywords before :: #. * However, you should translate terms enclosed in <>. #. -#: ../cli/src/connections.c:6143 +#: ../clients/cli/connections.c:6230 #, c-format msgid "" "---[ Property menu ]---\n" @@ -2404,13 +2432,13 @@ msgstr "" "change :: বৰ্তমান পৰিবৰ্তন কৰক\n" "remove [ |