The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_eap_gtc.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: ac51afa4f7bf1e3207400f372aa5009d3d2063cc $
19 * @file rlm_eap_gtc.c
20 * @brief EAP-GTC inner authentication method.
21 *
22 * @copyright 2000,2006 The FreeRADIUS server project
23 */
24RCSID("$Id: ac51afa4f7bf1e3207400f372aa5009d3d2063cc $")
25
26#include <freeradius-devel/eap/base.h>
27#include <freeradius-devel/util/debug.h>
28#include <freeradius-devel/server/virtual_servers.h>
29#include <freeradius-devel/server/pair.h>
30#include <freeradius-devel/unlang/call.h>
31#include <freeradius-devel/unlang/interpret.h>
32
33static int auth_type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
34 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
35
36/*
37 * EAP-GTC is just ASCII data carried inside of the EAP session.
38 * The length of the data is indicated by the encapsulating EAP
39 * protocol.
40 */
41typedef struct {
42 char const *challenge;
45
47 { FR_CONF_OFFSET("challenge", rlm_eap_gtc_t, challenge), .dflt = "Password: " },
48 { FR_CONF_OFFSET_TYPE_FLAGS("auth_type", FR_TYPE_VOID, 0, rlm_eap_gtc_t, auth_type), .func = auth_type_parse, .dflt = "pap" },
50};
51
53static fr_dict_t const *dict_radius;
54
57 { .out = &dict_freeradius, .proto = "freeradius" },
58 { .out = &dict_radius, .proto = "radius" },
59 { NULL }
60};
61
64
67 { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
68 { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
69 { NULL }
70};
71
72static unlang_action_t mod_session_init(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request);
73
74/** Translate a string auth_type into an enumeration value
75 *
76 * @param[in] ctx to allocate data.
77 * @param[out] out Where to write the auth_type we created or resolved.
78 * @param[in] parent Base structure address.
79 * @param[in] ci #CONF_PAIR specifying the name of the auth_type.
80 * @param[in] rule unused.
81 * @return
82 * - 0 on success.
83 * - -1 on failure.
84 */
85static int auth_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
86 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
87{
88 char const *auth_type = cf_pair_value(cf_item_to_pair(ci));
89
91 cf_log_err(ci, "Failed adding %s alias", attr_auth_type->name);
92 return -1;
93 }
95
96 return 0;
97}
98
99/*
100 * Keep processing the Auth-Type until it doesn't return YIELD.
101 */
102static unlang_action_t gtc_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
103{
104 rlm_rcode_t rcode;
105
106 eap_session_t *eap_session = mctx->rctx;
107 eap_round_t *eap_round = eap_session->this_round;
108
109 rcode = unlang_interpret_stack_result(request);
110
111 if (rcode != RLM_MODULE_OK) {
112 eap_round->request->code = FR_EAP_CODE_FAILURE;
113 RETURN_MODULE_RCODE(rcode);
114 }
115
116 eap_round->request->code = FR_EAP_CODE_SUCCESS;
118}
119
120/*
121 * Authenticate a previously sent challenge.
122 */
123static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
124{
125 rlm_eap_gtc_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_gtc_t);
126
127 eap_session_t *eap_session = eap_session_get(request->parent);
128 eap_round_t *eap_round = eap_session->this_round;
129
130 fr_pair_t *vp;
131 CONF_SECTION *unlang;
132
133 /*
134 * Get the Password.Cleartext for this user.
135 */
136
137 /*
138 * Sanity check the response. We need at least one byte
139 * of data.
140 */
141 if (eap_round->response->length <= 4) {
142 REDEBUG("Corrupted data");
143 eap_round->request->code = FR_EAP_CODE_FAILURE;
145 }
146
147 /*
148 * EAP packets can be ~64k long maximum, and
149 * we don't like that.
150 */
151 if (eap_round->response->type.length > 128) {
152 REDEBUG("Response is too large to understand");
153 eap_round->request->code = FR_EAP_CODE_FAILURE;
155 }
156
157 /*
158 * If there was a User-Password in the request,
159 * why the heck are they using EAP-GTC?
160 */
162 fr_pair_value_bstrndup(vp, (char const *)eap_round->response->type.data, eap_round->response->type.length, true);
163 vp->vp_tainted = true;
164
165 unlang = cf_section_find(unlang_call_current(request), "authenticate", inst->auth_type->name);
166 if (!unlang) unlang = cf_section_find(unlang_call_current(request->parent), "authenticate", inst->auth_type->name);
167 if (!unlang) {
168 RDEBUG2("authenticate %s { ... } sub-section not found.",
169 inst->auth_type->name);
170 eap_round->request->code = FR_EAP_CODE_FAILURE;
172 }
173
174 return unlang_module_yield_to_section(p_result, request, unlang, RLM_MODULE_FAIL, gtc_resume, NULL, 0, eap_session);
175}
176
177
178/*
179 * Initiate the EAP-GTC session by sending a challenge to the peer.
180 */
181static unlang_action_t mod_session_init(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
182{
183 eap_session_t *eap_session = eap_session_get(request->parent);
184 char challenge_str[1024];
185 int length;
186 eap_round_t *eap_round = eap_session->this_round;
187 rlm_eap_gtc_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_gtc_t);
188
189 if (xlat_eval(challenge_str, sizeof(challenge_str), request, inst->challenge, NULL, NULL) < 0) {
191 }
192
193 length = strlen(challenge_str);
194
195 /*
196 * We're sending a request...
197 */
198 eap_round->request->code = FR_EAP_CODE_REQUEST;
199
200 eap_round->request->type.data = talloc_array(eap_round->request, uint8_t, length);
201 if (!eap_round->request->type.data) RETURN_MODULE_FAIL;
202
203 memcpy(eap_round->request->type.data, challenge_str, length);
204 eap_round->request->type.length = length;
205
206 /*
207 * We don't need to authorize the user at this point.
208 *
209 * We also don't need to keep the challenge, as it's
210 * stored in 'eap_session->this_round', which will be given back
211 * to us...
212 */
213 eap_session->process = mod_process;
214
216}
217
218/*
219 * The module name should be the only globally exported symbol.
220 * That is, everything else should be 'static'.
221 */
224 .common = {
225 .magic = MODULE_MAGIC_INIT,
226 .name = "eap_gtc",
227 .inst_size = sizeof(rlm_eap_gtc_t),
229 },
230 .provides = { FR_EAP_METHOD_GTC },
231 .session_init = mod_session_init, /* Initialise a new EAP session */
232 .clone_parent_lists = true /* HACK */
233};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
Definition call.c:225
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:658
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:612
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:284
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:241
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:595
Common header for all CONF_* types.
Definition cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition cf_util.c:1028
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:664
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1594
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:289
eap_type_data_t type
Definition compose.h:39
size_t length
Definition compose.h:38
eap_packet_t * response
Packet we received from the peer.
Definition compose.h:49
eap_code_t code
Definition compose.h:36
eap_packet_t * request
Packet we will send to the peer.
Definition compose.h:50
Contains a pair of request and response packets.
Definition compose.h:48
#define MEM(x)
Definition debug.h:36
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
Definition dict_util.c:4601
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition dict_util.c:3399
int fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name)
Add an name to an integer attribute hashing the name for the integer value.
Definition dict_util.c:1957
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
Value of an enumerated attribute.
Definition dict.h:227
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
@ FR_EAP_CODE_FAILURE
Definition types.h:40
@ FR_EAP_CODE_REQUEST
Definition types.h:37
@ FR_EAP_CODE_SUCCESS
Definition types.h:39
size_t length
Definition types.h:111
uint8_t * data
Definition types.h:112
@ FR_EAP_METHOD_GTC
Definition types.h:51
rlm_rcode_t unlang_interpret_stack_result(request_t *request)
Get the current rcode for the frame.
Definition interpret.c:1294
static eap_session_t * eap_session_get(request_t *request)
Definition session.h:82
module_method_t process
Callback that should be used to process the next round.
Definition session.h:64
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:59
Tracks the progress of a single session of any EAP method.
Definition session.h:40
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_VOID
User data.
ssize_t xlat_eval(char *out, size_t outlen, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx)
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * rctx
Resume ctx that a module previously set.
Definition module_ctx.h:45
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
Definition pair.c:2784
static const conf_parser_t config[]
Definition base.c:183
#define pair_update_request(_attr, _da)
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define RETURN_MODULE_RCODE(_rcode)
Definition rcode.h:64
#define RETURN_MODULE_HANDLED
Definition rcode.h:58
#define RETURN_MODULE_INVALID
Definition rcode.h:59
#define RETURN_MODULE_OK
Definition rcode.h:57
#define RETURN_MODULE_FAIL
Definition rcode.h:56
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:42
static fr_dict_attr_t const * attr_user_password
Definition rlm_eap_gtc.c:63
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_t const * dict_freeradius
Definition rlm_eap_gtc.c:52
static int auth_type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
static fr_dict_t const * dict_radius
Definition rlm_eap_gtc.c:53
rlm_eap_submodule_t rlm_eap_gtc
static fr_dict_attr_t const * attr_auth_type
Definition rlm_eap_gtc.c:62
char const * challenge
Definition rlm_eap_gtc.c:42
fr_dict_attr_autoload_t rlm_eap_gtc_dict_attr[]
Definition rlm_eap_gtc.c:66
static unlang_action_t gtc_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_enum_value_t const * auth_type
Definition rlm_eap_gtc.c:43
fr_dict_autoload_t rlm_eap_gtc_dict[]
Definition rlm_eap_gtc.c:56
static conf_parser_t submodule_config[]
Definition rlm_eap_gtc.c:46
static unlang_action_t mod_session_init(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
size_t inst_size
Size of the module's instance data.
Definition module.h:203
void * data
Module's instance data.
Definition module.h:271
unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Definition module.c:248
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
module_t common
Common fields provided by all modules.
Definition submodule.h:50
Interface exported by EAP submodules.
Definition submodule.h:49
static fr_slen_t parent
Definition pair.h:851
static size_t char ** out
Definition value.h:997