Skip to content

Commit 2aae6da

Browse files
author
Bernhard Kaindl
committed
Commit it all in one go with working examples
I wanted to split this into as-small-as-possible individual commits and small PRs but have no time now, pushing as one to make it accessible for review. maybe split into smaller if needed for review, but it does not appear to large for one commit now. Let's see. It is working with the tow updated examples on my system, so it has real-live validation. The maybe not-obvious small changes and additiona are fixes for the real-live query from examples/async/list-connections-async.py by reading the many different VPNs and other connections on my system.
1 parent 63f4186 commit 2aae6da

File tree

10 files changed

+394
-174
lines changed

10 files changed

+394
-174
lines changed

examples/async/add-wifi-psk-connection-async.py

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -44,68 +44,76 @@
4444
# -> org.freedesktop.NetworkManager.Settings (Settings Profile Manager)
4545

4646
import asyncio
47+
import binascii
4748
import functools
4849
import pprint
4950
import sdbus
5051
import uuid
5152
from argparse import ArgumentParser, Namespace
52-
from sdbus_async.networkmanager import NetworkManagerSettings
53-
from sdbus_async.networkmanager import NetworkManagerConnectionProperties
53+
from passlib.utils.pbkdf2 import pbkdf2 # type: ignore
54+
from sdbus_async.networkmanager import (
55+
NetworkManagerSettings as SettingsManager,
56+
ConnectionProfile,
57+
ConnectionSettings,
58+
Ipv4Settings,
59+
Ipv6Settings,
60+
WirelessSettings,
61+
WirelessSecuritySettings,
62+
)
5463

5564

5665
async def add_wifi_psk_connection_profile_async(args: Namespace) -> None:
5766
"""Add a temporary (not yet saved) network connection profile"""
5867

5968
# If we add many connections passing the same id, things get messy. Check:
60-
if await NetworkManagerSettings().get_connections_by_id(args.conn_id):
69+
if await SettingsManager().get_connections_by_id(args.conn_id):
6170
print(f'Connection "{args.conn_id}" exists, remove it first')
6271
print(f'Run: nmcli connection delete "{args.conn_id}"')
6372
return
6473

65-
properties: NetworkManagerConnectionProperties = {
66-
"connection": {
67-
"id": ("s", args.conn_id),
68-
"uuid": ("s", str(uuid.uuid4())),
69-
"type": ("s", "802-11-wireless"),
70-
"autoconnect": ("b", args.auto),
71-
},
72-
"802-11-wireless": {
73-
"mode": ("s", "infrastructure"),
74-
"security": ("s", "802-11-wireless-security"),
75-
"ssid": ("ay", args.ssid.encode("utf-8")),
76-
},
77-
"802-11-wireless-security": {
78-
"key-mgmt": ("s", "wpa-psk"),
79-
"auth-alg": ("s", "open"),
80-
"psk": ("s", args.psk),
81-
},
82-
"ipv4": {"method": ("s", "auto")},
83-
"ipv6": {"method": ("s", "auto")},
84-
}
74+
if args.key_mgmt == "wpa-psk" and len(args.password) < 64:
75+
# Hash the password into a psk hash to not store it in clear form:
76+
pw = pbkdf2(args.password.encode(), args.ssid.encode(), 4096, 32)
77+
args.password = binascii.hexlify(pw).decode("utf-8")
78+
79+
profile = ConnectionProfile(
80+
connection=ConnectionSettings(
81+
uuid=str(uuid.uuid4()),
82+
connection_type='802-11-wireless',
83+
connection_id=args.conn_id,
84+
autoconnect=args.auto,
85+
),
86+
ipv4=Ipv4Settings(method="auto"),
87+
ipv6=Ipv6Settings(method="auto"),
88+
wifi=WirelessSettings(ssid=args.ssid.encode("utf-8")),
89+
wifi_security=WirelessSecuritySettings(
90+
key_mgmt=args.key_mgmt, auth_alg="open", psk=args.password
91+
),
92+
)
8593

8694
# To bind the new connection to a specific interface, use this:
8795
if args.interface_name:
88-
properties["connection"]["interface-name"] = ("s", args.interface_name)
89-
90-
networkmanager_settings = NetworkManagerSettings()
96+
profile.connection.interface_name = args.interface_name
97+
networkmanager_settings = SettingsManager()
9198
if args.save:
92-
await networkmanager_settings.add_connection(properties)
99+
await networkmanager_settings.add_connection(profile.to_dbus())
93100
print("New connection profile created and saved, show it with:")
94101
else:
95-
await networkmanager_settings.add_connection_unsaved(properties)
102+
await networkmanager_settings.add_connection_unsaved(profile.to_dbus())
96103
print("New unsaved connection profile created, show it with:")
97104

98105
print(f'nmcli connection show "{args.conn_id}"|grep -v -e -- -e default')
99106
print("Settings used:")
100-
functools.partial(pprint.pprint, sort_dicts=False)(properties)
107+
functools.partial(pprint.pprint, sort_dicts=False)(profile.to_dbus())
101108

