charon.plugins.eap-radius.server =
IP/Hostname of RADIUS server.
+charon.plugins.eap-radius.source =
+ Optional specific source IP to use.
+
charon.plugins.eap-radius.retransmit_base = 1.4
Base to use for calculating exponential back off.
charon.plugins.eap-radius.servers {}
Section to specify multiple RADIUS servers.
- Section to specify multiple RADIUS servers. The **nas_identifier**,
- **secret**, **sockets** and **port** (or **auth_port**) options can be
- specified for each server. A server's IP/Hostname can be configured using
- the **address** option. The **acct_port** [1813] option can be used to
- specify the port used for RADIUS accounting. For each RADIUS server a
- priority can be specified using the **preference** [0] option. The
+ Section to specify multiple RADIUS servers. The **source**,
+ **nas_identifier**, **secret**, **sockets** and **port** (or **auth_port**)
+ options can be specified for each server. A server's IP/Hostname can be
+ configured using the **address** option. The **acct_port** [1813] option can
+ be used to specify the port used for RADIUS accounting. For each RADIUS
+ server a priority can be specified using the **preference** [0] option. The
retransmission time for each server can set set using **retransmit_base**,
**retransmit_timeout** and **retransmit_tries**.
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2025 Tobias Brunner
* Copyright (C) 2009 Martin Willi
*
* Copyright (C) secunet Security Networks AG
{
enumerator_t *enumerator;
radius_config_t *config;
- char *nas_identifier, *secret, *address, *section;
+ char *nas_identifier, *secret, *address, *source, *section;
int auth_port, acct_port, sockets, preference;
u_int retransmit_tries;
double retransmit_timeout, retransmit_base;
DBG1(DBG_CFG, "no RADIUS secret defined");
return;
}
+ source = lib->settings->get_str(lib->settings,
+ "%s.plugins.eap-radius.source", NULL, lib->ns);
nas_identifier = lib->settings->get_str(lib->settings,
"%s.plugins.eap-radius.nas_identifier", "strongSwan",
lib->ns);
retransmit_base = lib->settings->get_double(lib->settings,
"%s.plugins.eap-radius.retransmit_base", 1.4, lib->ns);
- config = radius_config_create(address, address, auth_port, ACCT_PORT,
+ config = radius_config_create(address, address, source, auth_port, ACCT_PORT,
nas_identifier, secret, sockets, 0,
retransmit_tries, retransmit_timeout,
retransmit_base);
DBG1(DBG_CFG, "RADIUS server '%s' misses secret, skipped", section);
continue;
}
+ source = lib->settings->get_str(lib->settings,
+ "%s.plugins.eap-radius.servers.%s.source",
+ lib->settings->get_str(lib->settings,
+ "%s.plugins.eap-radius.source", NULL, lib->ns),
+ lib->ns, section);
nas_identifier = lib->settings->get_str(lib->settings,
"%s.plugins.eap-radius.servers.%s.nas_identifier",
lib->settings->get_str(lib->settings,
"%s.plugins.eap-radius.servers.%s.preference", 0,
lib->ns, section);
- config = radius_config_create(section, address, auth_port, acct_port,
+ config = radius_config_create(section, address, source, auth_port, acct_port,
nas_identifier, secret, sockets, preference,
retransmit_tries, retransmit_timeout,
retransmit_base);
/**
* See header
*/
-radius_config_t *radius_config_create(char *name, char *address,
+radius_config_t *radius_config_create(char *name, char *address, char *source,
uint16_t auth_port, uint16_t acct_port,
char *nas_identifier, char *secret,
int sockets, int preference,
while (sockets--)
{
- socket = radius_socket_create(address, auth_port, acct_port,
+ socket = radius_socket_create(address, source, auth_port, acct_port,
chunk_create(secret, strlen(secret)),
tries, timeout, base);
if (!socket)
*
* @param name server name
* @param address server address
+ * @param source optional source address
* @param auth_port server port for authentication
* @param acct_port server port for accounting
* @param nas_identifier NAS-Identifier to use with this server
* @param timeout retransmission timeout
* @param base base to calculate retransmission timeout
*/
-radius_config_t *radius_config_create(char *name, char *address,
+radius_config_t *radius_config_create(char *name, char *address, char *source,
uint16_t auth_port, uint16_t acct_port,
char *nas_identifier, char *secret,
int sockets, int preference,
/*
+ * Copyright (C) 2015-2025 Tobias Brunner
* Copyright (C) 2010 Martin Willi
*
* Copyright (C) secunet Security Networks AG
*/
char *address;
+ /**
+ * Source address
+ */
+ char *source;
+
/**
* current RADIUS identifier
*/
static bool check_connection(private_radius_socket_t *this,
int *fd, uint16_t port)
{
+ host_t *server, *src = NULL;
+
if (*fd == -1)
{
- host_t *server;
-
server = host_create_from_dns(this->address, AF_UNSPEC, port);
if (!server)
{
server->destroy(server);
return FALSE;
}
+ if (this->source)
+ {
+ src = host_create_from_string_and_family(this->source,
+ server->get_family(server), 0);
+ if (!src)
+ {
+ DBG1(DBG_CFG, "invalid source address '%s' to reach RADIUS "
+ "server %#H", this->source, server);
+ goto error;
+ }
+ if (bind(*fd, src->get_sockaddr(src),
+ *src->get_sockaddr_len(src)) == -1)
+ {
+ DBG1(DBG_CFG, "binding RADIUS socket to %H failed: %s", src,
+ strerror(errno));
+ goto error;
+ }
+ }
if (connect(*fd, server->get_sockaddr(server),
*server->get_sockaddr_len(server)) < 0)
{
DBG1(DBG_CFG, "connecting RADIUS socket to %#H failed: %s",
server, strerror(errno));
- server->destroy(server);
- close(*fd);
- *fd = -1;
- return FALSE;
+ goto error;
}
server->destroy(server);
+ DESTROY_IF(src);
}
return TRUE;
+
+error:
+ server->destroy(server);
+ DESTROY_IF(src);
+ close(*fd);
+ *fd = -1;
+ return FALSE;
}
/**
/**
* See header
*/
-radius_socket_t *radius_socket_create(char *address, uint16_t auth_port,
+radius_socket_t *radius_socket_create(char *address, char *source,
+ uint16_t auth_port,
uint16_t acct_port, chunk_t secret,
u_int tries, double timeout, double base)
{
.destroy = _destroy,
},
.address = address,
+ .source = source,
.auth_port = auth_port,
.auth_fd = -1,
.acct_port = acct_port,
* Create a radius_socket instance.
*
* @param address server name
+ * @param source optional source address
* @param auth_port server port for authentication
* @param acct_port server port for accounting
* @param secret RADIUS secret
* @param timeout retransmission timeout
* @param base base to calculate retransmission timeout
*/
-radius_socket_t *radius_socket_create(char *address, uint16_t auth_port,
- uint16_t acct_port, chunk_t secret,
- u_int tries, double timeout, double base);
+radius_socket_t *radius_socket_create(char *address, char *source,
+ uint16_t auth_port, uint16_t acct_port,
+ chunk_t secret, u_int tries,
+ double timeout, double base);
#endif /** RADIUS_SOCKET_H_ @}*/