Skip to content

Commit 2d830c4

Browse files
TCP Support
1 parent 06b389a commit 2d830c4

File tree

13 files changed

+336
-5
lines changed

13 files changed

+336
-5
lines changed

etc/radiusclient.conf.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ radius_deadtime 0
8787
# local address from which radius packets have to be sent
8888
bindaddr *
8989

90+
# Transport Protocol Support
91+
# Use "1" for using UDP and "2" for TCP protocol.
92+
radius_proto 1
93+
9094
# LOCAL settings
9195

9296
# program to execute for local login

include/freeradius-client.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ typedef struct value_pair
419419
#define TIMEOUT_RC 1
420420
#define REJECT_RC 2
421421

422+
/* Transport Protocol Types */
423+
#define PROTO_TCP 1
424+
#define PROTO_UDP 2
425+
422426
typedef struct send_data /* Used to pass information to sendserver() function */
423427
{
424428
uint8_t code; //!< RADIUS packet code.
@@ -430,6 +434,7 @@ typedef struct send_data /* Used to pass information to sendserver() function */
430434
int retries;
431435
VALUE_PAIR *send_pairs; //!< More a/v pairs to send.
432436
VALUE_PAIR *receive_pairs; //!< Where to place received a/v pairs.
437+
uint8_t radius_proto; //!< Transport protocol type.
433438
} SEND_DATA;
434439

435440
#ifndef MIN

lib/buildreq.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **r
7373
double now = 0;
7474
time_t dtime;
7575
unsigned type;
76+
int radius_proto = 0;
7677

7778
if (request_type != PW_ACCOUNTING_REQUEST) {
7879
aaaserver = rc_conf_srv(rh, "authserver");
@@ -84,6 +85,12 @@ int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **r
8485
if (aaaserver == NULL)
8586
return ERROR_RC;
8687

88+
radius_proto = rc_conf_int(rh, "radius_proto");
89+
if(1 == radius_proto)
90+
data.radius_proto = PROTO_UDP;
91+
else
92+
data.radius_proto = PROTO_TCP;
93+
8794
data.send_pairs = send;
8895
data.receive_pairs = NULL;
8996

lib/options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static OPTION config_options_default[] = {
5050
{"radius_retries", OT_INT, ST_UNDEF, NULL},
5151
{"radius_deadtime", OT_INT, ST_UNDEF, NULL},
5252
{"bindaddr", OT_STR, ST_UNDEF, NULL},
53+
{"radius_proto", OT_INT, ST_UNDEF, NULL},
5354
/* local options */
5455
{"login_local", OT_STR, ST_UNDEF, NULL},
5556
};

lib/sendserver.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,11 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
296296
}
297297
}
298298

