--- pyanaconda/isys/__init__.py | 2 + pyanaconda/kickstart.py | 44 ++++++++++++++++++- pyanaconda/network.py | 102 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 2 deletions(-) diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py index 13026c7..03871ad 100755 --- a/pyanaconda/isys/__init__.py +++ b/pyanaconda/isys/__init__.py @@ -50,6 +50,8 @@ log = logging.getLogger("anaconda") NM_SERVICE = "org.freedesktop.NetworkManager" NM_MANAGER_PATH = "/org/freedesktop/NetworkManager" NM_MANAGER_IFACE = "org.freedesktop.NetworkManager" +NM_SETTINGS_IFACE = "org.freedesktop.NetworkManager.Settings" +NM_SETTINGS_PATH = "/org/freedesktop/NetworkManager/Settings" NM_ACTIVE_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Connection.Active" NM_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Settings.Connection" NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device" diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py index 1994fa3..b18f417 100644 --- a/pyanaconda/kickstart.py +++ b/pyanaconda/kickstart.py @@ -39,6 +39,7 @@ from flags import flags from constants import * import sys import string +import dbus import urlgrabber import warnings import network @@ -582,11 +583,50 @@ class NetworkData(commands.network.F16_NetworkData): # Only set hostname return - # we can ignore this here (already activated in stage 1) - # only set hostname + # set hostname if self.essid: if self.hostname != "": self.anaconda.network.setHostname(self.hostname) + + bus = dbus.SystemBus() + nm_setts = bus.get_object(isys.NM_SERVICE, isys.NM_SETTINGS_PATH) + nm_setts_iface = dbus.Interface(nm_setts, isys.NM_SETTINGS_IFACE) + conn_list = nm_setts_iface.ListConnections() + conn_ids = set() + for conn_path in conn_list: + conn_obj = bus.get_object(isys.NM_SERVICE, conn_path) + conn_iface = dbus.Interface(conn_obj, isys.NM_CONNECTION_IFACE) + conn_ids.add(conn_iface.GetSettings()["connection"]["id"]) + + #otherwise activated from stage1 and can be skipped here + if not self.activate: + #do not duplicate connections + if self.essid in conn_ids: + return + + ip_setts = { + "addr": self.ip, + "netmask": self.netmask, + "gateway": self.gateway or "0.0.0.0", + } + dns_list = self.nameserver.rstrip(",").split(",") + + try: + if self.wepkey: + setts = network.WepConnSettings(self.essid, self.wepkey, + ip_setts, dns_list) + elif self.wpakey: + setts = network.WpaConnSettings(self.essid, self.wpakey, + ip_setts, dns_list) + else: + setts = network.WifiConnSettings(self.essid, ip_setts, + dns_list) + except network.InvalidConnSettingsError as isc_error: + log.error("Connection {0} not created".format(self.essid)) + return + + nm_setts_iface.AddConnection(setts.conmap) + return devices = self.anaconda.network.netdevices diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 88eb8e2..4f78e8a 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -29,6 +29,9 @@ import shutil import isys import iutil import socket +import re +import uuid +import ctypes import struct import os import time @@ -996,3 +999,102 @@ def resetResolver(): isys.resetResolv() urlgrabber.grabber.reset_curl_obj() +class InvalidConnSettingsError(Exception): + pass + +class WifiConnSettings(object): + def __init__(self, ssid, ip_setts, dns): + self.conmap = { + 'connection': { + 'id': ssid, + 'uuid': str(uuid.uuid1()), + 'type': '802-11-wireless', + }, + '802-11-wireless': { + 'ssid': dbus.ByteArray(ssid), + 'mode': 'infrastructure', + } + } + + if ip_setts.get("addr",""): + try: + addr = self.ip_str_to_nbo_long(ip_setts.get("addr")) + netmask = ip_setts.get("netmask", "") + gateway = self.ip_str_to_nbo_long(ip_setts.get("gateway")) + + ctypes.cdll.LoadLibrary("libnm-util.so.2") + nm_utils = ctypes.CDLL("libnm-util.so.2") + if netmask: + netmask = self.ip_str_to_nbo_long(netmask) + prefix = nm_utils.nm_utils_ip4_netmask_to_prefix(netmask) + else: + prefix = nm_utils.nm_utils_ip4_get_default_prefix(addr) + + dns_list = [] + for dns_addr_str in dns: + dns_list.append(dbus.UInt32(self.ip_str_to_nbo_long(dns_addr_str))) + + self.conmap['ipv4'] = { + 'addresses': dbus.Array([dbus.Array( + [dbus.UInt32(addr), + dbus.UInt32(prefix), dbus.UInt32(gateway)], + signature=dbus.Signature('u'))], signature=dbus.Signature('au'), + variant_level=1), + 'dns': dbus.Array(dns_list, signature=dbus.Signature('u'), + variant_level=1), + 'method': dbus.String("manual", variant_level=1), + } + except IPError as iperr: + log.error(iperr) + raise InvalidConnSettingsError(str(iperr)) + + def __getitem__(self, key): + return self.conmap.__getitem__(key) + + def __setitem__(self, key, value): + return self.conmap.__setitem__(key, value) + + @staticmethod + def ip_str_to_nbo_long(ipstr): + """ + @param ipstr: ip address as a string + @type ipstr: string + @return: ip address as a long in network byte order + @rtype: long + @raise IPError: in case when ipstr is not a valid IP address + """ + + addr_re = re.compile(r'([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})') + match = addr_re.match(ipstr) + if not match: + raise IPError("{0} is not a valid IPv4 address".format(ipstr)) + + ret = 0L + for i in range(4):# transform from the base 256 to decimal + ret = ret + (int(match.group(i+1)) * (256**(3-i))) + ret = socket.htonl(ret)# transform to network byte order + return ret + +class WepConnSettings(WifiConnSettings): + def __init__(self, ssid, key, ip_setts, dns, hashed_key=""): + "One of key, hashed_key must be present" + + super(WepConnSettings, self).__init__(ssid, ip_setts, dns) + self["802-11-wireless"]["security"] = "802-11-wireless-security" + self["802-11-wireless-security"] = {} + self["802-11-wireless-security"]["key-mgmt"] = "none" + self["802-11-wireless-security"]["wep-tx-keyidx"] = 0 + if hashed_key != "": + self["802-11-wireless-security"]["wep-key-type"] = 2 + self["802-11-wireless-security"]["wep-key0"] = hashed_key + else: + self["802-11-wireless-security"]["wep-key-type"] = 1 + self["802-11-wireless-security"]["wep-key0"] = key + +class WpaConnSettings(WifiConnSettings): + def __init__(self, ssid, key, ip_setts, dns): + super(WpaConnSettings, self).__init__(ssid, ip_setts, dns) + self["802-11-wireless"]["security"] = "802-11-wireless-security" + self["802-11-wireless-security"] = {} + self["802-11-wireless-security"]["key-mgmt"] = "wpa-psk" + self["802-11-wireless-security"]["psk"] = key -- 1.7.4.4 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list