blob: b93f6bb969c11798564e7e3bb6206c90508cb985 [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*****************************************************************************************************
2 * Software License Agreement (BSD License)
3 * Author : Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>
4 *
5 * Copyright (c) 2009-2010, Souheil Ben Ayed, Teraoka Laboratory of Keio University, and the WIDE Project
6 * All rights reserved.
7 *
8 * Redistribution and use of this software in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Souheil Ben Ayed <souheil@tera.ics.keio.ac.jp>.
21 *
22 * 4. Neither the name of Souheil Ben Ayed, Teraoka Laboratory of Keio University or the WIDE Project nor the
23 * names of its contributors may be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
27 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
30 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *****************************************************************************************************/
37
38#include "diameap_common.h"
39
40/* handler for DiamEAP server callback */
41static struct disp_hdl * handle;
42
43/* session handler for DiamEAP sessions state machine */
44static struct session_handler * diameap_server_reg = NULL;
45
46
47struct avp_max_occurences auth_avps[] =
48{
49{ "Service-Type", 1 },
50{ "Callback-Number", 1 },
51{ "Callback-Id", 1 },
52{ "Idle-Timeout", 1 },
53{ "Port-Limit", 1 },
54{ "NAS-Filter-Rule" - 1 },
55{ "Filter-Id", -1 },
56{ "Configuration-Token", -1 },
57{ "QoS-Filter-Rule", -1 },
58{ "Framed-Protocol", 1 },
59{ "Framed-Routing", 1 },
60{ "Framed-MTU", 1 },
61{ "Framed-Compression", -1 },
62{ "Framed-IP-Address", 1 },
63{ "Framed-IP-Netmask", 1 },
64{ "Framed-Route", -1 },
65{ "Framed-Pool", 1 },
66{ "Framed-Interface-Id", 1 },
67{ "Framed-IPv6-Prefix", -1 },
68{ "Framed-IPv6-Pool", 1 },
69{ "Framed-IPv6-Route", -1 },
70{ "Framed-IPX-Network", 1 },
71{ "Framed-Appletalk-Link", 1 },
72{ "Framed-Appletalk-Network", -1 },
73{ "Framed-Appletalk-Zone", 1 },
74{ "NAS-IPv6-Address", 0 },
75{ "NAS-Identifier", 0 },
76{ "NAS-IP-Address", 0 },
77{ "NAS-Port", 0 },
78{ "NAS-Port-Id", 0 },
79{ "NAS-Port-Type", 0 },
80{ "Called-Station-Id", 0 },
81{ "Calling-Station-Id", 0 },
82{ "Connect-Info", 0 },
83{ "Originating-Line-Info", 0 } };
84
85
86
87void diameap_cli_sess_cleanup(struct sess_state * diameap_sess_data, os0_t sid, void * opaque)
88{
89
90 CHECK_PARAMS_DO( diameap_sess_data, return );
91
92 if (diameap_sess_data != NULL)
93 {
94 if (diameap_sess_data->methodData != NULL)
95 {
96 struct plugin * cplugin;
97 if (diameap_plugin_get(diameap_sess_data->currentVendor,
98 diameap_sess_data->currentMethod, &cplugin))
99 {
100 TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sess_data->currentMethod,diameap_sess_data->currentVendor);
101 }
102
103 if (cplugin->eap_method_free)
104 {
105 (*cplugin->eap_method_free)(diameap_sess_data->methodData);
106 diameap_sess_data->methodData = NULL;
107 }
108 else
109 {
110 TRACE_DEBUG(FULL+1,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
111 if (diameap_sess_data->methodData != NULL)
112 {
113 free(diameap_sess_data->methodData);
114 diameap_sess_data->methodData = NULL;
115 }
116 }
117 if (diameap_sess_data->methodData)
118 {
119 TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
120 }
121 }
122
123 if (diameap_sess_data->user.password != NULL)
124 {
125 free(diameap_sess_data->user.password);
126 diameap_sess_data->user.password = NULL;
127 }
128
129 if (diameap_sess_data->user.userid != NULL)
130 {
131 free(diameap_sess_data->user.userid);
132 diameap_sess_data->user.userid = NULL;
133 }
134 free(diameap_sess_data);
135 diameap_sess_data = NULL;
136 }
137}
138
139static int diameap_initialize_diameap_sm(
140 struct diameap_state_machine * diameap_sm,
141 struct sess_state * diameap_sess_data)
142{
143 TRACE_ENTRY("%p %p", diameap_sm, diameap_sess_data);
144
145 int i;
146
147 /* Initialize Long Term Variables */
148 if (diameap_sess_data != NULL)
149 {
150 diameap_sm->invalid_eappackets = diameap_sess_data->invalid_eappackets;
151
152 /* Initialize eap state machine variables */
153 /*User*/
154 diameap_sm->eap_sm.user.id = diameap_sess_data->user.id;
155
156 if ((diameap_sess_data->user.userid != NULL)
157 && (diameap_sess_data->user.useridLength > 0))
158 {
159 diameap_sm->eap_sm.user.useridLength
160 = diameap_sess_data->user.useridLength;
161 CHECK_MALLOC(diameap_sm->eap_sm.user.userid= malloc(diameap_sm->eap_sm.user.useridLength+1));
162 U8COPY(diameap_sm->eap_sm.user.userid,0,diameap_sm->eap_sm.user.useridLength+1,diameap_sess_data->user.userid);
163 free(diameap_sess_data->user.userid);
164 diameap_sess_data->user.userid = NULL;
165
166 }
167 else
168 {
169 TRACE_DEBUG(INFO,"%s user not identified yet.",DIAMEAP_EXTENSION);
170 diameap_sm->eap_sm.user.useridLength = 0;
171 diameap_sm->eap_sm.user.userid = NULL;
172 }
173
174 if ((diameap_sess_data->user.password != NULL)
175 && (diameap_sess_data->user.passwordLength > 0))
176 {
177 diameap_sm->eap_sm.user.passwordLength
178 = diameap_sess_data->user.passwordLength;
179 CHECK_MALLOC(diameap_sm->eap_sm.user.password = malloc(diameap_sm->eap_sm.user.passwordLength+1));
180 U8COPY(diameap_sm->eap_sm.user.password,0,diameap_sm->eap_sm.user.passwordLength+1, diameap_sess_data->user.password);
181 free(diameap_sess_data->user.password);
182 diameap_sess_data->user.password = NULL;
183 }
184 else
185 {
186 diameap_sm->eap_sm.user.passwordLength = 0;
187 diameap_sm->eap_sm.user.password = NULL;
188 }
189
190 diameap_sm->eap_sm.user.methodId = diameap_sess_data->user.methodId;
191 for (i = 0; i < MAXMETHODS; i++)
192 {
193 diameap_sm->eap_sm.user.methods[i].method
194 = diameap_sess_data->user.methods[i].method;
195 diameap_sm->eap_sm.user.methods[i].vendor
196 = diameap_sess_data->user.methods[i].vendor;
197 }
198 for (i = 0; i < MAXPROPOSEDMETHODS; i++)
199 {
200 diameap_sm->eap_sm.user.proposedmethods[i].method
201 = diameap_sess_data->user.proposedmethods[i].method;
202 diameap_sm->eap_sm.user.proposedmethods[i].vendor
203 = diameap_sess_data->user.proposedmethods[i].vendor;
204 }
205
206 diameap_sm->eap_sm.user.pmethods = diameap_sess_data->user.pmethods;
207 diameap_sm->eap_sm.user.proposed_eap_method
208 = diameap_sess_data->user.proposed_eap_method;
209 diameap_sm->eap_sm.user.proposed_eap_method_vendor
210 = diameap_sess_data->user.proposed_eap_method_vendor;
211 diameap_sm->eap_sm.user.success = diameap_sess_data->user.success;
212
213 diameap_sm->eap_sm.currentId = diameap_sess_data->currentId;
214 diameap_sm->eap_sm.currentVendor = diameap_sess_data->currentVendor;
215 diameap_sm->eap_sm.lastId = diameap_sess_data->lastId;
216 diameap_sm->eap_sm.methodState = diameap_sess_data->methodState;
217 diameap_sm->eap_sm.currentMethod = diameap_sess_data->currentMethod;
218
219 diameap_sm->eap_sm.methodData = diameap_sess_data->methodData;
220 diameap_sess_data->methodData = NULL;
221
222 if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
223 {
224 diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
225 diameap_sm->eap_sm.currentMethod,
226 &diameap_sm->eap_sm.selectedMethod);
227 }
228
229 /* free session data*/
230 free(diameap_sess_data);
231 diameap_sess_data = NULL;
232
233 }
234 else
235 {
236 diameap_sm->invalid_eappackets = 0;
237
238 /* Initialize eap state machine variables */
239 /*User*/
240 diameap_sm->eap_sm.user.id = 0;
241 diameap_sm->eap_sm.user.userid = NULL;
242 diameap_sm->eap_sm.user.useridLength = 0;
243 diameap_sm->eap_sm.user.password = NULL;
244 diameap_sm->eap_sm.user.passwordLength = 0;
245 diameap_sm->eap_sm.user.methodId = -1;
246 for (i = 0; i < MAXMETHODS; i++)
247 {
248 diameap_sm->eap_sm.user.methods[i].method = TYPE_NONE;
249 diameap_sm->eap_sm.user.methods[i].vendor = VENDOR_IETF;
250 }
251 for (i = 0; i < MAXPROPOSEDMETHODS; i++)
252 {
253 diameap_sm->eap_sm.user.proposedmethods[i].method = TYPE_NONE;
254 diameap_sm->eap_sm.user.proposedmethods[i].vendor = VENDOR_IETF;
255 }
256
257 diameap_sm->eap_sm.user.pmethods = -1;
258 diameap_sm->eap_sm.user.proposed_eap_method = TYPE_NONE;
259 diameap_sm->eap_sm.user.proposed_eap_method_vendor = VENDOR_IETF;
260 diameap_sm->eap_sm.user.success = FALSE;
261
262 diameap_sm->eap_sm.currentId = -1;
263 diameap_sm->eap_sm.currentVendor = VENDOR_IETF;
264 diameap_sm->eap_sm.lastId = -1;
265 diameap_sm->eap_sm.methodState = EAP_M_PROPOSED;
266
267 diameap_sm->eap_sm.currentMethod = TYPE_NONE;
268
269 diameap_sm->eap_sm.methodData = NULL;
270
271 }
272
273 diameap_sm->result_code = 0;
274 fd_list_init(&diameap_sm->attributes, NULL);
275 fd_list_init(&diameap_sm->req_attributes, NULL);
276 fd_list_init(&diameap_sm->ans_attributes, NULL);
277 diameap_sm->failedavp = NULL;
278 diameap_sm->auth_request_val = AUTHENTICATE_ONLY;
279 diameap_sm->verify_authorization = FALSE;
280 diameap_sm->authSuccess = FALSE;
281 diameap_sm->authFailure = FALSE;
282 diameap_sm->lastReqEAPavp = NULL;
283 diameap_sm->privateUser = FALSE;
284 diameap_sm->authorized = FALSE;
285
286 diameap_sm->eap_sm.rxResp = FALSE;
287 diameap_sm->eap_sm.respId = -1;
288 diameap_sm->eap_sm.respMethod = TYPE_NONE;
289 diameap_sm->eap_sm.respVendor = VENDOR_IETF;
290 diameap_sm->eap_sm.respVendorMethod = TYPE_NONE;
291
292 return 0;
293}
294
295static int diameap_initialize_diameap_eap_interface(
296 struct diameap_eap_interface * eap_i)
297{
298 TRACE_ENTRY("%p", eap_i);
299
300 //Initialize AAA-EAP Interface
301 eap_i->aaaEapResp = FALSE;
302 eap_i->aaaEapRespData.data = NULL;
303 //Initialize EAP-AAA Interface
304 eap_i->aaaEapReq = FALSE;
305 eap_i->aaaEapNoReq = FALSE;
306 eap_i->aaaSuccess = FALSE;
307 eap_i->aaaFail = FALSE;
308 eap_i->aaaEapReqData.data = NULL;
309 eap_i->aaaEapMSKData = NULL;
310 eap_i->aaaEapEMSKData = NULL;
311 eap_i->aaaEapKeyAvailable = FALSE;
312 eap_i->aaaMethodTimeout = 0;
313
314 return 0;
315}
316
317static int diameap_failed_avp(struct diameap_state_machine * diameap_sm,
318 struct avp * invalidavp)
319{
320 TRACE_ENTRY("%p %p",diameap_sm,invalidavp);
321 if (!invalidavp)
322 return EINVAL;
323
324 if (!diameap_sm)
325 return EINVAL;
326
327 if (diameap_sm->failedavp == NULL)
328 {
329 CHECK_FCT( fd_msg_avp_new( dataobj_failed_avp, 0, &diameap_sm->failedavp) );
330
331 CHECK_FCT( fd_msg_avp_add( diameap_sm->failedavp, MSG_BRW_LAST_CHILD, invalidavp ) );
332
333 }
334 else
335 {
336 //add multiple AVPs in Failed-AVP
337 }
338 return 0;
339}
340
341static int diameap_parse_eap_resp(struct eap_state_machine * eap_sm,
342 struct eap_packet *eappacket)
343{
344 TRACE_ENTRY("%p %p",eap_sm, eappacket)
345
346 eap_sm->rxResp = FALSE;
347 eap_sm->respId = -1;
348 eap_sm->respMethod = TYPE_NONE;
349 eap_sm->respVendor = VENDOR_IETF;
350 eap_sm->respVendorMethod = TYPE_NONE;
351
352 if (eappacket->data == NULL)
353 {
354 TRACE_DEBUG(INFO,"%s Empty EAP packet",DIAMEAP_EXTENSION);
355 return 0;
356 }
357
358 u16 plength;
359 CHECK_FCT(diameap_eap_get_packetlength(eappacket,&plength));
360 if ((int) plength < EAP_HEADER)
361 {
362 TRACE_DEBUG(INFO,"%s EAP packet length less than EAP header.",DIAMEAP_EXTENSION);
363 return 0;
364 }
365
366 u16 length;
367 CHECK_FCT(diameap_eap_get_length(eappacket,&length));
368 if ((int) length < EAP_HEADER)
369 {
370 TRACE_DEBUG(INFO,"%sEAP packet length field less than EAP header.",DIAMEAP_EXTENSION);
371 return 0;
372 }
373
374 if (plength < length)
375 {
376 TRACE_DEBUG(INFO,"%sLength of received EAP packet is less than the value of the length field.",DIAMEAP_EXTENSION);
377 return 0;
378 }
379
380 eap_code code;
381 CHECK_FCT(diameap_eap_get_code(eappacket,&code));
382 if (code == EAP_REQUEST || code == EAP_SUCCESS || code == EAP_FAILURE)
383 {
384 TRACE_DEBUG(INFO,"%sOnly EAP Responses are accepted at EAP server side.",DIAMEAP_EXTENSION);
385 return 0;
386 }
387
388 u8 id;
389 CHECK_FCT(diameap_eap_get_identifier(eappacket,&id));
390 eap_sm->respId = id;
391
392 CHECK_FCT(diameap_eap_get_type(eappacket,&eap_sm->respMethod));
393 if ((eap_sm->methodState != EAP_M_PROPOSED) && (eap_sm->respMethod
394 == TYPE_NAK || eap_sm->respMethod == TYPE_EXPANDED_TYPES))
395 {
396 TRACE_DEBUG(INFO,"%sNAK or EXPANDED_NAK received after an EAP TYPE been selected",DIAMEAP_EXTENSION);
397 return 0;
398 }
399
400 if ((eap_sm->respMethod == TYPE_EXPANDED_TYPES) && (length < 20))
401 {
402 TRACE_DEBUG(INFO,"%s Truncated EAP Packet received.",DIAMEAP_EXTENSION);
403 return 0;
404 }
405
406 if ((eap_sm->respMethod == TYPE_NAK) && (eap_sm->currentMethod < 4))
407 {
408 TRACE_DEBUG(INFO,"%sNAK response not expected at this step (Only EAP type = 4 and above are accepted).",DIAMEAP_EXTENSION);
409 return 0;
410 }
411
412 if (eap_sm->respMethod == TYPE_EXPANDED_TYPES)
413 {
414 u8 *data = (u8 *) eappacket->data;
415 //int len = 0;
416 //u32 respVendor, respVendorMethod;
417 data += 5;
418 eap_sm->respVendor = G24BIGE(data);
419 data += 3;
420 eap_sm->respVendorMethod = G32BIGE(data);
421 data += 4;
422 /* while ((length - 12) > (len * 8))
423 {
424 if (((eap_type) G8(data)) != TYPE_EXPANDED_TYPES)
425 {
426 return FALSE;
427 }
428 data += 1;
429 respVendor = G24BIGE(data);
430 data += 3;
431 respVendorMethod = G32BIGE(data);
432 eap_sm->user.proposedmethods[len].method = respVendor;
433 eap_sm->user.proposedmethods[len].vendor = respVendorMethod;
434 len++;
435 data += 4;
436 }
437 eap_sm->user.methodId = 0;*/
438 }
439
440 if((eap_sm->respMethod == TYPE_IDENTITY) && (length < 6)){
441 TRACE_DEBUG(INFO,"%sUser Identity missing",DIAMEAP_EXTENSION);
442 return 0;
443 }
444
445 eap_sm->rxResp = TRUE;
446 return 0;
447}
448
449static int diameap_eappacket_new(struct eap_packet * eappacket,
450 struct avp_hdr * avpdata)
451{
452 TRACE_ENTRY("%p %p",eappacket,avpdata);
453 eappacket->ulength = (u16) avpdata->avp_value->os.len;
454 eappacket->data = (u8 *) avpdata->avp_value->os.data;
455 diameap_eap_get_packetlength(eappacket, &eappacket->length);
456 return 0;
457}
458
459static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
460 struct msg * req, struct diameap_eap_interface * eap_i)
461{
462 TRACE_ENTRY("%p %p %p",diameap_sm,req,eap_i);
463 struct avp * avp, *avp2;
464 struct avp_hdr * avpdata;
465 int ret;
466 int depth;
467
468 /* EAP-Payload data*/
469 avp = NULL;
470 CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
471 if (avp != NULL)
472 {
473 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
474 CHECK_FCT(diameap_eappacket_new(&eap_i->aaaEapRespData, avpdata));
475 eap_i->aaaEapResp = TRUE;
476 u16 length;
477 diameap_eap_get_length(&eap_i->aaaEapRespData, &length);
478 if (length >= 4)
479 {
480 eap_code code;
481 CHECK_FCT(diameap_eap_get_code(&eap_i->aaaEapRespData,&code));
482
483 if (code != EAP_RESPONSE)
484 {
485 diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
486 struct avp * invalidavp;
487 union avp_value val;
488 CHECK_FCT( fd_msg_avp_new ( dataobj_eap_payload, 0, &invalidavp));
489 val.os.data = eap_i->aaaEapRespData.data;
490 val.os.len = eap_i->aaaEapRespData.length;
491 CHECK_FCT( fd_msg_avp_setvalue( invalidavp, &val ))
492 CHECK_FCT( diameap_failed_avp(diameap_sm, invalidavp));
493 TRACE_DEBUG(INFO,"%sIncorrect EAP Packet. EAP Code != Response.",DIAMEAP_EXTENSION);
494 return 0;
495 }
496 else
497 {
498 CHECK_FCT(diameap_parse_eap_resp(&diameap_sm->eap_sm, &eap_i->aaaEapRespData));
499 if (diameap_sm->eap_sm.rxResp == FALSE)
500 {
501 diameap_sm->result_code = 1001; /*DIAMETER_MULTI_ROUND_AUTH*/
502 eap_i->aaaEapNoReq = TRUE;
503 eap_i->aaaEapResp = FALSE;
504 }
505 }
506 }
507 else
508 {
509 if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
510 {
511 diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
512 CHECK_FCT(diameap_failed_avp(diameap_sm, avp));
513 TRACE_DEBUG(INFO,"%sEAP packet length < Minimum EAP packet length.",DIAMEAP_EXTENSION);
514 return 1;
515 }
516 //EAP start received
517
518 }
519 }
520
521 /* User-Name AVP */
522 avp = NULL;
523 CHECK_FCT(fd_msg_search_avp(req, dataobj_user_name, &avp));
524 if (avp != NULL)
525 {
526 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
527 struct avp_attribute * attribute;
528 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
529 memset(attribute, 0, sizeof(struct avp_attribute));
530 fd_list_init(&attribute->chain, attribute);
531 attribute->attrib = "User-Name";
532 attribute->value.os.data = avpdata->avp_value->os.data;
533 attribute->value.os.len = avpdata->avp_value->os.len;
534 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
535 }
536
537 /* EAP-Key-Name AVP */
538
539 avp = NULL;
540 CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_key_name, &avp));
541 if (avp != NULL)
542 {
543 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
544 struct avp_attribute * attribute;
545 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
546 memset(attribute, 0, sizeof(struct avp_attribute));
547 fd_list_init(&attribute->chain, attribute);
548 attribute->attrib = "EAP-Key-Name";
549 attribute->value.os.data = avpdata->avp_value->os.data;
550 attribute->value.os.len = avpdata->avp_value->os.len;
551 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
552 }
553
554 /* Auth-Request-Type AVP */
555 avp = NULL;
556 CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_request_type, &avp));
557 if (avp != NULL)
558 {
559 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
560 diameap_sm->auth_request_val = avpdata->avp_value->i32;
561 }
562
563 /* Authorization-Lifetime AVP */
564 avp = NULL;
565 CHECK_FCT(fd_msg_search_avp(req, dataobj_authorization_lifetime, &avp));
566 if (avp != NULL)
567 {
568 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
569 struct avp_attribute * attribute;
570 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
571 memset(attribute, 0, sizeof(struct avp_attribute));
572 fd_list_init(&attribute->chain, attribute);
573 attribute->attrib = "Authorization-Lifetime";
574 attribute->value.u32 = avpdata->avp_value->u32;
575 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
576 }
577
578 /* Auth-Grace-Period AVP */
579 avp = NULL;
580 CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_grace_period, &avp));
581 if (avp != NULL)
582 {
583 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
584 struct avp_attribute * attribute;
585 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
586 memset(attribute, 0, sizeof(struct avp_attribute));
587 fd_list_init(&attribute->chain, attribute);
588 attribute->attrib = "Auth-Grace-Period";
589 attribute->value.u32 = avpdata->avp_value->u32;
590 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
591 }
592
593 /* Auth-Session-State AVP */
594 avp = NULL;
595 CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_session_state, &avp));
596 if (avp != NULL)
597 {
598 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
599 struct avp_attribute * attribute;
600 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
601 memset(attribute, 0, sizeof(struct avp_attribute));
602 fd_list_init(&attribute->chain, attribute);
603 attribute->attrib = "Auth-Session-State";
604 attribute->value.i32 = avpdata->avp_value->i32;
605 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
606 }
607
608 /* Origin-state-Id AVP */
609 avp = NULL;
610 CHECK_FCT(fd_msg_search_avp(req, dataobj_origin_state_id, &avp));
611 if (avp != NULL)
612 {
613 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
614 struct avp_attribute * attribute;
615 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
616 memset(attribute, 0, sizeof(struct avp_attribute));
617 fd_list_init(&attribute->chain, attribute);
618 attribute->attrib = "Origin-state-Id AVP";
619 attribute->value.u32 = avpdata->avp_value->u32;
620 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
621 }
622
623 /* NAS-Port AVP*/
624 avp = NULL;
625 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port, &avp));
626 if (avp != NULL)
627 {
628 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
629 struct avp_attribute * attribute;
630 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
631 memset(attribute, 0, sizeof(struct avp_attribute));
632 fd_list_init(&attribute->chain, attribute);
633 attribute->attrib = "NAS-Port";
634 attribute->value.u32 = avpdata->avp_value->u32;
635 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
636 }
637
638 /* NAS-Port-Id AVP */
639 avp = NULL;
640 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_id, &avp));
641 if (avp != NULL)
642 {
643 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
644 struct avp_attribute * attribute;
645 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
646 memset(attribute, 0, sizeof(struct avp_attribute));
647 fd_list_init(&attribute->chain, attribute);
648 attribute->attrib = "NAS-Port-Id";
649 attribute->value.os.data = avpdata->avp_value->os.data;
650 attribute->value.os.len = avpdata->avp_value->os.len;
651 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
652 }
653
654 /* NAS-Port-Type AVP */
655 avp = NULL;
656 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_type, &avp));
657 if (avp != NULL)
658 {
659 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
660 struct avp_attribute * attribute;
661 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
662 memset(attribute, 0, sizeof(struct avp_attribute));
663 fd_list_init(&attribute->chain, attribute);
664 attribute->attrib = "NAS-Port-Type";
665 attribute->value.u32 = avpdata->avp_value->u32;
666 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
667 }
668
669 /* Called-Station-Id AVP */
670 avp = NULL;
671 CHECK_FCT(fd_msg_search_avp(req, dataobj_called_station_id, &avp));
672 if (avp != NULL)
673 {
674 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
675 struct avp_attribute * attribute;
676 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
677 memset(attribute, 0, sizeof(struct avp_attribute));
678 fd_list_init(&attribute->chain, attribute);
679 attribute->attrib = "Called-Station-Id";
680 attribute->value.os.data = avpdata->avp_value->os.data;
681 attribute->value.os.len = avpdata->avp_value->os.len;
682 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
683 }
684
685 /* Calling-Station-Id AVP */
686 avp = NULL;
687 CHECK_FCT(fd_msg_search_avp(req, dataobj_calling_station_id, &avp));
688 if (avp != NULL)
689 {
690 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
691 struct avp_attribute * attribute;
692 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
693 memset(attribute, 0, sizeof(struct avp_attribute));
694 fd_list_init(&attribute->chain, attribute);
695 attribute->attrib = "Calling-Station-Id";
696 attribute->value.os.data = avpdata->avp_value->os.data;
697 attribute->value.os.len = avpdata->avp_value->os.len;
698 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
699 }
700
701 /* Connect-Info AVP */
702 avp = NULL;
703 CHECK_FCT(fd_msg_search_avp(req, dataobj_connect_info, &avp));
704 if (avp != NULL)
705 {
706 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
707 struct avp_attribute * attribute;
708 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
709 memset(attribute, 0, sizeof(struct avp_attribute));
710 fd_list_init(&attribute->chain, attribute);
711 attribute->attrib = "Connect-Info";
712 attribute->value.os.data = avpdata->avp_value->os.data;
713 attribute->value.os.len = avpdata->avp_value->os.len;
714 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
715 }
716
717 /* Originating-Line-Info AVP */
718 avp = NULL;
719 CHECK_FCT(fd_msg_search_avp(req, dataobj_originating_line_info, &avp));
720 if (avp != NULL)
721 {
722 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
723 struct avp_attribute * attribute;
724 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
725 memset(attribute, 0, sizeof(struct avp_attribute));
726 fd_list_init(&attribute->chain, attribute);
727 attribute->attrib = "Originating-Line-Info";
728 attribute->value.os.data = avpdata->avp_value->os.data;
729 attribute->value.os.len = avpdata->avp_value->os.len;
730 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
731 }
732
733 /* Service-Type AVP */
734 avp = NULL;
735 CHECK_FCT(fd_msg_search_avp(req, dataobj_service_type, &avp));
736 if (avp != NULL)
737 {
738 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
739 struct avp_attribute * attribute;
740 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
741 memset(attribute, 0, sizeof(struct avp_attribute));
742 fd_list_init(&attribute->chain, attribute);
743 attribute->attrib = "Service-Type";
744 attribute->value.u32 = avpdata->avp_value->u32;
745 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
746 }
747
748 /* Callback-Number AVP */
749 avp = NULL;
750 CHECK_FCT(fd_msg_search_avp(req, dataobj_callback_number, &avp));
751 if (avp != NULL)
752 {
753 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
754 struct avp_attribute * attribute;
755 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
756 memset(attribute, 0, sizeof(struct avp_attribute));
757 fd_list_init(&attribute->chain, attribute);
758 attribute->attrib = "Callback-Number";
759 attribute->value.os.data = avpdata->avp_value->os.data;
760 attribute->value.os.len = avpdata->avp_value->os.len;
761 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
762 }
763
764 /* Port-Limit AVP */
765 avp = NULL;
766 CHECK_FCT(fd_msg_search_avp(req, dataobj_port_limit, &avp));
767 if (avp != NULL)
768 {
769 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
770 struct avp_attribute * attribute;
771 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
772 memset(attribute, 0, sizeof(struct avp_attribute));
773 fd_list_init(&attribute->chain, attribute);
774 attribute->attrib = "Port-Limit";
775 attribute->value.u32 = avpdata->avp_value->u32;
776 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
777 }
778
779 /* Framed-Protocol AVP */
780 avp = NULL;
781 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_protocol, &avp));
782 if (avp != NULL)
783 {
784 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
785 struct avp_attribute * attribute;
786 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
787 memset(attribute, 0, sizeof(struct avp_attribute));
788 fd_list_init(&attribute->chain, attribute);
789 attribute->attrib = "Framed-Protocol";
790 attribute->value.u32 = avpdata->avp_value->u32;
791 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
792 }
793
794 /* Framed-MTU AVP */
795 avp = NULL;
796 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_mtu, &avp));
797 if (avp != NULL)
798 {
799 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
800 struct avp_attribute * attribute;
801 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
802 memset(attribute, 0, sizeof(struct avp_attribute));
803 fd_list_init(&attribute->chain, attribute);
804 attribute->attrib = "Framed-MTU";
805 attribute->value.u32 = avpdata->avp_value->u32;
806 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
807 }
808
809 /* Framed-Compression AVP */
810 avp = NULL;
811 avp2 = NULL;
812 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_compression, &avp));
813 if (avp != NULL)
814 {
815 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
816 u32 Pi_Code = avpdata->avp_code;
817 int depth;
818 do
819 {
820 struct avp_attribute * attribute;
821 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
822 memset(attribute, 0, sizeof(struct avp_attribute));
823 fd_list_init(&attribute->chain, attribute);
824 attribute->attrib = "Framed-Compression";
825 attribute->value.u32 = avpdata->avp_value->u32;
826 fd_list_insert_before(&diameap_sm->req_attributes,
827 &attribute->chain);
828 ret = 0;
829 depth = 0;
830 ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
831 if (avp2 != NULL)
832 {
833 CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
834 }
835 avp = avp2;
836 } while ((avp2 != NULL) && (ret == 0) && (ret == 0)
837 && (avpdata->avp_code == Pi_Code));
838 }
839
840 /* Framed-IP-Address AVP */
841 avp = NULL;
842 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_address, &avp));
843 if (avp != NULL)
844 {
845 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
846 struct avp_attribute * attribute;
847 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
848 memset(attribute, 0, sizeof(struct avp_attribute));
849 fd_list_init(&attribute->chain, attribute);
850 attribute->attrib = "Framed-IP-Address";
851 attribute->value.os.data = avpdata->avp_value->os.data;
852 attribute->value.os.len = avpdata->avp_value->os.len;
853 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
854 }
855
856 /* Framed-IP-Netmask AVP */
857 avp = NULL;
858 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_netmask, &avp));
859 if (avp != NULL)
860 {
861 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
862 struct avp_attribute * attribute;
863 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
864 memset(attribute, 0, sizeof(struct avp_attribute));
865 fd_list_init(&attribute->chain, attribute);
866 attribute->attrib = "Framed-IP-Netmask";
867 attribute->value.os.data = avpdata->avp_value->os.data;
868 attribute->value.os.len = avpdata->avp_value->os.len;
869 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
870 }
871
872 /* Framed-Interface-Id AVP */
873 avp = NULL;
874 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_interface_id, &avp));
875 if (avp != NULL)
876 {
877 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
878 struct avp_attribute * attribute;
879 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
880 memset(attribute, 0, sizeof(struct avp_attribute));
881 fd_list_init(&attribute->chain, attribute);
882 attribute->attrib = "Framed-Interface-Id";
883 attribute->value.u64 = avpdata->avp_value->u64;
884 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
885 }
886
887 /* Framed-IPv6-Prefix AVP */
888 avp = NULL;
889 avp2 = NULL;
890 CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ipv6_prefix, &avp));
891 if (avp != NULL)
892 {
893 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
894 u32 Pi_Code = avpdata->avp_code;
895 do
896 {
897 struct avp_attribute * attribute;
898 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
899 memset(attribute, 0, sizeof(struct avp_attribute));
900 fd_list_init(&attribute->chain, attribute);
901 attribute->attrib = "Framed-IPv6-Prefix";
902 attribute->value.u32 = avpdata->avp_value->u32;
903 fd_list_insert_before(&diameap_sm->req_attributes,
904 &attribute->chain);
905 ret = 0;
906 depth = 0;
907 ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
908 if (avp2 != NULL)
909 {
910 CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
911 }
912 avp = avp2;
913 } while ((avp2 != NULL) && (ret == 0) && (ret == 0)
914 && (avpdata->avp_code == Pi_Code));
915 }
916
917 /* Tunneling AVP */
918 avp = NULL;
919 avp2 = NULL;
920 CHECK_FCT(fd_msg_search_avp(req, dataobj_tunneling, &avp));
921 if (avp != NULL)
922 {
923 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
924 u32 Pi_Code = avpdata->avp_code;
925 int depth;
926 do
927 {
928 struct avp_attribute * attribute;
929 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
930 memset(attribute, 0, sizeof(struct avp_attribute));
931 fd_list_init(&attribute->chain, attribute);
932 attribute->attrib = "Tunneling";
933 //grouped AVP
934 fd_list_insert_before(&diameap_sm->req_attributes,
935 &attribute->chain);
936 ret = 0;
937 depth = 0;
938 ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
939 if (avp2 != NULL)
940 {
941 CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
942 }
943 avp = avp2;
944 } while ((avp2 != NULL) && (ret == 0) && (ret == 0)
945 && (avpdata->avp_code == Pi_Code));
946 }
947
948 /* NAS-Identifier AVP */
949 avp = NULL;
950 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_identifier, &avp));
951 if (avp != NULL)
952 {
953 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
954 struct avp_attribute * attribute;
955 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
956 memset(attribute, 0, sizeof(struct avp_attribute));
957 fd_list_init(&attribute->chain, attribute);
958 attribute->attrib = "NAS-Identifier";
959 attribute->value.os.data = avpdata->avp_value->os.data;
960 attribute->value.os.len = avpdata->avp_value->os.len;
961 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
962 }
963
964 /* NAS-IP-Address AVP */
965 avp = NULL;
966 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ip_address, &avp));
967 if (avp != NULL)
968 {
969 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
970 struct avp_attribute * attribute;
971 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
972 memset(attribute, 0, sizeof(struct avp_attribute));
973 fd_list_init(&attribute->chain, attribute);
974 attribute->attrib = "NAS-IP-Address";
975 attribute->value.os.data = avpdata->avp_value->os.data;
976 attribute->value.os.len = avpdata->avp_value->os.len;
977 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
978 }
979
980 /* NAS-IPv6-Address AVP */
981 avp = NULL;
982 CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ipv6_address, &avp));
983 if (avp != NULL)
984 {
985 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
986 struct avp_attribute * attribute;
987 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
988 memset(attribute, 0, sizeof(struct avp_attribute));
989 fd_list_init(&attribute->chain, attribute);
990 attribute->attrib = "NAS-IPv6-Address";
991 attribute->value.os.data = avpdata->avp_value->os.data;
992 attribute->value.os.len = avpdata->avp_value->os.len;
993 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
994 }
995
996 /* State AVP */
997 avp = NULL;
998 CHECK_FCT(fd_msg_search_avp(req, dataobj_state, &avp));
999 if (avp != NULL)
1000 {
1001 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
1002 struct avp_attribute * attribute;
1003 CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
1004 memset(attribute, 0, sizeof(struct avp_attribute));
1005 fd_list_init(&attribute->chain, attribute);
1006 attribute->attrib = "State";
1007 attribute->value.os.data = avpdata->avp_value->os.data;
1008 attribute->value.os.len = avpdata->avp_value->os.len;
1009 fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
1010 }
1011
1012 return 0;
1013}
1014
1015
1016static int diameap_sess_data_new(
1017 struct sess_state *diameap_sess_data,
1018 struct diameap_state_machine *diameap_sm)
1019{
1020 if (!diameap_sm)
1021 return EINVAL;
1022
1023 int i;
1024
1025 diameap_sess_data->invalid_eappackets = diameap_sm->invalid_eappackets;
1026
1027 diameap_sess_data->user.id = diameap_sm->eap_sm.user.id;
1028
1029 if ((diameap_sm->eap_sm.user.userid != NULL)
1030 && (diameap_sm->eap_sm.user.useridLength > 0))
1031 {
1032 diameap_sess_data->user.useridLength
1033 = diameap_sm->eap_sm.user.useridLength;
1034 CHECK_MALLOC(diameap_sess_data->user.userid= malloc(diameap_sess_data->user.useridLength+1));
1035 U8COPY(diameap_sess_data->user.userid,0,diameap_sess_data->user.useridLength+1,diameap_sm->eap_sm.user.userid);
1036 free(diameap_sm->eap_sm.user.userid);
1037 diameap_sm->eap_sm.user.userid = NULL;
1038
1039 }
1040 else
1041 {
1042 diameap_sess_data->user.useridLength = 0;
1043 diameap_sess_data->user.userid = NULL;
1044 }
1045
1046 if ((diameap_sm->eap_sm.user.password != NULL)
1047 && (diameap_sm->eap_sm.user.passwordLength > 0))
1048 {
1049 diameap_sess_data->user.passwordLength
1050 = diameap_sm->eap_sm.user.passwordLength;
1051 CHECK_MALLOC(diameap_sess_data->user.password = malloc(diameap_sess_data->user.passwordLength+1));
1052 U8COPY(diameap_sess_data->user.password,0,diameap_sess_data->user.passwordLength+1,diameap_sm->eap_sm.user.password);
1053 free(diameap_sm->eap_sm.user.password);
1054 diameap_sm->eap_sm.user.password = NULL;
1055 }
1056 else
1057 {
1058 diameap_sess_data->user.passwordLength = 0;
1059 diameap_sess_data->user.password = NULL;
1060 }
1061
1062 diameap_sess_data->user.methodId = diameap_sm->eap_sm.user.methodId;
1063 for (i = 0; i < MAXMETHODS; i++)
1064 {
1065 diameap_sess_data->user.methods[i].method
1066 = diameap_sm->eap_sm.user.methods[i].method;
1067 diameap_sess_data->user.methods[i].vendor
1068 = diameap_sm->eap_sm.user.methods[i].vendor;
1069 }
1070
1071 for (i = 0; i < MAXPROPOSEDMETHODS; i++)
1072 {
1073 diameap_sess_data->user.proposedmethods[i].method
1074 = diameap_sm->eap_sm.user.proposedmethods[i].method;
1075 diameap_sess_data->user.proposedmethods[i].vendor
1076 = diameap_sm->eap_sm.user.proposedmethods[i].vendor;
1077 }
1078
1079 diameap_sess_data->user.pmethods = diameap_sm->eap_sm.user.pmethods;
1080 diameap_sess_data->user.proposed_eap_method
1081 = diameap_sm->eap_sm.user.proposed_eap_method;
1082 diameap_sess_data->user.proposed_eap_method_vendor
1083 = diameap_sm->eap_sm.user.proposed_eap_method_vendor;
1084 diameap_sess_data->user.success = diameap_sm->eap_sm.user.success;
1085
1086 diameap_sess_data->currentId = diameap_sm->eap_sm.currentId;
1087 diameap_sess_data->currentMethod = diameap_sm->eap_sm.currentMethod;
1088 diameap_sess_data->currentVendor = diameap_sm->eap_sm.currentVendor;
1089 diameap_sess_data->lastId = diameap_sm->eap_sm.lastId;
1090 diameap_sess_data->methodState = diameap_sm->eap_sm.methodState;
1091
1092 diameap_sess_data->methodData = diameap_sm->eap_sm.methodData;
1093 diameap_sm->eap_sm.methodData = NULL;
1094
1095 return 0;
1096}
1097
1098static void free_attrib(struct auth_attribute * auth_attrib)
1099{
1100 if (auth_attrib == NULL)
1101 {
1102 return;
1103 }
1104 if (auth_attrib->attrib != NULL)
1105 {
1106 free(auth_attrib->attrib);
1107 auth_attrib->attrib = NULL;
1108 }
1109 if (auth_attrib->op != NULL)
1110 {
1111 free(auth_attrib->op);
1112 auth_attrib->op = NULL;
1113 }
1114 if (auth_attrib->value != NULL)
1115 {
1116 free(auth_attrib->value);
1117 auth_attrib->value = NULL;
1118 }
1119 free(auth_attrib);
1120 auth_attrib = NULL;
1121}
1122
1123static void free_avp_attrib(struct avp_attribute * avp_attrib)
1124{
1125 if(avp_attrib){
1126 free(avp_attrib);
1127 avp_attrib = NULL;
1128 }
1129}
1130
1131static void free_ans_attrib(struct avp_attribute * ans_attrib)
1132{
1133 if(ans_attrib){
1134 if (ans_attrib->tofree == 1)
1135 {
1136 if(ans_attrib->value.os.data){
1137 free(ans_attrib->value.os.data);
1138 ans_attrib->value.os.data = NULL;
1139 }
1140 }
1141 free(ans_attrib);
1142 ans_attrib = NULL;
1143 }
1144}
1145
1146static int diameap_unlink_attributes_lists(
1147 struct diameap_state_machine * diameap_sm)
1148{
1149 TRACE_ENTRY("%p ", diameap_sm);
1150 if (diameap_sm == NULL)
1151 {
1152 return EINVAL;
1153 }
1154
1155 while (!FD_IS_LIST_EMPTY(&diameap_sm->attributes))
1156 {
1157 struct fd_list * item = (struct fd_list *) diameap_sm->attributes.next;
1158 struct auth_attribute * auth = (struct auth_attribute *) item;
1159 fd_list_unlink(item);
1160 free_attrib(auth);
1161 }
1162
1163 while (!FD_IS_LIST_EMPTY(&diameap_sm->req_attributes))
1164 {
1165 struct fd_list * item =
1166 (struct fd_list *) diameap_sm->req_attributes.next;
1167 struct avp_attribute * avp = (struct avp_attribute *) item;
1168 fd_list_unlink(item);
1169 free_avp_attrib(avp);
1170 }
1171
1172 while (!FD_IS_LIST_EMPTY(&diameap_sm->ans_attributes))
1173 {
1174 struct fd_list * item =
1175 (struct fd_list *) diameap_sm->ans_attributes.next;
1176 struct avp_attribute * avp_ans = (struct avp_attribute *) item;
1177 fd_list_unlink(item);
1178 free_ans_attrib(avp_ans);
1179 }
1180
1181 return 0;
1182}
1183
1184static void diameap_free(struct diameap_state_machine * diameap_sm)
1185{
1186
1187 if (diameap_sm != NULL)
1188 {
1189 if (diameap_sm->eap_sm.user.userid != NULL)
1190 {
1191 free(diameap_sm->eap_sm.user.userid);
1192 diameap_sm->eap_sm.user.userid = NULL;
1193 }
1194
1195 if (diameap_sm->eap_sm.user.password != NULL)
1196 {
1197 free(diameap_sm->eap_sm.user.password);
1198 diameap_sm->eap_sm.user.password = NULL;
1199 }
1200
1201 diameap_sm->eap_sm.selectedMethod = NULL;
1202
1203 if (diameap_sm->eap_sm.methodData != NULL)
1204 {
1205
1206 struct plugin * cplugin;
1207 if (diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
1208 diameap_sm->eap_sm.currentMethod, &cplugin))
1209 {
1210 TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sm->eap_sm.currentMethod,diameap_sm->eap_sm.currentVendor);
1211 }
1212
1213 if (cplugin->eap_method_free)
1214 {
1215 (*cplugin->eap_method_free)(diameap_sm->eap_sm.methodData);
1216 diameap_sm->eap_sm.methodData = NULL;
1217 }
1218 else
1219 {
1220 TRACE_DEBUG(INFO,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
1221 if (diameap_sm->eap_sm.methodData != NULL)
1222 {
1223 free(diameap_sm->eap_sm.methodData);
1224 diameap_sm->eap_sm.methodData = NULL;
1225 }
1226 }
1227 if (diameap_sm->eap_sm.methodData)
1228 {
1229 TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
1230 }
1231 }
1232
1233 if (diameap_sm->failedavp != NULL)
1234 {
1235 CHECK_FCT_DO(fd_msg_free(diameap_sm->failedavp), );
1236 }
1237
1238 if (diameap_sm->lastReqEAPavp != NULL)
1239 {
1240 CHECK_FCT_DO(fd_msg_free(diameap_sm->lastReqEAPavp), );
1241 }
1242
1243 CHECK_FCT_DO(diameap_unlink_attributes_lists(diameap_sm), );
1244
1245 free(diameap_sm);
1246 diameap_sm = NULL;
1247 }
1248
1249}
1250
1251static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
1252 char * attribute, struct avp_attribute ** avp_attrib, int unlink,
1253 int *ret)
1254{
1255 TRACE_ENTRY("%p %p %p %d %p", avp_attributes, attribute, avp_attrib, unlink, ret);
1256 if (avp_attributes == NULL)
1257 {
1258 return EINVAL;
1259 }
1260 if (attribute == NULL)
1261 {
1262 return EINVAL;
1263 }
1264 struct fd_list * attrib;
1265 for (attrib = avp_attributes->next; attrib != avp_attributes; attrib
1266 = attrib->next)
1267 {
1268 *avp_attrib = (struct avp_attribute *) attrib;
1269 if (strcmp((*avp_attrib)->attrib, attribute) == 0)
1270 {
1271 *ret = 0;
1272 if (unlink == 1)
1273 {
1274 fd_list_unlink(&(*avp_attrib)->chain);
1275 }
1276 return 0;
1277 }
1278 }
1279 *avp_attrib = NULL;
1280 *ret = 1;
1281 return 0;
1282}
1283
1284static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
1285 char * attribute, struct auth_attribute ** auth_attrib, int unlink,
1286 int *ret)
1287{
1288
1289 TRACE_ENTRY("%p %p %p %d %p", auth_attributes, attribute, auth_attrib, unlink, ret);
1290
1291 if (auth_attributes == NULL)
1292 {
1293 return EINVAL;
1294 }
1295 if (attribute == NULL)
1296 {
1297 return EINVAL;
1298 }
1299
1300 struct fd_list * attrib;
1301
1302 for (attrib = auth_attributes->next; attrib != auth_attributes; attrib
1303 = attrib->next)
1304 {
1305 *auth_attrib = (struct auth_attribute *) attrib;
1306 if (strcmp((*auth_attrib)->attrib, attribute) == 0)
1307 {
1308 *ret = 0;
1309 if (unlink == 1)
1310 {
1311 fd_list_unlink(&(*auth_attrib)->chain);
1312 }
1313 return 0;
1314 }
1315 }
1316 *auth_attrib = NULL;
1317 *ret = 1;
1318 return 0;
1319}
1320
1321static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
1322 char * attribute, struct avp_attribute ** ans_attrib, int unlink,
1323 int *ret)
1324{
1325 TRACE_ENTRY("%p %p %p %d %p", ans_attributes, attribute, ans_attrib, unlink, ret);
1326 if (ans_attributes == NULL)
1327 {
1328 return EINVAL;
1329 }
1330 if (attribute == NULL)
1331 {
1332 return EINVAL;
1333 }
1334 struct fd_list * attrib;
1335 for (attrib = ans_attributes->next; attrib != ans_attributes; attrib
1336 = attrib->next)
1337 {
1338 *ans_attrib = (struct avp_attribute *) attrib;
1339 if (strcmp((*ans_attrib)->attrib, attribute) == 0)
1340 {
1341 *ret = 0;
1342 if (unlink == 1)
1343 {
1344 fd_list_unlink(&(*ans_attrib)->chain);
1345 }
1346 return 0;
1347 }
1348 }
1349 *ans_attrib = NULL;
1350 *ret = 1;
1351 return 0;
1352}
1353
1354static int diameap_answer_avp_attributes(
1355 struct diameap_state_machine * diameap_sm)
1356{
1357 TRACE_ENTRY("%p",diameap_sm);
1358
1359 if (diameap_sm == NULL)
1360 {
1361 return EINVAL;
1362 }
1363 int ret1, ret2;
1364 struct avp_attribute * avp_attrib;
1365 struct avp_attribute * ans_attrib;
1366 struct auth_attribute * auth_attrib;
1367
1368 /* Authorization-Lifetime */
1369 {
1370 CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes, "Authorization-Lifetime", &avp_attrib,1, &ret1));
1371
1372 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Authorization-Lifetime", &auth_attrib,1, &ret2));
1373
1374 if ((ret1 == 1) && (ret2 == 0) && (auth_attrib != NULL))
1375 {
1376
1377 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1378
1379 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1380
1381 fd_list_init(&ans_attrib->chain, NULL);
1382
1383 ans_attrib->attrib = "Authorization-Lifetime";
1384
1385 ans_attrib->value.u32 = atoi(auth_attrib->value);
1386
1387 fd_list_insert_before(&diameap_sm->ans_attributes,
1388 &ans_attrib->chain);
1389
1390 free_attrib(auth_attrib);
1391
1392 }
1393 if ((ret1 == 0) && (ret2 == 1) && (avp_attrib != NULL))
1394 {
1395
1396 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1397
1398 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1399
1400 fd_list_init(&ans_attrib->chain, NULL);
1401
1402 ans_attrib->attrib = "Authorization-Lifetime";
1403
1404 ans_attrib->value.u32 = avp_attrib->value.u32;
1405
1406 fd_list_insert_before(&diameap_sm->ans_attributes,
1407 &ans_attrib->chain);
1408
1409 free_avp_attrib(avp_attrib);
1410
1411 }
1412 if ((ret1 == 0) && (ret2 == 0) && (auth_attrib != NULL) && (avp_attrib
1413 != NULL))
1414 {
1415
1416 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1417
1418 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1419 fd_list_init(&ans_attrib->chain, NULL);
1420 ans_attrib->attrib = "Authorization-Lifetime";
1421 if (avp_attrib->value.u32 < atoi(auth_attrib->value))
1422 {
1423 ans_attrib->value.u32 = avp_attrib->value.u32;
1424 }
1425 else
1426 {
1427 ans_attrib->value.u32 = atoi(auth_attrib->value);
1428 }
1429 fd_list_insert_before(&diameap_sm->ans_attributes,
1430 &ans_attrib->chain);
1431 free_avp_attrib(avp_attrib);
1432 free_attrib(auth_attrib);
1433 }
1434 }
1435
1436 /* Auth-Grace-Period */
1437 {
1438 CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes, "Auth-Grace-Period", &avp_attrib,1, &ret1));
1439
1440 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Auth-Grace-Period", &auth_attrib,1, &ret2));
1441
1442 if ((ret1 == 1) && (ret2 == 0) && (auth_attrib != NULL))
1443 {
1444 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1445 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1446 fd_list_init(&ans_attrib->chain, NULL);
1447 ans_attrib->attrib = "Auth-Grace-Period";
1448 ans_attrib->value.u32 = atoi(auth_attrib->value);
1449 fd_list_insert_before(&diameap_sm->ans_attributes,
1450 &ans_attrib->chain);
1451 free_attrib(auth_attrib);
1452 }
1453 if ((ret1 == 0) && (ret2 == 1) && (avp_attrib != NULL))
1454 {
1455 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1456 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1457 fd_list_init(&ans_attrib->chain, NULL);
1458 ans_attrib->attrib = "Auth-Grace-Period";
1459 ans_attrib->value.u32 = avp_attrib->value.u32;
1460 fd_list_insert_before(&diameap_sm->ans_attributes,
1461 &ans_attrib->chain);
1462 free_avp_attrib(avp_attrib);
1463 }
1464 if ((ret1 == 0) && (ret2 == 0) && (auth_attrib != NULL) && (avp_attrib
1465 != NULL))
1466 {
1467 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1468 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1469 fd_list_init(&ans_attrib->chain, NULL);
1470 ans_attrib->attrib = "Auth-Grace-Period";
1471 if (avp_attrib->value.u32 < atoi(auth_attrib->value))
1472 {
1473 ans_attrib->value.u32 = avp_attrib->value.u32;
1474 }
1475 else
1476 {
1477 ans_attrib->value.u32 = atoi(auth_attrib->value);
1478 }
1479 fd_list_insert_before(&diameap_sm->ans_attributes,
1480 &ans_attrib->chain);
1481 free_attrib(auth_attrib);
1482 free_avp_attrib(avp_attrib);
1483 }
1484 }
1485
1486 /* Auth-Session-State */
1487 {
1488 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Auth-Session-State", &auth_attrib,1, &ret2));
1489 if ((ret2 == 0) && (auth_attrib != NULL))
1490 {
1491 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1492 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1493 fd_list_init(&ans_attrib->chain, NULL);
1494 ans_attrib->attrib = "Auth-Session-State";
1495 ans_attrib->value.i32 = atoi(auth_attrib->value);
1496 fd_list_insert_before(&diameap_sm->ans_attributes,
1497 &ans_attrib->chain);
1498 free_attrib(auth_attrib);
1499 }
1500 }
1501
1502 /* Re-Auth-Request-Type */
1503 {
1504 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Re-Auth-Request-Type", &auth_attrib,1, &ret2));
1505 if ((ret2 == 0) && (auth_attrib != NULL))
1506 {
1507 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1508 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1509 fd_list_init(&ans_attrib->chain, NULL);
1510 ans_attrib->attrib = "Re-Auth-Request-Type";
1511 ans_attrib->value.i32 = atoi(auth_attrib->value);
1512 fd_list_insert_before(&diameap_sm->ans_attributes,
1513 &ans_attrib->chain);
1514 free_attrib(auth_attrib);
1515 }
1516 else
1517 {
1518 ans_attrib = NULL;
1519 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes, "Authorization-Lifetime", &ans_attrib,0, &ret1));
1520 if ((ret1 == 0) && (ans_attrib != NULL))
1521 {
1522 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1523 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1524 fd_list_init(&ans_attrib->chain, NULL);
1525 ans_attrib->attrib = "Re-Auth-Request-Type";
1526 ans_attrib->value.i32 = 0;
1527 fd_list_insert_before(&diameap_sm->ans_attributes,
1528 &ans_attrib->chain);
1529 }
1530 }
1531 }
1532
1533 /* Session-Timeout */
1534 {
1535 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Session-Timeout", &auth_attrib,1, &ret2));
1536 if ((ret2 == 0) && (auth_attrib != NULL))
1537 {
1538 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1539 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1540 fd_list_init(&ans_attrib->chain, NULL);
1541 ans_attrib->attrib = "Session-Timeout";
1542 ans_attrib->value.u32 = atoi(auth_attrib->value);
1543 fd_list_insert_before(&diameap_sm->ans_attributes,
1544 &ans_attrib->chain);
1545 free_attrib(auth_attrib);
1546 }
1547 }
1548
1549 /* Multi-Round-Time-Out */
1550 {
1551 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Multi-Round-Time-Out", &auth_attrib,1, &ret2));
1552 if ((ret2 == 0) && (auth_attrib != NULL))
1553 {
1554 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1555 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1556 fd_list_init(&ans_attrib->chain, NULL);
1557 ans_attrib->attrib = "Multi-Round-Time-Out";
1558 ans_attrib->value.u32 = atoi(auth_attrib->value);
1559 fd_list_insert_before(&diameap_sm->ans_attributes,
1560 &ans_attrib->chain);
1561 free_attrib(auth_attrib);
1562 }
1563 }
1564
1565 /* Acct-Interim-Interval */
1566 {
1567 CHECK_FCT(diameap_get_auth_attribute(&diameap_sm->attributes, "Acct-Interim-Interval", &auth_attrib,1, &ret2));
1568 if ((ret2 == 0) && (auth_attrib != NULL))
1569 {
1570 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
1571 memset(ans_attrib, 0, sizeof(struct avp_attribute));
1572 fd_list_init(&ans_attrib->chain, NULL);
1573 ans_attrib->attrib = "Acct-Interim-Interval";
1574 ans_attrib->value.u32 = atoi(auth_attrib->value);
1575 fd_list_insert_before(&diameap_sm->ans_attributes,
1576 &ans_attrib->chain);
1577 free_attrib(auth_attrib);
1578 }
1579 }
1580
1581 return 0;
1582}
1583
1584#define DIAMEAP_STR 1
1585#define DIAMEAP_NUM 2
1586
1587#define DIAMEAP_OP_NO 0 //Not supported operator
1588#define DIAMEAP_OP_EQ 1 //==
1589#define DIAMEAP_OP_GT 2 //>
1590#define DIAMEAP_OP_LT 3 //<
1591#define DIAMEAP_OP_GE 4 //>=
1592#define DIAMEAP_OP_LE 5 //<=
1593#define DIAMEAP_OP_NE 6 //!=
1594#define DIAMEAP_OP_EX 7 //~=
1595#define EQ(A,B) A==B ? TRUE : FALSE
1596#define GT(A,B) A>B ? TRUE : FALSE
1597#define GE(A,B) A>=B ? TRUE : FALSE
1598#define LT(A,B) A<B ? TRUE : FALSE
1599#define LE(A,B) A<=B ? TRUE : FALSE
1600#define NE(A,B) A!=B ? TRUE : FALSE
1601
1602int diameap_get_operator(char *operator)
1603{
1604 TRACE_ENTRY("%p",operator);
1605 if (strcmp(operator, "==") == 0)
1606 {
1607 return DIAMEAP_OP_EQ;
1608 }
1609 if (strcmp(operator, ">") == 0)
1610 {
1611 return DIAMEAP_OP_GT;
1612 }
1613 if (strcmp(operator, "<") == 0)
1614 {
1615 return DIAMEAP_OP_LT;
1616 }
1617 if (strcmp(operator, ">=") == 0)
1618 {
1619 return DIAMEAP_OP_GE;
1620 }
1621 if (strcmp(operator, "<=") == 0)
1622 {
1623 return DIAMEAP_OP_LE;
1624 }
1625 if (strcmp(operator, "!=") == 0)
1626 {
1627 return DIAMEAP_OP_NE;
1628 }
1629 if (strcmp(operator, "~=") == 0)
1630 {
1631 return DIAMEAP_OP_EX;
1632 }
1633 return DIAMEAP_OP_NO;
1634}
1635
1636boolean is_operator(int format_type, char * operator)
1637{
1638 TRACE_ENTRY("%d %p",format_type,operator);
1639 if ((format_type == DIAMEAP_STR) && (strcmp(operator, "==") == 0 || strcmp(
1640 operator, "~=") == 0 || strcmp(operator, "!=") == 0))
1641 {
1642 return TRUE;
1643 }
1644 if ((format_type == DIAMEAP_NUM) && (strcmp(operator, "~=") != 0))
1645 {
1646 return TRUE;
1647 }
1648 return FALSE;
1649}
1650
1651union avp_value diameap_get_num(char * num, enum dict_avp_basetype datatype)
1652{
1653 TRACE_ENTRY("%p %d",num,datatype);
1654 union avp_value val;
1655 switch (datatype)
1656 {
1657 case AVP_TYPE_INTEGER32://i32
1658 val.i32 = atoi(num);
1659 break;
1660 case AVP_TYPE_INTEGER64://i64
1661 val.i64 = atoll(num);
1662 break;
1663 case AVP_TYPE_UNSIGNED32://u32
1664 val.u32 = strtoul(num, NULL, 10);
1665 break;
1666 case AVP_TYPE_UNSIGNED64://u64
1667 val.u64 = strtoull(num, NULL, 10);
1668 break;
1669 case AVP_TYPE_FLOAT32://f32
1670 val.f32 = atof(num);
1671 break;
1672 case AVP_TYPE_FLOAT64://f64
1673 val.f64 = strtod(num, NULL);
1674 break;
1675 default:
1676 TRACE_DEBUG(INFO, "%sUnknown AVP Base Type.",DIAMEAP_EXTENSION)
1677 ;
1678 }
1679 return val;
1680}
1681
1682boolean diameap_check(union avp_value *A, char * B, char * operator,
1683 enum dict_avp_basetype datatype)
1684{
1685 TRACE_ENTRY("%p %p %p %d",A,B,operator,datatype);
1686 if (((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
1687 operator) == TRUE)) || ((datatype != AVP_TYPE_OCTETSTRING)
1688 && (datatype != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM,
1689 operator) == TRUE)))
1690 {
1691 switch (diameap_get_operator(operator))
1692 {
1693 case DIAMEAP_OP_EQ:
1694 if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
1695 operator) == TRUE))
1696 {
1697 if (strcmp((char *)A->os.data, B) == 0)
1698 return TRUE;
1699 else
1700 return FALSE;
1701 }
1702 else if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1703 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1704 == TRUE))
1705 {
1706
1707 switch (datatype)
1708 {
1709 case AVP_TYPE_INTEGER32://i32
1710 return EQ(A->i32,diameap_get_num(B, datatype).i32);
1711 break;
1712 case AVP_TYPE_INTEGER64://i64
1713 return EQ(A->i64,diameap_get_num(B, datatype).i64);
1714 break;
1715 case AVP_TYPE_UNSIGNED32://u32
1716 return EQ(A->u32,diameap_get_num(B, datatype).u32);
1717 break;
1718 case AVP_TYPE_UNSIGNED64://u64
1719 return EQ(A->u64,diameap_get_num(B, datatype).u64);
1720 break;
1721 case AVP_TYPE_FLOAT32://f32
1722 return EQ(A->f32,diameap_get_num(B, datatype).f32);
1723 break;
1724 case AVP_TYPE_FLOAT64://f64
1725 return EQ(A->f64,diameap_get_num(B, datatype).f64);
1726 break;
1727 default:
1728 return FALSE;
1729 }
1730 }
1731 else
1732 {
1733 return FALSE;
1734 }
1735 break;
1736 case DIAMEAP_OP_EX:
1737 {
1738 //string only
1739 boolean authorized = FALSE;
1740 if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
1741 operator) == TRUE))
1742 {
1743 regex_t rule_regexp;
1744 regcomp(&rule_regexp, B, REG_EXTENDED | REG_NOSUB | REG_ICASE);
1745 if (regexec(&rule_regexp, (char *)A->os.data, 0, NULL, 0) != 0)
1746 {
1747 authorized = FALSE;
1748 }
1749 else
1750 {
1751 authorized = TRUE;
1752 }
1753 regfree(&rule_regexp);
1754 }
1755 return authorized;
1756 }
1757 case DIAMEAP_OP_GT:
1758
1759 if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1760 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1761 == TRUE))
1762 {
1763 switch (datatype)
1764 {
1765 case AVP_TYPE_INTEGER32://i32
1766 return GT(A->i32, diameap_get_num(B, datatype).i32);
1767 break;
1768 case AVP_TYPE_INTEGER64://i64
1769 return GT(A->i64, diameap_get_num(B, datatype).i64);
1770 break;
1771 case AVP_TYPE_UNSIGNED32://u32
1772 return GT(A->u32, diameap_get_num(B, datatype).u32);
1773 break;
1774 case AVP_TYPE_UNSIGNED64://u64
1775 return GT(A->u64, diameap_get_num(B, datatype).u64);
1776 break;
1777 case AVP_TYPE_FLOAT32://f32
1778 return GT(A->f32, diameap_get_num(B, datatype).f32);
1779 break;
1780 case AVP_TYPE_FLOAT64://f64
1781 return GT(A->f64, diameap_get_num(B, datatype).f64);
1782 break;
1783 default:
1784 return FALSE;
1785 }
1786 }
1787 else
1788 {
1789 return FALSE;
1790 }
1791 break;
1792 case DIAMEAP_OP_GE:
1793 if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1794 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1795 == TRUE))
1796 {
1797 switch (datatype)
1798 {
1799 case AVP_TYPE_INTEGER32://i32
1800 return GE(A->i32,diameap_get_num(B, datatype).i32);
1801 break;
1802 case AVP_TYPE_INTEGER64://i64
1803 return GE(A->i64,diameap_get_num(B, datatype).i64);
1804 break;
1805 case AVP_TYPE_UNSIGNED32://u32
1806 return GE(A->u32,diameap_get_num(B, datatype).u32);
1807 break;
1808 case AVP_TYPE_UNSIGNED64://u64
1809 return GE(A->u64,diameap_get_num(B, datatype).u64);
1810 break;
1811 case AVP_TYPE_FLOAT32://f32
1812 return GE(A->f32,diameap_get_num(B, datatype).f32);
1813 break;
1814 case AVP_TYPE_FLOAT64://f64
1815 return GE(A->f64,diameap_get_num(B, datatype).f64);
1816 break;
1817 default:
1818 return FALSE;
1819 }
1820 }
1821 else
1822 {
1823 return FALSE;
1824 }
1825 break;
1826 case DIAMEAP_OP_LT:
1827 if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1828 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1829 == TRUE))
1830 {
1831 switch (datatype)
1832 {
1833 case AVP_TYPE_INTEGER32://i32
1834 return LT(A->i32, diameap_get_num(B, datatype).i32);
1835 break;
1836 case AVP_TYPE_INTEGER64://i64
1837 return LT(A->i64, diameap_get_num(B, datatype).i64);
1838 break;
1839 case AVP_TYPE_UNSIGNED32://u32
1840 return LT(A->u32, diameap_get_num(B, datatype).u32);
1841 break;
1842 case AVP_TYPE_UNSIGNED64://u64
1843 return LT(A->u64, diameap_get_num(B, datatype).u64);
1844 break;
1845 case AVP_TYPE_FLOAT32://f32
1846 return LT(A->f32, diameap_get_num(B, datatype).f32);
1847 break;
1848 case AVP_TYPE_FLOAT64://f64
1849 return LT(A->f64, diameap_get_num(B, datatype).f64);
1850 break;
1851 default:
1852 return FALSE;
1853 }
1854 }
1855 else
1856 {
1857 return FALSE;
1858 }
1859 break;
1860 case DIAMEAP_OP_LE:
1861 if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1862 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1863 == TRUE))
1864 {
1865 switch (datatype)
1866 {
1867 case AVP_TYPE_INTEGER32://i32
1868 return LE(A->i32, diameap_get_num(B, datatype).i32);
1869 break;
1870 case AVP_TYPE_INTEGER64://i64
1871 return LE(A->i64, diameap_get_num(B, datatype).i64);
1872 break;
1873 case AVP_TYPE_UNSIGNED32://u32
1874 return LE(A->u32, diameap_get_num(B, datatype).u32);
1875 break;
1876 case AVP_TYPE_UNSIGNED64://u64
1877 return LE(A->u64, diameap_get_num(B, datatype).u64);
1878 break;
1879 case AVP_TYPE_FLOAT32://f32
1880 return LE(A->f32, diameap_get_num(B, datatype).f32);
1881 break;
1882 case AVP_TYPE_FLOAT64://f64
1883 return LE(A->f64, diameap_get_num(B, datatype).f64);
1884 break;
1885 default:
1886 return FALSE;
1887 }
1888 }
1889 else
1890 {
1891 return FALSE;
1892 }
1893 break;
1894 case DIAMEAP_OP_NE:
1895 if ((datatype == AVP_TYPE_OCTETSTRING) && (is_operator(DIAMEAP_STR,
1896 operator) == TRUE))
1897 {
1898 if (strcmp((char *)A->os.data, B) != 0)
1899 return TRUE;
1900 else
1901 return FALSE;
1902 }
1903 else if ((datatype != AVP_TYPE_OCTETSTRING) && (datatype
1904 != AVP_TYPE_GROUPED) && (is_operator(DIAMEAP_NUM, operator)
1905 == TRUE))
1906 {
1907 switch (datatype)
1908 {
1909 case AVP_TYPE_INTEGER32://i32
1910 return NE(A->i32, diameap_get_num(B, datatype).i32);
1911 break;
1912 case AVP_TYPE_INTEGER64://i64
1913 return NE(A->i64, diameap_get_num(B, datatype).i64);
1914 break;
1915 case AVP_TYPE_UNSIGNED32://u32
1916 return NE(A->u32, diameap_get_num(B, datatype).u32);
1917 break;
1918 case AVP_TYPE_UNSIGNED64://u64
1919 return NE(A->u64, diameap_get_num(B, datatype).u64);
1920 break;
1921 case AVP_TYPE_FLOAT32://f32
1922 return NE(A->f32, diameap_get_num(B, datatype).f32);
1923 break;
1924 case AVP_TYPE_FLOAT64://f64
1925 return NE(A->f64, diameap_get_num(B, datatype).f64);
1926 break;
1927 default:
1928 return FALSE;
1929 }
1930 }
1931 else
1932 {
1933 return FALSE;
1934 }
1935 break;
1936 }
1937 }
1938 return FALSE;
1939}
1940
1941char * diameap_attribute_operator(char * op, int * toadd, boolean *isrule)
1942{
1943 TRACE_ENTRY("%p %p %p",op,toadd,isrule);
1944 char * attribute_op;
1945
1946 if (op[0] == '+')
1947 {
1948 *toadd = 1;
1949 }
1950 else if (op[strlen(op) - 1] == '+')
1951 {
1952 *toadd = 2;
1953 }
1954 else
1955 {
1956 *toadd = 0;
1957 }
1958
1959 switch (*toadd)
1960 {
1961 case 1:
1962 attribute_op = malloc(strlen(op));
1963 memset(attribute_op, 0, strlen(op));
1964 strncpy(attribute_op, op + 1, strlen(op) - 1);
1965 attribute_op[strlen(op)] = '\0';
1966 break;
1967 case 2:
1968 attribute_op = malloc(strlen(op));
1969 memset(attribute_op, 0, strlen(op));
1970 strncpy(attribute_op, op, strlen(op) - 1);
1971 attribute_op[strlen(op)] = '\0';
1972 break;
1973 default:
1974 attribute_op = malloc(strlen(op) + 1);
1975 memset(attribute_op, 0, strlen(op) + 1);
1976 strcpy(attribute_op, op);
1977 attribute_op[strlen(op) + 1] = '\0';
1978 }
1979 if (strcmp(attribute_op, "=") == 0)
1980 {
1981 *isrule = FALSE;
1982 *toadd = 2;
1983 }
1984 else
1985 {
1986 *isrule = TRUE;
1987 }
1988
1989 return attribute_op;
1990}
1991
1992int diameap_answer_set_attribute_valueA(union avp_value *A, int *tofree,
1993 enum dict_avp_basetype datatype, union avp_value * rval)
1994{
1995 TRACE_ENTRY("%p %p %d %p",A,tofree,datatype,rval);
1996 if (datatype == AVP_TYPE_OCTETSTRING)
1997 {
1998 CHECK_MALLOC(rval->os.data=malloc(A->os.len));
1999 memcpy(rval->os.data,A->os.data,A->os.len);
2000 rval->os.len = A->os.len;
2001 *tofree = 1;
2002 }
2003 else
2004 {
2005 *rval = *A;
2006 }
2007 return 0;
2008}
2009int diameap_answer_set_attribute_valueB(char * B, int *tofree,
2010 enum dict_avp_basetype datatype, union avp_value * rval)
2011{
2012 TRACE_ENTRY("%p %p %d %p",B,tofree,datatype,rval);
2013 if (datatype == AVP_TYPE_OCTETSTRING)
2014 {
2015 CHECK_MALLOC(rval->os.data=malloc(strlen(B)));
2016 memcpy(rval->os.data,B,strlen(B));
2017 rval->os.len = strlen(B);
2018
2019 *tofree = 1;
2020 }
2021 else
2022 {
2023
2024 *rval = diameap_get_num(B, datatype);
2025 }
2026
2027 return 0;
2028}
2029
2030static int diameap_attribute_limits(char * attrib, int * max, int *ret)
2031{
2032 TRACE_ENTRY("%p %p %p",attrib,max,ret);
2033 if (attrib == NULL)
2034 {
2035 return EINVAL;
2036 }
2037 int i;
2038 for (i = 0; i < sizeof(auth_avps); i++)
2039 {
2040 if (strcmp(auth_avps[i].avp_attribute, attrib) == 0)
2041 {
2042 *max = auth_avps[i].max;
2043 *ret = 0;
2044 return 0;
2045 }
2046 }
2047 *max = 0;
2048 *ret = 1;
2049 return 0;
2050}
2051
2052static int diameap_answer_authorization_attributes(
2053 struct diameap_state_machine * diameap_sm)
2054{
2055 TRACE_ENTRY("%p",diameap_sm);
2056
2057 if (diameap_sm == NULL)
2058 {
2059 return EINVAL;
2060 }
2061 boolean checked = TRUE;
2062
2063 struct fd_list * attrib;
2064 struct auth_attribute * auth_attrib;
2065 struct avp_attribute * avp_attrib;
2066 int ret;
2067
2068 for (attrib = (&diameap_sm->attributes)->next; attrib
2069 != (&diameap_sm->attributes); attrib = attrib->next)
2070 {
2071 avp_attrib = NULL;
2072 auth_attrib = (struct auth_attribute *) attrib;
2073
2074 int toadd = 0;
2075 boolean isrule = FALSE;
2076 char * op;
2077
2078 op = diameap_attribute_operator(auth_attrib->op, &toadd, &isrule);
2079
2080 struct dict_object * dobj;
2081 struct dict_avp_data avpdata;
2082 fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME,
2083 auth_attrib->attrib, &dobj, ENOENT);
2084 fd_dict_getval(dobj, &avpdata);
2085
2086 checked = TRUE;
2087 if (isrule == TRUE)
2088 {
2089 CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes,auth_attrib->attrib,&avp_attrib,0,&ret));
2090 if (ret == 0)
2091 {
2092 checked = diameap_check(&avp_attrib->value, auth_attrib->value,
2093 op, avpdata.avp_basetype);
2094 }
2095 }
2096 if (checked == TRUE && toadd != 0)
2097 {
2098
2099 struct avp_attribute * ans_attrib;
2100 int max = 0;
2101 diameap_attribute_limits(auth_attrib->attrib, &max, &ret);
2102 if ((ret == 0) && (max != 0))
2103 {
2104 if (max == 1)//only one
2105 {
2106 int ret = 0;
2107 diameap_get_ans_attribute(&diameap_sm->ans_attributes,
2108 auth_attrib->attrib, &ans_attrib, 0, &ret);
2109 if (ret == 1)
2110 {
2111 ans_attrib = NULL;
2112 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
2113 memset(ans_attrib, 0, sizeof(struct avp_attribute));
2114 fd_list_init(&ans_attrib->chain, NULL);
2115 ans_attrib->attrib = strdup(auth_attrib->attrib);
2116 if (toadd == 1)
2117 {
2118 diameap_answer_set_attribute_valueA(
2119 &avp_attrib->value, &ans_attrib->tofree,
2120 avpdata.avp_basetype, &ans_attrib->value);
2121 }
2122 else
2123 {
2124 diameap_answer_set_attribute_valueB(
2125 auth_attrib->value, &ans_attrib->tofree,
2126 avpdata.avp_basetype, &ans_attrib->value);
2127 }
2128 fd_list_insert_before(&diameap_sm->ans_attributes,
2129 &ans_attrib->chain);
2130
2131 }
2132 else
2133 {
2134 //an answer avp is already added
2135 }
2136 }
2137 else
2138 {
2139 ans_attrib = NULL;
2140 CHECK_MALLOC(ans_attrib = malloc(sizeof(struct avp_attribute)));
2141 memset(ans_attrib, 0, sizeof(struct avp_attribute));
2142 fd_list_init(&ans_attrib->chain, NULL);
2143 ans_attrib->attrib = auth_attrib->attrib;
2144 if (toadd == 1)
2145 {
2146 diameap_answer_set_attribute_valueA(&avp_attrib->value,
2147 &ans_attrib->tofree, avpdata.avp_basetype,
2148 &ans_attrib->value);
2149 }
2150 else
2151 {
2152 diameap_answer_set_attribute_valueB(auth_attrib->value,
2153 &ans_attrib->tofree, avpdata.avp_basetype,
2154 &ans_attrib->value);
2155 }
2156 fd_list_insert_before(&diameap_sm->ans_attributes,
2157 &ans_attrib->chain);
2158 }
2159 }
2160 }
2161 if (checked == FALSE)
2162 {
2163
2164 diameap_sm->authorized = FALSE;
2165 return 0;
2166 }
2167 }
2168 diameap_sm->authorized = checked;
2169 return 0;
2170
2171 return 0;
2172}
2173
2174
2175
2176static int diameap_policy_decision(struct diameap_state_machine * diameap_sm,
2177 struct diameap_eap_interface *eap_i)
2178{
2179 TRACE_ENTRY("%p %p",diameap_sm,eap_i);
2180
2181 if ((eap_i->aaaFail == TRUE) && (eap_i->aaaSuccess == TRUE))
2182 {
2183 TRACE_DEBUG(INFO,"%s Incorrect EAP decision. EAP process should not return both success and failure for the same session.(please report this problem.)",DIAMEAP_EXTENSION);
2184 return -1;
2185 }
2186
2187 if (eap_i->aaaFail == TRUE)
2188 {
2189 diameap_sm->result_code = 4001; /* DIAMETER_AUTHENTICATION_REJECTED 4001 */
2190 diameap_sm->authFailure = TRUE;
2191 TRACE_DEBUG(FULL+1,"%s Auth failure: Authentication Rejected ",DIAMEAP_EXTENSION);
2192 return 0;
2193 }
2194
2195 if (eap_i->aaaSuccess == FALSE)
2196 {
2197 diameap_sm->result_code = 1001; /* DIAMETER_MULTI_ROUND_AUTH 1001 */
2198 return 0;
2199 }
2200
2201 if (eap_i->aaaSuccess == TRUE)
2202 {
2203 if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
2204 {
2205 if ((diameap_sm->verify_authorization == TRUE)
2206 && (diameap_sm->result_code == 0))
2207 {
2208 diameap_sm->result_code = 2001; /* DIAMETER_SUCCESS 2001 */
2209 diameap_sm->authSuccess = TRUE;
2210 TRACE_DEBUG(FULL+1,"%s Auth success: Authorization and Authentication ",DIAMEAP_EXTENSION);
2211 return 0;
2212 }
2213 else
2214 {
2215 //
2216 }
2217 }
2218 if (diameap_sm->auth_request_val == AUTHENTICATE_ONLY)
2219 {
2220 diameap_sm->result_code = 2001; /* DIAMETER_SUCCESS 2001 */
2221 diameap_sm->authSuccess = TRUE;
2222 TRACE_DEBUG(FULL+1,"%s Auth success: Authentication Only ",DIAMEAP_EXTENSION);
2223 return 0;
2224 }
2225 }
2226
2227 return 0;
2228}
2229
2230static int diameap_add_avps(struct diameap_state_machine * diameap_sm,
2231 struct msg * ans, struct msg * req)
2232{
2233 TRACE_ENTRY("%p %p %p",diameap_sm,ans,req);
2234
2235 struct avp * avp, *avp2;
2236 struct avp_hdr * avpdata;
2237 union avp_value avp_val;
2238 int ret = 0;
2239
2240 /* Origin-Host AVP and Origin-Realm AVP */
2241 {
2242 CHECK_FCT( fd_msg_add_origin ( ans, 0 ) );
2243 }
2244
2245 /* Auth-Application-Id AVP */
2246 {
2247 CHECK_FCT(fd_msg_avp_new(dataobj_auth_application_id, 0, &avp));
2248 avp_val.u32 = diameap_config->application_id;
2249 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2250 CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
2251 }
2252
2253 /* Auth-Request-Type AVP
2254 * Enumerated values:
2255 * AUTHENTICATE_ONLY 1
2256 * AUTHORIZE_ONLY 2
2257 * AUTHORIZE_AUTHENTICATE 3 */
2258 {
2259 CHECK_FCT(fd_msg_avp_new(dataobj_auth_request_type, 0, &avp));
2260 if (!diameap_config->authorize)
2261 {
2262 //AUTHENTICATE ONLY
2263 avp_val.i32 = AUTHENTICATE_ONLY;
2264 }
2265 else
2266 {
2267 if (diameap_sm->auth_request_val == 3)
2268 {
2269 //AUTHORIZE_AUTHENTICATE
2270 avp_val.i32 = AUTHORIZE_AUTHENTICATE;
2271 }
2272 else
2273 {
2274 //AUTHENTICATE_ONLY
2275 avp_val.i32 = AUTHENTICATE_ONLY;
2276 }
2277 }
2278 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2279 CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
2280 }
2281
2282 /* Proxy-Info AVP */
2283 CHECK_FCT(fd_msg_search_avp(req, dataobj_proxy_info, &avp));
2284 if (avp != NULL)
2285 {
2286 CHECK_FCT(fd_msg_avp_hdr ( avp, &avpdata ) );
2287 u32 proxy_info_code = avpdata->avp_code;
2288 int depth;
2289 do
2290 {
2291 ret = 0;
2292 depth = 0;
2293 CHECK_FCT(fd_msg_avp_hdr ( avp, &avpdata ) );
2294 if (avpdata->avp_code == proxy_info_code)
2295 {
2296 CHECK_FCT(fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp));
2297 }
2298 ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
2299 avp = avp2;
2300 } while ((avp != NULL) && (ret == 0) && (ret == 0));
2301 }
2302
2303 if (diameap_sm->eap_sm.user.userid)
2304 {
2305 /* User-Name AVP */
2306 {
2307 CHECK_FCT(fd_msg_avp_new(dataobj_user_name, 0, &avp));
2308
2309 if (diameap_sm->privateUser == FALSE)
2310 {
2311
2312 avp_val.os.data = diameap_sm->eap_sm.user.userid;
2313 avp_val.os.len = diameap_sm->eap_sm.user.useridLength;
2314 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2315 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2316 }
2317 else
2318 {
2319
2320 }
2321
2322 }
2323 }
2324 return 0;
2325}
2326
2327static int diameap_add_user_sessions_avps(
2328 struct diameap_state_machine * diameap_sm, struct msg * ans)
2329{
2330 TRACE_ENTRY("%p %p",diameap_sm,ans);
2331
2332 struct avp * avp;
2333 union avp_value avp_val;
2334 int ret;
2335
2336 /* Authorization-Lifetime AVP */
2337 {
2338 struct avp_attribute * ans_attrib;
2339 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Authorization-Lifetime",&ans_attrib,1,&ret));
2340 if ((ret == 0) && (ans_attrib != NULL))
2341 {
2342 CHECK_FCT(fd_msg_avp_new(dataobj_authorization_lifetime, 0, &avp));
2343 avp_val.u32 = ans_attrib->value.u32;
2344 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2345 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2346 free_ans_attrib(ans_attrib);
2347 }
2348 }
2349
2350 /* Auth-Grace-Period AVP */
2351 {
2352 struct avp_attribute * ans_attrib;
2353 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Auth-Grace-Period",&ans_attrib,1,&ret));
2354 if ((ret == 0) && (ans_attrib != NULL))
2355 {
2356 CHECK_FCT(fd_msg_avp_new(dataobj_auth_grace_period, 0, &avp));
2357 avp_val.u32 = ans_attrib->value.u32;
2358 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2359 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2360 free_ans_attrib(ans_attrib);
2361 }
2362 }
2363
2364 /* Auth-Session-State AVP */
2365 {
2366 struct avp_attribute * ans_attrib;
2367 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Auth-Session-State",&ans_attrib,1,&ret));
2368 if ((ret == 0) && (ans_attrib != NULL))
2369 {
2370 CHECK_FCT(fd_msg_avp_new(dataobj_auth_session_state, 0, &avp));
2371 avp_val.i32 = ans_attrib->value.i32;
2372 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2373 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2374 free_ans_attrib(ans_attrib);
2375 }
2376 }
2377
2378 /* Re-Auth-Request-Type AVP */
2379 {
2380 struct avp_attribute * ans_attrib;
2381 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Re-Auth-Request-Type",&ans_attrib,1,&ret));
2382 if ((ret == 0) && (ans_attrib != NULL))
2383 {
2384 CHECK_FCT(fd_msg_avp_new(dataobj_re_auth_request_type, 0, &avp));
2385 avp_val.i32 = ans_attrib->value.i32;
2386 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2387 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2388 free_ans_attrib(ans_attrib);
2389 }
2390 }
2391
2392 /* Session-Timeout AVP */
2393 {
2394 struct avp_attribute * ans_attrib;
2395 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Session-Timeout",&ans_attrib,1,&ret));
2396 if ((ret == 0) && (ans_attrib != NULL))
2397 {
2398 CHECK_FCT(fd_msg_avp_new(dataobj_session_timeout, 0, &avp));
2399 avp_val.u32 = ans_attrib->value.u32;
2400 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2401 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2402 free_ans_attrib(ans_attrib);
2403 }
2404 }
2405
2406 /* Acct-Interim-Interval AVP */
2407 {
2408 struct avp_attribute * ans_attrib;
2409 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Acct-Interim-Interval",&ans_attrib,1,&ret));
2410 if ((ret == 0) && (ans_attrib != NULL))
2411 {
2412 CHECK_FCT(fd_msg_avp_new(dataobj_acct_interim_interval, 0, &avp));
2413 avp_val.u32 = ans_attrib->value.u32;
2414 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2415 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2416 free_ans_attrib(ans_attrib);
2417 }
2418 }
2419 return 0;
2420}
2421
2422static int diameap_add_authorization_avps(
2423 struct diameap_state_machine * diameap_sm, struct msg * ans)
2424{
2425
2426 TRACE_ENTRY("%p %p",diameap_sm, ans);
2427
2428 struct avp * avp;
2429 union avp_value avp_val;
2430 int ret;
2431
2432 if (diameap_sm == NULL)
2433 {
2434 return EINVAL;
2435 }
2436 if (ans == NULL)
2437 {
2438 return EINVAL;
2439 }
2440
2441 /* Reply-Message */
2442 {
2443 struct avp_attribute * ans_attrib;
2444 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Reply-Message",&ans_attrib,1,&ret));
2445 while ((ret == 0) && (ans_attrib != NULL))
2446 {
2447 CHECK_FCT(fd_msg_avp_new(dataobj_reply_message, 0, &avp));
2448 avp_val.os.data = ans_attrib->value.os.data;
2449 avp_val.os.len = ans_attrib->value.os.len;
2450 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2451 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2452 free_ans_attrib(ans_attrib);
2453 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Reply-Message",&ans_attrib,1,&ret));
2454 }
2455
2456 }
2457
2458 /* Service-Type */
2459 {
2460 struct avp_attribute * ans_attrib;
2461 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Service-Type",&ans_attrib,1,&ret));
2462 if ((ret == 0) && (ans_attrib != NULL))
2463 {
2464 CHECK_FCT(fd_msg_avp_new(dataobj_service_type, 0, &avp));
2465 avp_val.i32 = ans_attrib->value.i32;
2466 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2467 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2468 free_ans_attrib(ans_attrib);
2469 }
2470 }
2471
2472 /* Callback-Number */
2473 {
2474 struct avp_attribute * ans_attrib;
2475 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Callback-Number",&ans_attrib,1,&ret));
2476 if ((ret == 0) && (ans_attrib != NULL))
2477 {
2478 CHECK_FCT(fd_msg_avp_new(dataobj_callback_number, 0, &avp));
2479 avp_val.os.data = ans_attrib->value.os.data;
2480 avp_val.os.len = ans_attrib->value.os.len;
2481 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2482 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2483 free_ans_attrib(ans_attrib);
2484 }
2485 }
2486
2487 /* Callback-Id */
2488 {
2489 struct avp_attribute * ans_attrib;
2490 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Callback-Id",&ans_attrib,1,&ret));
2491 if ((ret == 0) && (ans_attrib != NULL))
2492 {
2493 CHECK_FCT(fd_msg_avp_new(dataobj_callback_id, 0, &avp));
2494 avp_val.os.data = ans_attrib->value.os.data;
2495 avp_val.os.len = ans_attrib->value.os.len;
2496 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2497 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2498 free_ans_attrib(ans_attrib);
2499 }
2500 }
2501
2502 /* Idle-Timeout */
2503 {
2504 struct avp_attribute * ans_attrib;
2505 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Idle-Timeout",&ans_attrib,1,&ret));
2506 if ((ret == 0) && (ans_attrib != NULL))
2507 {
2508 CHECK_FCT(fd_msg_avp_new(dataobj_idle_timeout, 0, &avp));
2509 avp_val.u32 = ans_attrib->value.u32;
2510 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2511 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2512 free_ans_attrib(ans_attrib);
2513 }
2514 }
2515
2516 /* NAS-Filter-Rule */
2517 {
2518 struct avp_attribute * ans_attrib;
2519 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"NAS-Filter-Rule",&ans_attrib,1,&ret));
2520 if ((ret == 0) && (ans_attrib != NULL))
2521 {
2522 CHECK_FCT(fd_msg_avp_new(dataobj_nas_filter_rule, 0, &avp));
2523 avp_val.u32 = ans_attrib->value.u32;
2524 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2525 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2526 free_ans_attrib(ans_attrib);
2527 }
2528 }
2529
2530 /* Filter-Id */
2531 {
2532 struct avp_attribute * ans_attrib;
2533 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Filter-Id",&ans_attrib,1,&ret));
2534 while ((ret == 0) && (ans_attrib != NULL))
2535 {
2536 CHECK_FCT(fd_msg_avp_new(dataobj_filter_id, 0, &avp));
2537 avp_val.os.data = ans_attrib->value.os.data;
2538 avp_val.os.len = ans_attrib->value.os.len;
2539 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2540 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2541 free_ans_attrib(ans_attrib);
2542 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Filter-Id",&ans_attrib,1,&ret));
2543 }
2544
2545 }
2546
2547 /* Configuration-Token */
2548 {
2549 struct avp_attribute * ans_attrib;
2550 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Configuration-Token",&ans_attrib,1,&ret));
2551 while ((ret == 0) && (ans_attrib != NULL))
2552 {
2553 CHECK_FCT(fd_msg_avp_new(dataobj_configuration_token, 0, &avp));
2554 avp_val.os.data = ans_attrib->value.os.data;
2555 avp_val.os.len = ans_attrib->value.os.len;
2556 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2557 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2558 free_ans_attrib(ans_attrib);
2559 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Configuration-Token",&ans_attrib,1,&ret));
2560 }
2561 }
2562
2563 /* QoS-Filter-Rule */
2564 {
2565 struct avp_attribute * ans_attrib;
2566 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"QoS-Filter-Rule",&ans_attrib,1,&ret));
2567 while ((ret == 0) && (ans_attrib != NULL))
2568 {
2569 CHECK_FCT(fd_msg_avp_new(dataobj_qos_filter_rule, 0, &avp));
2570 avp_val.os.data = ans_attrib->value.os.data;
2571 avp_val.os.len = ans_attrib->value.os.len;
2572 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2573 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2574 free_ans_attrib(ans_attrib);
2575 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"QoS-Filter-Rule",&ans_attrib,1,&ret));
2576 }
2577
2578 }
2579
2580 /* Framed-Protocol */
2581 {
2582 struct avp_attribute * ans_attrib;
2583 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Protocol",&ans_attrib,1,&ret));
2584 if ((ret == 0) && (ans_attrib != NULL))
2585 {
2586 CHECK_FCT(fd_msg_avp_new(dataobj_framed_protocol, 0, &avp));
2587 avp_val.i32 = ans_attrib->value.i32;
2588 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2589 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2590 free_ans_attrib(ans_attrib);
2591 }
2592 }
2593
2594 /* Framed-Routing */
2595 {
2596 struct avp_attribute * ans_attrib;
2597 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Routing",&ans_attrib,1,&ret));
2598 if ((ret == 0) && (ans_attrib != NULL))
2599 {
2600 CHECK_FCT(fd_msg_avp_new(dataobj_framed_routing, 0, &avp));
2601 avp_val.i32 = ans_attrib->value.i32;
2602 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2603 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2604 free_ans_attrib(ans_attrib);
2605 }
2606
2607 }
2608
2609 /* Framed-MTU */
2610 {
2611 struct avp_attribute * ans_attrib;
2612 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-MTU",&ans_attrib,1,&ret));
2613 if ((ret == 0) && (ans_attrib != NULL))
2614 {
2615 CHECK_FCT(fd_msg_avp_new(dataobj_framed_mtu, 0, &avp));
2616 avp_val.u32 = ans_attrib->value.u32;
2617 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2618 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2619 free_ans_attrib(ans_attrib);
2620 }
2621 }
2622
2623 /* Framed-Compression */
2624 {
2625 struct avp_attribute * ans_attrib;
2626 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Compression",&ans_attrib,1,&ret));
2627 while ((ret == 0) && (ans_attrib != NULL))
2628 {
2629 CHECK_FCT(fd_msg_avp_new(dataobj_framed_compression, 0, &avp));
2630 avp_val.i32 = ans_attrib->value.i32;
2631 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2632 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2633 free_ans_attrib(ans_attrib);
2634 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Compression",&ans_attrib,1,&ret));
2635 }
2636
2637 }
2638 /* Framed-IP-Address */
2639 {
2640 struct avp_attribute * ans_attrib;
2641 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IP-Address",&ans_attrib,1,&ret));
2642 if ((ret == 0) && (ans_attrib != NULL))
2643 {
2644 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ip_address, 0, &avp));
2645 avp_val.os.data = ans_attrib->value.os.data;
2646 avp_val.os.len = ans_attrib->value.os.len;
2647 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2648 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2649 free_ans_attrib(ans_attrib);
2650 }
2651 }
2652
2653 /* Framed-IP-Netmask */
2654 {
2655 struct avp_attribute * ans_attrib;
2656 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IP-Netmask",&ans_attrib,1,&ret));
2657 if ((ret == 0) && (ans_attrib != NULL))
2658 {
2659 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ip_netmask, 0, &avp));
2660 avp_val.os.data = ans_attrib->value.os.data;
2661 avp_val.os.len = ans_attrib->value.os.len;
2662 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2663 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2664 free_ans_attrib(ans_attrib);
2665 }
2666 }
2667
2668 /* Framed-Route */
2669 {
2670 struct avp_attribute * ans_attrib;
2671 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Route",&ans_attrib,1,&ret));
2672 while ((ret == 0) && (ans_attrib != NULL))
2673 {
2674 CHECK_FCT(fd_msg_avp_new(dataobj_framed_route, 0, &avp));
2675 avp_val.os.data = ans_attrib->value.os.data;
2676 avp_val.os.len = ans_attrib->value.os.len;
2677 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2678 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2679 free_ans_attrib(ans_attrib);
2680 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Route",&ans_attrib,1,&ret));
2681 }
2682 }
2683
2684 /* Framed-Pool */
2685 {
2686 struct avp_attribute * ans_attrib;
2687 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Pool",&ans_attrib,1,&ret));
2688 if ((ret == 0) && (ans_attrib != NULL))
2689 {
2690 CHECK_FCT(fd_msg_avp_new(dataobj_framed_pool, 0, &avp));
2691 avp_val.os.data = ans_attrib->value.os.data;
2692 avp_val.os.len = ans_attrib->value.os.len;
2693 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2694 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2695 free_ans_attrib(ans_attrib);
2696 }
2697 }
2698
2699 /* Framed-Interface-Id */
2700 {
2701 struct avp_attribute * ans_attrib;
2702 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-Interface-Id",&ans_attrib,1,&ret));
2703 if ((ret == 0) && (ans_attrib != NULL))
2704 {
2705 CHECK_FCT(fd_msg_avp_new(dataobj_framed_interface_id, 0, &avp));
2706 avp_val.u64 = ans_attrib->value.u64;
2707 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2708 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2709 free_ans_attrib(ans_attrib);
2710 }
2711 }
2712
2713 /* Framed-IPv6-Prefix */
2714 {
2715 struct avp_attribute * ans_attrib;
2716 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Prefix",&ans_attrib,1,&ret));
2717 while ((ret == 0) && (ans_attrib != NULL))
2718 {
2719 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_prefix, 0, &avp));
2720 avp_val.os.data = ans_attrib->value.os.data;
2721 avp_val.os.len = ans_attrib->value.os.len;
2722 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2723 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2724 free_ans_attrib(ans_attrib);
2725 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Prefix",&ans_attrib,1,&ret));
2726 }
2727 }
2728
2729 /* Framed-IPv6-Route */
2730 {
2731 struct avp_attribute * ans_attrib;
2732 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Route",&ans_attrib,1,&ret));
2733 while ((ret == 0) && (ans_attrib != NULL))
2734 {
2735 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_route, 0, &avp));
2736 avp_val.os.data = ans_attrib->value.os.data;
2737 avp_val.os.len = ans_attrib->value.os.len;
2738 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2739 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2740 free_ans_attrib(ans_attrib);
2741 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Route",&ans_attrib,1,&ret));
2742 }
2743 }
2744
2745 /* Framed-IPv6-Pool */
2746 {
2747 struct avp_attribute * ans_attrib;
2748 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPv6-Pool",&ans_attrib,1,&ret));
2749 if ((ret == 0) && (ans_attrib != NULL))
2750 {
2751 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipv6_pool, 0, &avp));
2752 avp_val.os.data = ans_attrib->value.os.data;
2753 avp_val.os.len = ans_attrib->value.os.len;
2754 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2755 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2756 free_ans_attrib(ans_attrib);
2757 }
2758 }
2759
2760 /* Framed-IPX-Network */
2761 {
2762 struct avp_attribute * ans_attrib;
2763 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-IPX-Network",&ans_attrib,1,&ret));
2764 if ((ret == 0) && (ans_attrib != NULL))
2765 {
2766 CHECK_FCT(fd_msg_avp_new(dataobj_framed_ipx_network, 0, &avp));
2767 avp_val.u32 = ans_attrib->value.u32;
2768 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2769 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2770 free_ans_attrib(ans_attrib);
2771 }
2772
2773 }
2774 /* Framed-AppleTalk-Link */
2775 {
2776 struct avp_attribute * ans_attrib;
2777 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Link",&ans_attrib,1,&ret));
2778 if ((ret == 0) && (ans_attrib != NULL))
2779 {
2780 CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_link, 0, &avp));
2781 avp_val.u32 = ans_attrib->value.u32;
2782 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2783 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2784 free_ans_attrib(ans_attrib);
2785 }
2786
2787 }
2788
2789 /* Framed-AppleTalk-Network */
2790 {
2791 struct avp_attribute * ans_attrib;
2792 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Network",&ans_attrib,1,&ret));
2793 while ((ret == 0) && (ans_attrib != NULL))
2794 {
2795 CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_network, 0, &avp));
2796 avp_val.u32 = ans_attrib->value.u32;
2797 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2798 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2799 free_ans_attrib(ans_attrib);
2800 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Network",&ans_attrib,1,&ret));
2801 }
2802
2803 }
2804
2805 /* Framed-AppleTalk-Zone */
2806 {
2807 struct avp_attribute * ans_attrib;
2808 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-AppleTalk-Zone",&ans_attrib,1,&ret));
2809 if ((ret == 0) && (ans_attrib != NULL))
2810 {
2811 CHECK_FCT(fd_msg_avp_new(dataobj_framed_appletalk_zone, 0, &avp));
2812 avp_val.os.data = ans_attrib->value.os.data;
2813 avp_val.os.len = ans_attrib->value.os.len;
2814 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2815 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2816 free_ans_attrib(ans_attrib);
2817 }
2818 }
2819
2820 /* Tunneling */
2821 //
2822
2823 /* State */
2824 //
2825 return 0;
2826}
2827
2828static int diameap_add_result_code(struct diameap_state_machine * diameap_sm,
2829 struct msg * ans, struct session * sess)
2830{
2831 TRACE_ENTRY("%p %p",diameap_sm,ans);
2832 struct avp * avp;
2833 union avp_value avp_val;
2834 int ret;
2835
2836 /* Result-Code AVP */
2837 CHECK_FCT(fd_msg_avp_new(dataobj_result_code, 0, &avp));
2838 avp_val.u32 = diameap_sm->result_code;
2839 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2840 /* Add Result-Code AVP to the message */
2841 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2842
2843 /* Multi_Round_Time_Out AVP */
2844 if (diameap_sm->result_code == 1001)
2845 {
2846 struct timespec sess_timeout;
2847 CHECK_FCT(fd_msg_avp_new(dataobj_multi_round_time_out, 0, &avp));
2848 struct avp_attribute * ans_attrib;
2849 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Multi-Round-Time-Out",&ans_attrib,1,&ret));
2850 if ((ret == 0) && (ans_attrib != NULL))
2851 {
2852 avp_val.u32 = ans_attrib->value.u32;
2853 /* Update the session timeout with multi-round-time-out value */
2854 CHECK_SYS(clock_gettime(CLOCK_REALTIME,&sess_timeout));
2855 sess_timeout.tv_sec += diameap_config->multi_round_time_out;
2856 CHECK_FCT(fd_sess_settimeout(sess, &sess_timeout));
2857 free_ans_attrib(ans_attrib);
2858 }
2859 else
2860 {
2861 avp_val.u32 = diameap_config->multi_round_time_out;
2862 /* Update the session timeout with multi-round-time-out value */
2863 CHECK_SYS(clock_gettime(CLOCK_REALTIME,&sess_timeout));
2864 sess_timeout.tv_sec += diameap_config->multi_round_time_out;
2865 CHECK_FCT(fd_sess_settimeout(sess, &sess_timeout));
2866 }
2867 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2868 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2869 }
2870 return 0;
2871}
2872
2873static int diameap_add_eap_payload(struct diameap_state_machine * diameap_sm,
2874 struct msg * ans, struct diameap_eap_interface *eap_i)
2875{
2876 TRACE_ENTRY("%p %p",diameap_sm,ans);
2877 struct avp * avp;
2878 union avp_value avp_val;
2879 int ret;
2880 u32 Framed_MTU = 1500; //1500 default value
2881 u32 NAS_Port_Type_HeaderLength = 4;
2882 int EAP_Max_Length = 0;
2883
2884 /* get Framed-MTU AVP value */
2885 {
2886 struct avp_attribute * ans_attrib;
2887 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"Framed-MTU",&ans_attrib,0,&ret));
2888 if ((ret == 0) && (ans_attrib != NULL))
2889 {
2890 Framed_MTU = ans_attrib->value.u32;
2891 }
2892 }
2893
2894 /* get NAS-Port-Type AVP value */
2895 {
2896 struct avp_attribute * ans_attrib;
2897 CHECK_FCT(diameap_get_ans_attribute(&diameap_sm->ans_attributes,"NAS-Port-Type",&ans_attrib,0,&ret));
2898 if ((ret == 0) && (ans_attrib != NULL))
2899 {
2900 // = ans_attrib->value.i32;
2901 }
2902 }
2903
2904 //TD take the link type into consideration when calculating EAP_MAX_Length
2905 EAP_Max_Length = Framed_MTU - NAS_Port_Type_HeaderLength;
2906
2907 if (eap_i->aaaEapReqData.length <= EAP_Max_Length)
2908 {
2909
2910 /* EAP-Payload AVP */
2911 {
2912 CHECK_FCT(fd_msg_avp_new(dataobj_eap_payload, 0, &avp));
2913 avp_val.os.data = eap_i->aaaEapReqData.data;
2914 avp_val.os.len = eap_i->aaaEapReqData.length;
2915 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2916 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2917
2918 if (diameap_sm->lastReqEAPavp != NULL)
2919 {
2920 fd_msg_free(diameap_sm->lastReqEAPavp);
2921 diameap_sm->lastReqEAPavp = NULL;
2922 }
2923
2924 CHECK_FCT(fd_msg_avp_new(dataobj_eap_payload, 0, &diameap_sm->lastReqEAPavp));
2925 avp_val.os.data = eap_i->aaaEapReqData.data;
2926 avp_val.os.len = eap_i->aaaEapReqData.length;
2927 CHECK_FCT(fd_msg_avp_setvalue(diameap_sm->lastReqEAPavp, &avp_val));
2928
2929 }
2930 }
2931 else
2932 {
2933 //if EAP Packet length > EAP_Max_Length
2934 }
2935 return 0;
2936}
2937
2938static int diameap_send(struct msg ** rmsg)
2939{
2940 TRACE_ENTRY("%p",rmsg);
2941 CHECK_FCT( fd_msg_send( rmsg, NULL, NULL));
2942 return 0;
2943}
2944
2945static int diameap_add_eap_success_avps(
2946 struct diameap_state_machine * diameap_sm, struct msg * ans,
2947 struct diameap_eap_interface *eap_i)
2948{
2949 TRACE_ENTRY("%p %p %p",diameap_sm,ans,eap_i);
2950 struct avp * avp;
2951 union avp_value avp_val;
2952 int ret;
2953
2954 /* EAP-Master-Session-Key AVP */
2955 if (eap_i->aaaEapKeyAvailable == TRUE)
2956 {
2957 CHECK_FCT(fd_msg_avp_new(dataobj_eap_master_session_key, 0, &avp));
2958 avp_val.os.data = eap_i->aaaEapMSKData;
2959 avp_val.os.len = eap_i->aaaEapMSKLength;
2960 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2961 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2962
2963 }
2964
2965 /* EAP-Key-Name AVP */
2966 struct avp_attribute * avp_attrib = NULL;
2967
2968 CHECK_FCT(diameap_get_avp_attribute(&diameap_sm->req_attributes,"EAP-Key-Name",&avp_attrib,1,&ret))
2969 if ((avp_attrib != NULL) && (ret != 1))
2970 {
2971 if (avp_attrib->value.os.len == 0)
2972 {
2973 CHECK_FCT(fd_msg_avp_new(dataobj_eap_key_name, 0, &avp));
2974 avp_val.os.data = NULL;//
2975 avp_val.os.len = 0;//
2976 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
2977 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
2978 free_avp_attrib(avp_attrib);
2979 }
2980 }
2981
2982 return 0;
2983}
2984
2985int diameap_authorize(struct diameap_state_machine * diameap_sm)
2986{
2987 TRACE_ENTRY("%p",diameap_sm);
2988
2989 CHECK_FCT(diameap_authorization_get_attribs(&diameap_sm->eap_sm.user, &diameap_sm->attributes));
2990
2991 diameap_sm->authorized = TRUE;
2992
2993 CHECK_FCT_DO(diameap_answer_authorization_attributes(diameap_sm),
2994 );
2995 if (diameap_sm->authorized == FALSE)
2996 {
2997 diameap_sm->result_code = 4001; /* DIAMETER_AUTHENTICATION_REJECTED 4001 */
2998 }
2999 return 0;
3000}
3001
3002static int diameap_add_accounting_eap_auth_method(
3003 struct diameap_state_machine * diameap_sm, struct msg * ans)
3004{
3005 TRACE_ENTRY("%p %p",diameap_sm,ans);
3006 int i = 0;
3007 struct avp * avp;
3008 union avp_value avp_val;
3009 /* Accounting-EAP-Auth-Method AVP */
3010 while (i < diameap_sm->eap_sm.user.methodId)
3011 {
3012 CHECK_FCT(fd_msg_avp_new(dataobj_accounting_eap_auth_method, 0, &avp));
3013
3014 avp_val.u64 = (u64) (((diameap_sm->eap_sm.user.methods[i].vendor)
3015 * pow((double) 2, (double) 32))
3016 + diameap_sm->eap_sm.user.methods[i].method);
3017 CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
3018 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
3019 i++;
3020 }
3021 return 0;
3022}
3023
3024static int diameap_add_eap_reissued_payload(struct msg * ans, struct msg * req)
3025{
3026 TRACE_ENTRY("%p %p", ans, req);
3027 struct avp * avp, *re_avp;
3028 union avp_value avp_val;
3029 struct avp_hdr * avphdr;
3030
3031 if ((ans == NULL) || (req == NULL))
3032 {
3033 return EINVAL;
3034 }
3035 avp = NULL;
3036 CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
3037 if (avp != NULL)
3038 {
3039 CHECK_FCT( fd_msg_avp_hdr(avp, &avphdr));
3040 CHECK_FCT( fd_msg_avp_new(dataobj_eap_reissued_payload, 0, &re_avp));
3041 CHECK_MALLOC(avp_val.os.data=malloc(avphdr->avp_value->os.len));
3042 memcpy(avp_val.os.data,avphdr->avp_value->os.data,avphdr->avp_value->os.len);
3043 avp_val.os.len = avphdr->avp_value->os.len;
3044 CHECK_FCT(fd_msg_avp_setvalue(re_avp, &avp_val));
3045 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, re_avp ) );
3046 }
3047 else
3048 {
3049 TRACE_DEBUG(INFO,"%sUnable to find EAP-Payload AVP in received Diameter-EAP-Request.",DIAMEAP_EXTENSION);
3050 return 1;
3051 }
3052
3053 return 0;
3054}
3055
3056
3057
3058
3059static int diameap_server_callback(struct msg ** rmsg, struct avp * ravp,
3060 struct session * sess, void * opaque, enum disp_action * action)
3061{
3062 TRACE_ENTRY("%p %p %p %p", rmsg, ravp, sess, action);
3063
3064 struct sess_state * diameap_sess_data = NULL;
3065 struct diameap_state_machine * diameap_sm = NULL;
3066 struct diameap_eap_interface eap_i;
3067 struct msg *req, *ans;
3068 boolean non_fatal_error = FALSE;
3069
3070 if (rmsg == NULL)
3071 return EINVAL;
3072
3073 req = *rmsg;
3074
3075 CHECK_FCT_DO(fd_sess_state_retrieve(diameap_server_reg, sess, &diameap_sess_data),
3076 { TRACE_DEBUG(INFO,"%s retrieving session state failed.",DIAMEAP_EXTENSION); goto s_end;});
3077
3078 CHECK_MALLOC_DO(diameap_sm = malloc(sizeof(struct diameap_state_machine)),
3079 goto s_end);
3080 memset(diameap_sm, 0, sizeof(struct diameap_state_machine));
3081
3082 if (diameap_sess_data)
3083 {
3084 diameap_sm->state = DIAMEAP_RECEIVED;
3085 diameap_sm->eap_sm.eap_state = EAP_IDLE;
3086 }
3087 else
3088 {
3089 diameap_sm->state = DIAMEAP_DISABLED;
3090 diameap_sm->eap_sm.eap_state = EAP_INITIALIZE;
3091 }
3092
3093 while (diameap_sm->state != DIAMEAP_IDLE && diameap_sm->state
3094 != DIAMEAP_END)
3095 {
3096 switch (diameap_sm->state)
3097 {
3098 case DIAMEAP_DISABLED:
3099 if (rmsg)
3100 {
3101 diameap_sm->state = DIAMEAP_INITIALIZE;
3102 }
3103 else
3104 {
3105 TRACE_DEBUG(INFO,"%sReceived empty Diameter EAP Request message.",DIAMEAP_EXTENSION);
3106 goto s_end;
3107 }
3108 break;
3109
3110 case DIAMEAP_INITIALIZE:
3111
3112 CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
3113 { TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
3114 ;
3115 CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
3116 { TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
3117 ;
3118 TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
3119 ;
3120 CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
3121 ;
3122
3123 if ((diameap_sm->result_code != 0))
3124 {
3125 diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
3126 }
3127 else
3128 {
3129 diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
3130 }
3131 break;
3132
3133 case DIAMEAP_RECEIVED:
3134
3135 CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
3136 { TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
3137 ;
3138 CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
3139 { TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
3140 ;
3141 TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
3142 ;
3143 CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
3144 ;
3145
3146 if (diameap_sm->result_code != 0)
3147 {
3148 diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
3149 }
3150 else
3151 {
3152 diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
3153 }
3154 break;
3155
3156 case DIAMEAP_AUTHENTICATION_VERIFY:
3157 {
3158
3159 TRACE_DEBUG(FULL+1,"%sVerify authentication",DIAMEAP_EXTENSION);
3160 CHECK_FCT_DO(diameap_eap_statemachine(&diameap_sm->eap_sm, &eap_i,&non_fatal_error),
3161 { TRACE_DEBUG(INFO,"%s EAP process failed.",DIAMEAP_EXTENSION); goto s_end;});
3162
3163 if (non_fatal_error == TRUE)
3164 {
3165 TRACE_DEBUG(FULL+1,"%sAuthentication verify finished with a non-fatal-error.",DIAMEAP_EXTENSION);
3166 diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
3167 }
3168 else
3169 {
3170 diameap_sm->state = DIAMEAP_SELECT_DECISION;
3171
3172 }
3173 }
3174 break;
3175
3176 case DIAMEAP_SELECT_DECISION:
3177
3178 CHECK_FCT_DO( diameap_policy_decision(diameap_sm,&eap_i),
3179 goto s_end)
3180 ;
3181
3182 if ((eap_i.aaaSuccess == TRUE) && (diameap_sm->auth_request_val
3183 == AUTHORIZE_AUTHENTICATE)
3184 && (diameap_sm->verify_authorization == FALSE))
3185 {
3186 diameap_sm->state = DIAMEAP_AUTHORIZATION_VERIFY;
3187 }
3188 else
3189 {
3190 diameap_sm->state = DIAMEAP_DIAMETER_EAP_ANSWER;
3191 }
3192 break;
3193
3194 case DIAMEAP_AUTHORIZATION_VERIFY:
3195 diameap_sm->verify_authorization = TRUE;
3196 TRACE_DEBUG(FULL+1,"%sVerify authorization",DIAMEAP_EXTENSION)
3197 ;
3198 CHECK_FCT_DO(diameap_authorize(diameap_sm),
3199 { TRACE_DEBUG(INFO,"%s Authorization check process failed.",DIAMEAP_EXTENSION); goto s_end;})
3200 ;
3201 diameap_sm->state = DIAMEAP_SELECT_DECISION;
3202
3203 break;
3204
3205 case DIAMEAP_DIAMETER_EAP_ANSWER:
3206 TRACE_DEBUG(FULL+1,"%screate Diameter EAP Answer",DIAMEAP_EXTENSION)
3207 ;
3208 CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
3209 goto s_end)
3210 ;
3211 ans = *rmsg;
3212 TRACE_DEBUG(FULL+1,"%sAdding AVPs to Diameter EAP Answer.",DIAMEAP_EXTENSION)
3213 ;
3214 CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
3215 { TRACE_DEBUG(INFO,"%s Unable to add AVPs to Diameter-EAP-Answer message.",DIAMEAP_EXTENSION);goto s_end;})
3216 ;
3217 if (diameap_sm->authFailure == FALSE)
3218 {
3219 if (diameap_sm->eap_sm.user.id != 0)
3220 {
3221 TRACE_DEBUG(FULL+1,"%sSelect authentication attributes.",DIAMEAP_EXTENSION);
3222 CHECK_FCT_DO(diameap_authentication_get_attribs(&diameap_sm->eap_sm.user, &diameap_sm->attributes),
3223 { TRACE_DEBUG(INFO,"%s Unable to get user's session attributes.",DIAMEAP_EXTENSION); goto s_end;});
3224 TRACE_DEBUG(FULL+1,"%sCreate answer authentication attributes.",DIAMEAP_EXTENSION);
3225 CHECK_FCT_DO(diameap_answer_avp_attributes(diameap_sm),
3226 { TRACE_DEBUG(INFO,"%s Unable to generate answer attributes.",DIAMEAP_EXTENSION); goto s_end;});
3227 }
3228
3229 if (diameap_sm->authSuccess == FALSE)
3230 {
3231 diameap_sm->state = DIAMEAP_SEND_REQUEST;
3232 }
3233 else
3234 {
3235
3236 diameap_sm->state = DIAMEAP_SEND_SUCCESS;
3237 }
3238 }
3239 else
3240 {
3241 diameap_sm->state = DIAMEAP_SEND_FAILURE;
3242 }
3243 break;
3244
3245 case DIAMEAP_SEND_REQUEST:
3246 TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3247 ;
3248 CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
3249 { TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3250 ;
3251 TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3252 ;
3253 CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,&eap_i),
3254 { TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3255 ;
3256 TRACE_DEBUG(FULL+1,"%sStoring DiamEAP session data.",DIAMEAP_EXTENSION)
3257 ;
3258 CHECK_MALLOC(diameap_sess_data = malloc(sizeof(struct sess_state)))
3259 ;
3260 memset(diameap_sess_data, 0, sizeof(struct sess_state));
3261 diameap_sess_data_new(diameap_sess_data, diameap_sm);
3262
3263 CHECK_FCT_DO(fd_sess_state_store(diameap_server_reg, sess, &diameap_sess_data),
3264 { TRACE_DEBUG(INFO,"%s Storing session state failed.",DIAMEAP_EXTENSION); goto s_end;})
3265 ;
3266
3267 CHECK_FCT_DO( diameap_send(rmsg),
3268 goto s_end)
3269 ;
3270
3271 diameap_sm->state = DIAMEAP_IDLE;
3272 break;
3273
3274 case DIAMEAP_SEND_FAILURE:
3275 TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3276 ;
3277 CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
3278 { TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3279 ;
3280 TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3281 ;
3282 CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,&eap_i),
3283 { TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3284 ;
3285
3286 LOG_N("%s Auth FAIL: %.*s",DIAMEAP_EXTENSION, diameap_sm->eap_sm.user.useridLength, diameap_sm->eap_sm.user.userid);
3287
3288 CHECK_FCT_DO( diameap_send(rmsg),
3289 goto s_end)
3290 ;
3291 diameap_sm->state = DIAMEAP_END;
3292 break;
3293
3294 case DIAMEAP_SEND_SUCCESS:
3295 TRACE_DEBUG(FULL+1,"%sAdding User session AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3296 ;
3297 CHECK_FCT_DO(diameap_add_user_sessions_avps(diameap_sm,ans),
3298 { TRACE_DEBUG(INFO,"%s Adding user's session AVPs failed.",DIAMEAP_EXTENSION); goto s_end;})
3299 ;
3300
3301 if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
3302 {
3303 TRACE_DEBUG(FULL+1,"%sAdding Authorization AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION);
3304 CHECK_FCT_DO(diameap_add_authorization_avps(diameap_sm,ans),
3305 { TRACE_DEBUG(INFO,"%s Adding Authorization AVPs failed.",DIAMEAP_EXTENSION); goto s_end;});
3306 }
3307 TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3308 ;
3309 CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
3310 { TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3311 ;
3312 TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3313 ;
3314 CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,&eap_i),
3315 { TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
3316 ;
3317 TRACE_DEBUG(FULL+1,"%sAdding EAP success AVPs AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3318 ;
3319 CHECK_FCT_DO( diameap_add_eap_success_avps(diameap_sm, ans, &eap_i),
3320 goto s_end)
3321 ;
3322 TRACE_DEBUG(FULL+1,"%sAdding Accounting-EAP-Auth-Method AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
3323 ;
3324 CHECK_FCT_DO(diameap_add_accounting_eap_auth_method(diameap_sm, ans),
3325 { TRACE_DEBUG(INFO,"%s Adding accounting AVP failed",DIAMEAP_EXTENSION); goto s_end;})
3326 ;
3327
3328 LOG_N("%s Auth Success: %.*s",DIAMEAP_EXTENSION, diameap_sm->eap_sm.user.useridLength, diameap_sm->eap_sm.user.userid);
3329
3330 CHECK_FCT_DO( diameap_send(rmsg),
3331 goto s_end)
3332 ;
3333 diameap_sm->state = DIAMEAP_END;
3334 break;
3335
3336 case DIAMEAP_SEND_ERROR_MSG:
3337 diameap_sm->invalid_eappackets++;
3338 if (diameap_sm->invalid_eappackets
3339 == diameap_config->max_invalid_eap_packet)
3340 {
3341 diameap_sm->result_code = 4001;//DIAMETER_AUTHENTICATION_REJECTED
3342 TRACE_DEBUG(FULL,"%s Maximum permitted invalid EAP Packet reached. Diameter Authentication Rejected.",DIAMEAP_EXTENSION);
3343 }
3344
3345 CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
3346 goto s_end)
3347 ;
3348
3349 ans = *rmsg;
3350 CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
3351 { TRACE_DEBUG(INFO,"%s Adding AVPs to Diameter-EAP-Answer message failed.",DIAMEAP_EXTENSION);goto s_end;})
3352 ;
3353 if ((non_fatal_error == TRUE) && (diameap_sm->result_code == 0))
3354 {
3355 diameap_sm->result_code = 1001;
3356 }
3357
3358 if (diameap_sm->result_code == 1001)
3359 {
3360 CHECK_FCT_DO( diameap_add_eap_reissued_payload(ans,req), goto s_end);
3361 }
3362
3363 if (diameap_sm->result_code == 5004)
3364 {
3365 CHECK_FCT_DO( fd_msg_avp_add( ans , MSG_BRW_LAST_CHILD, diameap_sm->failedavp ),goto s_end );
3366 }
3367
3368 CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess), goto s_end)
3369 ;
3370
3371 CHECK_FCT_DO( diameap_send(rmsg), goto s_end)
3372 ;
3373 diameap_sm->state = DIAMEAP_IDLE;
3374 break;
3375
3376 case DIAMEAP_END:
3377 break;
3378
3379 case DIAMEAP_IDLE:
3380 break;
3381 }
3382 }
3383
3384 diameap_free(diameap_sm);
3385
3386 s_end: return 0;
3387}
3388
3389int diameap_start_server(void)
3390{
3391 struct disp_when when;
3392
3393 /*create handler for sessions */
3394 CHECK_FCT(fd_sess_handler_create(&diameap_server_reg, diameap_cli_sess_cleanup, NULL, NULL));
3395
3396 /* Register the callback */
3397 memset(&when, 0, sizeof(when));
3398 when.command = dataobj_diameap_cmd;
3399 when.app = dataobj_diameap_app;
3400
3401 /* Register the callback for EAP Application */
3402 CHECK_FCT(fd_disp_register(diameap_server_callback, DISP_HOW_CC, &when, NULL,
3403 &handle));
3404
3405 if (handle == NULL)
3406 {
3407 TRACE_DEBUG(INFO, "%sCannot register the callback !!!",DIAMEAP_EXTENSION);
3408 return 1;
3409 }
3410 return 0;
3411}
3412
3413int diameap_stop_server(void)
3414{
3415 CHECK_FCT(fd_sess_handler_destroy(&diameap_server_reg, NULL));
3416 CHECK_FCT(fd_disp_unregister(&handle, NULL));
3417
3418 return 0;
3419}