Fixed the --wep-* and --wpa-* options (Gentoo#281099).
[cnetworkmanager.git] / cnetworkmanager
blobe8657a8aec0749a1bef0525246cbe64cef166043
1 #!/usr/bin/python
2 VERSION = "0.21"
4 import sys
5 import time
6 import dbus
7 from networkmanager import NetworkManager
8 from networkmanager.monitor import Monitor
9 from networkmanager.applet import NetworkManagerSettings, SYSTEM_SERVICE, USER_SERVICE
10 from networkmanager.applet.service import NetworkManagerUserSettings
11 import networkmanager.applet.settings as settings
12 from networkmanager.util import Table
14 # must be set before we ask for signals
15 from dbus.mainloop.glib import DBusGMainLoop
16 DBusGMainLoop(set_as_default=True)
17 # for calling quit
18 import gobject
19 loop = gobject.MainLoop()
20 LOOP = False
22 from optparse import OptionParser
24 op = OptionParser(version="%prog " + VERSION)
26 op.add_option("-t", "--terse",
27 action="store_true", default=False,
28 help="No table headings and padding, suitable for parsing")
30 # TODO http://docs.python.org/lib/optparse-adding-new-types.html
31 op.add_option("-w", "--wifi",
32 choices=["0","1","off","on","no","yes","false","true"],
33 metavar="BOOL",
34 help="Enable or disable wireless")
35 op.add_option("-o", "--online",
36 choices=["0","1","off","on","no","yes","false","true"],
37 metavar="BOOL",
38 help="Enable or disable network at all")
39 op.add_option("--state",
40 action="store_true", default=False,
41 help="Print the NM state")
42 op.add_option("--we", "--wireless-enabled",
43 action="store_true", default=False,
44 help="Print whether the WiFi is enabled")
45 op.add_option("--whe", "--wireless-hardware-enabled",
46 action="store_true", default=False,
47 help="Print whether the WiFi hardware is enabled")
49 op.add_option("-d", "--device-list", "--dev",
50 action="store_true", default=False,
51 help="List devices")
52 op.add_option("--device-info", "--di",
53 help="Info about device DEV (by interface or UDI(TODO))",
54 metavar="DEV")
56 op.add_option("-a", "--ap-list", "--ap", "-n", "--nets",# -n is a stopgap
57 action="store_true", default=False,
58 help="List access points")
59 op.add_option("--ap-info", "--ai",
60 help="Info about access point AP (by hw address or UDI(TODO))",
61 metavar="AP")
63 op.add_option("-u", "--usrcon",
64 action="store_true", default=False,
65 help="List user connection settings")
66 op.add_option("-s", "--syscon",
67 action="store_true", default=False,
68 help="List system connection settings")
69 op.add_option("--con-info", "--ci",
70 help="Info about connection settings ID (of the *user*/system KIND)",
71 metavar="[KIND,]ID")
73 op.add_option("-c", "--actcon",
74 action="store_true", default=False,
75 help="List active connections")
77 op.add_option("--demo",
78 action="store_true", default=False,
79 help="Run a random demonstration of the API")
80 op.add_option("--activate-connection",
81 help="activate the KIND(user/system) connection ID on device DEV using APMAC.",
82 metavar="[KIND],ID,[DEV],[APMAC]")
83 op.add_option("-m", "--monitor",
84 action="store_true", default=False,
85 help="loop to show dbus signals")
87 op.add_option("-C", "--connect",
88 help="Connect to a wireless network SSID (creating the configuration using the key options below)",
89 metavar="SSID")
90 op.add_option("--unprotected",
91 action="store_true", default=False,
92 help="network does not require a key")
93 op.add_option("--wep-hex",
94 metavar="KEY",
95 help="use this WEP key of 26 hex digits")
96 op.add_option("--wep-pass",
97 metavar="KEY",
98 help="use this WEP passphrase")
99 op.add_option("--wpa-psk-hex",
100 metavar="KEY",
101 help="use this WPA key of 64 hex digits")
102 op.add_option("--wpa-pass",
103 metavar="KEY",
104 help="use this WPA passphrase")
106 (options, args) = op.parse_args()
108 Table.terse = options.terse
110 nm = NetworkManager()
112 true_choices = ["1", "on", "yes", "true"]
113 if options.wifi != None:
114 nm["WirelessEnabled"] = options.wifi in true_choices
115 if options.we:
116 print nm["WirelessEnabled"]
117 if options.online != None:
118 try:
119 nm.Sleep(not options.online in true_choices)
120 except dbus.exceptions.DBusException, e:
121 if e.get_dbus_name() != "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake":
122 raise
124 if options.state:
125 print nm["State"]
126 if options.whe:
127 print nm["WirelessHardwareEnabled"]
128 # style option: pretend that properties are methods (er, python properties)
129 # nm["WirelessEnabled"] -> nm.WirelessEnabled() (er, nm.WirelessEnabled )
131 if options.device_list:
132 devs = nm.GetDevices()
133 t = Table("Interface", "Type", "State")
134 for dev in devs:
135 t.row(dev["Interface"], dev["DeviceType"], dev["State"])
136 print t
138 # --device-info, TODO clean up
139 def get_device(dev_spec, hint):
140 candidates = []
141 # print "Hint:", hint
142 devs = NetworkManager().GetDevices()
143 for dev in devs:
144 # print dev
145 if dev._settings_type() == hint:
146 candidates.append(dev)
147 # print "Candidates:", candidates
148 if len(candidates) == 1:
149 return candidates[0]
150 for dev in devs:
151 if dev["Interface"] == dev_spec:
152 return dev
153 print "Device '%s' not found" % dev_spec
154 return None
156 if options.device_info != None:
157 d = get_device(options.device_info, "no hint")
158 if d == None:
159 print "not found"
160 else:
161 props = ["Udi", "Interface", "Driver", "Capabilities",
162 # "Ip4Address", # bogus, remembers last addr even after disused
163 "State",
164 # "Ip4Config", "Dhcp4Config", # only __repr__
165 "Managed", "DeviceType"]
166 if d._settings_type() == "802-11-wireless":
167 props.extend(["Mode", "WirelessCapabilities"])
168 elif d._settings_type() == "802-3-ethernet":
169 props.extend(["Carrier"])
171 print Table.from_items(d, *props)
173 if options.ap_list:
174 devs = nm.GetDevices()
175 # nm.get_wifi_devices()
176 # nm.get_devices_by_type(Device.Type.WIRELESS)
177 for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
178 aap = dev["ActiveAccessPoint"]
179 t = Table("Active", "HwAddress", "Ssid")
180 for ap in dev.GetAccessPoints():
181 active = "*" if ap.object_path == aap.object_path else ""
182 t.row(active, ap["HwAddress"], ap["Ssid"])
183 print t
185 if options.ap_info != None:
186 devs = nm.GetDevices()
187 for dev in filter(lambda d: d._settings_type() == "802-11-wireless", devs):
188 aap = dev["ActiveAccessPoint"]
189 for ap in dev.GetAccessPoints():
190 if ap["HwAddress"] == options.ap_info:
191 t = Table.from_items(ap, "Flags", "WpaFlags", "RsnFlags",
192 "Ssid", "Frequency", "HwAddress",
193 "Mode", "MaxBitrate", "Strength")
194 t.row("Active", ap.object_path == aap.object_path)
195 print t
197 #def is_opath(x):
198 # return is_instance(x, str) and x[0] == "/"
200 def get_service_name(svc):
201 if svc == "" or svc == "user":
202 svc = USER_SERVICE
203 elif svc == "system":
204 svc = SYSTEM_SERVICE
205 return svc
207 # move this to networkmanagersettings
208 def get_connection(svc, conn_spec):
209 # if is_opath(conn_spec):
210 # return conn_spec
211 applet = NetworkManagerSettings(get_service_name(svc))
212 for conn in applet.ListConnections():
213 cs = conn.GetSettings()
214 if cs["connection"]["id"] == conn_spec:
215 return conn
216 print "Connection '%s' not found" % conn_spec
217 return None
219 def get_connection_devtype(conn):
220 cs = conn.GetSettings()
221 return cs["connection"]["type"]
223 def list_conections(svc):
224 acs = nm["ActiveConnections"]
225 acos = map(lambda a: a["Connection"].object_path, acs)
227 try:
228 applet = NetworkManagerSettings(svc)
229 except dbus.exceptions.DBusException, e:
230 print e
231 return
232 t = Table("Active", "Name", "Type")
233 for conn in applet.ListConnections():
234 cs = conn.GetSettings()
235 active = "*" if conn.object_path in acos else ""
236 t.row(active, cs["connection"]["id"], cs["connection"]["type"])
237 print t
239 if options.usrcon:
240 list_conections(USER_SERVICE)
241 if options.syscon:
242 list_conections(SYSTEM_SERVICE)
244 if options.con_info != None:
245 (svc, con) = ("", options.con_info)
246 if "," in con:
247 (svc, con) = con.split(",")
249 c = get_connection(svc, con)
250 cs = c.GetSettings()
251 print Table.from_nested_dict(cs)
252 type = cs["connection"]["type"]
253 secu = cs[type]["security"]
254 cse = c.GetSecrets(secu, [], False)
255 print Table.from_nested_dict(cse)
257 # this shows we do need to add __str__ to the objects
258 if options.actcon:
259 acs = nm["ActiveConnections"]
260 t = Table("State", "Name", "AP", "Devices", "Default route")
261 for ac in acs:
262 cid = ac["Connection"].GetSettings()["connection"]["id"]
263 try:
264 apmac = ac["SpecificObject"]["HwAddress"]
265 except: # no AP for wired. TODO figure out "/" object
266 apmac = ""
267 devs = ", ".join(map(lambda d: d["Interface"], ac["Devices"]))
268 hdr = "*" if ac["Default"] else ""
269 t.row(ac["State"], cid, apmac, devs, hdr)
270 print t
272 if options.monitor:
273 m = Monitor()
274 LOOP = True
276 def print_state_changed(*args):
277 print time.strftime("(%X)"),
278 print "State:", ", ".join(map(str,args))
280 if options.connect != None:
281 ssid = options.connect
282 try:
283 us = NetworkManagerUserSettings([]) # request_name may fail
284 except dbus.exceptions.NameExistsException, e:
285 print "Another applet is running:", e
286 sys.exit(1)
288 c = None
289 if options.unprotected:
290 c = settings.WiFi(ssid)
291 if options.wep_hex != None:
292 c = settings.Wep(ssid, "", options.wep_hex)
293 if options.wep_pass != None:
294 c = settings.Wep(ssid, options.wep_pass)
295 if options.wpa_psk_hex != None:
296 c = settings.WpaPsk(ssid, "", options.wpa_psk_hex)
297 if options.wpa_pass != None:
298 c = settings.WpaPsk(ssid, options.wpa_pass)
299 if c == None:
300 print "Error, connection settings not specified"
301 sys.exit(1)
303 svc = USER_SERVICE
304 svc_conn = us.addCon(c.conmap)
305 hint = svc_conn.settings["connection"]["type"]
306 dev = get_device("", hint)
307 appath = "/"
308 nm._connect_to_signal("StateChanged", print_state_changed)
309 # must be async because ourselves are providing the service
310 dummy_handler = lambda *args: None
311 nm.ActivateConnection(svc, svc_conn, dev, appath,
312 reply_handler=dummy_handler,
313 error_handler=dummy_handler)
314 LOOP = True
316 if options.activate_connection != None:
317 (svc, conpath, devpath, appath) = options.activate_connection.split(',')
318 svc = get_service_name(svc)
319 conn = get_connection(svc, conpath)
320 hint = get_connection_devtype(conn)
321 dev = get_device(devpath, hint)
322 if appath == "":
323 appath = "/"
324 nm._connect_to_signal("StateChanged", print_state_changed)
325 # TODO make it accept both objects and opaths
326 nm.ActivateConnection(svc, conn, dev, appath)
327 # TODO (optionally) block only until a stable state is reached
328 LOOP = True
331 ######## demo ##########
333 from dbusclient import DBusMio
334 mio = DBusMio(dbus.SystemBus(), "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
335 i = mio.Introspect()
336 d = mio.GetDevices()
338 if options.demo:
339 nm = NetworkManager()
341 # TODO: generic signal (adapt cnm monitor), print name and args
343 nm["WirelessEnabled"] = "yes"
345 devs = nm.GetDevices()
347 for d in devs:
348 print "\n DEVICE"
349 # TODO: find API for any object
350 d._connect_to_signal("StateChanged", print_state_changed)
352 LOOP = True
353 ######## demo end ##########
355 # TODO wrap this
356 if LOOP:
357 try:
358 print "Entering mainloop"
359 loop.run()
360 except KeyboardInterrupt:
361 print "Loop exited"