summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/wireless.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/wireless.c')
-rw-r--r--mdk-stage1/wireless.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/mdk-stage1/wireless.c b/mdk-stage1/wireless.c
new file mode 100644
index 000000000..2fde04f84
--- /dev/null
+++ b/mdk-stage1/wireless.c
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <sys/ioctl.h>
+#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>
+#include <linux/if.h>
+#include <linux/wireless.h>
+
+#include "automatic.h"
+#include "stage1.h"
+#include "log.h"
+#include "utils.h"
+#include "wireless.h"
+
+#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()
+{
+ return socket(AF_INET, SOCK_DGRAM, 0);
+}
+
+int wireless_close_socket(int socket)
+{
+ return close(socket);
+}
+
+static int wireless_ioctl(int socket, const char *ifname, int request, struct iwreq *wrq)
+{
+ strncpy(wrq->ifr_name, ifname, IFNAMSIZ);
+ return ioctl(socket, request, wrq);
+}
+
+int wireless_is_aware(int socket, const char *ifname)
+{
+ struct iwreq wrq;
+ return wireless_ioctl(socket, ifname, SIOCGIWNAME, &wrq) == 0;
+}
+
+enum return_type configure_wireless(const char *ifname)
+{
+ enum return_type results;
+ 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;
+ 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_list_auto("Please select your wireless security mode.",
+ security, &choice, "wireless_security", security_auto);
+ if (results != RETURN_OK) {
+ return RETURN_BACK;
+ }
+
+ 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 between 8 and 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 either a string of 10 or 26 hexadecimal digits, without any separators, "
+ "or a string of 5 or 13 ASCII characters enclosed in double quote marks (e.g. \"12345\").";
+ 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;
+ }
+
+ 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);
+ }
+ }
+
+ 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 -D nl80211,wext -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;
+ }
+
+ return RETURN_OK;
+}