Branch data Line data Source code
1 : : /*
2 : : * hostapd / EAP-Identity
3 : : * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : #include "includes.h"
10 : :
11 : : #include "common.h"
12 : : #include "eap_i.h"
13 : :
14 : :
15 : : struct eap_identity_data {
16 : : enum { CONTINUE, SUCCESS, FAILURE } state;
17 : : int pick_up;
18 : : };
19 : :
20 : :
21 : 129 : static void * eap_identity_init(struct eap_sm *sm)
22 : : {
23 : : struct eap_identity_data *data;
24 : :
25 : 129 : data = os_zalloc(sizeof(*data));
26 [ - + ]: 129 : if (data == NULL)
27 : 0 : return NULL;
28 : 129 : data->state = CONTINUE;
29 : :
30 : 129 : return data;
31 : : }
32 : :
33 : :
34 : 0 : static void * eap_identity_initPickUp(struct eap_sm *sm)
35 : : {
36 : : struct eap_identity_data *data;
37 : 0 : data = eap_identity_init(sm);
38 [ # # ]: 0 : if (data) {
39 : 0 : data->pick_up = 1;
40 : : }
41 : 0 : return data;
42 : : }
43 : :
44 : :
45 : 129 : static void eap_identity_reset(struct eap_sm *sm, void *priv)
46 : : {
47 : 129 : struct eap_identity_data *data = priv;
48 : 129 : os_free(data);
49 : 129 : }
50 : :
51 : :
52 : 129 : static struct wpabuf * eap_identity_buildReq(struct eap_sm *sm, void *priv,
53 : : u8 id)
54 : : {
55 : 129 : struct eap_identity_data *data = priv;
56 : : struct wpabuf *req;
57 : : const char *req_data;
58 : : size_t req_data_len;
59 : :
60 [ + - ]: 129 : if (sm->eapol_cb->get_eap_req_id_text) {
61 : 129 : req_data = sm->eapol_cb->get_eap_req_id_text(sm->eapol_ctx,
62 : : &req_data_len);
63 : : } else {
64 : 0 : req_data = NULL;
65 : 0 : req_data_len = 0;
66 : : }
67 : 129 : req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req_data_len,
68 : : EAP_CODE_REQUEST, id);
69 [ - + ]: 129 : if (req == NULL) {
70 : 0 : wpa_printf(MSG_ERROR, "EAP-Identity: Failed to allocate "
71 : : "memory for request");
72 : 0 : data->state = FAILURE;
73 : 0 : return NULL;
74 : : }
75 : :
76 : 129 : wpabuf_put_data(req, req_data, req_data_len);
77 : :
78 : 129 : return req;
79 : : }
80 : :
81 : :
82 : 129 : static Boolean eap_identity_check(struct eap_sm *sm, void *priv,
83 : : struct wpabuf *respData)
84 : : {
85 : : const u8 *pos;
86 : : size_t len;
87 : :
88 : 129 : pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
89 : : respData, &len);
90 [ - + ]: 129 : if (pos == NULL) {
91 : 0 : wpa_printf(MSG_INFO, "EAP-Identity: Invalid frame");
92 : 0 : return TRUE;
93 : : }
94 : :
95 : 129 : return FALSE;
96 : : }
97 : :
98 : :
99 : 129 : static void eap_identity_process(struct eap_sm *sm, void *priv,
100 : : struct wpabuf *respData)
101 : : {
102 : 129 : struct eap_identity_data *data = priv;
103 : : const u8 *pos;
104 : : size_t len;
105 : :
106 [ - + ]: 129 : if (data->pick_up) {
107 [ # # ]: 0 : if (eap_identity_check(sm, data, respData)) {
108 : 0 : wpa_printf(MSG_DEBUG, "EAP-Identity: failed to pick "
109 : : "up already started negotiation");
110 : 0 : data->state = FAILURE;
111 : 0 : return;
112 : : }
113 : 0 : data->pick_up = 0;
114 : : }
115 : :
116 : 129 : pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
117 : : respData, &len);
118 [ - + ]: 129 : if (pos == NULL)
119 : 0 : return; /* Should not happen - frame already validated */
120 : :
121 : 129 : wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
122 [ - + ]: 129 : if (sm->identity)
123 : 0 : sm->update_user = TRUE;
124 : 129 : os_free(sm->identity);
125 [ + - ]: 129 : sm->identity = os_malloc(len ? len : 1);
126 [ - + ]: 129 : if (sm->identity == NULL) {
127 : 0 : data->state = FAILURE;
128 : : } else {
129 : 129 : os_memcpy(sm->identity, pos, len);
130 : 129 : sm->identity_len = len;
131 : 129 : data->state = SUCCESS;
132 : : }
133 : : }
134 : :
135 : :
136 : 167 : static Boolean eap_identity_isDone(struct eap_sm *sm, void *priv)
137 : : {
138 : 167 : struct eap_identity_data *data = priv;
139 : 167 : return data->state != CONTINUE;
140 : : }
141 : :
142 : :
143 : 38 : static Boolean eap_identity_isSuccess(struct eap_sm *sm, void *priv)
144 : : {
145 : 38 : struct eap_identity_data *data = priv;
146 : 38 : return data->state == SUCCESS;
147 : : }
148 : :
149 : :
150 : 1 : int eap_server_identity_register(void)
151 : : {
152 : : struct eap_method *eap;
153 : : int ret;
154 : :
155 : 1 : eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
156 : : EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
157 : : "Identity");
158 [ - + ]: 1 : if (eap == NULL)
159 : 0 : return -1;
160 : :
161 : 1 : eap->init = eap_identity_init;
162 : 1 : eap->initPickUp = eap_identity_initPickUp;
163 : 1 : eap->reset = eap_identity_reset;
164 : 1 : eap->buildReq = eap_identity_buildReq;
165 : 1 : eap->check = eap_identity_check;
166 : 1 : eap->process = eap_identity_process;
167 : 1 : eap->isDone = eap_identity_isDone;
168 : 1 : eap->isSuccess = eap_identity_isSuccess;
169 : :
170 : 1 : ret = eap_server_method_register(eap);
171 [ - + ]: 1 : if (ret)
172 : 0 : eap_server_method_free(eap);
173 : 1 : return ret;
174 : : }
|