diff options
Diffstat (limited to 'mdk-stage1/wireless.c')
-rw-r--r-- | mdk-stage1/wireless.c | 160 |
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; +} |