summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Whitaker <mageia@martin-whitaker.me.uk>2020-11-27 22:21:55 +0000
committerMartin Whitaker <mageia@martin-whitaker.me.uk>2020-11-28 20:42:18 +0000
commit74d06fdd97e629f832b2e320b4217dde6baa8c33 (patch)
treefc91a5708b1d2b7e30e808a5982417734b2e70ae
parent6db6d998b91537eac4c21cbe5ea36e93fff8c5d2 (diff)
downloaddrakx-74d06fdd97e629f832b2e320b4217dde6baa8c33.tar
drakx-74d06fdd97e629f832b2e320b4217dde6baa8c33.tar.gz
drakx-74d06fdd97e629f832b2e320b4217dde6baa8c33.tar.bz2
drakx-74d06fdd97e629f832b2e320b4217dde6baa8c33.tar.xz
drakx-74d06fdd97e629f832b2e320b4217dde6baa8c33.zip
Add support for WPA/WPA2 in installer stage 1 (mga#9541).
-rw-r--r--mdk-stage1/NEWS2
-rw-r--r--mdk-stage1/wireless.c161
2 files changed, 82 insertions, 81 deletions
diff --git a/mdk-stage1/NEWS b/mdk-stage1/NEWS
index c278f1c5a..ad6352209 100644
--- a/mdk-stage1/NEWS
+++ b/mdk-stage1/NEWS
@@ -1,3 +1,5 @@
+- add support for WPA/WPA2 (mga#9541)
+
2.49
- sync with kernel 5.9
diff --git a/mdk-stage1/wireless.c b/mdk-stage1/wireless.c
index c9e363048..42039ef7a 100644
--- a/mdk-stage1/wireless.c
+++ b/mdk-stage1/wireless.c
@@ -1,7 +1,9 @@
/*
* Olivier Blin (oblin)
+ * Martin Whitaker (martinw)
*
* Copyright 2005 Mandriva
+ * Copyright 2020 Mageia
*
* This software may be freely redistributed under the terms of the GNU
* public license.
@@ -16,7 +18,9 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
+#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/types.h>
@@ -29,11 +33,10 @@
#include "utils.h"
#include "wireless.h"
-static int wireless_ioctl(int socket, const char *ifname, int request, struct iwreq *wrq);
-static int wireless_set_mode_managed(int socket, const char *ifname);
-static int wireless_disable_key(int socket, const char *ifname);
-static int wireless_set_restricted_key(int socket, const char *ifname, const char *key);
-static int wireless_set_essid(int socket, const char *ifname, const char *essid);
+#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant.conf"
+#define WPA_SUPPLICANT_CTRL "/var/run/wpa_supplicant"
+#define WPA_SUPPLICANT_LOG "/var/log/wpa_supplicant.log"
+#define WPA_SUPPLICANT_PID "/var/run/wpa_supplicant.pid"
int wireless_open_socket()
{
@@ -57,104 +60,100 @@ int wireless_is_aware(int socket, const char *ifname)
return wireless_ioctl(socket, ifname, SIOCGIWNAME, &wrq) == 0;
}
-static int wireless_set_mode_managed(int socket, const char *ifname)
-{
- struct iwreq wrq;
-
- wrq.u.mode = IW_MODE_INFRA; /* managed */
-
- return wireless_ioctl(socket, ifname, SIOCSIWMODE, &wrq) == 0;
-}
-
-static int wireless_set_essid(int socket, const char *ifname, const char *essid)
-{
- struct iwreq wrq;
-
- wrq.u.essid.flags = 1;
- wrq.u.essid.pointer = (void *) essid;
- wrq.u.essid.length = strlen(essid) + 1;
-
- return wireless_ioctl(socket, ifname, SIOCSIWESSID, &wrq) == 0;
-}
-
-static int wireless_disable_key(int socket, const char *ifname)
-{
- struct iwreq wrq;
-
- wrq.u.data.flags = IW_ENCODE_DISABLED;
- wrq.u.data.pointer = NULL;
- wrq.u.data.length = 0;
-
- return wireless_ioctl(socket, ifname, SIOCSIWENCODE, &wrq) == 0;
-}
-
-static int wireless_set_restricted_key(int socket, const char *ifname, const char *key)
-{
- struct iwreq wrq;
- char real_key[IW_ENCODING_TOKEN_MAX];
- int key_len = 0;
- unsigned int tmp;
-
- while (sscanf(key + 2*key_len, "%2X", &tmp) == 1)
- real_key[key_len++] = (char) tmp;
-
- wrq.u.data.flags = IW_ENCODE_RESTRICTED;
- wrq.u.data.pointer = (char *) real_key;
- wrq.u.data.length = key_len;
-
- return wireless_ioctl(socket, ifname, SIOCSIWENCODE, &wrq) == 0;
-}
-
enum return_type configure_wireless(const char *ifname)
{
enum return_type results;
- char * questions[] = { "ESSID", "WEP key", NULL };
- char * questions_auto[] = { "essid", "wep_key" };
+ char * security[] = { "No security", "WEP", "WPA/WPA2 Personal", NULL };
+ char * security_auto[] = { "none", "wep", "wpa_psk", NULL };
+ char * choice = NULL;
+ char * message = NULL;
+ char * questions[] = { "ESSID", "", NULL };
+ char * questions_auto[] = { "essid", "" };
+ char * key_mgmt = NULL;
static char ** answers = NULL;
- int wsock = wireless_open_socket();
+ FILE * fd;
+ char cmd[256];
+ int status;
+ int wsock = wireless_open_socket();
if (!wireless_is_aware(wsock, ifname)) {
log_message("interface %s doesn't support wireless", ifname);
wireless_close_socket(wsock);
return RETURN_OK;
}
+ wireless_close_socket(wsock);
- results = ask_from_entries_auto("Please enter your wireless settings. "
- "The ESSID is your wireless network identifier. "
- "The WEP key must be entered in hexadecimal, without any separator.",
- questions, &answers, 32, questions_auto, NULL);
+ results = ask_from_list_auto("Please select your wireless security mode.",
+ security, &choice, "wireless_security", security_auto);
if (results != RETURN_OK) {
- wireless_close_socket(wsock);
return RETURN_BACK;
}
- if (!wireless_set_mode_managed(wsock, ifname)) {
- stg1_error_message("unable to set mode Managed on device \"%s\": %s", ifname, strerror(errno));
- wireless_close_socket(wsock);
- return RETURN_ERROR;
+ if (streq(choice, security[2])) {
+ message = "Please enter your wireless settings. "
+ "The ESSID is your wireless network identifier. "
+ "The passphrase must be a string of 8 to 63 ASCII characters.";
+ questions[1] = "passphrase";
+ questions_auto[1] = "wpa_psk";
+ key_mgmt = "WPA-PSK";
+ } else if (streq(choice, security[1])) {
+ message = "Please enter your wireless settings. "
+ "The ESSID is your wireless network identifier. "
+ "The WEP key must be a string of 10 or 26 hexadecimal digits, without any separators.";
+ questions[1] = "WEP key";
+ questions_auto[1] = "wep_key";
+ key_mgmt = "NONE";
+ } else {
+ message = "Please enter your wireless settings. "
+ "The ESSID is your wireless network identifier.";
+ questions[1] = NULL;
+ questions_auto[1] = NULL;
+ key_mgmt = "NONE";
+ }
+ results = ask_from_entries_auto(message, questions, &answers, 32, questions_auto, NULL);
+ if (results != RETURN_OK) {
+ return RETURN_BACK;
}
- if (answers[1] && !streq(answers[1], "")) {
- log_message("setting WEP key \"%s\" on device \"%s\"", answers[1], ifname);
- if (!wireless_set_restricted_key(wsock, ifname, answers[1])) {
- stg1_error_message("unable to set WEP key \"%s\" on device \"%s\": %s", answers[1], ifname, strerror(errno));
- return RETURN_ERROR;
- }
- } else {
- log_message("disabling WEP key on device \"%s\"", ifname);
- if (!wireless_disable_key(wsock, ifname)) {
- stg1_error_message("unable to disable WEP key on device \"%s\": %s", ifname, strerror(errno));
- return RETURN_ERROR;
+ fd = fopen(WPA_SUPPLICANT_PID, "r");
+ if (fd) {
+ unsigned pid = 0;
+ unsigned count = fscanf(fd, "%u", &pid);
+ fclose(fd);
+ if (count == 1 && pid > 1) {
+ log_message("terminating wpa_supplicant (pid %u)", pid);
+ kill(pid, SIGQUIT);
+ sleep(1);
}
}
- /* most devices perform discovery when ESSID is set, it needs to be last */
- log_message("setting ESSID \"%s\" on device \"%s\"", answers[0], ifname);
- if (!wireless_set_essid(wsock, ifname, answers[0])) {
- stg1_error_message("unable to set ESSID \"%s\" on device \"%s\": %s", answers[0], ifname, strerror(errno));
+ fd = fopen(WPA_SUPPLICANT_CONF, "w");
+ if (fd == NULL) {
+ stg1_error_message("unable to create " WPA_SUPPLICANT_CONF ": %s", strerror(errno));
+ return RETURN_ERROR;
+ }
+ fprintf(fd, "ctrl_interface=" WPA_SUPPLICANT_CTRL "\n");
+ fprintf(fd, "ap_scan=1\n");
+ fprintf(fd, "network={\n");
+ fprintf(fd, " key_mgmt=%s\n", key_mgmt);
+ fprintf(fd, " scan_ssid=1\n");
+ fprintf(fd, " ssid=\"%s\"\n", answers[0]);
+ if (streq(choice, security[2])) {
+ fprintf(fd, " psk=\"%s\"\n", answers[1]);
+ } else if (streq(choice, security[1])) {
+ fprintf(fd, " wep_key0=%s\n", answers[1]);
+ }
+ fprintf(fd, "}\n");
+ fclose(fd);
+
+ snprintf(cmd, sizeof(cmd), "/usr/sbin/wpa_supplicant -B -i %s -c %s -f %s -P %s",
+ ifname, WPA_SUPPLICANT_CONF, WPA_SUPPLICANT_LOG, WPA_SUPPLICANT_PID);
+ log_message("running %s", cmd);
+ status = system(cmd);
+ if (status != 0) {
+ stg1_error_message("unable to start wpa_supplicant daemon for interface \"%s\": %d", ifname, status);
return RETURN_ERROR;
}
- wireless_close_socket(wsock);
return RETURN_OK;
}