6 * Implementation of the interface between the radius server and
10 * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
37 #include "eap_psk_ssm.h"
39 static CONF_PARSER moduleConfig[] = {
40 { "private_key", PW_TYPE_STRING_PTR,
41 offsetof(PSK_CONF, privateKey), NULL, NULL },
42 { "server_name", PW_TYPE_STRING_PTR,
43 offsetof(PSK_CONF, id_s), NULL, "pskserver" },
44 { "peer_nai_attribute", PW_TYPE_STRING_PTR,
45 offsetof(PSK_CONF, peerNaiAttribute), NULL, "eapPskPeerNAI" },
46 { "peer_key_attribute", PW_TYPE_STRING_PTR,
47 offsetof(PSK_CONF, peerKeyAttribute), NULL, "eapPskPeerKey" },
48 { "users_file_path", PW_TYPE_STRING_PTR,
49 offsetof(PSK_CONF, usersFilePath), NULL, "/etc/raddb/users.psk" },
50 { "nb_retry", PW_TYPE_INTEGER,
51 offsetof(PSK_CONF, nbRetry), NULL, "3" },
52 { "max_delay", PW_TYPE_INTEGER,
53 offsetof(PSK_CONF, maxDelay), NULL, "5" },
54 { NULL, -1, 0, NULL, NULL } /* end the list */
59 *@memo this function add value pair to reply
61 static void addReply(VALUE_PAIR** vp,
62 const char* name, unsigned char* value, int len)
64 VALUE_PAIR *reply_attr;
65 reply_attr = pairmake(name, "", T_OP_EQ);
68 "add_reply failed to create attribute %s: %s\n",
73 memcpy(reply_attr->vp_octets, value, len);
74 reply_attr->length = len;
75 pairadd(vp, reply_attr);
79 *@memo this function detaches the module
81 static int pskDetach(void *arg)
83 PSK_CONF *inst = (PSK_CONF *) arg;
85 if (inst->privateKey) free(inst->privateKey);
86 if (inst->id_s) free(inst->id_s);
87 if (inst->peerNaiAttribute) free(inst->peerNaiAttribute);
88 if (inst->peerKeyAttribute) free(inst->peerKeyAttribute);
89 if(inst->usersFilePath) free(inst->usersFilePath);
98 *@memo this function attaches the module
100 static int pskAttach(CONF_SECTION *cs, void **instance)
104 inst = (PSK_CONF*)malloc(sizeof(*inst));
106 radlog(L_ERR, "rlm_eap_psk: out of memory");
109 memset(inst, 0, sizeof(*inst));
111 // parse the configuration attributes
112 if (cf_section_parse(cs, inst, moduleConfig) < 0) {
124 *@memo this function begins the conversation when the EAP-Identity response is received
125 * send an initial eap-psk request, ie IDREQ
126 *@param handler, pointer to specific information about the eap-psk protocol
128 static int pskInitiate(void *type_arg, EAP_HANDLER *handler)
130 PSK_SESSION *session;
131 PSK_CONF *conf=(PSK_CONF*)type_arg;
135 radlog(L_ERR,"rlm_eap_psk: Cannot initiate EAP-PSK without having its configuration");
139 DEBUG2("rlm_eap_psk: privateKey: %s",conf->privateKey);
140 DEBUG2("rlm_eap_psk: id_s: %s", conf->id_s);
141 DEBUG2("rlm_eap_psk: peerNaiAttribute: %s", conf->peerNaiAttribute);
142 DEBUG2("rlm_eap_psk: peerKeyAttribute: %s", conf->peerKeyAttribute);
143 DEBUG2("rlm_eap_psk: usersFilePath: %s", conf->usersFilePath);
145 // allocate memory in order to save the state of session
146 handler->opaque=malloc(sizeof(PSK_SESSION));
147 if(!handler->opaque) {
148 radlog(L_ERR,"rlm_eap_psk: Out of memory");
152 // save this pointer in the handler
153 session=(PSK_SESSION *)handler->opaque;
154 handler->free_opaque=pskFreeSession;
156 // initializing session information
157 memset(session,0,sizeof(PSK_SESSION));
160 handler->stage=AUTHENTICATE;
162 // initiate the eap-psk protocol
163 return pskProcess(conf,session,NULL,handler->eap_ds->request);
171 *@memo this function uses specific EAP-Type authentication mechanism to authenticate the user
172 * may be called many times
173 *@param handler, pointer to specific information about the eap-psk protocol
175 static int pskAuthenticate(void *arg, EAP_HANDLER *handler)
177 PSK_SESSION *session;
178 PSK_CONF *conf=(PSK_CONF*)arg;
183 radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without having EAP-PSK configuration");
187 if(!handler->opaque) {
188 radlog(L_ERR,"rlm_eap_psk: Cannot authenticate without EAP-PSK session information");
192 // find the session information
193 session=(PSK_SESSION *)handler->opaque;
195 resul=pskProcess(conf,session,handler->eap_ds->response,handler->eap_ds->request);
197 if(handler->eap_ds->request->code==PW_EAP_SUCCESS) {
199 addReply(&handler->request->reply->vps,"MS-MPPE-Recv-Key",session->msk,32);
200 addReply(&handler->request->reply->vps,"MS-MPPE-Send-Key",&session->msk[32],32);
208 EAP_TYPE rlm_eap_psk = {
211 pskInitiate, // Start the initial request, after Identity
213 pskAuthenticate, // authentication