Add trunc and truncf.
[dragonfly.git] / contrib / hostapd-0.4.9 / eap_gtc.c
1 /*
2  * hostapd / EAP-GTC (RFC 3748)
3  * Copyright (c) 2004, 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 #include <netinet/in.h>
19
20 #include "hostapd.h"
21 #include "common.h"
22 #include "eap_i.h"
23
24
25 struct eap_gtc_data {
26         enum { CONTINUE, SUCCESS, FAILURE } state;
27 };
28
29
30 static void * eap_gtc_init(struct eap_sm *sm)
31 {
32         struct eap_gtc_data *data;
33
34         data = malloc(sizeof(*data));
35         if (data == NULL)
36                 return data;
37         memset(data, 0, sizeof(*data));
38         data->state = CONTINUE;
39
40         return data;
41 }
42
43
44 static void eap_gtc_reset(struct eap_sm *sm, void *priv)
45 {
46         struct eap_gtc_data *data = priv;
47         free(data);
48 }
49
50
51 static u8 * eap_gtc_buildReq(struct eap_sm *sm, void *priv, int id,
52                              size_t *reqDataLen)
53 {
54         struct eap_gtc_data *data = priv;
55         struct eap_hdr *req;
56         u8 *pos;
57         char *msg = "Password";
58         size_t msg_len;
59
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;
68         }
69
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);
76
77         data->state = CONTINUE;
78
79         return (u8 *) req;
80 }
81
82
83 static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
84                              u8 *respData, size_t respDataLen)
85 {
86         struct eap_hdr *resp;
87         u8 *pos;
88         size_t len;
89
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;
96         }
97
98         return FALSE;
99 }
100
101
102 static void eap_gtc_process(struct eap_sm *sm, void *priv,
103                             u8 *respData, size_t respDataLen)
104 {
105         struct eap_gtc_data *data = priv;
106         struct eap_hdr *resp;
107         u8 *pos;
108         size_t rlen;
109
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;
114         }
115
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);
121
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;
129         }
130 }
131
132
133 static Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv)
134 {
135         struct eap_gtc_data *data = priv;
136         return data->state != CONTINUE;
137 }
138
139
140 static Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv)
141 {
142         struct eap_gtc_data *data = priv;
143         return data->state == SUCCESS;
144 }
145
146
147 const struct eap_method eap_method_gtc =
148 {
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,
158 };