我正在为Ubuntu Linux创build一个需要连接到WiFi AP的软件。 WiFinetworking不是预定义的,在软件的单次运行(用户是订购变更的用户)期间可以多次更改。 这个想法是这样的:给定一组SSID及其WPA或WEP密码,软件应该能够在突发事件之间在networking之间切换,而不需要在系统中的任何地方改变任何configuration文件。
看起来,这个巨大的问题是将密码传递给连接。 以下是我迄今为止的操作:
起初我以为可以通过d-bus把密码传给Connman,但这个版本的connman,也不是1.11,似乎都没有公开任何方法。 然后我发现可以将service_<SSID>.conf
文件转储到/var/lib/connman/
目录。 该文件的内容非常简单,如下所示:
[service_SSID] Type=wifi Name=Network-SSID Passphrase=here-goes-the-passphrase
创build此文件后,连接到networking需要在适当的服务中调用net.connman.Service.Connect()方法。 问题是connman不会parsingconfiguration文件,除非重新启动。 这需要sudo权限,额外的时间,并提高所有“现在可能出错”的事情发生的风险。 然后我觉得密码可能会传递给wpa_supplicant d-bus API,但是我找不到任何东西。
谷歌search也失败了我。 就好像从来没有人试过这样做过。
命令sudo iwconfig wlan0 essid <SSID> key s:<PASSPHRASE>
导致SET failed on device wlan0 ; Invalid argument.
SET failed on device wlan0 ; Invalid argument.
错误。 另外,它需要sudo,我想避免。
我试图弄清楚wpa_gui程序是如何做到的。 首先我发现它也需要sudo,并且直接向/var/run/wpa_supplicant/wlan0
发送一堆命令。 复制这种行为对我来说是最后的手段,如果我没有弄清楚什么是简单的。
所以,最大的问题是:如何使用Python来连接到WEP / WPA保护的WiFinetworking?
我也想知道是否在这里使用connman是一个好方法,如果我不应该回到networkingpipe理器,这是Ubuntu的默认。
这显示了如何为WPA执行此操作。
首先,沟connman和使用NetworkManager。 下面的示例脚本显示了如何启用无线支持,检查具有给定SSID的网络是否可用,使用WPA密码短语连接到该SSID,然后断开与网络的连接并禁用无线功能。 我相当肯定这个脚本可以改进,但是现在的版本足以作为一个例子:
#!/usr/bin/python # This script shows how to connect to a WPA protected WiFi network # by communicating through D-Bus to NetworkManager 0.9. # # Reference URLs: # http://projects.gnome.org/NetworkManager/developers/ # http://projects.gnome.org/NetworkManager/developers/settings-spec-08.html import dbus import time SEEKED_SSID = "skynet" SEEKED_PASSPHRASE = "qwertyuiop" if __name__ == "__main__": bus = dbus.SystemBus() # Obtain handles to manager objects. manager_bus_object = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager") manager = dbus.Interface(manager_bus_object, "org.freedesktop.NetworkManager") manager_props = dbus.Interface(manager_bus_object, "org.freedesktop.DBus.Properties") # Enable Wireless. If Wireless is already enabled, this does nothing. was_wifi_enabled = manager_props.Get("org.freedesktop.NetworkManager", "WirelessEnabled") if not was_wifi_enabled: print "Enabling WiFi and sleeping for 10 seconds ..." manager_props.Set("org.freedesktop.NetworkManager", "WirelessEnabled", True) # Give the WiFi adapter some time to scan for APs. This is absolutely # the wrong way to do it, and the program should listen for # AccessPointAdded() signals, but it will do. time.sleep(10) # Get path to the 'wlan0' device. If you're uncertain whether your WiFi # device is wlan0 or something else, you may utilize manager.GetDevices() # method to obtain a list of all devices, and then iterate over these # devices to check if DeviceType property equals NM_DEVICE_TYPE_WIFI (2). device_path = manager.GetDeviceByIpIface("wlan0") print "wlan0 path: ", device_path # Connect to the device's Wireless interface and obtain list of access # points. device = dbus.Interface(bus.get_object("org.freedesktop.NetworkManager", device_path), "org.freedesktop.NetworkManager.Device.Wireless") accesspoints_paths_list = device.GetAccessPoints() # Identify our access point. We do this by comparing our desired SSID # to the SSID reported by the AP. our_ap_path = None for ap_path in accesspoints_paths_list: ap_props = dbus.Interface( bus.get_object("org.freedesktop.NetworkManager", ap_path), "org.freedesktop.DBus.Properties") ap_ssid = ap_props.Get("org.freedesktop.NetworkManager.AccessPoint", "Ssid") # Returned SSID is a list of ASCII values. Let's convert it to a proper # string. str_ap_ssid = "".join(chr(i) for i in ap_ssid) print ap_path, ": SSID =", str_ap_ssid if str_ap_ssid == SEEKED_SSID: our_ap_path = ap_path break if not our_ap_path: print "AP not found :(" exit(2) print "Our AP: ", our_ap_path # At this point we have all the data we need. Let's prepare our connection # parameters so that we can tell the NetworkManager what is the passphrase. connection_params = { "802-11-wireless": { "security": "802-11-wireless-security", }, "802-11-wireless-security": { "key-mgmt": "wpa-psk", "psk": SEEKED_PASSPHRASE }, } # Establish the connection. settings_path, connection_path = manager.AddAndActivateConnection( connection_params, device_path, our_ap_path) print "settings_path =", settings_path print "connection_path =", connection_path # Wait until connection is established. This may take a few seconds. NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2 print """Waiting for connection to reach """ \ """NM_ACTIVE_CONNECTION_STATE_ACTIVATED state ...""" connection_props = dbus.Interface( bus.get_object("org.freedesktop.NetworkManager", connection_path), "org.freedesktop.DBus.Properties") state = 0 while True: # Loop forever until desired state is detected. # # A timeout should be implemented here, otherwise the program will # get stuck if connection fails. # # IF PASSWORD IS BAD, NETWORK MANAGER WILL DISPLAY A QUERY DIALOG! # This is something that should be avoided, but I don't know how, yet. # # Also, if connection is disconnected at this point, the Get() # method will raise an org.freedesktop.DBus.Error.UnknownMethod # exception. This should also be anticipated. state = connection_props.Get( "org.freedesktop.NetworkManager.Connection.Active", "State") if state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED: break time.sleep(0.001) print "Connection established!" # # Connection is established. Do whatever is necessary. # ... # print "Sleeping for 5 seconds ..." time.sleep(5) print "Disconnecting ..." # Clean up: disconnect and delete connection settings. If program crashes # before this point is reached then connection settings will be stored # forever. # Some pre-init cleanup feature should be devised to deal with this problem, # but this is an issue for another topic. manager.DeactivateConnection(connection_path) settings = dbus.Interface( bus.get_object("org.freedesktop.NetworkManager", settings_path), "org.freedesktop.NetworkManager.Settings.Connection") settings.Delete() # Disable Wireless (optional step) if not was_wifi_enabled: manager_props.Set("org.freedesktop.NetworkManager", "WirelessEnabled", False) print "DONE!" exit(0)