EAP module for all EAP based authentications
[freeradius.git] / src / modules / rlm_eap / mem.c
1 /*
2  * mem.c  Memory allocation, deallocation stuff.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2000,2001  The FreeRADIUS server project
21  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
22  */
23
24 #include <stdio.h>
25 #include "eap.h"
26
27 /*
28  *      Allocate a new EAP_PACKET
29  */
30 EAP_PACKET *eap_packet_alloc()
31 {
32         EAP_PACKET   *rp;
33
34         if ((rp = malloc(sizeof(EAP_PACKET))) == NULL) {
35                 radlog(L_ERR, "out of memory");
36                 return NULL;
37         }
38         memset(rp, 0, sizeof(EAP_PACKET));
39         return rp;
40 }
41
42 /*
43  *      Free a EAP_PACKET
44  */
45 void eap_packet_free(EAP_PACKET **eap_packet_ptr)
46 {
47         EAP_PACKET *eap_packet;
48
49         if (!eap_packet_ptr) return;
50         eap_packet = *eap_packet_ptr;
51         if (!eap_packet) return;
52
53         if (eap_packet->typedata) free(eap_packet->typedata);
54         if (eap_packet->rad_vps) pairfree(&(eap_packet->rad_vps));
55
56         free(eap_packet);
57
58         *eap_packet_ptr = NULL;
59 }
60
61 /*
62  *      Allocate a new EAP_PACKET
63  */
64 EAP_DS *eap_ds_alloc()
65 {
66         EAP_DS  *eap_ds;
67         
68         if ((eap_ds = malloc(sizeof(EAP_DS))) == NULL) {
69                 radlog(L_ERR, "out of memory");
70                 return NULL;
71         }
72         memset(eap_ds, 0, sizeof(EAP_DS));
73         if ((eap_ds->response = eap_packet_alloc(sizeof(EAP_PACKET))) == NULL) {
74                 eap_ds_free(&eap_ds);
75                 return NULL;
76         }
77         if ((eap_ds->request = eap_packet_alloc(sizeof(EAP_PACKET))) == NULL) {
78                 eap_ds_free(&eap_ds);
79                 return NULL;
80         }
81
82         return eap_ds;
83 }
84
85 void eap_ds_free(EAP_DS **eap_ds_p)
86 {
87         EAP_DS *eap_ds;
88
89         if (!eap_ds_p) return;
90         eap_ds = *eap_ds_p;
91         if (!eap_ds) return;
92
93         if (eap_ds->response) eap_packet_free(&(eap_ds->response));
94         if (eap_ds->request) eap_packet_free(&(eap_ds->request));
95
96         if (eap_ds->username) pairfree(&(eap_ds->username));
97         if (eap_ds->password) pairfree(&(eap_ds->password));
98
99         free(eap_ds);
100         *eap_ds_p = NULL;
101 }
102
103 void free_type_list(EAP_TYPES **i)
104 {
105         EAP_TYPES       *c, *next;
106
107         c = *i;
108         while (c) {
109                 next = c->next;
110                 if(c->type->detach) (c->type->detach)(&(c->type_stuff));
111                 if (c->handle) lt_dlclose(c->handle);
112                 free(c);
113                 c = next;
114         }
115         *i = NULL;
116 }
117
118 void node_free(EAP_LIST **node)
119 {
120         if (node == NULL) return;
121         if (*node == NULL) return;
122         if ((*node)->eap_ds) eap_ds_free(&((*node)->eap_ds));
123
124         (*node)->next = NULL;
125         free(*node);
126         *node = NULL;
127 }
128
129 void list_free(EAP_LIST **list)
130 {
131         EAP_LIST *node, *next;
132
133         if (!list) return;
134         node = *list;
135
136         while (node) {
137                 next = node->next;
138                 node_free(&node);
139                 node = next;
140         }
141
142         *list = NULL;
143 }
144
145 int list_add(EAP_LIST **list, EAP_DS *eap_ds)
146 {
147         EAP_LIST        *node, **last;
148
149         if (!eap_ds) return 0;
150         
151         last = list;
152         while (*last) *last = (*last)->next;
153         
154         eap_ds->timestamp = time(NULL);
155         eap_ds->finished = 1;
156
157         node = malloc(sizeof(EAP_LIST));
158         if (!node) {
159                 radlog(L_ERR, "rlm_eap: out of memory");
160                 return 0;
161         }
162
163         node->next = NULL;
164         node->eap_ds = eap_ds;
165
166         *last = node;
167         return 1;
168 }
169
170 /*
171  * List should contain only recent packets with life < X seconds.
172  */
173 void list_clean(EAP_LIST **first, time_t limit)
174 {
175         time_t  now;
176         EAP_LIST *node, *next;
177         EAP_LIST **last = first;
178
179         now = time(NULL);
180
181         for (node = *first; node; node = next) {
182                 next = node->next;
183                 if ((now - node->eap_ds->timestamp) > limit) {
184                         radlog(L_INFO, "rlm_eap:  list_clean deleted one item");
185                         *last = next;
186                         node_free(&node);
187                 } else  {
188                         last = &(node->next);
189                 }
190         }
191 }
192
193 void remove_item(EAP_LIST **first, EAP_LIST *item)
194 {
195         time_t  now;
196         EAP_LIST *node, *next;
197         EAP_LIST **last = first;
198
199         now = time(NULL);
200
201         for (node = *first; node; node = next) {
202                 next = node->next;
203                 if (node == item) {
204                         radlog(L_INFO, "rlm_eap:  remove_item deleted one item");
205                         *last = next;
206                         node_free(&node);
207                 } else  {
208                         last = &(node->next);
209                 }
210         }
211 }