102109

103110
if __name__ == "__main__":
104111
p = ArgumentParser(description="Optional arguments have example values:")
105112
conn_id = "MyConnectionExample"
106113
p.add_argument("-c", dest="conn_id", default=conn_id, help="Connection Id")
107114
p.add_argument("-s", dest="ssid", default="CafeSSID", help="WiFi SSID")
108-
p.add_argument("-p", dest="psk", default="Coffee!!", help="WiFi PSK")
115+
p.add_argument("-k", dest="key_mgmt", default="wpa-psk", help="key-mgmt")
116+
p.add_argument("-p", dest="password", default="Coffee!!", help="WiFi PSK")
109117
p.add_argument("-i", dest="interface_name", default="", help="WiFi device")
110118
p.add_argument("-a", dest="auto", action="store_true", help="autoconnect")
111119
p.add_argument("--save", dest="save", action="store_true", help="Save")

examples/async/list-connections-async.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# | ipv6: method: disabled
2020
import asyncio
2121
import sdbus
22+
import pprint
2223
from sdbus_async.networkmanager import (
2324
NetworkManagerSettings,
2425
NetworkConnectionSettings,
@@ -29,33 +30,30 @@
2930
async def list_connection_profiles_async() -> None:
3031
networkmanager_settings = NetworkManagerSettings()
3132
connections_paths: List[str] = await networkmanager_settings.connections
32-
for connection_path in connections_paths:
33-
connection_settings = NetworkConnectionSettings(connection_path)
34-
settings = await connection_settings.get_settings()
35-
connection = settings["connection"]
36-
37-
# Skip connection profiles for bridges and wireless networks
38-
if connection["type"][1] in ("bridge", "802-11-wireless"):
39-
continue
40-
41-
print("-------------------------------------------------------------")
42-
print("name:", connection["id"][1])
43-
print("uuid:", connection["uuid"][1])
44-
print("type:", connection["type"][1])
45-
if "interface-name" in connection:
46-
print(" interface-name:", connection["interface-name"][1])
47-
48-
if "ipv4" in settings:
49-
ipv4 = settings["ipv4"]
50-
print("ipv4: method:", ipv4["method"][1])
51-
if "address-data" in ipv4:
52-
for a in ipv4["address-data"][1]:
53-
print(f' ipaddr: {a["address"][1]}/{a["prefix"][1]}')
54-
if "route-metric" in ipv4:
55-
print(f' route-metric: {ipv4["route-metric"][1]}')
56-
57-
if "ipv6" in settings:
58-
print("ipv6: method:", settings["ipv6"]["method"][1])
33+
for dbus_connection_path in connections_paths:
34+
await print_connection_profile(dbus_connection_path)
35+
36+
37+
async def print_connection_profile(connection_path: str) -> None:
38+
connectionsettings_service = NetworkConnectionSettings(connection_path)
39+
profile = await connectionsettings_service.connection_profile()
40+
connection = profile.connection
41+
print("-------------------------------------------------------------")
42+
print("name:", connection.connection_id)
43+
print("uuid:", connection.uuid)
44+
print("type:", connection.connection_type)
45+
if connection.interface_name:
46+
print(" interface-name:", connection.interface_name)
47+
if profile.ipv4:
48+
print("ipv4: method:", profile.ipv4.method)
49+
if profile.ipv4.address_data:
50+
for address in profile.ipv4.address_data:
51+
print(f' ipaddr: {address.address}/{address.prefix}')
52+
if profile.ipv4.route_metric:
53+
print(f' route-metric: {profile.ipv4.route_metric}')
54+
if profile.ipv6:
55+
print("ipv6: method:", profile.ipv6.method)
56+
pprint.pprint(profile.to_dbus())
5957

6058

6159
if __name__ == "__main__":

sdbus_async/networkmanager/__init__.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,59 @@
193193
NmVpnPluginInvalidConnectionError,
194194
NmVpnPluginInteractiveNotSupportedError,
195195
)
196+
from .settings.connection import ConnectionSettings
197+
from .settings.profile import ConnectionProfile
198+
from .settings.ipv4 import Ipv4Settings
199+
from .settings.ipv6 import Ipv6Settings
200+
from .settings.adsl import AdslSettings
201+
from .settings.bluetooth import BluetoothSettings
202+
from .settings.bond import BondSettings
203+
from .settings.bond_port import BondPortSettings
204+
from .settings.bridge import BridgeSettings
205+
from .settings.bridge_port import BridgePortSettings
206+
from .settings.cdma import CdmaSettings
207+
from .settings.dcb import DcbSettings
208+
from .settings.ethernet import EthernetSettings
209+
from .settings.gsm import GsmSettings
210+
from .settings.hostname import HostnameSettings
211+
from .settings.ieee802_1x import Ieee8021XSettings
212+
from .settings.infiniband import InfinibandSettings
213+
from .settings.ip_tunnel import IpTunnelSettings
214+
from .settings.lowpan import LowpanSettings
215+
from .settings.macsec import MacsecSettings
216+
from .settings.macvlan import MacvlanSettings
217+
from .settings.match import MatchSettings
218+
from .settings.olpc_mesh import OlpcMeshSettings
219+
from .settings.ovs_bridge import OvsBridgeSettings
220+
from .settings.ovs_dpdk import OvsDpdkSettings
221+
from .settings.ovs_external_ids import OvsExternalIdsSettings
222+
from .settings.ovs_interface import OvsInterfaceSettings
223+
from .settings.ovs_patch import OvsPatchSettings
224+
from .settings.ovs_port import OvsPortSettings
225+
from .settings.ppp import PppSettings
226+
from .settings.pppoe import PppoeSettings
227+
from .settings.proxy import ProxySettings
228+
from .settings.serial import SerialSettings
229+
from .settings.team import TeamSettings
230+
from .settings.team_port import TeamPortSettings
231+
from .settings.tun import TunSettings
232+
from .settings.user import UserSettings
233+
from .settings.veth import VethSettings
234+
from .settings.vlan import VlanSettings
235+
from .settings.vpn import VpnSettings
236+
from .settings.vrf import VrfSettings
237+
from .settings.vxlan import VxlanSettings
238+
from .settings.wifi_p2p import WifiP2PSettings
239+
from .settings.wimax import WimaxSettings
240+
from .settings.wireguard import WireguardSettings
241+
from .settings.wireless import WirelessSettings
242+
from .settings.wireless_security import WirelessSecuritySettings
243+
from .settings.wpan import WpanSettings
244+
from .settings.datatypes import (
245+
AddressData,
246+
RouteData,
247+
WireguardPeers,
248+
)
196249
from .types import (
197250
NetworkManagerSetting,
198251
NetworkManagerSettingsDomain,
@@ -303,6 +356,59 @@
303356
'WiFiP2PPeer',
304357
'ConfigCheckpoint',
305358

359+
'ConnectionProfile',
360+
'ConnectionSettings',
361+
'AdslSettings',
362+
'BluetoothSettings',
363+
'BondPortSettings',
364+
'BondSettings',
365+
'BridgePortSettings',
366+
'BridgeSettings',
367+
'CdmaSettings',
368+
'DcbSettings',
369+
'EthernetSettings',
370+
'GsmSettings',
371+
'HostnameSettings',
372+
'Ieee8021XSettings',
373+
'InfinibandSettings',
374+
'IpTunnelSettings',
375+
'Ipv4Settings',
376+
'Ipv6Settings',
377+
'LowpanSettings',
378+
'MacsecSettings',
379+
'MacvlanSettings',
380+
'MatchSettings',
381+
'OlpcMeshSettings',
382+
'OvsBridgeSettings',
383+
'OvsDpdkSettings',
384+
'OvsExternalIdsSettings',
385+
'OvsInterfaceSettings',
386+
'OvsPatchSettings',
387+
'OvsPortSettings',
388+
'PppSettings',
389+
'PppoeSettings',
390+
'ProxySettings',
391+
'SerialSettings',
392+
'TeamPortSettings',
393+
'TeamSettings',
394+
'TunSettings',
395+
'UserSettings',
396+
'VethSettings',
397+
'VlanSettings',
398+
'VpnSettings',
399+
'VrfSettings',
400+
'VxlanSettings',
401+
'WifiP2PSettings',
402+
'WimaxSettings',
403+
'WireguardSettings',
404+
'WirelessSecuritySettings',
405+
'WirelessSettings',
406+
'WpanSettings',
407+
408+
'AddressData',
409+
'RouteData',
410+
'WireguardPeers',
411+
306412
'DEVICE_TYPE_TO_CLASS',
307413

308414
'NetworkManagerBaseError',

sdbus_async/networkmanager/objects.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
NetworkManagerSettingsInterfaceAsync,
6464
NetworkManagerVPNConnectionInterfaceAsync,
6565
NetworkManagerWifiP2PPeerInterfaceAsync)
66+
from .settings.profile import ConnectionProfile
6667

6768
NETWORK_MANAGER_SERVICE_NAME = 'org.freedesktop.NetworkManager'
6869

@@ -159,7 +160,7 @@ async def get_connections_by_id(self, connection_id: str) -> List[str]:
159160
which use the given connection identifier.
160161
161162
:param str connection_id: The connection identifier of the connections,
162-
e.g. "Ethernet connection 1"
163+
e.g. "Wired connection 1"
163164
:return: List of connection profile paths using the given identifier.
164165
"""
165166
connection_paths_with_matching_id = []
@@ -196,6 +197,9 @@ def __init__(self, settings_path: str,
196197
settings_path,
197198
bus)
198199

200+
async def connection_profile(self) -> ConnectionProfile:
201+
return ConnectionProfile.from_dbus(await self.get_settings())
202+
199203

200204
class NetworkDeviceGeneric(
201205
NetworkManagerDeviceInterfaceAsync,

0 commit comments

Comments
 (0)