2 # cnetworkmanager: Command Line Interface for NetworkManager
3 # by: http://en.opensuse.org/User:Mvidner
4 # license: http://www.gnu.org/licenses/gpl-2.0.html or later
7 print "cnetworkmanager %s - Command Line Interface for NetworkManager" % VERSION
19 from binascii
import hexlify
20 import ConfigParser
# knm config
21 from optparse
import OptionParser
27 print "Install python-1-dbus.rpm or or python-dbus.rpm or python-dbus.deb"
29 import xml
.dom
.minidom
33 # todo - only if loop wanted
34 print "Install python-gobject2.rpm or pygobject2.rpm or python-gobject.deb"
36 # python-gnome.rpm has gconf for nm-applet...
40 from dbus
.mainloop
.glib
import DBusGMainLoop
41 DBusGMainLoop(set_as_default
=True)
45 bus
= dbus
.SystemBus()
47 # FOOC = connection (service) string
48 # FOOI = interface string
51 # foopi = property interface
52 NMC
= 'org.freedesktop.NetworkManager'
54 PI
= 'org.freedesktop.DBus.Properties'
55 SSC
= "org.freedesktop.NetworkManagerSystemSettings"
56 USC
= "org.freedesktop.NetworkManagerUserSettings"
57 NMIC
= "org.freedesktop.NetworkManagerInfo"
60 ii
= dbus
.Interface(obj
, 'org.freedesktop.DBus.Introspectable')
64 # TODO: pull them from introspection.xml
65 NM_STATE
= ["UNKNOWN", "ASLEEP", "CONNECTING", "CONNECTED", "DISCONNECTED",]
67 def __init__(self
, opath
):
69 self
.nmo
= bus
.get_object(NMC
, self
.opath
)
70 self
.nmi
= dbus
.Interface(self
.nmo
, NMI
)
71 self
.nmpi
= dbus
.Interface(self
.nmo
, PI
)
77 "Dumps its own info (not owned objects)."
83 for device
in self
.Devices():
87 print "Active Connections"
88 aconns
= self
.ActiveConnections()
93 print "Wifi Networks:"
94 for dev
in self
.Devices():
97 def reply_handler(self
, opath
):
98 print "Connected:", opath
100 def err_handler(self
, *args
):
103 def silent_handler(self
, *args
):
107 def quitter_handler(self
, *args
):
108 # exit the loop that runs only because of us
114 "Detects NM version and chooses appropriate class"
116 nmo
= bus
.get_object(NMC
, opath
)
117 nmi
= dbus
.Interface(nmo
, NMI
)
119 dummy
= nmi
.getDevices()
121 except dbus
.exceptions
.DBusException
:
128 def SetWifiEnabled(self
, v
):
129 # TODO: async call, catch the state signal and exit
130 # weird: synchronous call works, but times out
131 # asynchronous call does not work
132 self
.nmi
.setWirelessEnabled(v
,
133 reply_handler
=self
.quitter_handler
,
134 error_handler
=self
.quitter_handler
)
138 def SetOnline(self
, v
):
141 reply_handler
=self
.quitter_handler
,
142 error_handler
=self
.quitter_handler
)
145 reply_handler
=self
.quitter_handler
,
146 error_handler
=self
.quitter_handler
)
151 print "State:", self
.NM_STATE
[self
.nmi
.state()]
152 we
= self
.nmi
.getWirelessEnabled()
153 if isinstance(we
, tuple):
154 print "Wifi enabled:", bool(we
[0])
155 print "Wifi HW enabled:", bool(we
[1])
157 print "Wifi enabled:", bool(we
)
160 dup
= self
.nmi
.getDialup()
162 except dbus
.exceptions
.DBusException
, e
:
163 #if e.get_dbus_name() == "org.freedesktop.NetworkManager.NoDialup":
169 opaths
= self
.nmi
.getDevices()
170 return map(cDevice_06
, opaths
)
172 def ActiveConnections(self
):
173 return [] # at most one active connection, FIXME find it
175 def reply_handler(self
):
176 print "Connection requested"
178 def err_handler(self
, *args
):
181 def ActivateConnection(self
, conn
, device
, ap
):
182 # passing *_handler makes the call asynchronous
183 self
.nmi
.setActiveDevice(device
.opath
, ssid_str(conn
.Ssid()),
184 reply_handler
=self
.reply_handler
,
185 error_handler
=self
.err_handler
,
192 def SetWifiEnabled(self
, v
):
193 self
.nmpi
.Set(NMI
, "WirelessEnabled", v
)
195 def SetOnline(self
, v
):
196 self
.nmi
.Sleep(not v
)
199 print "State:", self
.NM_STATE
[self
.nmpi
.Get(NMI
, "State")]
200 print "Wifi enabled:", self
.nmpi
.Get(NMI
, "WirelessEnabled")
201 print "Wifi HW enabled:", self
.nmpi
.Get(NMI
, "WirelessHardwareEnabled")
204 opaths
= self
.nmi
.GetDevices()
205 return map(cDevice_07
, opaths
)
207 def ActiveConnections(self
):
208 aconns
= self
.nmpi
.Get(NMI
, "ActiveConnections")
209 return map(cActiveConnection
, aconns
)
211 def ActivateConnection(self
, conn
, device
, ap
):
212 # passing *_handler makes the call asynchronous
213 self
.nmi
.ActivateConnection(USC
,
214 conn
.__dbus
_object
_path
__,
217 reply_handler
=self
.reply_handler
,
218 error_handler
=self
.err_handler
,
222 class cActiveConnection
:
223 def __init__(self
, opath
):
228 co
= bus
.get_object(NMC
, self
.opath
)
229 copi
= dbus
.Interface(co
, PI
)
230 for P
in ["ServiceName", "Connection", "SpecificObject",]:
231 print " %s: %s" % (P
, copi
.Get(NMI
, P
))
232 devs
= copi
.Get(NMI
, "Devices")
237 def bitmask_str(map, value
):
239 for mask
in sorted(map.keys()):
240 if value
& mask
: ret
.append(map[mask
])
245 def __init__(self
, opath
):
247 self
.devo
= bus
.get_object(NMC
, self
.opath
)
248 self
.devi
= dbus
.Interface(self
.devo
, NMI
+ ".Device")
249 self
.devpi
= dbus
.Interface(self
.devo
, PI
)
253 DEVICE_TYPE
= ["UNKNOWN", "802_3_ETHERNET", "802_11_WIRELESS",
254 "GSM", "CDMA",] #OLPC: 3 is MESH
256 def DeviceType(self
):
257 return self
.DEVICE_TYPE
[self
.DeviceType0()]
259 def ip_str(self
, i32
):
261 ret
.append("%d" % (i32
% 256))
263 ret
.append("%d" % (i32
% 256))
265 ret
.append("%d" % (i32
% 256))
267 ret
.append("%d" % (i32
% 256))
271 def DumpIp4Config(self
, opath
):
272 print " Ip4Config:", opath
273 o
= bus
.get_object(NMC
, opath
)
274 pi
= dbus
.Interface(o
, PI
)
276 for P
in ["Address", "Netmask", "Broadcast", "Gateway",]: # beta2?
277 print " %s: %s" % (P
, self
.ip_str(pi
.Get(NMI
, P
)))
280 addrs
= pi
.Get(NMI
, "Addresses")
282 print " %s/%s via %s" % tuple(map(self
.ip_str
, addr
))
283 nss
= pi
.Get(NMI
, "Nameservers")
284 print " Nameservers:", " ".join(map(self
.ip_str
, nss
))
285 doms
= pi
.Get(NMI
, "Domains")
286 print " Domains:", " ".join(doms
)
288 NM_DEVICE_CAP
= {1: "NM_SUPPORTED", 2: "CARRIER_DETECT", 4: "SCANNING", }
292 print "Device:", self
.opath
295 IW_MODE
= ["AUTO", "ADHOC", "INFRA", "MASTER",
296 "REPEAT", "SECOND", "MONITOR",]
302 for ap
in self
.APs():
309 class cDevice_06(cDevice
):
310 def DeviceType0(self
):
312 self
.dt
= self
.devi
.getProperties()[2]
314 self
.__class
__ = cDeviceEth_06
316 self
.__class
__ = cDeviceWifi_06
320 "UNKNOWN", "DEVICE_PREPARE", "DEVICE_CONFIG", "NEED_USER_KEY",
321 "IP_CONFIG_START", "IP_CONFIG_GET", "IP_CONFIG_COMMIT",
322 "ACTIVATED", "FAILED", "CANCELLED", ]
326 print " Driver:", self
.devi
.getDriver()
327 props
= self
.devi
.getProperties() # osusb ussss sssii biuus as
328 print " Self:", props
[0] # o
329 print " Interface:", props
[1] # s
330 print " Type:", self
.DEVICE_TYPE
[props
[2]] # u
331 print " UDI:", props
[3] # s
332 print " Active:", bool(props
[4]) # b
333 print " Activation Stage:", self
.NM_ACT_STAGE
[props
[5]] # u
334 print " IP:", props
[6] # s
335 print " Mask:", props
[7] # s
336 print " Bcast:", props
[8] # s
337 print " HwAddress:", props
[9] # s
338 print " GW:", props
[10] # s
339 print " NS1:", props
[11] # s
340 print " NS2:", props
[12] # s
344 print " (unknown device type, not dumping more)"
346 class cDeviceEth_06(cDevice_06
, cDeviceEth
):
348 props
= self
.devi
.getProperties() # osusb ussss sssii biuus as
349 print " Link Active:", bool(props
[15]) # b
350 print " Speed:", props
[16] # i
351 print " Generic Capabilities:", bitmask_str(self
.NM_DEVICE_CAP
, props
[17]) # u
353 class cDeviceWifi_06(cDevice_06
):
355 0x00000001: "PROTO_NONE",
356 0x00000002: "PROTO_WEP",
357 0x00000004: "PROTO_WPA",
358 0x00000008: "PROTO_WPA2",
359 0x00000010: "RESERVED1",
360 0x00000020: "RESERVED2",
361 0x00000040: "KEY_MGMT_PSK",
362 0x00000080: "KEY_MGMT_802_1X",
363 0x00000100: "RESERVED3",
364 0x00000200: "RESERVED4",
365 0x00000400: "RESERVED5",
366 0x00000800: "RESERVED6",
367 0x00001000: "CIPHER_WEP40",
368 0x00002000: "CIPHER_WEP104",
369 0x00004000: "CIPHER_TKIP",
370 0x00008000: "CIPHER_CCMP",
374 self
.wdevi
= dbus
.Interface(self
.devo
, NMI
+ ".Device.Wireless")
375 aps
= self
.devi
.getProperties()[20]
376 return map(cAP_06
, aps
)
379 props
= self
.devi
.getProperties() # osusb ussss sssii biuus as
380 print " Mode:", self
.IW_MODE
[props
[13]] # i
381 print " Strength:", props
[14] # i
382 print " Link Active:", bool(props
[15]) # b
383 print " Speed:", props
[16] # i
384 print " Generic Capabilities:", bitmask_str(self
.NM_DEVICE_CAP
, props
[17]) # u
385 print " Capabilities:", bitmask_str(self
.NM_802_11_CAP
, props
[18]) # u
386 print " Current net:", props
[19] # s
387 nets
= props
[20] # as
388 print " Seen nets:", " ".join(nets
)
390 print " Access Points"
391 for ap
in self
.APs():
394 class cDevice_07(cDevice
):
395 def DeviceType0(self
):
397 self
.dt
= self
.devpi
.Get(NMI
, "DeviceType")
399 self
.__class
__ = cDeviceEth_07
401 self
.__class
__ = cDeviceWifi_07
405 "UNKNOWN", "UNMANAGED", "UNAVAILABLE", "DISCONNECTED", "PREPARE",
406 "CONFIG", "NEED_AUTH", "IP_CONFIG", "ACTIVATED", "FAILED",]
411 # "Ip4Config", only for NM_DEVICE_STATE_ACTIVATED
412 for P
in ["Udi", "Interface", "Driver",]:
413 print " %s: %s" % (P
, self
.devpi
.Get(NMI
, P
))
414 addr
= self
.devpi
.Get(NMI
, "Ip4Address")
415 print " Ip4Address:", self
.ip_str(addr
)
416 caps
= self
.devpi
.Get(NMI
, "Capabilities")
417 print " Capabilities:", bitmask_str(self
.NM_DEVICE_CAP
, caps
)
418 state
= self
.NM_DEVICE_STATE
[self
.devpi
.Get(NMI
, "State")]
419 print " Dev State:", state
420 if state
== "ACTIVATED":
421 self
.DumpIp4Config(self
.devpi
.Get(NMI
, "Ip4Config"))
423 dt
= self
.DeviceType()
424 print " Dev Type:", dt
427 class cDeviceEth_07(cDevice_07
, cDeviceEth
):
429 for P
in ["HwAddress", "Speed", "Carrier"]:
430 print " %s: %s" % (P
, self
.devpi
.Get(NMI
, P
))
432 class cDeviceWifi_07(cDevice_07
):
433 NM_802_11_DEVICE_CAP
= {1:"CIPHER_WEP40", 2:"CIPHER_WEP104",
434 4:"CIPHER_TKIP", 8:"CIPHER_CCMP",
438 self
.wdevi
= dbus
.Interface(self
.devo
, NMI
+ ".Device.Wireless")
439 aps
= self
.wdevi
.GetAccessPoints()
440 return map(cAP_07
, aps
)
443 print " Dev Mode:", self
.IW_MODE
[self
.devpi
.Get(NMI
, "Mode")]
444 wcaps
= self
.devpi
.Get(NMI
, "WirelessCapabilities")
445 print " Wifi Capabilities:", bitmask_str(self
.NM_802_11_DEVICE_CAP
, wcaps
)
446 for P
in ["HwAddress", "Bitrate", "ActiveAccessPoint"]:
447 print " %s: %s" % (P
, self
.devpi
.Get(NMI
, P
))
449 print " Access Points"
450 for ap
in self
.APs():
453 """An AP found around us"""
455 def __init__(self
, opath
):
457 self
.apo
= bus
.get_object(NMC
, self
.opath
)
458 self
.appi
= dbus
.Interface(self
.apo
, PI
)
460 self
.devi
= dbus
.Interface(self
.apo
, NMI
+ ".Devices")
462 NM_802_11_AP_FLAGS
= {1: "PRIVACY",}
465 1: "PAIR_WEP40", 2: "PAIR_WEP104", 4: "PAIR_TKIP", 8: "PAIR_CCMP",
466 16: "GROUP_WEP40", 32: "GROUP_WEP104", 64: "GROUP_TKIP",
467 128: "GROUP_CCMP", 256: "KEY_MGMT_PSK", 512: "KEY_MGMT_802_1X",}
469 def ListNets(self
, marker
= " "):
471 mbr
= self
.Mbr() / 1024 # 07 1000, 06 1024?
472 priv_s
= self
.PrivS()
473 print "%s%3d: %s (%dMb%s)" % (marker
, self
.Strength(), self
.Ssid(), mbr
, priv_s
)
476 def Mbr(self
, props
=None):
478 props
= self
.devi
.getProperties()
483 props
= self
.devi
.getProperties()
484 caps_s
= bitmask_str(cDeviceWifi_06
.NM_802_11_CAP
, props
[7]) + ","
486 if caps_s
.find("PROTO_WEP,") != -1:
488 if caps_s
.find("PROTO_WPA,") != -1:
490 if caps_s
.find("PROTO_WPA2,") != -1:
492 if caps_s
.find("KEY_MGMT_802_1X,") != -1:
493 priv_s
+= " Enterprise"
496 def Strength(self
, props
=None):
498 props
= self
.devi
.getProperties()
501 def Ssid(self
, props
=None):
503 props
= self
.devi
.getProperties()
508 props
= self
.devi
.getProperties() # ossid iiib
509 print " Self:", props
[0]
510 print " Ssid:", self
.Ssid(props
)
511 print " HwAddress:", props
[2]
512 print " Strength:", self
.Strength(props
)
513 print " Frequency:", props
[4]
514 print " MaxBitrate:", self
.Mbr(props
)
515 print " AP Mode:", cDevice
.IW_MODE
[props
[6]]
516 print " Capabilities:", bitmask_str(cDeviceWifi_06
.NM_802_11_CAP
, props
[7])
517 print " Broadcast:", props
[8]
525 def opath_validchar(c
):
526 # _ is also escaped even though it is valid
528 string
.ascii_letters
.find(c
) != -1 or \
529 string
.digits
.find(c
) != -1
534 # TODO find a more elegant way
535 if not opath_validchar(c
):
541 def opath_unescape(s
):
543 unhex
= lambda xx
: chr(eval("0x"+xx
))
545 return re
.sub("_.._", lambda p
: unhex(p
.group()[1:3]), s
)
549 return self
.appi
.Get(NMI
, "MaxBitrate")
552 priv
= self
.appi
.Get(NMI
, "Flags") != 0
553 wpa
= self
.appi
.Get(NMI
, "WpaFlags") != 0
554 wpa2
= self
.appi
.Get(NMI
, "RsnFlags") != 0
557 if not wpa
and not wpa2
:
558 priv_s
= priv_s
+ " WEP"
560 priv_s
= priv_s
+ " WPA"
562 priv_s
= priv_s
+ " WPA2"
566 return int(self
.appi
.Get(NMI
, "Strength"))
569 return ssid_str(self
.appi
.Get(NMI
, "Ssid"))
572 print " AP:", self
.opath
573 print " Ssid:", self
.Ssid()
574 for P
in ["Frequency", "HwAddress", "MaxBitrate",]:
575 print " %s: %s" % (P
, self
.appi
.Get(NMI
, P
))
576 print " Strength:", self
.Strength()
577 print " AP Mode:", cDevice
.IW_MODE
[self
.appi
.Get(NMI
, "Mode")]
578 print " AP Flags:", bitmask_str(self
.NM_802_11_AP_FLAGS
,
579 self
.appi
.Get(NMI
, "Flags"))
580 print " AP WPA Flags:", bitmask_str(self
.NM_802_11_AP_SEC
,
581 self
.appi
.Get(NMI
, "WpaFlags"))
582 print " AP RSN Flags:", bitmask_str(self
.NM_802_11_AP_SEC
,
583 self
.appi
.Get(NMI
, "RsnFlags"))
585 # this is the client side of the applet; see also UserSettings
587 def __init__(self
, svc
, opath
):
590 self
.so
= bus
.get_object(self
.svc
, self
.opath
)
591 self
.si
= dbus
.Interface(self
.so
, 'org.freedesktop.NetworkManagerSettings')
594 return self
.svc
== SSC
;
597 for conn
in self
.Connections():
602 def DumpSystem(self
):
603 sspi
= dbus
.Interface(self
.so
, PI
)
604 print "Unmanaged Devices"
605 umds
= sspi
.Get(NMI
, "UnmanagedDevices")
608 # dump_settings_conn(svc, conn) umd?
611 def myConnection(self
, opath
):
612 return cConnection(self
.svc
, opath
)
614 def Connections(self
):
615 opaths
= self
.si
.ListConnections()
616 return map(self
.myConnection
, opaths
)
618 NETWORK_TYPE_ALLOWED
= 1
619 class cApplet_06(cApplet
):
620 def __init__(self
, svc
, opath
):
623 self
.io
= bus
.get_object(self
.svc
, self
.opath
)
624 self
.ii
= dbus
.Interface(self
.io
, 'org.freedesktop.NetworkManagerInfo')
629 def myConnection(self
, opath
):
630 return cConnection_06(self
, opath
)
632 # TODO also VPN conns
633 def Connections(self
):
634 names
= self
.ii
.getNetworks(NETWORK_TYPE_ALLOWED
)
635 return map(self
.myConnection
, names
)
638 def __init__(self
, svc
, opath
):
641 self
.co
= bus
.get_object(self
.svc
, self
.opath
)
642 self
.ci
= dbus
.Interface(self
.co
, 'org.freedesktop.NetworkManagerSettings.Connection')
645 print "Conn:", self
.opath
646 settings
= self
.Settings()
649 si
= dbus
.Interface(self
.co
, 'org.freedesktop.NetworkManagerSettings.Connection.Secrets')
650 security
= settings
.Security()
652 print " SECRETS:", security
654 secrets
= cSettings(si
.GetSecrets(security
,[],False))
658 return cSettings(self
.ci
.GetSettings())
660 def dump_time(unixtime
):
661 return time
.asctime(time
.localtime(unixtime
))
663 class cConnection_06
:
664 def __init__(self
, applet
, id):
669 print "Conn:", self
.id
671 np
= self
.applet
.ii
.getNetworkProperties(self
.id, NETWORK_TYPE_ALLOWED
)
674 print " time:", dump_time(np
[1])
675 print " trusted:", bool(np
[2])
676 print " bssids:", ", ".join(np
[3])
678 print " we_cipher:", enctype
680 print " secret:", np
[5]
682 print " wep_auth_algorithm:", np
[6]
684 print " wpa_psk_key_mgt:", np
[6]
685 print " wpa_psk_wpa_version:", np
[7]
687 return # nm-applet will not tell kfn anyway
688 devp
= "/org/freedesktop/NetworkManager/Devices/ath0" #FIXME
689 netp
= devp
+ "/Networks/" + opath_escape(self
.id)
692 kfn
= self
.applet
.ii
.getKeyForNetwork(devp
, netp
, ssid
, attempt
, newkey
)
697 NM_AUTH_TYPE_WPA_PSK_AUTO
= 0x00000000
698 NM_AUTH_TYPE_NONE
= 0x00000001
699 NM_AUTH_TYPE_WEP40
= 0x00000002
700 NM_AUTH_TYPE_WPA_PSK_TKIP
= 0x00000004
701 NM_AUTH_TYPE_WPA_PSK_CCMP
= 0x00000008
702 NM_AUTH_TYPE_WEP104
= 0x00000010
703 NM_AUTH_TYPE_WPA_EAP
= 0x00000020
704 NM_AUTH_TYPE_LEAP
= 0x00000040
706 IW_AUTH_ALG_OPEN_SYSTEM
= 0x00000001
707 IW_AUTH_ALG_SHARED_KEY
= 0x00000002
708 IW_AUTH_ALG_LEAP
= 0x00000004
711 def __init__(self
, conmap
):
712 #print "INIT", conmap
716 return self
.conmap
["connection"]["type"]
719 return self
.conmap
["connection"]["id"]
722 s
= self
.conmap
["802-11-wireless"]["ssid"]
728 return self
.conmap
["connection"]["timestamp"]
736 def SeenBssids(self
):
738 return self
.conmap
["802-11-wireless"]["seen-bssids"]
746 return NM_AUTH_TYPE_WEP104
748 return NM_AUTH_TYPE_WPA_PSK_AUTO
750 return NM_AUTH_TYPE_NONE
751 print "Defaulting cipher type to none"
752 return NM_AUTH_TYPE_NONE
756 return self
.conmap
["802-11-wireless-security"]["psk"]
760 return self
.conmap
["802-11-wireless-security"]["wep-key0"]
766 def WepAuthAlgorithm(self
):
767 print "FIXME Defaulting WEP auth alg to open"
768 return IW_AUTH_ALG_OPEN_SYSTEM
771 print "FIXME Defaulting PSK key mgmt to 2"
774 def PskWpaVersion(self
):
775 print "FIXME Defaulting WPA version to 2"
780 return self
.conmap
[self
.Type()]["security"]
784 def isNet(self
, net_name
):
785 return self
.ID() == net_name
or self
.Ssid() == net_name
787 # FIXME check spec/NM what to censor
788 secrets
= dict.fromkeys(["wep-key0", "psk"])
791 "For GetSettings: censor secrets."
794 for n1
, v1
in self
.conmap
.iteritems():
796 for n2
, v2
in v1
.iteritems():
798 if self
.secrets
.has_key(n2
):
804 "For GetSecrets: only secrets."
813 for n1
, v1
in self
.conmap
.iteritems():
815 for n2
, v2
in v1
.iteritems():
816 print " %s: %s" % (n2
, v2
)
818 def mkconmap_wifi(ssid
):
821 'id': '_cnm_handcrafted_',
822 'uuid': str(uuid
.uuid1()), # new in oS 11.1
823 'type': '802-11-wireless',
826 'ssid': dbus
.ByteArray(ssid
),
827 'mode': 'infrastructure',
828 'security': '802-11-wireless-security',
830 '802-11-wireless-security': {
835 def elongate(s
, tlen
):
836 "repeat string s to target length tlen"
839 copies_needed
= int(math
.ceil(tlen
/ float(len(s
))))
840 return (s
* copies_needed
)[:tlen
]
842 # http://www.mail-archive.com/networkmanager-list@gnome.org/msg07935.html
843 def wep_passphrase_to_hash(p
):
844 return hashlib
.md5(elongate(p
, 64)).hexdigest()
846 def mkconmap_wep_pass(ssid
, key
):
847 cm
= mkconmap_wifi(ssid
)
848 cm
["802-11-wireless-security"]["key-mgmt"] = "none"
849 cm
["802-11-wireless-security"]["wep-tx-keyidx"] = 0
850 cm
["802-11-wireless-security"]["wep-key0"] = wep_passphrase_to_hash(key
)
853 def mkconmap_wep(ssid
, key
):
854 cm
= mkconmap_wifi(ssid
)
855 cm
["802-11-wireless-security"]["key-mgmt"] = "none"
856 cm
["802-11-wireless-security"]["wep-tx-keyidx"] = 0
857 cm
["802-11-wireless-security"]["wep-key0"] = key
860 def mkconmap_psk(ssid
, key
):
861 cm
= mkconmap_wifi(ssid
)
862 cm
["802-11-wireless-security"]["key-mgmt"] = "wpa-psk"
863 cm
["802-11-wireless-security"]["wep-tx-keyidx"] = 0
864 cm
["802-11-wireless-security"]["psk"] = key
868 # server analog of cApplet
869 class UserSettings(dbus
.service
.Object
):
871 def __init__(self
, opath
, conmaps
):
872 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
873 #print "CONMAPS:", conmaps
874 self
.conns
= map(self
.newCon
, conmaps
)
876 def addCon(self
, conmap
):
877 c
= self
.newCon(conmap
)
882 def newCon(self
, conmap
):
883 cpath
= "/MyConnection/%d" % self
.counter
884 self
.counter
= self
.counter
+ 1
885 c
= Connection(cpath
, conmap
)
886 self
.NewConnection(cpath
) # announce it
889 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings',
890 in_signature
='', out_signature
='ao')
891 def ListConnections(self
):
892 return [c
.__dbus
_object
_path
__ for c
in self
.conns
]
894 #this is for EMITTING a signal, not receiving it
895 @dbus.service
.signal(dbus_interface
='org.freedesktop.NetworkManagerSettings',
897 def NewConnection(self
, opath
):
899 #print "signalling newconn:", opath
901 def GetByNet(self
, net_name
):
902 "Returns connection, or None"
904 if c
.isNet(net_name
):
909 class UserSettings_06(UserSettings
):
911 def __init__(self
, opath
, conmaps
):
912 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
913 #print "CONMAPS:", conmaps
914 self
.conns
= map(self
.newCon
, conmaps
)
917 def newCon(self
, conmap
):
918 cpath
= "/MyConnection/%d" % self
.counter
919 self
.counter
= self
.counter
+ 1
920 c
= Connection_06(cpath
, conmap
)
921 #self.NewConnection(cpath) # announce it
924 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
925 in_signature
="i", out_signature
='as')
926 def getNetworks(self
, i
):
927 # FIXME bytearray to str WHERE?
928 #n = [ssid_str(c.Ssid()) for c in self.conns]
929 n
= [c
.ID() for c
in self
.conns
]
930 print "getNetworks:", n
933 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
934 in_signature
="", out_signature
='ao') # out??
935 def getVPNConnections(self
):
938 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
940 #out_signature='sibasi') #varies
941 def getNetworkProperties(self
, net
, type):
943 # type is 1, NETWORK_TYPE_ALLOWED
944 c
= self
.GetByNet(net
)
946 return c
.getNetworkProperties()
947 print "Oops, could not getNetworkProperties for " + net
950 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
951 in_signature
="oosib")
952 #out_signature="isi") varies
953 def getKeyForNetwork(self
, dev
, net
, ssid
, attempt
, newkey
):
954 print "GKFN", dev
, net
, ssid
, attempt
, bool(newkey
)
956 m
= "Cannot ask for key"
958 raise dbus
.exceptions
.DBusException(m
)
960 snet
= opath_unescape(net
[net
.rfind("/")+1 : ]) # only stuff after /
961 c
= self
.GetByNet(snet
)
963 return c
.getKeyForNetwork()
964 print "Oops, could not getKeyForNetwork " + net
966 @dbus.service
.method(dbus_interface
="org.freedesktop.NetworkManagerInfo",
968 #in_signature="sbs isi", varies
969 def updateNetworkInfo(self
, ssid
, automatic
, bssid
, *security
):
970 print "Connected successfully"
974 print " automatic:", bool(automatic
)
975 print " bssid:", bssid
976 print " security:", security
979 def GetByNet(self
, net_name
):
980 "Returns connection, or None"
982 if c
.isNet(net_name
):
987 # server analog of cConnection
988 class Connection(dbus
.service
.Object
):
989 def __init__(self
, opath
, conmap
):
990 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
991 self
.settings
= cSettings(conmap
)
993 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection',
994 in_signature
='', out_signature
='a{sa{sv}}')
995 def GetSettings(self
):
996 #print "Getting settings:", self. __dbus_object_path__
997 # return self.settings.ConMap()
998 # grr, censoring secrets makes NM complain!?
999 return self
.settings
.conmap
1001 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection.Secrets',
1002 in_signature
='sasb', out_signature
='a{sa{sv}}')
1003 def GetSecrets(self
, tag
, hints
, ask
):
1004 # FIXME respect args
1005 print "Getting secrets:", self
.__dbus
_object
_path
__
1006 return self
.settings
.SecMap()
1008 @dbus.service
.method(dbus_interface
='org.freedesktop.NetworkManagerSettings.Connection',
1009 in_signature
='', out_signature
='s')
1011 return self
.settings
.ID()
1014 return self
.settings
.Ssid()
1016 def isNet(self
, net_name
):
1017 return self
.settings
.isNet(net_name
)
1019 class Connection_06(Connection
):
1020 def __init__(self
, opath
, conmap
):
1021 dbus
.service
.Object
.__init
__(self
, bus
, opath
)
1023 self
.settings
= cSettings(conmap
)
1025 # dbus.service.method
1026 def getNetworkProperties(self
):
1027 # essid, timestamp, ?, bssids, we_cipher, ?, ...
1028 # we_cipher=16: i wep_auth_algorithm
1029 # we_cipher=0: i wpa_psk_key_mgt, i wpa_psk_wpa_version
1030 ssid
= ssid_str(self
.settings
.Ssid())
1031 time
= self
.settings
.Timestamp() # last sucessfully connected? seen?
1032 trusted
= self
.settings
.Trusted()
1033 bssids
= dbus
.Array(self
.settings
.SeenBssids(), signature
="s")
1034 r
= [ssid
, time
, trusted
, bssids
]
1035 security
= self
.getKeyForNetwork("fake key")
1039 # dbus.service.method
1040 def getKeyForNetwork(self
, fake
="no"):
1042 key
= self
.settings
.Key()
1047 cip
= self
.settings
.WeCipher()
1048 if cip
== NM_AUTH_TYPE_NONE
:
1049 security
= tuple([cip
])
1050 elif cip
== NM_AUTH_TYPE_WEP40
or cip
== NM_AUTH_TYPE_WEP104
:
1051 wep_auth_algorithm
= self
.settings
.WepAuthAlgorithm()
1052 security
= (cip
, key
, wep_auth_algorithm
)
1053 elif cip
== NM_AUTH_TYPE_WPA_PSK_AUTO
or cip
== NM_AUTH_TYPE_TKIP
or \
1054 cip
== NM_AUTH_TYPE_CCMP
:
1055 wpa_psk_key_mgt
= self
.settings
.PskKeyMgt()
1056 wpa_psk_wpa_version
= self
.settings
.PskWpaVersion()
1057 security
= (cip
, key
, wpa_psk_key_mgt
, wpa_psk_wpa_version
)
1058 elif cip
== NM_AUTH_TYPE_WPA_EAP
:
1059 security
= tuple([cip
]) # TODO more...
1060 elif cip
== NM_AUTH_TYPE_LEAP
:
1061 security
= tuple([cip
]) # TODO more...
1065 class ConfigParserKNM
:
1066 "Parse ~/.kde/share/config/knetworkmanagerrc"
1069 p
= ConfigParser
.RawConfigParser()
1070 ok
= p
.read(os
.getenv("HOME") + "/.kde/share/config/knetworkmanagerrc")
1073 for s
in p
.sections():
1076 if path
[0] in ["ConnectionSetting", "ConnectionSecrets"]:
1078 self
.conmaps_d
.setdefault(cid
, {})
1082 for (n
, v
) in p
.items(s
):
1083 # WTF, Value_ is transfrmed to value_
1084 if n
[:6] == "value_":
1086 v
= self
.ParseValue(v
)
1088 if len(values
) != 0: # empty 802-1x confuses NM!?
1089 self
.conmaps_d
[cid
].setdefault(part
, {})
1090 self
.conmaps_d
[cid
][part
].update(**values
)
1091 #print "PARSED", cid, part, values
1094 return self
.conmaps_d
.values()
1096 def ParseValue(self
, v
):
1097 v
= eval('"%s"' % v
) # unescape backslashes
1098 dom
= xml
.dom
.minidom
.parseString(v
)
1099 return self
.ParseNode(dom
.documentElement
)
1101 def ParseNode(self
, n
):
1104 v
= self
.NodeText(n
)
1109 return dbus
.Byte(int(v
))
1112 elif t
== "int32" or t
== "uint32":
1118 if c
.localName
!= None: # whitespace
1119 v
.append(self
.ParseNode(c
))
1123 def NodeText(self
, n
):
1124 if n
.hasChildNodes():
1125 return n
.firstChild
.wholeText
1129 def abbr_signal_handler(*args
, **kwargs
):
1130 ifc
= kwargs
["interface"]
1131 sig
= kwargs
["member"]
1132 opath
= kwargs
["path"]
1133 line
= "SIG %s: %s.%s%s" % (abbrev(opath
,"/"), abbrev(ifc
,"."), sig
, args
)
1139 bus
.add_signal_receiver(self
.abbr_signal_handler
,
1140 path_keyword
="path",
1141 interface_keyword
="interface",
1142 member_keyword
="member")
1144 def abbr_signal_handler(self
, *args
, **kwargs
):
1145 ifc
= kwargs
["interface"]
1146 sig
= kwargs
["member"]
1147 opath
= kwargs
["path"]
1148 line
= "SIG %s: %s.%s%s" % (self
.abbrev(opath
,"/"),
1149 self
.abbrev(ifc
,"."),
1153 def abbrev(self
, s
, sep
):
1154 words
= s
.split(sep
)
1155 words
= map (self
.a1
, words
)
1156 result
= sep
.join(words
)
1157 if not self
.amap
.has_key(s
):
1158 print "ABBR %s is %s" % (result
, s
)
1159 self
.amap
[s
] = result
1161 if self
.amap
[s
] != result
:
1162 print "ABBR COLLISION %s was %s now %s" % (s
, self
.amap
[s
], result
)
1173 op
= OptionParser(version
="%prog " + VERSION
)
1174 op
.add_option("-d", "--dev",
1175 action
="store_true", default
=False,
1176 help="list devices")
1177 op
.add_option("-c", "--actcon",
1178 action
="store_true", default
=False,
1179 help="list active connections")
1180 op
.add_option("-u", "--usrcon",
1181 action
="store_true", default
=False,
1182 help="list user connection settings (can CRASH nm-applet)")
1183 op
.add_option("-s", "--syscon",
1184 action
="store_true", default
=False,
1185 help="list system connection settings")
1186 op
.add_option("-a", "--ap",
1187 action
="store_true", default
=False,
1188 help="list found access points")
1189 op
.add_option("-n", "--nets",
1190 action
="store_true", default
=False,
1191 help="list found wireless networks")
1192 # TODO http://docs.python.org/lib/optparse-adding-new-types.html
1193 op
.add_option("-w", "--wifi",
1194 choices
=["0","1","off","on","no","yes","false","true"],
1196 help="enable or disable wireless")
1197 op
.add_option("-o", "--online",
1198 choices
=["0","1","off","on","no","yes","false","true"],
1200 help="enable or disable network at all")
1202 op
.add_option("-C", "--connect",
1203 help="connect to a wireless network NET (using knetworkmanagerrc or the key options below)",
1205 op
.add_option("--unprotected",
1206 action
="store_true", default
=False,
1207 help="network does not require a key")
1208 op
.add_option("--wep-hex",
1210 help="use this WEP key of 26 hex digits")
1211 op
.add_option("--wep-pass",
1213 help="use this WEP passphrase")
1214 op
.add_option("--wpa-psk-hex",
1216 help="use this WPA key of 64 hex digits")
1217 op
.add_option("--wpa-pass",
1219 help="use this WPA passphrase")
1220 op
.add_option("-m", "--monitor",
1221 action
="store_true", default
=False,
1222 help="loop to show dbus signals")
1225 (options
, args
) = op
.parse_args()
1233 nmp
= '/org/freedesktop/NetworkManager'
1236 except dbus
.exceptions
.DBusException
, e
:
1238 print "NetworkManager is not running"
1240 if options
.dev
or options
.actcon
:
1243 true_choices
= ["1", "on", "yes", "true"]
1244 if options
.wifi
!= None:
1245 nm
.SetWifiEnabled(options
.wifi
in true_choices
)
1246 if options
.online
!= None:
1247 nm
.SetOnline(options
.online
in true_choices
)
1253 print "SYSTEM Connections"
1254 if nm
.Api() == "06":
1255 print "Cannot do that with NM 0.6"
1257 ss
= cApplet(SSC
, '/org/freedesktop/NetworkManagerSettings')
1261 print "USER Connections"
1263 if nm
.Api() == "06":
1264 us
= cApplet_06(NMIC
, "/org/freedesktop/NetworkManagerInfo")
1266 us
= cApplet(USC
, '/org/freedesktop/NetworkManagerSettings')
1268 except dbus
.exceptions
.DBusException
, e
:
1270 #if e.get_dbus_name() == "org.freedesktop.DBus.Error.ServiceUnknown":
1271 print "Applet is not running"
1273 nmo
= bus
.get_object(NMC
, nmp
)
1274 nmi
= dbus
.Interface(nmo
, NMI
)
1276 def service_pid(name
):
1277 DBS
= 'org.freedesktop.DBus'
1279 dbo
= bus
.get_object(DBS
, '/')
1280 dbi
= dbus
.Interface(dbo
, DBI
)
1281 owner
= dbi
.GetNameOwner(name
)
1282 pid
= dbi
.GetConnectionUnixProcessID(owner
)
1285 # TODO UserSettings_06
1286 if options
.connect
!= None:
1287 if nm
.Api() == "06":
1291 brn
= bus
.request_name(name
, _dbus_bindings
.NAME_FLAG_DO_NOT_QUEUE
)
1292 if brn
== _dbus_bindings
.REQUEST_NAME_REPLY_EXISTS
:
1293 print "Could not provide settings service, another applet is running (pid %s)" % service_pid(name
)
1295 cfg
= ConfigParserKNM()
1296 if nm
.Api() == "06":
1297 us
= UserSettings_06("/org/freedesktop/NetworkManagerInfo",
1300 us
= UserSettings("/org/freedesktop/NetworkManagerSettings",
1303 def Connect(wanted_net
): # any. or take arg. net is config name or ssid name
1304 # ... in general, look for string in all config data. ssid for wifi, whatever for dialup
1305 # TODO also respect autoconnect
1307 # ActivateConn wants setting device ap; can find device from ap? ap is "specific" for wifi devices
1308 #print "Connection wanted to", wanted_net
1309 found_con
= found_ap
= found_dev
= None
1310 for dev
in nm
.Devices():
1311 for ap
in dev
.APs():
1312 if wanted_net
== ap
.Ssid():
1315 break # FIXME both loops
1316 found_con
= us
.GetByNet(wanted_net
)
1317 if found_ap
== None:
1318 print "No AP found with SSID", wanted_net
1320 if found_con
== None:
1321 print "No settings for net %s, assuming no key is needed" % wanted_net
1322 c
= mkconmap_wifi(wanted_net
)
1323 found_con
= us
.addCon(c
)
1324 nm
.ActivateConnection(found_con
, found_dev
, found_ap
) # TODO async
1325 # TODO run loop, exit it when we have serviced the required calls
1328 if options
.connect
!= None:
1329 if options
.unprotected
:
1330 c
= mkconmap_wifi(options
.connect
)
1332 if options
.wep_hex
!= None:
1333 c
= mkconmap_wep(options
.connect
, options
.wep_hex
)
1335 if options
.wep_pass
!= None:
1336 c
= mkconmap_wep_pass(options
.connect
, options
.wep_pass
)
1338 if options
.wpa_psk_hex
!= None:
1339 c
= mkconmap_psk(options
.connect
, options
.wpa_psk_hex
)
1341 if options
.wpa_pass
!= None:
1342 wpa_psk_hex
= hexlify(pbkdf2
.pbkdf2(options
.wpa_pass
, options
.connect
, 4096, 32))
1343 print "pbkdf2", wpa_psk_hex
1344 c
= mkconmap_psk(options
.connect
, wpa_psk_hex
)
1346 if Connect(options
.connect
):
1353 loop
= gobject
.MainLoop()