/* * 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 #include #include #include #include #include #include #include #include #include #include #include #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; }