Import of WPA supplicant 0.4.9
[dragonfly.git] / contrib / wpa_supplicant-0.4.9 / eap_otp.c
1 /*
2  * WPA Supplicant / EAP-OTP (RFC 3748)
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "common.h"
20 #include "eap_i.h"
21 #include "wpa_supplicant.h"
22 #include "config_ssid.h"
23
24
25 static void * eap_otp_init(struct eap_sm *sm)
26 {
27         return (void *) 1;
28 }
29
30
31 static void eap_otp_deinit(struct eap_sm *sm, void *priv)
32 {
33 }
34
35
36 static u8 * eap_otp_process(struct eap_sm *sm, void *priv,
37                             struct eap_method_ret *ret,
38                             const u8 *reqData, size_t reqDataLen,
39                             size_t *respDataLen)
40 {
41         struct wpa_ssid *config = eap_get_config(sm);
42         const struct eap_hdr *req;
43         struct eap_hdr *resp;
44         const u8 *pos, *password;
45         u8 *rpos;
46         size_t password_len, len;
47
48         pos = eap_hdr_validate(EAP_TYPE_OTP, reqData, reqDataLen, &len);
49         if (pos == NULL) {
50                 ret->ignore = TRUE;
51                 return NULL;
52         }
53         req = (const struct eap_hdr *) reqData;
54         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
55                           pos, len);
56
57         if (config == NULL ||
58             (config->password == NULL && config->otp == NULL)) {
59                 wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
60                 eap_sm_request_otp(sm, config, (const char *) pos, len);
61                 ret->ignore = TRUE;
62                 return NULL;
63         }
64
65         if (config->otp) {
66                 password = config->otp;
67                 password_len = config->otp_len;
68         } else {
69                 password = config->password;
70                 password_len = config->password_len;
71         }
72
73         ret->ignore = FALSE;
74
75         ret->methodState = METHOD_DONE;
76         ret->decision = DECISION_COND_SUCC;
77         ret->allowNotifications = FALSE;
78
79         *respDataLen = sizeof(struct eap_hdr) + 1 + password_len;
80         resp = malloc(*respDataLen);
81         if (resp == NULL)
82                 return NULL;
83         resp->code = EAP_CODE_RESPONSE;
84         resp->identifier = req->identifier;
85         resp->length = host_to_be16(*respDataLen);
86         rpos = (u8 *) (resp + 1);
87         *rpos++ = EAP_TYPE_OTP;
88         memcpy(rpos, password, password_len);
89         wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
90                               password, password_len);
91
92         if (config->otp) {
93                 wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
94                 memset(config->otp, 0, config->otp_len);
95                 free(config->otp);
96                 config->otp = NULL;
97                 config->otp_len = 0;
98         }
99
100         return (u8 *) resp;
101 }
102
103
104 const struct eap_method eap_method_otp =
105 {
106         .method = EAP_TYPE_OTP,
107         .name = "OTP",
108         .init = eap_otp_init,
109         .deinit = eap_otp_deinit,
110         .process = eap_otp_process,
111 };