Skip to content

Commit 5224df7

Browse files
jimdigrizalandekok
authored andcommitted
rlm_rest: support UNIX (including abstract) sockets
1 parent ce8e3f7 commit 5224df7

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

raddb/mods-available/rest

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ rest {
4949
#
5050
connect_uri = "http://127.0.0.1"
5151

52+
#
53+
# When set, connects to the server over a UNIX socket which may be
54+
# helpful for those with (pseudo)security constraints that make it
55+
# easier to use an UNIX socket than explain to an auditor the use of
56+
# non-TLS HTTP localhost connections.
57+
#
58+
# NOTE: This is not allowed to be an xlat as it can lead to security issues.
59+
#
60+
# connect_uri_socket = "/run/myprogram.sock"
61+
62+
#
63+
# When set, connect_uri_socket is an abstract UNIX socket
64+
#
65+
# connect_uri_socket_abstract = "no"
66+
5267
#
5368
# How long before new connection attempts timeout, defaults to 4.0 seconds.
5469
#

src/modules/rlm_rest/rest.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@ void *mod_conn_create(TALLOC_CTX *ctx, void *instance)
413413
SET_OPTION(CURLOPT_SSL_VERIFYHOST, 0);
414414
SET_OPTION(CURLOPT_CONNECT_ONLY, 1);
415415
SET_OPTION(CURLOPT_URL, inst->connect_uri);
416+
/* libcurl ignores this when connect_uri_socket is NULL */
417+
SET_OPTION(
418+
inst->connect_uri_socket_abstract
419+
? CURLOPT_ABSTRACT_UNIX_SOCKET
420+
: CURLOPT_UNIX_SOCKET_PATH,
421+
inst->connect_uri_socket);
416422
SET_OPTION(CURLOPT_NOSIGNAL, 1);
417423

418424
DEBUG("rlm_rest (%s): Connecting to \"%s\"", inst->xlat_name, inst->connect_uri);
@@ -2062,6 +2068,12 @@ int rest_request_config(rlm_rest_t *instance, rlm_rest_section_t *section,
20622068
* Setup any header options and generic headers.
20632069
*/
20642070
SET_OPTION(CURLOPT_URL, uri);
2071+
/* libcurl ignores this when connect_uri_socket is NULL */
2072+
SET_OPTION(
2073+
instance->connect_uri_socket_abstract
2074+
? CURLOPT_ABSTRACT_UNIX_SOCKET
2075+
: CURLOPT_UNIX_SOCKET_PATH,
2076+
instance->connect_uri_socket);
20652077
SET_OPTION(CURLOPT_NOSIGNAL, 1);
20662078
SET_OPTION(CURLOPT_USERAGENT, "FreeRADIUS " RADIUSD_VERSION_STRING);
20672079

src/modules/rlm_rest/rest.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ typedef struct rlm_rest_t {
166166

167167
char const *connect_uri; //!< URI we attempt to connect to, to pre-establish
168168
//!< TCP connections.
169+
char const *connect_uri_socket; //!< UNIX socket path we connect to.
170+
bool connect_uri_socket_abstract; //!< If the UNIX socket is an abstract socket.
169171

170172
struct timeval connect_timeout_tv; //!< Connection timeout timeval.
171173
long connect_timeout; //!< Connection timeout ms.

src/modules/rlm_rest/rlm_rest.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ RCSID("$Id$")
2929
#include <freeradius-devel/rad_assert.h>
3030

3131
#include <ctype.h>
32+
#include <sys/un.h>
3233
#include "rest.h"
3334

3435
/*
@@ -57,7 +58,7 @@ static CONF_PARSER tls_config[] = {
5758
* buffer over-flows.
5859
*/
5960
static const CONF_PARSER section_config[] = {
60-
{ "uri", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_XLAT, rlm_rest_section_t, uri), "" },
61+
{ "uri", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_XLAT, rlm_rest_section_t, uri), "" },
6162
{ "method", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_rest_section_t, method_str), "GET" },
6263
{ "body", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_rest_section_t, body_str), "none" },
6364
{ "attr_num", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_rest_section_t, attr_num), "no" },
@@ -85,6 +86,8 @@ static const CONF_PARSER section_config[] = {
8586

8687
static const CONF_PARSER module_config[] = {
8788
{ "connect_uri", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_rest_t, connect_uri), NULL },
89+
{ "connect_uri_socket", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_rest_t, connect_uri_socket), NULL },
90+
{ "connect_uri_socket_abstract", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_rest_t, connect_uri_socket_abstract), "no" },
8891
{ "connect_timeout", FR_CONF_OFFSET(PW_TYPE_TIMEVAL, rlm_rest_t, connect_timeout_tv), "4.0" },
8992
{ "http_negotiation", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_rest_t, http_negotiation_str), "default" },
9093

@@ -940,6 +943,16 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
940943
return -1;
941944
}
942945

946+
if (inst->connect_uri_socket) {
947+
struct sockaddr_un sa;
948+
size_t max_len = sizeof(sa.sun_path) - 1; /* account for trailing NUL */
949+
950+
if (strlen(inst->connect_uri_socket) > max_len) {
951+
cf_log_err_cs(conf, "connect_uri_socket too long, limit is %ld bytes.", max_len);
952+
return -1;
953+
}
954+
}
955+
943956
inst->http_negotiation = fr_str2int(http_negotiation_table, inst->http_negotiation_str, -1);
944957
if (inst->http_negotiation == -1) {
945958
cf_log_err_cs(conf, "Unsupported HTTP version \"%s\".", inst->http_negotiation_str);

0 commit comments

Comments
 (0)