3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2026-02-09 04:47:59 +01:00
iwd/src/eap-gtc.c
Pinghao Wu d510f332b6 eap-gtc: Try to auth even if request not Password
There are some server implementations that send requests that are
not "Password" but still want us send password. This commit modify
the behavior to send a warning and still try to auth with password.

This makes me able to auth with server in my school which sends
"Enter Aruba Login".

wpa_supplicant does not check if it is "Password".
2019-12-12 10:22:58 -06:00

182 lines
4.5 KiB
C

/*
*
* Wireless daemon for Linux
*
* Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <ell/ell.h>
#include "src/missing.h"
#include "src/eap.h"
#include "src/eap-private.h"
struct eap_gtc_state {
char *password;
};
static void eap_gtc_free(struct eap_state *eap)
{
struct eap_gtc_state *gtc = eap_get_data(eap);
eap_set_data(eap, NULL);
if (gtc->password)
explicit_bzero(gtc->password, strlen(gtc->password));
l_free(gtc->password);
l_free(gtc);
}
static void eap_gtc_handle_request(struct eap_state *eap,
const uint8_t *pkt, size_t len)
{
struct eap_gtc_state *gtc = eap_get_data(eap);
size_t secret_len = strlen(gtc->password);
uint8_t response[5 + secret_len];
if (len < 8 || strncmp((const char *)pkt, "Password", 8))
l_warn("GTC request not understood, proceeding anyway: %.*s",
(int) len, (const char *) pkt);
memcpy(response + 5, gtc->password, secret_len);
eap_send_response(eap, EAP_TYPE_GTC, response, 5 + secret_len);
eap_method_success(eap);
return;
}
static int eap_gtc_check_settings(struct l_settings *settings,
struct l_queue *secrets,
const char *prefix,
struct l_queue **out_missing)
{
const struct eap_secret_info *secret;
char identity_key[72];
char password_key[72];
char password_key_old[72];
L_AUTO_FREE_VAR(char *, identity);
L_AUTO_FREE_VAR(char *, password) = NULL;
snprintf(identity_key, sizeof(identity_key), "%sIdentity", prefix);
snprintf(password_key, sizeof(password_key), "%sPassword", prefix);
identity = l_settings_get_string(settings, "Security", identity_key);
if (!identity) {
secret = l_queue_find(secrets, eap_secret_info_match,
identity_key);
if (secret)
return 0;
eap_append_secret(out_missing, EAP_SECRET_REMOTE_USER_PASSWORD,
identity_key, password_key, NULL,
EAP_CACHE_TEMPORARY);
return 0;
}
password = l_settings_get_string(settings, "Security", password_key);
if (!password) {
snprintf(password_key_old, sizeof(password_key_old),
"%sGTC-Secret", prefix);
password = l_settings_get_string(settings, "Security",
password_key_old);
if (password) {
explicit_bzero(password, strlen(password));
l_warn("Setting '%s' is deprecated, use '%s' instead",
password_key_old, password_key);
return 0;
}
secret = l_queue_find(secrets, eap_secret_info_match,
password_key);
if (secret)
return 0;
eap_append_secret(out_missing, EAP_SECRET_REMOTE_PASSWORD,
password_key, NULL, identity,
EAP_CACHE_TEMPORARY);
} else
explicit_bzero(password, strlen(password));
return 0;
}
static bool eap_gtc_load_settings(struct eap_state *eap,
struct l_settings *settings,
const char *prefix)
{
struct eap_gtc_state *gtc;
char password_key[72];
char *password;
snprintf(password_key, sizeof(password_key), "%sPassword", prefix);
password = l_settings_get_string(settings, "Security", password_key);
if (!password) {
snprintf(password_key, sizeof(password_key), "%sGTC-Secret",
prefix);
password = l_settings_get_string(settings, "Security",
password_key);
if (!password)
return false;
}
gtc = l_new(struct eap_gtc_state, 1);
gtc->password = password;
eap_set_data(eap, gtc);
return true;
}
static struct eap_method eap_gtc = {
.request_type = EAP_TYPE_GTC,
.exports_msk = false,
.name = "GTC",
.free = eap_gtc_free,
.handle_request = eap_gtc_handle_request,
.check_settings = eap_gtc_check_settings,
.load_settings = eap_gtc_load_settings,
};
static int eap_gtc_init(void)
{
l_debug("");
return eap_register_method(&eap_gtc);
}
static void eap_gtc_exit(void)
{
l_debug("");
eap_unregister_method(&eap_gtc);
}
EAP_METHOD_BUILTIN(eap_gtc, eap_gtc_init, eap_gtc_exit)