iwd/src/eap.h

179 lines
5.2 KiB
C
Raw Normal View History

/*
*
* Wireless daemon for Linux
*
* Copyright (C) 2013-2014 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
*
*/
#include <stdint.h>
#include <stdbool.h>
#include <asm/byteorder.h>
#include <linux/types.h>
struct eap_state;
enum eap_result {
EAP_RESULT_SUCCESS,
EAP_RESULT_FAIL,
EAP_RESULT_TIMEOUT,
};
eap: Validate settings, report passwords needed With the goal of requesting the required passwords/passphrases, such as the TLS private key passphrase, from the agent, add a static method eap_check_settings to validate the settings and calculate what passwords are needed for those settings, if any. This is separate from eap_load_settings because that can only be called later, once we've got an eap state machine object. We need to get all the needed EAP credentials from the user before we even start connecting. While we do this, we also validate the settings and output any error messages through l_error (this could be changed so the messages go somewhere else in the future), so I removed the error messages from eap_load_settings and that method now assumes that eap_check_settings has been called before. eap_check_settings calls the appropriate method's .check_settings method if the settings are complete enough to contain the method name. The policy is that any data can be provided inside the l_settings object (from the network provisioning/config file), but some of the more sensitive fields, like private key passwords, can be optionally omitted and then the UI will ask for them and iwd will be careful with caching them. Within struct eap_secret_info, "id" is mainly for the EAP method to locate the info in the list. "value" is the actual value returned by agent. "parameter" is an optional string to be passed to the agent. For a private key passphrase it may be the path to the key file, for a password it may be the username for which the password is requested.
2018-04-18 07:03:22 +02:00
enum eap_secret_type {
EAP_SECRET_LOCAL_PKEY_PASSPHRASE,
EAP_SECRET_REMOTE_PASSWORD,
EAP_SECRET_REMOTE_USER_PASSWORD,
};
struct eap_secret_info {
char *id;
enum eap_secret_type type;
char *parameter;
char *value;
};
typedef void (*eap_tx_packet_func_t)(const uint8_t *eap_data, size_t len,
void *user_data);
typedef void (*eap_key_material_func_t)(const uint8_t *msk_data, size_t msk_len,
const uint8_t *emsk_data, size_t emsk_len,
const uint8_t *iv, size_t iv_len,
void *user_data);
typedef void (*eap_complete_func_t)(enum eap_result result, void *user_data);
typedef void (*eap_event_func_t)(unsigned int event, const void *event_data,
void *user_data);
struct eap_state *eap_new(eap_tx_packet_func_t tx_packet,
eap_complete_func_t complete, void *user_data);
void eap_free(struct eap_state *eap);
eap: Validate settings, report passwords needed With the goal of requesting the required passwords/passphrases, such as the TLS private key passphrase, from the agent, add a static method eap_check_settings to validate the settings and calculate what passwords are needed for those settings, if any. This is separate from eap_load_settings because that can only be called later, once we've got an eap state machine object. We need to get all the needed EAP credentials from the user before we even start connecting. While we do this, we also validate the settings and output any error messages through l_error (this could be changed so the messages go somewhere else in the future), so I removed the error messages from eap_load_settings and that method now assumes that eap_check_settings has been called before. eap_check_settings calls the appropriate method's .check_settings method if the settings are complete enough to contain the method name. The policy is that any data can be provided inside the l_settings object (from the network provisioning/config file), but some of the more sensitive fields, like private key passwords, can be optionally omitted and then the UI will ask for them and iwd will be careful with caching them. Within struct eap_secret_info, "id" is mainly for the EAP method to locate the info in the list. "value" is the actual value returned by agent. "parameter" is an optional string to be passed to the agent. For a private key passphrase it may be the path to the key file, for a password it may be the username for which the password is requested.
2018-04-18 07:03:22 +02:00
bool eap_secret_info_match(const void *a, const void *b);
void eap_append_secret(struct l_queue **out_missing, enum eap_secret_type type,
const char *id, const char *parameter);
void eap_secret_info_free(void *data);
bool eap_check_settings(struct l_settings *settings, struct l_queue *secrets,
const char *prefix, bool set_key_material,
struct l_queue **out_missing);
bool eap_load_settings(struct eap_state *eap, struct l_settings *settings,
const char *prefix);
void eap_set_key_material_func(struct eap_state *eap,
eap_key_material_func_t func);
void eap_set_event_func(struct eap_state *eap, eap_event_func_t func);
void eap_set_mtu(struct eap_state *eap, size_t mtu);
size_t eap_get_mtu(struct eap_state *eap);
void eap_rx_packet(struct eap_state *eap, const uint8_t *pkt, size_t len);
2018-02-14 01:00:40 +01:00
void __eap_handle_request(struct eap_state *eap, uint16_t id,
const uint8_t *pkt, size_t len);
void eap_discard_success_and_failure(struct eap_state *eap, bool discard);
2016-11-15 23:44:07 +01:00
void eap_init(uint32_t default_mtu);
void eap_exit(void);
/* EAP method API */
enum eap_type {
EAP_TYPE_IDENTITY = 1,
EAP_TYPE_NOTIFICATION = 2,
EAP_TYPE_NAK = 3,
__EAP_TYPE_MIN_METHOD = 4,
EAP_TYPE_MD5_CHALLENGE = 4,
2018-04-03 22:58:52 +02:00
EAP_TYPE_GTC = 6,
EAP_TYPE_TLS_EAP = 13,
2017-08-21 23:09:03 +02:00
EAP_TYPE_SIM = 18,
EAP_TYPE_TTLS = 21,
2017-08-21 23:09:06 +02:00
EAP_TYPE_AKA = 23,
2018-01-24 00:29:11 +01:00
EAP_TYPE_PEAP = 25,
2018-01-20 01:21:22 +01:00
EAP_TYPE_EXTENSIONS = 33,
2017-08-30 23:00:23 +02:00
EAP_TYPE_AKA_PRIME = 50,
2016-12-14 23:15:30 +01:00
EAP_TYPE_MSCHAPV2 = 26,
2018-04-27 01:02:44 +02:00
EAP_TYPE_PWD = 52,
EAP_TYPE_EXPANDED = 254,
};
enum eap_code {
EAP_CODE_REQUEST = 1,
EAP_CODE_RESPONSE = 2,
EAP_CODE_SUCCESS = 3,
EAP_CODE_FAILURE = 4,
};
struct eap_method {
enum eap_type request_type;
uint8_t vendor_id[3];
uint32_t vendor_type;
bool exports_msk;
const char *name;
eap: Validate settings, report passwords needed With the goal of requesting the required passwords/passphrases, such as the TLS private key passphrase, from the agent, add a static method eap_check_settings to validate the settings and calculate what passwords are needed for those settings, if any. This is separate from eap_load_settings because that can only be called later, once we've got an eap state machine object. We need to get all the needed EAP credentials from the user before we even start connecting. While we do this, we also validate the settings and output any error messages through l_error (this could be changed so the messages go somewhere else in the future), so I removed the error messages from eap_load_settings and that method now assumes that eap_check_settings has been called before. eap_check_settings calls the appropriate method's .check_settings method if the settings are complete enough to contain the method name. The policy is that any data can be provided inside the l_settings object (from the network provisioning/config file), but some of the more sensitive fields, like private key passwords, can be optionally omitted and then the UI will ask for them and iwd will be careful with caching them. Within struct eap_secret_info, "id" is mainly for the EAP method to locate the info in the list. "value" is the actual value returned by agent. "parameter" is an optional string to be passed to the agent. For a private key passphrase it may be the path to the key file, for a password it may be the username for which the password is requested.
2018-04-18 07:03:22 +02:00
bool (*check_settings)(struct l_settings *settings,
struct l_queue *secrets, const char *prefix,
struct l_queue **out_missing);
bool (*load_settings)(struct eap_state *eap,
struct l_settings *settings,
const char *prefix);
void (*free)(struct eap_state *eap);
void (*handle_request)(struct eap_state *eap,
const uint8_t *pkt, size_t len);
2016-11-29 23:31:22 +01:00
void (*handle_retransmit)(struct eap_state *eap,
const uint8_t *pkt, size_t len);
const char *(*get_identity)(struct eap_state *eap);
};
struct eap_method_desc {
const char *name;
int (*init)(void);
void (*exit)(void);
} __attribute__((aligned(8)));
#define EAP_METHOD_BUILTIN(name, init, exit) \
static struct eap_method_desc __eap_builtin_ ## name \
__attribute__((used, section("__eap"), aligned(8))) = { \
#name, init, exit \
}; \
2015-11-02 16:54:12 +01:00
int eap_register_method(struct eap_method *method);
2015-11-03 04:38:45 +01:00
int eap_unregister_method(struct eap_method *method);
2015-11-02 16:54:12 +01:00
void eap_set_data(struct eap_state *eap, void *data);
void *eap_get_data(struct eap_state *eap);
void eap_send_response(struct eap_state *eap,
enum eap_type request_type,
uint8_t *buf, size_t len);
void eap_set_key_material(struct eap_state *eap,
const uint8_t *msk_data, size_t msk_len,
const uint8_t *emsk_data, size_t emsk_len,
const uint8_t *iv, size_t iv_len);
void eap_start_complete_timeout(struct eap_state *eap);
2018-02-22 01:47:19 +01:00
bool eap_method_is_success(struct eap_state *eap);
void eap_method_success(struct eap_state *eap);
void eap_method_error(struct eap_state *eap);
void eap_method_event(struct eap_state *eap, unsigned int type,
const void *data);
void eap_save_last_id(struct eap_state *eap, uint8_t *last_id);
void eap_restore_last_id(struct eap_state *eap, uint8_t last_id);