The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
auth.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: 0a05c113d967b248f2287ccf579293685f21675d $
19 *
20 * @file src/lib/server/auth.c
21 * @brief The old authentication state machine.
22 *
23 * @copyright 2000,2006 The FreeRADIUS server project
24 * @copyright 2000 Miquel van Smoorenburg (miquels@cistron.nl)
25 * @copyright 2000 Jeff Carneal (jeff@apex.net)
26 */
27RCSID("$Id: 0a05c113d967b248f2287ccf579293685f21675d $")
28
29#include <freeradius-devel/io/listen.h>
30#include <freeradius-devel/server/auth.h>
31#include <freeradius-devel/server/module.h>
32#include <freeradius-devel/server/protocol.h>
33#include <freeradius-devel/server/state.h>
34#include <freeradius-devel/unlang/call.h>
35
36#include <freeradius-devel/util/print.h>
37#include <freeradius-devel/radius/defs.h>
38
39
40/*
41 * Run a virtual server auth and postauth
42 *
43 */
45{
46 RDEBUG("Virtual server %s received request NOT IMPLEMENTED", cf_section_name2(unlang_call_current(request)));
47 log_request_pair_list(L_DBG_LVL_1, request, NULL, &request->request_pairs, NULL);
48
49 /*
50 * Just push the virtual server onto the stack?
51 *
52 * Except that the caller expects this function to be run
53 * _synchronously_, and all of that needs to be fixed.
54 */
56
57#if 0
58 {
59 fr_pair_t *username, *parent_username = NULL;
61
62 username = fr_pair_find_by_num(&request->request_pairs, 0, FR_STRIPPED_USER_NAME);
63 if (!username) username = fr_pair_find_by_num(&request->request_pairs, 0, FR_USER_NAME);
64
65 if (request->parent) {
66 parent_username = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_STRIPPED_USER_NAME);
67 if (!parent_username) parent_username = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_USER_NAME);
68 }
69
70 /*
71 * Complain about possible issues related to tunnels.
72 */
73 if (username && parent_username) {
74 /*
75 * Look at the full User-Name with realm.
76 */
77 if (parent_username->da->attr == FR_STRIPPED_USER_NAME) {
78 vp = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_USER_NAME);
79 if (!vp) goto runit;
80 } else {
81 vp = parent_username;
82 }
83
84 /*
85 * If the names aren't identical, we do some detailed checks.
86 */
87 if (strcmp(vp->vp_strvalue, username->vp_strvalue) != 0) {
88 char const *outer, *inner;
89
90 outer = strchr(vp->vp_strvalue, '@');
91
92 /*
93 * If there's no realm, or there's a user identifier before
94 * the realm name, check the user identifier.
95 *
96 * It SHOULD be "anonymous", or "anonymous@realm"
97 */
98 if (outer) {
99 if ((outer != vp->vp_strvalue) &&
100 ((vp->vp_length < 10) || (memcmp(vp->vp_strvalue, "anonymous@", 10) != 0))) {
101 RWDEBUG("Outer User-Name is not anonymized. User privacy is compromised.");
102 } /* else it is anonymized */
103
104 /*
105 * Check when there's no realm, and without the trailing '@'
106 */
107 } else if ((vp->vp_length < 9) || (memcmp(vp->vp_strvalue, "anonymous", 9) != 0)) {
108 RWDEBUG("Outer User-Name is not anonymized. User privacy is compromised.");
109
110 } /* else the user identifier is anonymized */
111
112 /*
113 * Look for an inner realm, which may or may not exist.
114 */
115 inner = strchr(username->vp_strvalue, '@');
116 if (outer && inner) {
117 outer++;
118 inner++;
119
120 /*
121 * The realms are different, do
122 * more detailed checks.
123 */
124 if (strcmp(outer, inner) != 0) {
125 size_t outer_len, inner_len;
126
127 outer_len = vp->vp_length;
128 outer_len -= (outer - vp->vp_strvalue);
129
130 inner_len = username->vp_length;
131 inner_len -= (inner - username->vp_strvalue);
132
133 /*
134 * Inner: secure.example.org
135 * Outer: example.org
136 */
137 if (inner_len > outer_len) {
138 char const *suffix;
139
140 suffix = inner + (inner_len - outer_len) - 1;
141
142 if ((*suffix != '.') ||
143 (strcmp(suffix + 1, outer) != 0)) {
144 RWDEBUG("Possible spoofing: Inner realm '%s' is not a "
145 "subdomain of the outer realm '%s'", inner, outer);
146 }
147
148 } else {
149 RWDEBUG("Possible spoofing: Inner realm and "
150 "outer realms are different");
151 }
152 }
153 }
154
155 } else {
156 RWDEBUG("Outer and inner identities are the same. User privacy is compromised.");
157 }
158 }
159 }
160
161 if (!request->async) {
162#ifdef STATIC_ANALYZER
163 if (!request->parent) RETURN_MODULE_FAIL;
164#endif
165 fr_assert(request->parent != NULL);
166
167 request->async = talloc_memdup(request, request->parent->async, sizeof(fr_async_t));
168 talloc_set_name_const(request->async, talloc_get_name(request->parent->async));
169 }
170
171 RDEBUG("server %s {", cf_section_name2(unlang_call_current(request)));
172 request->async->process(&final,
173 MODULE_CTX(module_rlm_by_data(request->async->process_inst), NULL, NULL, NULL),
174 request);
175 RDEBUG("} # server %s", cf_section_name2(unlang_call_current(request)));
176
178
179 if (!request->reply->code ||
180 (request->reply->code == FR_RADIUS_CODE_ACCESS_REJECT)) {
182 }
183
184 if (request->reply->code == FR_RADIUS_CODE_ACCESS_CHALLENGE) {
186 }
187
189#endif
190}
191
192/*
193 * Debug the packet if requested.
194 */
195void common_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *pairs, bool received)
196{
197#ifdef WITH_IFINDEX_NAME_RESOLUTION
198 char if_name[IFNAMSIZ];
199#endif
200
201 if (!packet) return;
202 if (!RDEBUG_ENABLED) return;
203
204
205 log_request(L_DBG, L_DBG_LVL_1, request, __FILE__, __LINE__, "%s code %u Id %i from %s%pV%s:%i to %s%pV%s:%i "
206#ifdef WITH_IFINDEX_NAME_RESOLUTION
207 "%s%s%s"
208#endif
209 "length %zu",
210 received ? "Received" : "Sent",
211 packet->code,
212 packet->id,
213 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
214 fr_box_ipaddr(packet->socket.inet.src_ipaddr),
215 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
216 packet->socket.inet.src_port,
217 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
218 fr_box_ipaddr(packet->socket.inet.dst_ipaddr),
219 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
220 packet->socket.inet.dst_port,
221#ifdef WITH_IFINDEX_NAME_RESOLUTION
222 packet->socket.inet.ifindex ? "via " : "",
223 packet->socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
224 packet->socket.inet.ifindex ? " " : "",
225#endif
226 packet->data_len);
227
228 if (received) {
229 log_request_pair_list(L_DBG_LVL_1, request, NULL, pairs, NULL);
230 } else {
231 log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, pairs, NULL);
232 }
233}
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
void common_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *pairs, bool received)
Definition auth.c:195
unlang_action_t rad_virtual_server(rlm_rcode_t *p_result, request_t *request)
Definition auth.c:44
#define RCSID(id)
Definition build.h:485
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
Definition call.c:225
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1184
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:139
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
Definition defs.h:43
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
Definition defs.h:35
Minimal data structure to use the new code.
Definition listen.h:59
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
Definition log.c:852
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition log.c:610
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition log.c:828
#define RWDEBUG(fmt,...)
Definition log.h:361
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition log.h:70
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:59
#define MODULE_CTX(_mi, _thread, _env_data, _rctx)
Wrapper to create a module_ctx_t as a compound literal.
Definition module_ctx.h:128
#define fr_assert(_expr)
Definition rad_assert.h:38
#define RDEBUG(fmt,...)
Definition radclient.h:53
#define RDEBUG_ENABLED()
Definition radclient.h:49
#define RETURN_MODULE_REJECT
Definition rcode.h:55
#define RETURN_MODULE_HANDLED
Definition rcode.h:58
#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
username
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
unsigned int code
Packet code (type).
Definition packet.h:61
fr_socket_t socket
This packet was received on.
Definition packet.h:57
int id
Packet ID (used to link requests/responses).
Definition packet.h:60
size_t data_len
Length of packet data.
Definition packet.h:64
int af
AF_INET, AF_INET6, or AF_UNIX.
Definition socket.h:78
#define fr_box_ipaddr(_val)
Definition value.h:305