00001 00016 #include <stdlib.h> 00017 #include <stdio.h> 00018 #include <string.h> 00019 00020 #include "common.h" 00021 #include "eap_i.h" 00022 #include "wpa_supplicant.h" 00023 #include "config_ssid.h" 00024 00025 00026 static void * eap_otp_init(struct eap_sm *sm) 00027 { 00028 return (void *) 1; 00029 } 00030 00031 00032 static void eap_otp_deinit(struct eap_sm *sm, void *priv) 00033 { 00034 } 00035 00036 00037 static u8 * eap_otp_process(struct eap_sm *sm, void *priv, 00038 struct eap_method_ret *ret, 00039 const u8 *reqData, size_t reqDataLen, 00040 size_t *respDataLen) 00041 { 00042 struct wpa_ssid *config = eap_get_config(sm); 00043 const struct eap_hdr *req; 00044 struct eap_hdr *resp; 00045 const u8 *pos, *password; 00046 u8 *rpos; 00047 size_t password_len, len; 00048 00049 pos = eap_hdr_validate(EAP_TYPE_OTP, reqData, reqDataLen, &len); 00050 if (pos == NULL) { 00051 ret->ignore = TRUE; 00052 return NULL; 00053 } 00054 req = (const struct eap_hdr *) reqData; 00055 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message", 00056 pos, len); 00057 00058 if (config == NULL || 00059 (config->password == NULL && config->otp == NULL)) { 00060 wpa_printf(MSG_INFO, "EAP-OTP: Password not configured"); 00061 eap_sm_request_otp(sm, config, (const char *) pos, len); 00062 ret->ignore = TRUE; 00063 return NULL; 00064 } 00065 00066 if (config->otp) { 00067 password = config->otp; 00068 password_len = config->otp_len; 00069 } else { 00070 password = config->password; 00071 password_len = config->password_len; 00072 } 00073 00074 ret->ignore = FALSE; 00075 00076 ret->methodState = METHOD_DONE; 00077 ret->decision = DECISION_COND_SUCC; 00078 ret->allowNotifications = FALSE; 00079 00080 *respDataLen = sizeof(struct eap_hdr) + 1 + password_len; 00081 resp = malloc(*respDataLen); 00082 if (resp == NULL) 00083 return NULL; 00084 resp->code = EAP_CODE_RESPONSE; 00085 resp->identifier = req->identifier; 00086 resp->length = host_to_be16(*respDataLen); 00087 rpos = (u8 *) (resp + 1); 00088 *rpos++ = EAP_TYPE_OTP; 00089 memcpy(rpos, password, password_len); 00090 wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response", 00091 password, password_len); 00092 00093 if (config->otp) { 00094 wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password"); 00095 memset(config->otp, 0, config->otp_len); 00096 free(config->otp); 00097 config->otp = NULL; 00098 config->otp_len = 0; 00099 } 00100 00101 return (u8 *) resp; 00102 } 00103 00104 00105 const struct eap_method eap_method_otp = 00106 { 00107 .method = EAP_TYPE_OTP, 00108 .name = "OTP", 00109 .init = eap_otp_init, 00110 .deinit = eap_otp_deinit, 00111 .process = eap_otp_process, 00112 }; 00113