Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCP Support #64

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions etc/radiusclient.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ radius_deadtime 0
# local address from which radius packets have to be sent
bindaddr *

# Transport Protocol Support
# Use "1" for using UDP and "2" for TCP protocol.
radius_proto 1

# LOCAL settings

# program to execute for local login
Expand Down
5 changes: 5 additions & 0 deletions include/freeradius-client.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ typedef struct value_pair
#define TIMEOUT_RC 1
#define REJECT_RC 2

/* Transport Protocol Types */
#define PROTO_TCP 1
#define PROTO_UDP 2

typedef struct send_data /* Used to pass information to sendserver() function */
{
uint8_t code; //!< RADIUS packet code.
Expand All @@ -430,6 +434,7 @@ typedef struct send_data /* Used to pass information to sendserver() function */
int retries;
VALUE_PAIR *send_pairs; //!< More a/v pairs to send.
VALUE_PAIR *receive_pairs; //!< Where to place received a/v pairs.
uint8_t radius_proto; //!< Transport protocol type.
} SEND_DATA;

#ifndef MIN
Expand Down
7 changes: 7 additions & 0 deletions lib/buildreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **r
double now = 0;
time_t dtime;
unsigned type;
int radius_proto = 0;

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

radius_proto = rc_conf_int(rh, "radius_proto");
if(1 == radius_proto)
data.radius_proto = PROTO_UDP;
else
data.radius_proto = PROTO_TCP;

data.send_pairs = send;
data.receive_pairs = NULL;

Expand Down
1 change: 1 addition & 0 deletions lib/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static OPTION config_options_default[] = {
{"radius_retries", OT_INT, ST_UNDEF, NULL},
{"radius_deadtime", OT_INT, ST_UNDEF, NULL},
{"bindaddr", OT_STR, ST_UNDEF, NULL},
{"radius_proto", OT_INT, ST_UNDEF, NULL},
/* local options */
{"login_local", OT_STR, ST_UNDEF, NULL},
};
Expand Down
14 changes: 13 additions & 1 deletion lib/sendserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,11 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
}
}

sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);
if(PROTO_TCP == data->radius_proto)
sockfd = socket (our_sockaddr.ss_family, SOCK_STREAM, 0);
else
sockfd = socket (our_sockaddr.ss_family, SOCK_DGRAM, 0);

