All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mem.c
Go to the documentation of this file.
1 /*
2  * mem.c Memory allocation, deallocation stuff.
3  *
4  * Version: $Id: b059e4278e0aa6b31ff6d1b5d6255a0be836a105 $
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2001,2006 The FreeRADIUS server project
21  * Copyright 2001 hereUare Communications, Inc. <raghud@hereuare.com>
22  */
23 
24 RCSID("$Id: b059e4278e0aa6b31ff6d1b5d6255a0be836a105 $")
25 
26 #include <stdio.h>
27 #include "rlm_eap.h"
28 
29 /*
30  * Allocate a new eap_packet_t
31  */
33 {
35 
36  eap_round = talloc_zero(eap_session, eap_round_t);
37  if (!eap_round) return NULL;
38 
39  eap_round->response = talloc_zero(eap_round, eap_packet_t);
40  if (!eap_round->response) {
41  talloc_free(eap_round);
42  return NULL;
43  }
44  eap_round->request = talloc_zero(eap_round, eap_packet_t);
45  if (!eap_round->request) {
46  talloc_free(eap_round);
47  return NULL;
48  }
49 
50  return eap_round;
51 }
52 
53 static int _eap_session_free(eap_session_t *eap_session)
54 {
55  REQUEST *request = eap_session->request;
56 
57  if (eap_session->identity) {
58  talloc_free(eap_session->identity);
59  eap_session->identity = NULL;
60  }
61 
62 #ifdef WITH_VERIFY_PTR
63  if (eap_session->prev_round) rad_assert(talloc_parent(eap_session->prev_round) == eap_session);
64  if (eap_session->this_round) rad_assert(talloc_parent(eap_session->this_round) == eap_session);
65 #endif
66 
67  /*
68  * Give helpful debug messages if:
69  *
70  * we're debugging TLS sessions, which don't finish,
71  * and which aren't deleted early due to a likely RADIUS
72  * retransmit which nukes our ID, and therefore our state.
73  */
74  if (((request && RDEBUG_ENABLED) || (!request && DEBUG_ENABLED)) &&
75  (eap_session->tls && !eap_session->finished && (time(NULL) > (eap_session->updated + 3)))) {
76  ROPTIONAL(RWDEBUG, WARN, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
77  ROPTIONAL(RWDEBUG, WARN, "!! EAP session %p did not finish! !!",
78  eap_session);
79  ROPTIONAL(RWDEBUG, WARN, "!! See http://wiki.freeradius.org/guide/Certificate_Compatibility !!");
80  ROPTIONAL(RWDEBUG, WARN, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
81  }
82 
83  ROPTIONAL(RDEBUG4, DEBUG4, "Freeing eap_session_t %p", eap_session);
84 
85  /*
86  * Remove it from request data
87  */
88  if (request) request_data_get(request, NULL, REQUEST_DATA_EAP_SESSION);
89 
90  return 0;
91 }
92 
93 /** Allocate a new eap_session_t
94  *
95  * Allocates a new eap_session_t, and inserts it into the REQUEST_DATA_EAP_SESSION index
96  * of the request.
97  *
98  * @note The eap_session_t will remove itself from the #REQUEST_DATA_EAP_SESSION index
99  * if it is freed. This is to simplify management of the request data entry.
100  *
101  * @param inst This session belongs to.
102  * @param request That generated this eap_session_t.
103  * @return
104  * - A new #eap_session_t on success.
105  * - NULL on failure.
106  */
108 {
109  eap_session_t *eap_session;
110 
111  eap_session = talloc_zero(NULL, eap_session_t);
112  if (!eap_session) {
113  ERROR("Failed allocating eap_session");
114  return NULL;
115  }
116  eap_session->inst = inst;
117  eap_session->request = request;
118  eap_session->updated = request->timestamp.tv_sec;
119 
120  talloc_set_destructor(eap_session, _eap_session_free);
121 
122  /*
123  * If the index is removed by something else
124  * like the state being cleaned up, then we
125  * still want the eap_session to be freed, which
126  * is why we set free_opaque to true.
127  *
128  * We must pass a NULL pointer to associate the
129  * the EAP_SESSION data with, else we'll break
130  * tunelled EAP, where the inner EAP module is
131  * a different instance to the outer one.
132  */
133  request_data_add(request, NULL, REQUEST_DATA_EAP_SESSION, eap_session, true, true, true);
134 
135  return eap_session;
136 }
void * inst
Instance of the eap module this session was created by.
Definition: eap.h:65
bool tls
Whether EAP method uses TLS.
Definition: eap.h:88
#define RDEBUG_ENABLED
True if request debug level 1 messages are enabled.
Definition: log.h:237
bool finished
Whether we consider this session complete.
Definition: eap.h:89
eap_packet_t * request
Packet we will send to the peer.
Definition: eap.h:45
#define inst
eap_round_t * prev_round
Previous response/request pair.
Definition: eap.h:75
REQUEST * request
Request that contains the response we're processing.
Definition: eap.h:71
#define rad_assert(expr)
Definition: rad_assert.h:38
Tracks the progress of a single session of any EAP method.
Definition: eap.h:60
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition: eap.h:77
void * request_data_get(REQUEST *request, void *unique_ptr, int unique_int)
Get opaque data from a request.
Definition: request.c:374
#define ROPTIONAL(_l_request, _l_global, fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:357
static int _eap_session_free(eap_session_t *eap_session)
Definition: mem.c:53
Contains a pair of request and response packets.
Definition: eap.h:43
#define DEBUG4(fmt,...)
Definition: log.h:178
char * identity
NAI (User-Name) from EAP-Identity.
Definition: eap.h:73
#define REQUEST_DATA_EAP_SESSION
Definition: eap.h:106
struct timeval timestamp
When we started processing the request.
Definition: radiusd.h:214
int request_data_add(REQUEST *request, void *unique_ptr, int unique_int, void *opaque, bool free_on_replace, bool free_on_parent, bool persist)
Add opaque data to a REQUEST.
Definition: request.c:279
#define WARN(fmt,...)
Definition: log.h:144
Structure to hold EAP data.
Definition: eap_types.h:132
#define RDEBUG4(fmt,...)
Definition: log.h:246
eap_packet_t * response
Packet we received from the peer.
Definition: eap.h:44
#define RWDEBUG(fmt,...)
Definition: log.h:251
eap_round_t * eap_round_alloc(eap_session_t *eap_session)
Definition: mem.c:32
#define RCSID(id)
Definition: build.h:135
eap_session_t * eap_session_alloc(rlm_eap_t *inst, REQUEST *request)
Allocate a new eap_session_t.
Definition: mem.c:107
#define DEBUG_ENABLED
True if global debug level 1 messages are enabled.
Definition: log.h:169
#define ERROR(fmt,...)
Definition: log.h:145
time_t updated
The last time we received a packet for this EAP session.
Definition: eap.h:86