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: bd1af8935a967aeb2c1e40db0670ad5db964708d $
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: bd1af8935a967aeb2c1e40db0670ad5db964708d $")
25
26#include <freeradius-devel/eap/base.h>
27#include <freeradius-devel/server/pair.h>
28#include <freeradius-devel/unlang/call.h>
29
30static int auth_type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
31 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
32
33/*
34 * EAP-GTC is just ASCII data carried inside of the EAP session.
35 * The length of the data is indicated by the encapsulating EAP
36 * protocol.
37 */
38typedef struct {
39 char const *challenge;
42
46
48 { FR_CONF_OFFSET("challenge", rlm_eap_gtc_t, challenge), .dflt = "Password: " },
49 { FR_CONF_OFFSET_TYPE_FLAGS("auth_type", FR_TYPE_VOID, 0, rlm_eap_gtc_t, auth_type), .func = auth_type_parse, .dflt = "pap" },
51};
52
54static fr_dict_t const *dict_radius;
55
58 { .out = &dict_freeradius, .proto = "freeradius" },
59 { .out = &dict_radius, .proto = "radius" },
61};
62
65
68 { .out = &attr_auth_type, .name = "Auth-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
69 { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
71};
72
73static unlang_action_t mod_session_init(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request);
74
75/** Translate a string auth_type into an enumeration value
76 *
77 * @param[in] ctx to allocate data.
78 * @param[out] out Where to write the auth_type we created or resolved.
79 * @param[in] parent Base structure address.
80 * @param[in] ci #CONF_PAIR specifying the name of the auth_type.
81 * @param[in] rule unused.
82 * @return
83 * - 0 on success.
84 * - -1 on failure.
85 */
86static int auth_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
87 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
88{
89 char const *auth_type = cf_pair_value(cf_item_to_pair(ci));
90
92 cf_log_err(ci, "Failed adding %s alias", attr_auth_type->name);
93 return -1;
94 }
96
97 return 0;
98}
99
100/*
101 * Keep processing the Auth-Type until it doesn't return YIELD.
102 */
103static unlang_action_t gtc_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
104{
105 rlm_eap_gtc_rctx_t *rctx = talloc_get_type_abort(mctx->rctx, rlm_eap_gtc_rctx_t);
106 rlm_rcode_t rcode;
107
108 eap_session_t *eap_session = eap_session_get(request->parent);
109 eap_round_t *eap_round = eap_session->this_round;
110
111 rcode = rctx->section_result.rcode;
112 if (rcode != RLM_MODULE_OK) {
113 eap_round->request->code = FR_EAP_CODE_FAILURE;
114 RETURN_UNLANG_RCODE(rcode);
115 }
116
117 eap_round->request->code = FR_EAP_CODE_SUCCESS;
119}
120
121/*
122 * Authenticate a previously sent challenge.
123 */
124static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
125{
126 rlm_eap_gtc_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_gtc_t);
127 rlm_eap_gtc_rctx_t *rctx = talloc_get_type_abort(mctx->rctx, rlm_eap_gtc_rctx_t);
128
129 eap_session_t *eap_session = eap_session_get(request->parent);
130 eap_round_t *eap_round = eap_session->this_round;
131
132 fr_pair_t *vp;
133 CONF_SECTION *unlang;
134
135 /*
136 * Get the Password.Cleartext for this user.
137 */
138
139 /*
140 * Sanity check the response. We need at least one byte
141 * of data.
142 */
143 if (eap_round->response->length <= 4) {
144 REDEBUG("Corrupted data");
145 eap_round->request->code = FR_EAP_CODE_FAILURE;
147 }
148
149 /*
150 * EAP packets can be ~64k long maximum, and
151 * we don't like that.
152 */
153 if (eap_round->response->type.length > 128) {
154 REDEBUG("Response is too large to understand");
155 eap_round->request->code = FR_EAP_CODE_FAILURE;
157 }
158
159 /*
160 * If there was a User-Password in the request,
161 * why the heck are they using EAP-GTC?
162 */
164 fr_pair_value_bstrndup(vp, (char const *)eap_round->response->type.data, eap_round->response->type.length, true);
165
166 unlang = cf_section_find(unlang_call_current(request), "authenticate", inst->auth_type->name);
167 if (!unlang) unlang = cf_section_find(unlang_call_current(request->parent), "authenticate", inst->auth_type->name);
168 if (!unlang) {
169 RDEBUG2("authenticate %s { ... } sub-section not found.",
170 inst->auth_type->name);
171 eap_round->request->code = FR_EAP_CODE_FAILURE;
173 }
174
175 return unlang_module_yield_to_section(&rctx->section_result, request, unlang, RLM_MODULE_FAIL, gtc_resume, NULL, 0, rctx);
176}
177
178
179/*
180 * Initiate the EAP-GTC session by sending a challenge to the peer.
181 */
183{
184 eap_session_t *eap_session = eap_session_get(request->parent);
185 char challenge_str[1024];
186 int length;
187 eap_round_t *eap_round = eap_session->this_round;
188 rlm_eap_gtc_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_eap_gtc_t);
189
190 if (xlat_eval(challenge_str, sizeof(challenge_str), request, inst->challenge, NULL, NULL) < 0) {
192 }
193
194 length = strlen(challenge_str);
195
196 /*
197 * We're sending a request...
198 */
199 eap_round->request->code = FR_EAP_CODE_REQUEST;
200
201 eap_round->request->type.data = talloc_array(eap_round->request, uint8_t, length);
202 if (!eap_round->request->type.data) RETURN_UNLANG_FAIL;
203
204 memcpy(eap_round->request->type.data, challenge_str, length);
205 eap_round->request->type.length = length;
206
207 /*
208 * We don't need to authorize the user at this point.
209 *
210 * We also don't need to keep the challenge, as it's
211 * stored in 'eap_session->this_round', which will be given back
212 * to us...
213 */
214 eap_session->process = mod_process;
215
217}
218
219/*
220 * The module name should be the only globally exported symbol.
221 * That is, everything else should be 'static'.
222 */
225 .common = {
226 .magic = MODULE_MAGIC_INIT,
227 .name = "eap_gtc",
231 },
232 .provides = { FR_EAP_METHOD_GTC },
233 .session_init = mod_session_init, /* Initialise a new EAP session */
234 .clone_parent_lists = true /* HACK */
235};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:506
#define UNUSED
Definition build.h:336
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
Definition call.c:214
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:611
#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:280
#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:238
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
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:1029
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:665
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1581
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
eap_type_data_t type
Definition compose.h:38
size_t length
Definition compose.h:37
eap_packet_t * response
Packet we received from the peer.
Definition compose.h:48
eap_code_t code
Definition compose.h:35
eap_packet_t * request
Packet we will send to the peer.
Definition compose.h:49
Contains a pair of request and response packets.
Definition compose.h:47
#define MEM(x)
Definition debug.h:46
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
Definition dict_util.c:4915
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
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:2229
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
fr_dict_enum_value_t const * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition dict_util.c:3701
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
Value of an enumerated attribute.
Definition dict.h:253
#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 rcode
The current rcode, from executing the instruction or merging the result from a frame.
Definition interpret.h:134
static eap_session_t * eap_session_get(request_t *request)
Definition session.h:85
module_method_t process
Callback that should be used to process the next round.
Definition session.h:65
eap_round_t * this_round
The EAP response we're processing, and the EAP request we're building.
Definition session.h:60
Tracks the progress of a single session of any EAP method.
Definition session.h:41
@ 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:2812
#define pair_update_request(_attr, _da)
#define REDEBUG(fmt,...)
#define RDEBUG2(fmt,...)
#define RETURN_UNLANG_HANDLED
Definition rcode.h:65
#define RETURN_UNLANG_INVALID
Definition rcode.h:66
#define RETURN_UNLANG_RCODE(_rcode)
Definition rcode.h:61
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
#define RETURN_UNLANG_OK
Definition rcode.h:64
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_OK
The module is OK, continue.
Definition rcode.h:49
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
static fr_dict_attr_t const * attr_user_password
Definition rlm_eap_gtc.c:64
static unlang_action_t gtc_resume(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
unlang_result_t section_result
Definition rlm_eap_gtc.c:44
static fr_dict_t const * dict_freeradius
Definition rlm_eap_gtc.c:53
static int auth_type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_t const * dict_radius
Definition rlm_eap_gtc.c:54
rlm_eap_submodule_t rlm_eap_gtc
static fr_dict_attr_t const * attr_auth_type
Definition rlm_eap_gtc.c:63
char const * challenge
Definition rlm_eap_gtc.c:39
fr_dict_attr_autoload_t rlm_eap_gtc_dict_attr[]
Definition rlm_eap_gtc.c:67
fr_dict_enum_value_t const * auth_type
Definition rlm_eap_gtc.c:40
fr_dict_autoload_t rlm_eap_gtc_dict[]
Definition rlm_eap_gtc.c:57
static conf_parser_t submodule_config[]
Definition rlm_eap_gtc.c:47
static unlang_action_t mod_session_init(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
void * data
Module's instance data.
Definition module.h:293
#define MODULE_RCTX(_ctype)
Definition module.h:259
#define MODULE_INST(_ctype)
Definition module.h:257
conf_parser_t const * config
How to convert a CONF_SECTION to a module instance.
Definition module.h:206
unlang_action_t unlang_module_yield_to_section(unlang_result_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:236
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:858
static size_t char ** out
Definition value.h:1030