The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 27661cb13a6695ea2649d9a9cf047677575a6858 $
19  * @file rlm_eap_gtc.c
20  * @brief EAP-GTC inner authentication method.
21  *
22  * @copyright 2000,2006 The FreeRADIUS server project
23  */
24 RCSID("$Id: 27661cb13a6695ea2649d9a9cf047677575a6858 $")
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 
33 static 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  */
41 typedef 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 
52 static fr_dict_t const *dict_freeradius;
53 static 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 
72 static 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  */
85 static 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  */
102 static 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  */
123 static 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->inst->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  */
181 static 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->inst->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:444
#define UNUSED
Definition: build.h:313
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:626
#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:268
#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:563
Common header for all CONF_* types.
Definition: cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:629
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:970
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1511
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:265
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
fr_dict_attr_t * fr_dict_attr_unconst(fr_dict_attr_t const *da)
Coerce to non-const.
Definition: dict_util.c:4191
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
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:1547
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:2992
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
Value of an enumerated attribute.
Definition: dict.h:209
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
@ 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:1278
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
static eap_session_t * eap_session_get(request_t *request)
Definition: session.h:82
Tracks the progress of a single session of any EAP method.
Definition: session.h:40
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
ssize_t xlat_eval(char *out, size_t outlen, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx)
Definition: merged_model.c:215
unsigned char uint8_t
Definition: merged_model.c:30
void * rctx
Resume ctx that a module previously set.
Definition: module_ctx.h:45
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:42
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:2781
static const conf_parser_t config[]
Definition: base.c:188
#define pair_update_request(_attr, _da)
Definition: radclient-ng.c:60
#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
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)
Definition: rlm_eap_gtc.c:123
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
Definition: rlm_eap_gtc.c:223
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)
Definition: rlm_eap_gtc.c:102
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)
Definition: rlm_eap_gtc.c:181
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:516
RETURN_MODULE_FAIL
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
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:844
static size_t char ** out
Definition: value.h:984