The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_idn.c
Go to the documentation of this file.
1/*
2 * This program is 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: 2a81a4fb3bcc34c3f7b450aa3f06a2628d63fd3f $
19 * @file rlm_idn.c
20 * @brief Internationalized Domain Name encoding for DNS aka IDNA aka RFC3490
21 *
22 * @copyright 2013 Brian S. Julin (bjulin@clarku.edu)
23 */
24RCSID("$Id: 2a81a4fb3bcc34c3f7b450aa3f06a2628d63fd3f $")
25
26#include <freeradius-devel/server/base.h>
27#include <freeradius-devel/server/module_rlm.h>
28#include <freeradius-devel/unlang/xlat_func.h>
29
30#include <idna.h>
31
32/*
33 * Structure for module configuration
34 */
35typedef struct {
38} rlm_idn_t;
39
40/*
41 * The primary use case for this module is DNS-safe encoding of realms
42 * appearing in requests for a DDDS scheme. Some notes on that usage
43 * scenario:
44 *
45 * RFC2865 5.1 User-Name may be one of:
46 *
47 * 1) UTF-8 text: in which case this conversion is needed
48 *
49 * 2) realm part of an NAI: in which case this conversion should do nothing
50 * since only ASCII digits, ASCII alphas, ASCII dots, and ASCII hyphens
51 * are allowed.
52 *
53 * 3) "A name in ASN.1 form used in Public Key authentication systems.":
54 * I count four things in that phrase that are rather ... vague.
55 * However, most X.509 docs yell at you to IDNA internationalized
56 * domain names to IA5String, so if it is coming from inside an X.509
57 * certificate IDNA should be idempotent in the encode direction.
58 *
59 * Except for that last loophole, which we will leave up to the user
60 * to sort out, we should be safe in processing the realm as UTF-8.
61 */
62
63
64/*
65 * A mapping of configuration file names to internal variables.
66 */
67static const conf_parser_t mod_config[] = {
68 /*
69 * If a STRINGPREP profile other than NAMEPREP is ever desired,
70 * we can implement an option, and it will default to NAMEPREP settings.
71 * ...and if we want raw punycode or to tweak Bootstring parameters,
72 * we can do similar things. All defaults should result in IDNA
73 * ToASCII with the use_std3_ascii_rules flag set, allow_unassigned unset,
74 * because that is the foreseeable use case.
75 *
76 * Note that doing anything much different will require choosing the
77 * appropriate libidn API functions, as we currently call the IDNA
78 * convenience functions.
79 *
80 * Also note that right now we do not provide ToUnicode, which may or
81 * may not be useful as an xlat... depends on how the results need to
82 * be used.
83 */
84
85 { FR_CONF_OFFSET("allow_unassigned", rlm_idn_t, allow_unassigned), .dflt = "no" },
86 { FR_CONF_OFFSET("use_std3_ascii_rules", rlm_idn_t, use_std3_ascii_rules), .dflt = "yes" },
88};
89
91 { .required = true, .concat = true, .type = FR_TYPE_STRING },
93};
94
95/** Convert domain name to ASCII punycode
96 *
97@verbatim
98%idn(<domain>)
99@endverbatim
100 *
101 * @ingroup xlat_functions
102 */
103static xlat_action_t xlat_idna(TALLOC_CTX *ctx, fr_dcursor_t *out,
104 xlat_ctx_t const *xctx,
105 request_t *request, fr_value_box_list_t *in)
106{
107 rlm_idn_t const *inst = talloc_get_type_abort(xctx->mctx->mi->data, rlm_idn_t);
108 char *idna = NULL;
109 int res;
110 size_t len;
111 int flags = 0;
112 fr_value_box_t *arg = fr_value_box_list_head(in);
113 fr_value_box_t *vb;
114
115 if (inst->use_std3_ascii_rules) {
116 flags |= IDNA_USE_STD3_ASCII_RULES;
117 }
118 if (inst->allow_unassigned) {
119 flags |= IDNA_ALLOW_UNASSIGNED;
120 }
121
122 res = idna_to_ascii_8z(arg->vb_strvalue, &idna, flags);
123 if (res) {
124 if (idna) {
125 free (idna); /* Docs unclear, be safe. */
126 }
127
128 REDEBUG("%s", idna_strerror(res));
129 return XLAT_ACTION_FAIL;
130 }
131
132 len = strlen(idna);
133
134 /* 253 is max DNS length */
135 if (len > 253) {
136 /* Never provide a truncated result, as it may be queried. */
137 REDEBUG("Conversion was truncated");
138
139 free(idna);
140 return XLAT_ACTION_FAIL;
141 }
142
143 MEM(vb = fr_value_box_alloc_null(ctx));
144 MEM(fr_value_box_strdup(ctx, vb, NULL, idna, false) >= 0);
146 free(idna);
147
148 return XLAT_ACTION_DONE;
149}
150
151static int mod_bootstrap(module_inst_ctx_t const *mctx)
152{
153 xlat_t *xlat;
154
155 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, NULL, xlat_idna, FR_TYPE_STRING);
158
159 return 0;
160}
161
162extern module_rlm_t rlm_idn;
164 .common = {
165 .magic = MODULE_MAGIC_INIT,
166 .name = "idn",
167 .inst_size = sizeof(rlm_idn_t),
169 .bootstrap = mod_bootstrap
170 }
171};
#define RCSID(id)
Definition build.h:483
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:642
#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
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:579
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:36
static fr_slen_t in
Definition dict.h:824
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
static xlat_action_t xlat_idna(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Convert domain name to ASCII punycode.
Definition rlm_idn.c:103
free(array)
@ FR_TYPE_STRING
String of printable characters.
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition module_rlm.c:257
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
static const conf_parser_t config[]
Definition base.c:183
#define REDEBUG(fmt,...)
Definition radclient.h:52
bool use_std3_ascii_rules
Definition rlm_idn.c:36
module_rlm_t rlm_idn
Definition rlm_idn.c:163
static xlat_arg_parser_t const xlat_idna_arg[]
Definition rlm_idn.c:90
static int mod_bootstrap(module_inst_ctx_t const *mctx)
Definition rlm_idn.c:151
bool allow_unassigned
Definition rlm_idn.c:37
static const conf_parser_t mod_config[]
Definition rlm_idn.c:67
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
void * boot
Data allocated during the boostrap phase.
Definition module.h:274
eap_aka_sim_process_conf_t * inst
bool required
Argument must be present, and non-empty.
Definition xlat.h:148
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:168
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumend by an xlat function.
Definition xlat.h:147
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
Definition value.c:3927
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:632
static size_t char ** out
Definition value.h:997
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition xlat_ctx.h:52
An xlat calling ctx.
Definition xlat_ctx.h:49
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
Definition xlat_func.c:402
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:365
@ XLAT_FUNC_FLAG_PURE
Definition xlat_func.h:38