299-
sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
299+
if(PROTO_TCP == data->radius_proto)
300+
sockfd = socket (our_sockaddr.ss_family, SOCK_STREAM, 0);
301+
else
302+
sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
303+
300304
if (sockfd < 0)
301305
{
302306
memset (secret, '\0', sizeof (secret));
@@ -386,6 +390,14 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
386390
for (;;)
387391
{
388392
do {
393+
if(PROTO_TCP == data->radius_proto) {
394+
if((connect(sockfd, SA(auth_addr->ai_addr), auth_addr->ai_addrlen)) != 0)
395+
{
396+
rc_log(LOG_ERR, "%s: Connect Call Failed : %s", __FUNCTION__, strerror(errno));
397+
result = -1;
398+
break;
399+
}
400+
}
389401
result = sendto (sockfd, (char *) auth, (unsigned int)total_length,
390402
(int) 0, SA(auth_addr->ai_addr), auth_addr->ai_addrlen);
391403
} while (result == -1 && errno == EINTR);

tests/Makefile.am

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
SUBDIRS = docker
66
EXTRA_DIST = radiusclient-ipv6.conf servers-ipv6 \
7-
radiusclient.conf servers README
7+
radiusclient.conf servers radiusclient-tcp.conf servers-tcp README
88

9-
nodist_check_SCRIPTS = basic-tests.sh ipv6-tests.sh
10-
TESTS = basic-tests.sh ipv6-tests.sh
9+
nodist_check_SCRIPTS = basic-tests.sh ipv6-tests.sh tcp-tests.sh
10+
TESTS = basic-tests.sh ipv6-tests.sh tcp-tests.sh
1111

1212
TESTS_ENVIRONMENT = \
1313
top_builddir="$(top_builddir)" \

tests/docker/freeradius-users

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@ test6 Cleartext-Password := "test"
2323
Framed-IP-Netmask = 255.255.255.0,
2424
Framed-Routing = Broadcast-Listen,
2525
Framed-MTU = 1500,
26-

tests/docker/radius-clients.conf

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,150 @@ client localhost2 {
310310
# coa_server = coa
311311
}
312312

313+
client localhost {
314+
# Allowed values are:
315+
# dotted quad (1.2.3.4)
316+
# hostname (radius.example.com)
317+
ipaddr = 0.0.0.0/0
318+
proto = tcp
319+
# OR, you can use an IPv6 address, but not both
320+
# at the same time.
321+
# ipv6addr = :: # any. ::1 == localhost
322+
323+
#
324+
# A note on DNS: We STRONGLY recommend using IP addresses
325+
# rather than host names. Using host names means that the
326+
# server will do DNS lookups when it starts, making it
327+
# dependent on DNS. i.e. If anything goes wrong with DNS,
328+
# the server won't start!
329+
#
330+
# The server also looks up the IP address from DNS once, and
331+
# only once, when it starts. If the DNS record is later
332+
# updated, the server WILL NOT see that update.
333+
#
334+
335+
# One client definition can be applied to an entire network.
336+
# e.g. 127/8 should be defined with "ipaddr = 127.0.0.0" and
337+
# "netmask = 8"
338+
#
339+
# If not specified, the default netmask is 32 (i.e. /32)
340+
#
341+
# We do NOT recommend using anything other than 32. There
342+
# are usually other, better ways to achieve the same goal.
343+
# Using netmasks of other than 32 can cause security issues.
344+
#
345+
# You can specify overlapping networks (127/8 and 127.0/16)
346+
# In that case, the smallest possible network will be used
347+
# as the "best match" for the client.
348+
#
349+
# Clients can also be defined dynamically at run time, based
350+
# on any criteria. e.g. SQL lookups, keying off of NAS-Identifier,
351+
# etc.
352+
# See raddb/sites-available/dynamic-clients for details.
353+
#
354+
355+
# netmask = 32
356+
357+
#
358+
# The shared secret use to "encrypt" and "sign" packets between
359+
# the NAS and FreeRADIUS. You MUST change this secret from the
360+
# default, otherwise it's not a secret any more!
361+
#
362+
# The secret can be any string, up to 8k characters in length.
363+
#
364+
# Control codes can be entered vi octal encoding,
365+
# e.g. "\101\102" == "AB"
366+
# Quotation marks can be entered by escaping them,
367+
# e.g. "foo\"bar"
368+
#
369+
# A note on security: The security of the RADIUS protocol
370+
# depends COMPLETELY on this secret! We recommend using a
371+
# shared secret that is composed of:
372+
#
373+
# upper case letters
374+
# lower case letters
375+
# numbers
376+
#
377+
# And is at LEAST 8 characters long, preferably 16 characters in
378+
# length. The secret MUST be random, and should not be words,
379+
# phrase, or anything else that is recognizable.
380+
#
381+
# The default secret below is only for testing, and should
382+
# not be used in any real environment.
383+
#
384+
secret = testing123
385+
386+
#
387+
# Old-style clients do not send a Message-Authenticator
388+
# in an Access-Request. RFC 5080 suggests that all clients
389+
# SHOULD include it in an Access-Request. The configuration
390+
# item below allows the server to require it. If a client
391+
# is required to include a Message-Authenticator and it does
392+
# not, then the packet will be silently discarded.
393+
#
394+
# allowed values: yes, no
395+
require_message_authenticator = no
396+
397+
#
398+
# The short name is used as an alias for the fully qualified
399+
# domain name, or the IP address.
400+
#
401+
# It is accepted for compatibility with 1.x, but it is no
402+
# longer necessary in 2.0
403+
#
404+
# shortname = localhost
405+
406+
#
407+
# the following three fields are optional, but may be used by
408+
# checkrad.pl for simultaneous use checks
409+
#
410+
411+
#
412+
# The nastype tells 'checkrad.pl' which NAS-specific method to
413+
# use to query the NAS for simultaneous use.
414+
#
415+
# Permitted NAS types are:
416+
#
417+
# cisco
418+
# computone
419+
# livingston
420+
# juniper
421+
# max40xx
422+
# multitech
423+
# netserver
424+
# pathras
425+
# patton
426+
# portslave
427+
# tc
428+
# usrhiper
429+
# other # for all other types
430+
431+
#
432+
nas_type = other # localhost isn't usually a NAS...
433+
434+
#
435+
# The following two configurations are for future use.
436+
# The 'naspasswd' file is currently used to store the NAS
437+
# login name and password, which is used by checkrad.pl
438+
# when querying the NAS for simultaneous use.
439+
#
440+
# login = !root
441+
# password = someadminpas
442+
443+
#
444+
# As of 2.0, clients can also be tied to a virtual server.
445+
# This is done by setting the "virtual_server" configuration
446+
# item, as in the example below.
447+
#
448+
# virtual_server = home1
449+
450+
#
451+
# A pointer to the "home_server_pool" OR a "home_server"
452+
# section that contains the CoA configuration for this
453+
# client. For an example of a coa home server or pool,
454+
# see raddb/sites-available/originate-coa
455+
# coa_server = coa
456+
}
313457
# IPv6 Client
314458
#client ::1 {
315459
# secret = testing123

tests/radiusclient-ipv6.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ radius_deadtime 0
7878
# local address from which radius packets have to be sent
7979
bindaddr *
8080

81+
# Transport Protocol Support
82+
# Use "1" for using UDP and "2" for TCP protocol.
83+
radius_proto 1
84+
8185
# file which holds sequence number for communication with the
8286
# RADIUS server
8387
seqfile /var/run/radius.seq

tests/radiusclient-tcp.conf

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# General settings
2+
3+
# specify which authentication comes first respectively which
4+
# authentication is used. possible values are: "radius" and "local".
5+
# if you specify "radius,local" then the RADIUS server is asked
6+
# first then the local one. if only one keyword is specified only
7+
# this server is asked.
8+
auth_order radius,local
9+
10+
# maximum login tries a user has
11+
login_tries 4
12+
13+
# timeout for all login tries
14+
# if this time is exceeded the user is kicked out
15+
login_timeout 60
16+
17+
# name of the nologin file which when it exists disables logins.
18+
# it may be extended by the ttyname which will result in
19+
# a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable
20+
# logins on /dev/ttyS2)
21+
nologin /etc/nologin
22+
23+
# name of the issue file. it's only display when no username is passed
24+
# on the radlogin command line
25+
issue /usr/local/etc/radiusclient/issue
26+
27+
# RADIUS settings
28+
29+
# RADIUS server to use for authentication requests. this config
30+
# item can appear more then one time. if multiple servers are
31+
# defined they are tried in a round robin fashion if one
32+
# server is not answering.
33+
# optionally you can specify a the port number on which is remote
34+
# RADIUS listens separated by a colon from the hostname. if
35+
# no port is specified /etc/services is consulted of the radius
36+
# service. if this fails also a compiled in default is used.
37+
authserver localhost
38+
39+
# RADIUS server to use for accouting requests. All that I
40+
# said for authserver applies, too.
41+
#
42+
acctserver localhost
43+
44+
# file holding shared secrets used for the communication
45+
# between the RADIUS client and server
46+
servers ./servers-tcp-temp
47+
48+
# dictionary of allowed attributes and values
49+
# just like in the normal RADIUS distributions
50+
dictionary ../etc/dictionary
51+
52+
# file which specifies mapping between ttyname and NAS-Port attribute
53+
mapfile ../etc/port-id-map
54+
55+
# default authentication realm to append to all usernames if no
56+
# realm was explicitly specified by the user
57+
# the radiusd directly form Livingston doesnt use any realms, so leave
58+
# it blank then
59+
default_realm
60+
61+
# time to wait for a reply from the RADIUS server
62+
radius_timeout 10
63+
64+
# resend request this many times before trying the next server
65+
radius_retries 3
66+
67+
# The length of time in seconds that we skip a nonresponsive RADIUS
68+
# server for transaction requests. Server(s) being in the "dead" state
69+
# are tried only after all other non-dead servers have been tried and
70+
# failed or timeouted. The deadtime interval starts when the server
71+
# does not respond to an authentication/accounting request transmissions.
72+
# When the interval expires, the "dead" server would be re-tried again,
73+
# and if it's still down then it will be considered "dead" for another
74+
# such interval and so on. This option is no-op if there is only one
75+
# server in the list. Set to 0 in order to disable the feature.
76+
radius_deadtime 0
77+
78+
# local address from which radius packets have to be sent
79+
bindaddr *
80+
81+
# Transport Protocol Support
82+
# Use "1" for using UDP and "2" for TCP protocol.
83+
radius_proto 1
84+
85+
# file which holds sequence number for communication with the
86+
# RADIUS server
87+
seqfile /var/run/radius.seq
88+
89+
# LOCAL settings
90+
91+
# program to execute for local login
92+
# it must support the -f flag for preauthenticated login
93+
login_local /bin/login

0 commit comments

Comments
 (0)