Re: [PATCH 1/2] enable establishing wpa connection in "early networking"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2011-05-24 at 12:12 +0200, Vratislav Podzimek wrote:
> ---
>  loader/loader.c |    2 +
>  loader/loader.h |    4 +-
>  loader/net.c    |  283 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  loader/net.h    |   15 +++
>  4 files changed, 302 insertions(+), 2 deletions(-)
> 
> diff --git a/loader/loader.c b/loader/loader.c
> index 3b0204b..ec07b78 100644
> --- a/loader/loader.c
> +++ b/loader/loader.c
> @@ -1050,6 +1050,8 @@ static void parseCmdLineFlags(struct loaderData_s * loaderData) {
>                  loaderData->mtu = argToLong(v);
>              } else if (!strcasecmp(k, "wepkey")) {
>                  loaderData->wepkey = g_strdup(v);
> +            } else if (!strcasecmp(k, "wpakey")) {
> +                loaderData->wpakey = g_strdup(v);
>              } else if (!strcasecmp(k, "linksleep")) {
>                  num_link_checks = argToLong(v);
>              } else if (!strcasecmp(k, "nicdelay")) {
> diff --git a/loader/loader.h b/loader/loader.h
> index d761a4a..b81fc40 100644
> --- a/loader/loader.h
> +++ b/loader/loader.h
> @@ -130,7 +130,9 @@ struct loaderData_s {
>      int bootIf_set;
>      char * netCls;
>      int netCls_set;
> -    char *ipv4, *netmask, *gateway, *dns, *domain, *hostname, *peerid, *ethtool, *subchannels, *portname, *essid, *wepkey, *nettype, *ctcprot, *options, *macaddr;
> +    char *ipv4, *netmask, *gateway, *dns, *domain, *hostname, *peerid, *ethtool;
> +    char *subchannels, *portname, *nettype, *ctcprot, *options, *macaddr;
> +    char *essid, *wepkey, *wpakey;
>  #ifdef ENABLE_IPV6
>      char *ipv6;
>      char *ipv6prefix;
> diff --git a/loader/net.c b/loader/net.c
> index ebb8e3c..51a0840 100644
> --- a/loader/net.c
> +++ b/loader/net.c
> @@ -54,6 +54,14 @@
>  #include "windows.h"
>  #include "ibft.h"
>  
> +#include <nm-device.h>
> +#include <nm-setting-connection.h>
> +#include <nm-setting-wireless.h>
> +#include <nm-setting-ip4-config.h>
> +#include <nm-utils.h>
> +#include <dbus/dbus.h>
> +#include <dbus/dbus-glib.h>
> +
>  /* boot flags */
>  extern uint64_t flags;
>  
> @@ -1819,6 +1827,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) {
>   * kickstart install so that we can do things like grab the ks.cfg from
>   * the network */
>  int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) {
> +    int rc = -1;
>  
>      if ((is_nm_connected() == TRUE) &&
>          (loaderData->netDev != NULL) && (loaderData->netDev_set == 1))
> @@ -1826,8 +1835,30 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) {
>  
>      iface_init_iface_t(iface);
>  
> -    return activateDevice(loaderData, iface);
> +    if (loaderData->essid != NULL) {
> +        if (loaderData->wepkey != NULL)
> +            rc = add_and_activate_wifi_connection(&(loaderData->netDev),
> +                    loaderData->essid, WIFI_PROTECTION_WEP, loaderData->wepkey,
> +                    loaderData->ipinfo_set, loaderData->ipv4);
> +
> +        else if (loaderData->wpakey != NULL)
> +            rc = add_and_activate_wifi_connection(&(loaderData->netDev),
> +                    loaderData->essid, WIFI_PROTECTION_WPA, loaderData->wpakey,
> +                    loaderData->ipinfo_set, loaderData->ipv4);
> +
> +        else
> +            rc = add_and_activate_wifi_connection(&(loaderData->netDev),
> +                    loaderData->essid, WIFI_PROTECTION_UNPROTECTED, NULL,
> +                    loaderData->ipinfo_set, loaderData->ipv4);
> +
> +        if (rc == 0) {
changed to (rc == WIFI_ACTIVATION_OK) and same in kickstart.c

> +            loaderData->netDev_set = 1;
> +            return 0;
> +        }
> +        else logMessage(ERROR, "wifi activation failed");
> +    }
>  
> +    return activateDevice(loaderData, iface);
>  }
>  
>  int disconnectDevice(char *device) {
> @@ -2179,4 +2210,254 @@ int isURLRemote(char *url) {
>      }
>  }
>  
> +gboolean byte_array_cmp(const GByteArray *array, char *string) {
> +    //returns TRUE if array and char* contain the same strings
> +    int i=0;
> +    gboolean ret = TRUE;
> +    if (array->len != strlen(string)) {
> +        return FALSE;
> +    }
> +    while (i<array->len && ret) {
> +        ret = ret && array->data[i] == string[i];
> +        i++;
> +    }
> +    return ret;
> +}
> +
> +NMAccessPoint* get_best_ap(NMDeviceWifi *device, char *ssid) {
> +    const GPtrArray *aps;
> +    int i;
> +    NMAccessPoint *candidate = NULL;
> +    guint8 max = 0;
> +    aps = nm_device_wifi_get_access_points(device);
> +
> +    if (!aps) return NULL;
> +
> +    for (i = 0; i < aps->len; i++) {
> +        NMAccessPoint *ap = g_ptr_array_index(aps, i);
> +        const GByteArray *byte_ssid = nm_access_point_get_ssid(ap);
> +        if (byte_array_cmp(byte_ssid, ssid)) {
> +            if (nm_access_point_get_strength(ap) > max) {
> +                max = nm_access_point_get_strength(ap);
> +                candidate = ap;
> +            }
> +        }
> +    }
> +    return candidate;
> +}
> +
> +gboolean get_device_and_ap(NMClient *client, char **iface, char *ssid,
> +            NMDeviceWifi **device, NMAccessPoint **ap) {
> +    //returns TRUE if device and ap (according to iface and ssid)
> +    //were found
> +    //iface, device and ap are used for storing the results
> +    //iface is also used as argument
> +
> +    const GPtrArray *devices;
> +    int i;
> +    NMAccessPoint *candidate_ap = NULL;
> +    NMDevice *candidate = NULL;
> +    char *tmp_iface = NULL;
> +    char *dev_iface = NULL;
> +
> +    devices = nm_client_get_devices(client);
> +
> +    for (i = 0; i < devices->len; i++) {
> +        candidate = g_ptr_array_index(devices, i);
> +        tmp_iface = (char *)nm_device_get_iface(candidate);
> +
> +        if (!tmp_iface) continue;
> +        dev_iface = strdup((char *)tmp_iface);
> +        if (strcmp(*iface, "") && strcmp(dev_iface, *iface)) continue;
> +        if (NM_IS_DEVICE_WIFI(candidate)) {
> +            candidate_ap = get_best_ap((NMDeviceWifi*)candidate, ssid);
> +            if (candidate_ap != NULL) {
> +                *device = (NMDeviceWifi*)candidate;
> +                *ap = candidate_ap;
> +                *iface = dev_iface;
> +                return TRUE;
> +            }
> +        }
> +        else free(dev_iface);
> +    }
> +    return FALSE;
> +}
> +
> +
> +static void
> +add_cb(NMClient *client,
> +        const char *connection_path,
> +        const char *active_path,
> +        GError *error,
> +        gpointer user_data) {
> +    if (error) logMessage(ERROR, "Error adding wifi connection: %s", error->message);
> +}
> +
> +guint32 ip_str_to_nbo(char* ip) {
> +    //get NBO representation of ip address
> +    struct in_addr tmp_addr = { 0 };
> +
> +    inet_pton(AF_INET, ip, &tmp_addr);
> +    return tmp_addr.s_addr;
> +}
> +
> +
> +int add_and_activate_wifi_connection(char **iface, char *ssid,
> +    int protection, char *password, int ip_method_manual, char *address) {
> +
> +    NMClient *client = NULL;
> +    NMDeviceWifi *device = NULL;
> +    NMAccessPoint *ap = NULL;
> +    GMainLoop *loop;
> +    GMainContext *ctx;
> +    DBusGConnection *DBconnection;
> +    GError *error;
> +    GByteArray *ssid_ba;
> +    int ssid_len;
> +    gboolean success = FALSE;
> +    gint8 count = 0, ret;
> +    NMConnection *connection;
> +    NMSettingConnection *s_con;
> +    NMSettingWireless *s_wireless;
> +    NMSettingWirelessSecurity *s_sec;
> +    NMSettingIP4Config *s_ip;
> +    char *uuid;
> +
> +    if (*iface == NULL) *iface = "";
> +    error = NULL;
> +    DBconnection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
> +    if (DBconnection == NULL) {
> +      g_error_free(error);
> +      return WIFI_ACTIVATION_DBUS_ERROR;
> +    }
> +
> +    client = nm_client_new();
> +    if (!client) return WIFI_ACTIVATION_NM_CLIENT_ERROR;
> +
> +    if (!nm_client_wireless_hardware_get_enabled(client))
> +        return WIFI_ACTIVATION_WIFI_HW_DISABLED;
> +
> +    if (!nm_client_wireless_get_enabled(client))
> +        nm_client_wireless_set_enabled(client, TRUE);
> +
> +    if (!ssid) return WIFI_ACTIVATION_BAD_SSID;
> +    ssid_len = strlen(ssid);
> +    if (!ssid_len || ssid_len > 32) return WIFI_ACTIVATION_BAD_SSID;
> +    ssid_ba = g_byte_array_sized_new(ssid_len);
> +    g_byte_array_append(ssid_ba, (unsigned char *) ssid, ssid_len);
> +
> +    loop = g_main_loop_new(NULL, FALSE);
> +    ctx = g_main_loop_get_context(loop);
> +
> +    while (g_main_context_pending(ctx))
> +        g_main_context_iteration(ctx, FALSE);
> +
> +    /* display status */
> +    if (FL_CMDLINE(flags))
> +        printf(_("Waiting for NetworkManager to activate wifi.\n"));
> +    else
> +        winStatus(55, 3, NULL,
> +                  _("Waiting for NetworkManager to activate wifi.\n"), 0);
> +
> +    while (count < 45 && !success) {
> +        while (g_main_context_pending(ctx))
> +            g_main_context_iteration(ctx, FALSE);
> +        success = get_device_and_ap(client, iface, ssid, &device, &ap);
> +        sleep(1);
> +        count++;
> +    }
> +
> +    if (!FL_CMDLINE(flags)) newtPopWindow();
> +
> +    if (!success) return WIFI_ACTIVATION_CANNOT_FIND_AP;
> +
> +    connection = nm_connection_new();
> +
> +    s_con = (NMSettingConnection*) nm_setting_connection_new();
> +    uuid = nm_utils_uuid_generate();
> +    g_object_set(G_OBJECT (s_con),
> +        NM_SETTING_CONNECTION_UUID, uuid,
> +        NM_SETTING_CONNECTION_ID, ssid,
> +        NM_SETTING_CONNECTION_TYPE, "802-11-wireless",
> +        NULL);
> +    g_free(uuid);
> +    nm_connection_add_setting(connection, NM_SETTING (s_con));
> +
> +    s_wireless = (NMSettingWireless*) nm_setting_wireless_new();
> +    g_object_set(G_OBJECT (s_wireless),
> +        NM_SETTING_WIRELESS_SSID, ssid_ba,
> +        NM_SETTING_WIRELESS_MODE, "infrastructure",
> +        NULL);
> +    g_byte_array_free(ssid_ba, TRUE);
> +    if ((protection == WIFI_PROTECTION_WEP) || protection == WIFI_PROTECTION_WPA) {
> +        g_object_set(G_OBJECT (s_wireless),
> +            NM_SETTING_WIRELESS_SEC, "802-11-wireless-security",
> +            NULL);
> +    }
> +    nm_connection_add_setting(connection, NM_SETTING (s_wireless));
> +
> +    if (protection == WIFI_PROTECTION_WEP) {
> +        s_sec = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new();
> +        g_object_set (G_OBJECT (s_sec),
> +            NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
> +            NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
> +            NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, 1,
> +            NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, password,
> +            NULL);
> +        if (strlen(password) == 32) {
> +            g_object_set(G_OBJECT (s_sec),
> +                NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, 2,
> +                NULL);
> +        }
> +        nm_connection_add_setting(connection, NM_SETTING (s_sec));
> +
> +    } else if (protection == WIFI_PROTECTION_WPA) {
> +        s_sec = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new();
> +        g_object_set(G_OBJECT (s_sec),
> +            NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
> +            NM_SETTING_WIRELESS_SECURITY_PSK, password,
> +            NULL);
> +        nm_connection_add_setting(connection, NM_SETTING (s_sec));
> +    }
> +
> +    if (ip_method_manual) {
> +        GPtrArray *addresses = g_ptr_array_new();
> +        GArray *address_array = g_array_new(FALSE, FALSE, sizeof(guint32));
> +        guint32 nbo_ip = ip_str_to_nbo(address);
> +        guint32 mask = 24;
> +        guint32 gw = 0;
> +
> +        g_array_append_val(address_array, nbo_ip);
> +        g_array_append_val(address_array, mask);
> +        g_array_append_val(address_array, gw);
> +
> +        g_ptr_array_add(addresses, address_array);
> +
> +        s_ip = (NMSettingIP4Config*) nm_setting_ip4_config_new();
> +        g_object_set(G_OBJECT (s_ip),
> +            NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
> +            NM_SETTING_IP4_CONFIG_ADDRESSES, addresses,
> +            NULL);
> +        nm_connection_add_setting(connection, NM_SETTING (s_ip));
> +        g_array_free(address_array, TRUE);
> +        g_ptr_array_free(addresses, TRUE);
> +    }
> +
> +    const char *ap_path = nm_object_get_path((NMObject*) ap);
> +    nm_client_add_and_activate_connection(client, connection,
> +            (NMDevice*) device, ap_path, (NMClientAddActivateFn) add_cb,
> +            NULL);
> +
> +    ret = wait_for_iface_activation(*iface);
> +    if (!FL_CMDLINE(flags)) newtPopWindow();
> +    if (ret == 0) {
> +        g_main_loop_unref(loop);
> +        return WIFI_ACTIVATION_OK;
> +    }
> +
> +    *iface = NULL;
> +    g_main_loop_unref(loop);
> +    return WIFI_ACTIVATION_TIMED_OUT;
> +}
> +
>  /* vim:set shiftwidth=4 softtabstop=4: */
> diff --git a/loader/net.h b/loader/net.h
> index 2a74cdf..cb1c39e 100644
> --- a/loader/net.h
> +++ b/loader/net.h
> @@ -82,8 +82,23 @@ int wait_for_iface_activation(char * ifname);
>  int wait_for_iface_disconnection(char *ifname);
>  int isURLRemote(char *url);
>  int isValidIPv4Address(const char *address);
> +int add_and_activate_wifi_connection (char **iface, char *ssid,
> +				      int protection, char *password,
> +				      int ip_method_manual, char *address);
>  #ifdef ENABLE_IPV6
>  int isValidIPv6Address(const char *address);
>  #endif
>  
>  #endif
> +
> +#define WIFI_PROTECTION_UNPROTECTED 0
> +#define WIFI_PROTECTION_WEP 1
> +#define WIFI_PROTECTION_WPA 2
> +
> +#define WIFI_ACTIVATION_OK 0
> +#define WIFI_ACTIVATION_DBUS_ERROR 1
> +#define WIFI_ACTIVATION_NM_CLIENT_ERROR 2
> +#define WIFI_ACTIVATION_WIFI_HW_DISABLED 3
> +#define WIFI_ACTIVATION_BAD_SSID 4
> +#define WIFI_ACTIVATION_CANNOT_FIND_AP 5
> +#define WIFI_ACTIVATION_TIMED_OUT 6


_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux