2013-02-21 4 views
10

나는 Wi-Fi AP에 연결해야하는 Ubuntu Linux 용 소프트웨어를 만들고 있습니다. WiFi 네트워크는 미리 정의되지 않으며 소프트웨어를 한 번 실행하는 동안 여러 번 변경할 수 있습니다 (사용자가 변경을 요청한 사용자 임). 아이디어는 이것입니다 : SSID 세트와 WPA 또는 WEP 암호 문구가 주어지면 소프트웨어는 시스템의 모든 위치에서 구성 파일을 변경할 필요없이 바꿔서 네트워크간에 전환 할 수 있어야합니다.리눅스의 Python에서 보호 된 WiFi에 연결하기

거대한 문제는 연결에 패스워드를 전달하는 것입니다. 여기까지 내가 지금까지 운영해온 것은 다음과 같습니다.

  • WiFi 동글이 장착 된 우분투 12.10 기기. 소프트웨어를 실행하고,
  • connman 연결을 요청하는 데 사용 될
  • 파이썬, 0.79
  • wpa_supplicant를 V1.0
  • 내가 생각했던
  • 처음에는

D-버스 가능하다면 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의 기본값)로 되돌려서는 안되는지 궁금합니다.

답변

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 년 전이지만이 [link] (https://developer.gnome.org/NetworkManager/unstable/spec.html#org.freedesktop.NetworkManager)에 따르면 보안 (WEP, WPA2 등)의 유형을 입력해야 할 필요가있을뿐 암호 (psk)를 입력하면됩니다. AddAndActivateConnection의 첫 번째 매개 변수 인용 :'연결 설정 및 속성; 주어진 장비와 특정 개체를 사용하여 불완전한 누락 설정이 자동으로 완료되면 ** security ** 및 ** key-mgmt ** ** connection_params **를 제거하고 성공적으로 연결했습니다. :) – kv1dr