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