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: 53a8f7dfa8b94462a3c3cd38a5089f719feaece4 $
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: 53a8f7dfa8b94462a3c3cd38a5089f719feaece4 $")
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/rcode.h>
34#include <freeradius-devel/server/state.h>
35#include <freeradius-devel/unlang/call.h>
36#include <freeradius-devel/util/debug.h>
37
38#include <freeradius-devel/util/print.h>
39#include <freeradius-devel/radius/defs.h>
40
41#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
42
43/*
44 * Run a virtual server auth and postauth
45 *
46 */
48{
49 RDEBUG("Virtual server %s received request NOT IMPLEMENTED", cf_section_name2(unlang_call_current(request)));
50 log_request_pair_list(L_DBG_LVL_1, request, NULL, &request->request_pairs, NULL);
51
52 /*
53 * Just push the virtual server onto the stack?
54 *
55 * Except that the caller expects this function to be run
56 * _synchronously_, and all of that needs to be fixed.
57 */
59
60#if 0
61 {
62 fr_pair_t *username, *parent_username = NULL;
64
65 username = fr_pair_find_by_num(&request->request_pairs, 0, FR_STRIPPED_USER_NAME);
66 if (!username) username = fr_pair_find_by_num(&request->request_pairs, 0, FR_USER_NAME);
67
68 if (request->parent) {
69 parent_username = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_STRIPPED_USER_NAME);
70 if (!parent_username) parent_username = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_USER_NAME);
71 }
72
73 /*
74 * Complain about possible issues related to tunnels.
75 */
76 if (username && parent_username) {
77 /*
78 * Look at the full User-Name with realm.
79 */
80 if (parent_username->da->attr == FR_STRIPPED_USER_NAME) {
81 vp = fr_pair_find_by_num(&request->parent->request_pairs, 0, FR_USER_NAME);
82 if (!vp) goto runit;
83 } else {
84 vp = parent_username;
85 }
86
87 /*
88 * If the names aren't identical, we do some detailed checks.
89 */
90 if (strcmp(vp->vp_strvalue, username->vp_strvalue) != 0) {
91 char const *outer, *inner;
92
93 outer = strchr(vp->vp_strvalue, '@');
94
95 /*
96 * If there's no realm, or there's a user identifier before
97 * the realm name, check the user identifier.
98 *
99 * It SHOULD be "anonymous", or "anonymous@realm"
100 */
101 if (outer) {
102 if ((outer != vp->vp_strvalue) &&
103 ((vp->vp_length < 10) || (memcmp(vp->vp_strvalue, "anonymous@", 10) != 0))) {
104 RWDEBUG("Outer User-Name is not anonymized. User privacy is compromised.");
105 } /* else it is anonymized */
106
107 /*
108 * Check when there's no realm, and without the trailing '@'
109 */
110 } else if ((vp->vp_length < 9) || (memcmp(vp->vp_strvalue, "anonymous", 9) != 0)) {
111 RWDEBUG("Outer User-Name is not anonymized. User privacy is compromised.");
112
113 } /* else the user identifier is anonymized */
114
115 /*
116 * Look for an inner realm, which may or may not exist.
117 */
118 inner = strchr(username->vp_strvalue, '@');
119 if (outer && inner) {
120 outer++;
121 inner++;
122
123 /*
124 * The realms are different, do
125 * more detailed checks.
126 */
127 if (strcmp(outer, inner) != 0) {
128 size_t outer_len, inner_len;
129
130 outer_len = vp->vp_length;
131 outer_len -= (outer - vp->vp_strvalue);
132
133 inner_len = username->vp_length;
134 inner_len -= (inner - username->vp_strvalue);
135
136 /*
137 * Inner: secure.example.org
138 * Outer: example.org
139 */
140 if (inner_len > outer_len) {
141 char const *suffix;
142
143 suffix = inner + (inner_len - outer_len) - 1;
144
145 if ((*suffix != '.') ||
146 (strcmp(suffix + 1, outer) != 0)) {
147 RWDEBUG("Possible spoofing: Inner realm '%s' is not a "
148 "subdomain of the outer realm '%s'", inner, outer);
149 }
150
151 } else {
152 RWDEBUG("Possible spoofing: Inner realm and "
153 "outer realms are different");
154 }
155 }
156 }
157
158 } else {
159 RWDEBUG("Outer and inner identities are the same. User privacy is compromised.");
160 }
161 }
162 }
163
164 if (!request->async) {
165#ifdef STATIC_ANALYZER
166 if (!request->parent) RETURN_MODULE_FAIL;
167#endif
168 fr_assert(request->parent != NULL);
169
170 request->async = talloc_memdup(request, request->parent->async, sizeof(fr_async_t));
171 talloc_set_name_const(request->async, talloc_get_name(request->parent->async));
172 }
173
174 RDEBUG("server %s {", cf_section_name2(unlang_call_current(request)));
175 request->async->process(&final,
176 MODULE_CTX(module_rlm_by_data(request->async->process_inst), NULL, NULL, NULL),
177 request);
178 RDEBUG("} # server %s", cf_section_name2(unlang_call_current(request)));
179
181
182 if (!request->reply->code ||
183 (request->reply->code == FR_RADIUS_CODE_ACCESS_REJECT)) {
185 }
186
187 if (request->reply->code == FR_RADIUS_CODE_ACCESS_CHALLENGE) {
189 }
190
192#endif
193}
194
195/*
196 * Debug the packet if requested.
197 */
198void common_packet_debug(request_t *request, fr_packet_t *packet, fr_pair_list_t *pairs, bool received)
199{
200#ifdef WITH_IFINDEX_NAME_RESOLUTION
201 char if_name[IFNAMSIZ];
202#endif
203
204 if (!packet) return;
205 if (!RDEBUG_ENABLED) return;
206
207
208 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 "
209#ifdef WITH_IFINDEX_NAME_RESOLUTION
210 "%s%s%s"
211#endif
212 "length %zu",
213 received ? "Received" : "Sent",
214 packet->code,
215 packet->id,
216 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
217 fr_box_ipaddr(packet->socket.inet.src_ipaddr),
218 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
219 packet->socket.inet.src_port,
220 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
221 fr_box_ipaddr(packet->socket.inet.dst_ipaddr),
222 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
223 packet->socket.inet.dst_port,
224#ifdef WITH_IFINDEX_NAME_RESOLUTION
225 packet->socket.inet.ifindex ? "via " : "",
226 packet->socket.inet.ifindex ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
227 packet->socket.inet.ifindex ? " " : "",
228#endif
229 packet->data_len);
230
231 if (received) {
232 log_request_pair_list(L_DBG_LVL_1, request, NULL, pairs, NULL);
233 } else {
234 log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, pairs, NULL);
235 }
236}
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:198
unlang_action_t rad_virtual_server(rlm_rcode_t *p_result, request_t *request)
Definition auth.c:47
#define RCSID(id)
Definition build.h:483
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:1185
#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:58
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:854
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:612
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:830
#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:294