2013-02-21 10 views
10

私はWi-Fi APに接続する必要のあるUbuntu Linux用のソフトウェアを作成しています。 WiFiネットワークはあらかじめ定義されておらず、ソフトウェアの1回の実行中に複数回変更することができます(ユーザーは変更を注文します)。これは、SSIDとWPAまたはWEPのパスフレーズのセットがあれば、システム内の任意の設定ファイルを変更する必要なく、ソフトウェアがネットワーク上のネットワークを切り替えることができるはずです。Linux上のPythonから保護されたWiFiに接続する

巨大な問題は、接続にパスフレーズを渡すことです。これまで私がこれまで行ってきたことは次のとおりです。

  • Ubuntu 12.10マシンにはWiFiドングルが装備されています。ソフトウェアを実行し、
  • connmanの接続を要求するために使用される
  • パイソン、0.79
  • wpa_supplicantのv1.0を
  • 私はそれが可能だろうと思った
  • まず

D-BUSパスフレーズをdバス経由でconnmanに渡すことは可能ですが、connmanのこのバージョンも1.11も、そのための方法を公開していないようです。それから、ディレクトリにservice_<SSID>.confファイルをダンプすることができることが分かりました。ファイルの内容は非常にシンプルであり、次のようになります。このファイルが作成されたら

[service_SSID] 
Type=wifi 
Name=Network-SSID 
Passphrase=here-goes-the-passphrase 

を、ネットワークに接続すると、適切なサービスでnet.connman.Service.Connect()メソッドへの単純な呼び出しが必要です。問題は、connmanが再起動されない限り、configファイルを解析しないということです。これにはsudo特権、追加の時間が必要であり、 "今何が間違っているかもしれないか"のすべての事態が発生する危険性があります。その後、パスフレーズがwpa_supplicantのd-bus APIに何らかの形で渡される可能性があるとわかりましたが、何も見つけられませんでした。

Googleの検索も失敗しました。あたかもこれまでこれをやろうとしたことがないかのようです。

コマンドsudo iwconfig wlan0 essid <SSID> key s:<PASSPHRASE>の結果はSET failed on device wlan0 ; Invalid argument.になります。また、私は避けたいsudoが必要です。

私はwpa_guiプログラムがどのようにその魔法をしているのか理解しようとしました。まず第一に私はそれがまたsudoが必要であることを発見し、それは直接/var/run/wpa_supplicant/wlan0に一連のコマンドを送ります。もっと単純なことが分からなければ、この行動を複製することは私の最後の手段になります。

それでは大きな疑問は、WEP/WPAで保護されたWiFiネットワークに接続するためにPythonを使用する方法です。
connmanを使用するのが良いアプローチで、UbuntuのデフォルトであるNetwork Managerに戻すべきではないかと思っています。

答えて

5

これは、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) 
+0

あなたはWEPのセキュリティ規定について教えてください。 – Natim

+0

申し訳ありませんが、WEPでこれを行う方法を調査する必要はありませんので、ここではお手伝いできません。私はそれがはるかに異なっているとは思わない。 – ZalewaPL

+3

@ ZalewaPL私はそれが最後の返信からほぼ1年ですが、この[リンク](https://developer.gnome.org/NetworkManager/unstable/spec.html#org.freedesktop.NetworkManager)によると、セキュリティのタイプ(WEP、WPA2など)を入力する必要があっても、パスワード(psk)を入力するだけで済みます。 AddAndActivateConnectionの最初のパラメータの引用: '接続の設定とプロパティ。不完全な設定が不足している場合は、指定されたデバイスと特定のオブジェクトを使用して自動的に完了します。 '** security **と** key-mgmt **を** connection_params **から削除して正常に接続しました。 :) – kv1dr

関連する問題