if (sockfd < 0)
{
memset (secret, '\0', sizeof (secret));
Expand Down Expand Up @@ -386,6 +390,14 @@ int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
for (;;)
{
do {
if(PROTO_TCP == data->radius_proto) {
if((connect(sockfd, SA(auth_addr->ai_addr), auth_addr->ai_addrlen)) != 0)
{
rc_log(LOG_ERR, "%s: Connect Call Failed : %s", __FUNCTION__, strerror(errno));
result = -1;
break;
}
}
result = sendto (sockfd, (char *) auth, (unsigned int)total_length,
(int) 0, SA(auth_addr->ai_addr), auth_addr->ai_addrlen);
} while (result == -1 && errno == EINTR);
Expand Down
6 changes: 3 additions & 3 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

SUBDIRS = docker
EXTRA_DIST = radiusclient-ipv6.conf servers-ipv6 \
radiusclient.conf servers README
radiusclient.conf servers radiusclient-tcp.conf servers-tcp README

nodist_check_SCRIPTS = basic-tests.sh ipv6-tests.sh
TESTS = basic-tests.sh ipv6-tests.sh
nodist_check_SCRIPTS = basic-tests.sh ipv6-tests.sh tcp-tests.sh
TESTS = basic-tests.sh ipv6-tests.sh tcp-tests.sh

TESTS_ENVIRONMENT = \
top_builddir="$(top_builddir)" \
Expand Down
1 change: 0 additions & 1 deletion tests/docker/freeradius-users
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@ test6 Cleartext-Password := "test"
Framed-IP-Netmask = 255.255.255.0,
Framed-Routing = Broadcast-Listen,
Framed-MTU = 1500,

144 changes: 144 additions & 0 deletions tests/docker/radius-clients.conf
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,150 @@ client localhost2 {
# coa_server = coa
}

client localhost {
# Allowed values are:
# dotted quad (1.2.3.4)
# hostname (radius.example.com)
ipaddr = 0.0.0.0/0
proto = tcp
# OR, you can use an IPv6 address, but not both
# at the same time.
# ipv6addr = :: # any. ::1 == localhost

#
# A note on DNS: We STRONGLY recommend using IP addresses
# rather than host names. Using host names means that the
# server will do DNS lookups when it starts, making it
# dependent on DNS. i.e. If anything goes wrong with DNS,
# the server won't start!
#
# The server also looks up the IP address from DNS once, and
# only once, when it starts. If the DNS record is later
# updated, the server WILL NOT see that update.
#

# One client definition can be applied to an entire network.
# e.g. 127/8 should be defined with "ipaddr = 127.0.0.0" and
# "netmask = 8"
#
# If not specified, the default netmask is 32 (i.e. /32)
#
# We do NOT recommend using anything other than 32. There
# are usually other, better ways to achieve the same goal.
# Using netmasks of other than 32 can cause security issues.
#
# You can specify overlapping networks (127/8 and 127.0/16)
# In that case, the smallest possible network will be used
# as the "best match" for the client.
#
# Clients can also be defined dynamically at run time, based
# on any criteria. e.g. SQL lookups, keying off of NAS-Identifier,
# etc.
# See raddb/sites-available/dynamic-clients for details.
#

# netmask = 32

#
# The shared secret use to "encrypt" and "sign" packets between
# the NAS and FreeRADIUS. You MUST change this secret from the
# default, otherwise it's not a secret any more!
#
# The secret can be any string, up to 8k characters in length.
#
# Control codes can be entered vi octal encoding,
# e.g. "\101\102" == "AB"
# Quotation marks can be entered by escaping them,
# e.g. "foo\"bar"
#
# A note on security: The security of the RADIUS protocol
# depends COMPLETELY on this secret! We recommend using a
# shared secret that is composed of:
#
# upper case letters
# lower case letters
# numbers
#
# And is at LEAST 8 characters long, preferably 16 characters in
# length. The secret MUST be random, and should not be words,
# phrase, or anything else that is recognizable.
#
# The default secret below is only for testing, and should
# not be used in any real environment.
#
secret = testing123

#
# Old-style clients do not send a Message-Authenticator
# in an Access-Request. RFC 5080 suggests that all clients
# SHOULD include it in an Access-Request. The configuration
# item below allows the server to require it. If a client
# is required to include a Message-Authenticator and it does
# not, then the packet will be silently discarded.
#
# allowed values: yes, no
require_message_authenticator = no

#
# The short name is used as an alias for the fully qualified
# domain name, or the IP address.
#
# It is accepted for compatibility with 1.x, but it is no
# longer necessary in 2.0
#
# shortname = localhost

#
# the following three fields are optional, but may be used by
# checkrad.pl for simultaneous use checks
#

#
# The nastype tells 'checkrad.pl' which NAS-specific method to
# use to query the NAS for simultaneous use.
#
# Permitted NAS types are:
#
# cisco
# computone
# livingston
# juniper
# max40xx
# multitech
# netserver
# pathras
# patton
# portslave
# tc
# usrhiper
# other # for all other types

#
nas_type = other # localhost isn't usually a NAS...

#
# The following two configurations are for future use.
# The 'naspasswd' file is currently used to store the NAS
# login name and password, which is used by checkrad.pl
# when querying the NAS for simultaneous use.
#
# login = !root
# password = someadminpas

#
# As of 2.0, clients can also be tied to a virtual server.
# This is done by setting the "virtual_server" configuration
# item, as in the example below.
#
# virtual_server = home1

#
# A pointer to the "home_server_pool" OR a "home_server"
# section that contains the CoA configuration for this
# client. For an example of a coa home server or pool,
# see raddb/sites-available/originate-coa
# coa_server = coa
}
# IPv6 Client
#client ::1 {
# secret = testing123
Expand Down
4 changes: 4 additions & 0 deletions tests/radiusclient-ipv6.conf
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ radius_deadtime 0
# local address from which radius packets have to be sent
bindaddr *

# Transport Protocol Support
# Use "1" for using UDP and "2" for TCP protocol.
radius_proto 1

# file which holds sequence number for communication with the
# RADIUS server
seqfile /var/run/radius.seq
Expand Down
93 changes: 93 additions & 0 deletions tests/radiusclient-tcp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# General settings

# specify which authentication comes first respectively which
# authentication is used. possible values are: "radius" and "local".
# if you specify "radius,local" then the RADIUS server is asked
# first then the local one. if only one keyword is specified only
# this server is asked.
auth_order radius,local

# maximum login tries a user has
login_tries 4

# timeout for all login tries
# if this time is exceeded the user is kicked out
login_timeout 60

# name of the nologin file which when it exists disables logins.
# it may be extended by the ttyname which will result in
# a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable
# logins on /dev/ttyS2)
nologin /etc/nologin

# name of the issue file. it's only display when no username is passed
# on the radlogin command line
issue /usr/local/etc/radiusclient/issue

# RADIUS settings

# RADIUS server to use for authentication requests. this config
# item can appear more then one time. if multiple servers are
# defined they are tried in a round robin fashion if one
# server is not answering.
# optionally you can specify a the port number on which is remote
# RADIUS listens separated by a colon from the hostname. if
# no port is specified /etc/services is consulted of the radius
# service. if this fails also a compiled in default is used.
authserver localhost

# RADIUS server to use for accouting requests. All that I
# said for authserver applies, too.
#
acctserver localhost

# file holding shared secrets used for the communication
# between the RADIUS client and server
servers ./servers-tcp-temp

# dictionary of allowed attributes and values
# just like in the normal RADIUS distributions
dictionary ../etc/dictionary

# file which specifies mapping between ttyname and NAS-Port attribute
mapfile ../etc/port-id-map

# default authentication realm to append to all usernames if no
# realm was explicitly specified by the user
# the radiusd directly form Livingston doesnt use any realms, so leave
# it blank then
default_realm

# time to wait for a reply from the RADIUS server
radius_timeout 10

# resend request this many times before trying the next server
radius_retries 3

# The length of time in seconds that we skip a nonresponsive RADIUS
# server for transaction requests. Server(s) being in the "dead" state
# are tried only after all other non-dead servers have been tried and
# failed or timeouted. The deadtime interval starts when the server
# does not respond to an authentication/accounting request transmissions.
# When the interval expires, the "dead" server would be re-tried again,
# and if it's still down then it will be considered "dead" for another
# such interval and so on. This option is no-op if there is only one
# server in the list. Set to 0 in order to disable the feature.
radius_deadtime 0

# local address from which radius packets have to be sent
bindaddr *

# Transport Protocol Support
# Use "1" for using UDP and "2" for TCP protocol.
radius_proto 1

# file which holds sequence number for communication with the
# RADIUS server
seqfile /var/run/radius.seq

# LOCAL settings

# program to execute for local login
# it must support the -f flag for preauthenticated login
login_local /bin/login
4 changes: 4 additions & 0 deletions tests/radiusclient.conf
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ radius_deadtime 0
# local address from which radius packets have to be sent
bindaddr *

# Transport Protocol Support
# Use "1" for using UDP and "2" for TCP protocol.
radius_proto 1

# file which holds sequence number for communication with the
# RADIUS server
seqfile /var/run/radius.seq
Expand Down
3 changes: 3 additions & 0 deletions tests/servers-tcp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Server Name or Client/Server pair Key
## ---------------- ---------------
localhost/localhost testing123
Loading