The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
xlat_pair.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
5  * (at 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: da3a48948135cca202e585d5cffad878447c8b2e $
19  *
20  * @brief Protocol agnostic encode/decoders
21  * @file unlang/xlat_pair.c
22  *
23  * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
24  */
25 RCSID("$Id: da3a48948135cca202e585d5cffad878447c8b2e $")
26 
27 #include <freeradius-devel/unlang/xlat_priv.h>
28 
29 /** Keep decoding pairs until all of the data has been used.
30  *
31  * @param[in] ctx to allocate new pairs in.
32  * @param[in] out the cursor to update
33  * @param[in] parent to use as the root
34  * @param[in] data to decode.
35  * @param[in] data_len The length of the incoming data.
36  * @param[in] decode_ctx Any decode specific data such as secrets or configurable.
37  * @param[in] decode the function used to decode one specific pair.
38  * @return
39  * - <= 0 on error. May be the offset (as a negative value) where the error occurred.
40  * - > 0 on success. How many bytes were decoded.
41  */
43  uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_t decode)
44 {
45  uint8_t const *p, *end;
46  fr_pair_list_t tmp;
47 
48  /*
49  * Catch idiocies.
50  */
51  if (data_len == 0) return 0;
52 
53  fr_pair_list_init(&tmp);
54 
55  p = data;
56  end = data + data_len;
57 
58  while (p < end) {
59  ssize_t len;
60 
61  len = decode(ctx, &tmp, parent, p, end - p, decode_ctx);
62  if (len <= 0) {
63  fr_pair_list_free(&tmp);
64  return len - (p - data);
65  }
66  p += len;
67  }
68 
69  /*
70  * Add the pairs to the cursor
71  */
72  fr_pair_list_append(out, &tmp);
73 
74  return data_len;
75 }
76 
77 
78 /** Decode all of the value boxes into the output cursor
79  *
80  * @param[in] ctx to allocate new pairs in.
81  * @param[in] out the cursor to update
82  * @param[in] request the request
83  * @param[in] decode_ctx Any decode specific data such as secrets or configurable.
84  * @param[in] decode the function used to decode one specific pair.
85  * @param[in] in the list of value boxes to decode
86  * @return
87  * - <= 0 on error. May be the offset (as a negative value) where the error occurred.
88  * - > 0 on success. How many value boxes were decoded
89  */
91  request_t *request, void *decode_ctx, fr_pair_decode_t decode,
92  fr_value_box_list_t *in)
93 {
94  int decoded = 0;
95  fr_pair_t *vp = NULL;
96  fr_dict_attr_t const *parent = fr_dict_root(request->dict);
98 
100 
102  ssize_t len;
103 
104  if (vb->type != FR_TYPE_OCTETS) {
105  RWDEBUG("Skipping value \"%pV\", expected value of type %s, got type %s",
106  vb,
108  fr_type_to_str(vb->type));
109  continue;
110  }
111 
112  len = fr_pair_decode_multi(ctx, &head, parent,
113  vb->vb_octets, vb->vb_length, decode_ctx, decode);
114  if (len <= 0) {
116  return -decoded;
117  }
118  decoded++; /* one more VB, but there may be many pairs in the decoded vps. */
119  }
120 
121  if (RDEBUG_ENABLED2) {
122  char const *name = parent->name;
123 
124  while ((vp = fr_pair_list_next(&head, vp))) {
125  RDEBUG2("decode %s: &%pP", name, vp);
126  }
127  }
128 
129  decoded = fr_pair_list_num_elements(&head);
130 
132 
133  return decoded;
134 }
#define RCSID(id)
Definition: build.h:444
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:1997
static fr_slen_t in
Definition: dict.h:645
ssize_t(* fr_pair_decode_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx)
A generic interface for decoding fr_pair_ts.
Definition: pair.h:130
#define RWDEBUG(fmt,...)
Definition: log.h:361
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
#define RDEBUG_ENABLED2()
Definition: radclient.h:50
#define RDEBUG2(fmt,...)
Definition: radclient.h:54
static decode_fail_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code, udp_handle_t *h, request_t *request, udp_request_t *u, uint8_t const request_authenticator[static RADIUS_AUTH_VECTOR_LENGTH], uint8_t *data, size_t data_len)
Decode response packet data, extracting relevant information and validating the packet.
static char const * name
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
static fr_slen_t head
Definition: xlat.h:408
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition: pair_inline.c:70
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
Definition: pair_inline.c:113
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
Definition: pair_inline.c:182
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
Definition: pair_inline.c:151
static fr_slen_t parent
Definition: pair.h:844
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition: types.h:433
static fr_slen_t data
Definition: value.h:1259
#define fr_value_box_list_foreach(_list_head, _iter)
Definition: value.h:199
static size_t char ** out
Definition: value.h:984
int xlat_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out, request_t *request, void *decode_ctx, fr_pair_decode_t decode, fr_value_box_list_t *in)
Decode all of the value boxes into the output cursor.
Definition: xlat_pair.c:90
static ssize_t fr_pair_decode_multi(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_t decode)
Keep decoding pairs until all of the data has been used.
Definition: xlat_pair.c:42