Import of hostapd 0.4.9
[dragonfly.git] / contrib / hostapd-0.4.9 / eap_gtc.c
blob674f83735f1f7bac53594144273838471dc09bec
1 /*
2 * hostapd / EAP-GTC (RFC 3748)
3 * Copyright (c) 2004, Jouni Malinen <jkmaline@cc.hut.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <netinet/in.h>
20 #include "hostapd.h"
21 #include "common.h"
22 #include "eap_i.h"
25 struct eap_gtc_data {
26 enum { CONTINUE, SUCCESS, FAILURE } state;
30 static void * eap_gtc_init(struct eap_sm *sm)
32 struct eap_gtc_data *data;
34 data = malloc(sizeof(*data));
35 if (data == NULL)
36 return data;
37 memset(data, 0, sizeof(*data));
38 data->state = CONTINUE;
40 return data;
44 static void eap_gtc_reset(struct eap_sm *sm, void *priv)
46 struct eap_gtc_data *data = priv;
47 free(data);
51 static u8 * eap_gtc_buildReq(struct eap_sm *sm, void *priv, int id,
52 size_t *reqDataLen)
54 struct eap_gtc_data *data = priv;
55 struct eap_hdr *req;
56 u8 *pos;
57 char *msg = "Password";
58 size_t msg_len;
60 msg_len = strlen(msg);
61 *reqDataLen = sizeof(*req) + 1 + msg_len;
62 req = malloc(*reqDataLen);
63 if (req == NULL) {
64 wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
65 "request");
66 data->state = FAILURE;
67 return NULL;
70 req->code = EAP_CODE_REQUEST;
71 req->identifier = id;
72 req->length = htons(*reqDataLen);
73 pos = (u8 *) (req + 1);
74 *pos++ = EAP_TYPE_GTC;
75 memcpy(pos, msg, msg_len);
77 data->state = CONTINUE;
79 return (u8 *) req;
83 static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
84 u8 *respData, size_t respDataLen)
86 struct eap_hdr *resp;
87 u8 *pos;
88 size_t len;
90 resp = (struct eap_hdr *) respData;
91 pos = (u8 *) (resp + 1);
92 if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_GTC ||
93 (len = ntohs(resp->length)) > respDataLen) {
94 wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
95 return TRUE;
98 return FALSE;
102 static void eap_gtc_process(struct eap_sm *sm, void *priv,
103 u8 *respData, size_t respDataLen)
105 struct eap_gtc_data *data = priv;
106 struct eap_hdr *resp;
107 u8 *pos;
108 size_t rlen;
110 if (sm->user == NULL || sm->user->password == NULL) {
111 wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
112 data->state = FAILURE;
113 return;
116 resp = (struct eap_hdr *) respData;
117 pos = (u8 *) (resp + 1);
118 pos++;
119 rlen = ntohs(resp->length) - sizeof(*resp) - 1;
120 wpa_hexdump_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
122 if (rlen != sm->user->password_len ||
123 memcmp(pos, sm->user->password, rlen) != 0) {
124 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
125 data->state = FAILURE;
126 } else {
127 wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success");
128 data->state = SUCCESS;
133 static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
135 struct eap_gtc_data *data = priv;
136 return data->state != CONTINUE;
140 static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
142 struct eap_gtc_data *data = priv;
143 return data->state == SUCCESS;
147 const struct eap_method eap_method_gtc =
149 .method = EAP_TYPE_GTC,
150 .name = "GTC",
151 .init = eap_gtc_init,
152 .reset = eap_gtc_reset,
153 .buildReq = eap_gtc_buildReq,
154 .check = eap_gtc_check,
155 .process = eap_gtc_process,
156 .isDone = eap_gtc_isDone,
157 .isSuccess = eap_gtc_isSuccess,