Skip to content

Commit

Permalink
TCP Support
Browse files Browse the repository at this point in the history
  • Loading branch information
aravindprasads committed Oct 1, 2015
1 parent 06b389a commit 2d830c4
Show file tree
Hide file tree
Showing 13 changed files with 336 additions and 5 deletions.
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

0 comments on commit 2d830c4

Please sign in to comment.