Add support for a tls flag in sudo_parse_host_port().
If the string "(tls)" appears at the end, the tls flag is set to true and the default tls port is used if necessary.
This commit is contained in:
@@ -208,8 +208,8 @@ __dso_public int sudo_getgrouplist2_v1(const char *name, gid_t basegid, GETGROUP
|
|||||||
#define sudo_getgrouplist2(_a, _b, _c, _d) sudo_getgrouplist2_v1((_a), (_b), (_c), (_d))
|
#define sudo_getgrouplist2(_a, _b, _c, _d) sudo_getgrouplist2_v1((_a), (_b), (_c), (_d))
|
||||||
|
|
||||||
/* host_port.c */
|
/* host_port.c */
|
||||||
__dso_public bool sudo_parse_host_port_v1(char *str, char **hostp, char **portp, char *defport);
|
__dso_public bool sudo_parse_host_port_v1(char *str, char **hostp, char **portp, bool *tlsp, char *defport, char *defport_tls);
|
||||||
#define sudo_parse_host_port(_a, _b, _c, _d) sudo_parse_host_port_v1((_a), (_b), (_c), (_d))
|
#define sudo_parse_host_port(_a, _b, _c, _d, _e, _f) sudo_parse_host_port_v1((_a), (_b), (_c), (_d), (_e), (_f))
|
||||||
|
|
||||||
/* key_val.c */
|
/* key_val.c */
|
||||||
__dso_public char *sudo_new_key_val_v1(const char *key, const char *value);
|
__dso_public char *sudo_new_key_val_v1(const char *key, const char *value);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
* Copyright (c) 2019-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
||||||
#include "sudo_compat.h"
|
#include "sudo_compat.h"
|
||||||
@@ -40,10 +41,12 @@
|
|||||||
* Fills in hostp and portp which may point within str, which is modified.
|
* Fills in hostp and portp which may point within str, which is modified.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
sudo_parse_host_port_v1(char *str, char **hostp, char **portp, char *defport)
|
sudo_parse_host_port_v1(char *str, char **hostp, char **portp, bool *tlsp,
|
||||||
|
char *defport, char *defport_tls)
|
||||||
{
|
{
|
||||||
char *port, *host = str;
|
char *flags, *port, *host = str;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
bool tls = false;
|
||||||
debug_decl(sudo_parse_host_port, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_parse_host_port, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* Check for IPv6 address like [::0] followed by optional port */
|
/* Check for IPv6 address like [::0] followed by optional port */
|
||||||
@@ -56,11 +59,17 @@ sudo_parse_host_port_v1(char *str, char **hostp, char **portp, char *defport)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
*port++ = '\0';
|
*port++ = '\0';
|
||||||
if (*port == ':') {
|
switch (*port) {
|
||||||
port++;
|
case ':':
|
||||||
} else if (*port == '\0') {
|
port++;
|
||||||
port = NULL; /* no port specified */
|
break;
|
||||||
} else {
|
case '\0':
|
||||||
|
port = NULL; /* no port specified */
|
||||||
|
break;
|
||||||
|
case '(':
|
||||||
|
/* flag, handled below */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"invalid IPv6 address %s", str);
|
"invalid IPv6 address %s", str);
|
||||||
goto done;
|
goto done;
|
||||||
@@ -71,13 +80,24 @@ sudo_parse_host_port_v1(char *str, char **hostp, char **portp, char *defport)
|
|||||||
*port++ = '\0';
|
*port++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for optional tls flag at the end. */
|
||||||
|
flags = strchr(port ? port : host, '(');
|
||||||
|
if (flags != NULL) {
|
||||||
|
if (strcasecmp(flags, "(tls)") == 0)
|
||||||
|
tls = true;
|
||||||
|
*flags = '\0';
|
||||||
|
if (port == flags)
|
||||||
|
port = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (port == NULL)
|
if (port == NULL)
|
||||||
port = defport;
|
port = tls ? defport_tls : defport;
|
||||||
else if (*port == '\0')
|
else if (*port == '\0')
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
*hostp = host;
|
*hostp = host;
|
||||||
*portp = port;
|
*portp = port;
|
||||||
|
*tlsp = tls;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-License-Identifier: ISC
|
* SPDX-License-Identifier: ISC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010 Todd C. Miller <Todd.Miller@sudo.ws>
|
* Copyright (c) 2019-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -47,22 +47,34 @@ struct host_port_test {
|
|||||||
const char *str; /* input string */
|
const char *str; /* input string */
|
||||||
const char *host; /* parsed host */
|
const char *host; /* parsed host */
|
||||||
const char *port; /* parsed port */
|
const char *port; /* parsed port */
|
||||||
|
bool tls; /* parsed TLS flag */
|
||||||
char *defport; /* default port */
|
char *defport; /* default port */
|
||||||
|
char *defport_tls; /* default port */
|
||||||
bool ret; /* return value */
|
bool ret; /* return value */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct host_port_test test_data[] = {
|
static struct host_port_test test_data[] = {
|
||||||
{ "xerxes", "xerxes", "12345", "12345", true },
|
/* No TLS */
|
||||||
{ "xerxes:12345", "xerxes", "12345", "67890", true },
|
{ "xerxes", "xerxes", "12345", false, "12345", NULL, true },
|
||||||
{ "127.0.0.1", "127.0.0.1", "12345", "12345", true },
|
{ "xerxes:12345", "xerxes", "12345", false, "67890", NULL, true },
|
||||||
{ "127.0.0.1:12345", "127.0.0.1", "12345", "67890", true },
|
{ "127.0.0.1", "127.0.0.1", "12345", false, "12345", NULL, true },
|
||||||
{ "[::1]", "::1", "12345", "12345", true },
|
{ "127.0.0.1:12345", "127.0.0.1", "12345", false, "67890", NULL, true },
|
||||||
{ "[::1]:12345", "::1", "12345", "67890", true },
|
{ "[::1]", "::1", "12345", false, "12345", NULL, true },
|
||||||
|
{ "[::1]:12345", "::1", "12345", false, "67890", NULL, true },
|
||||||
|
|
||||||
{ "xerxes:", NULL, NULL, "12345", false }, /* missing port */
|
/* With TLS */
|
||||||
{ "127.0.0.1:", NULL, NULL, "12345", false }, /* missing port */
|
{ "xerxes(tls)", "xerxes", "12345", true, "5678", "12345", true },
|
||||||
{ "[::1:12345", NULL, NULL, "67890", false }, /* missing bracket */
|
{ "xerxes:12345(tls)", "xerxes", "12345", true, "5678", "67890", true },
|
||||||
{ "[::1]:", NULL, NULL, "12345", false }, /* missing port */
|
{ "127.0.0.1(tls)", "127.0.0.1", "12345", true, "5678", "12345", true },
|
||||||
|
{ "127.0.0.1:12345(tls)", "127.0.0.1", "12345", true, "5678", "67890", true },
|
||||||
|
{ "[::1](tls)", "::1", "12345", true, "5678", "12345", true },
|
||||||
|
{ "[::1]:12345(tls)", "::1", "12345", true, "5678", "67890", true },
|
||||||
|
|
||||||
|
/* Errors */
|
||||||
|
{ "xerxes:", NULL, NULL, false, "12345", NULL, false }, /* missing port */
|
||||||
|
{ "127.0.0.1:", NULL, NULL, false, "12345", NULL, false }, /* missing port */
|
||||||
|
{ "[::1:12345", NULL, NULL, false, "67890", NULL, false }, /* missing bracket */
|
||||||
|
{ "[::1]:", NULL, NULL, false, "12345", NULL, false }, /* missing port */
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,18 +83,20 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int i, errors = 0, ntests = 0;
|
int i, errors = 0, ntests = 0;
|
||||||
char *host, *port, *copy = NULL;
|
char *host, *port, *copy = NULL;
|
||||||
bool ret;
|
bool ret, tls;
|
||||||
|
|
||||||
initprogname(argc > 0 ? argv[0] : "host_port_test");
|
initprogname(argc > 0 ? argv[0] : "host_port_test");
|
||||||
|
|
||||||
for (i = 0; test_data[i].str != NULL; i++) {
|
for (i = 0; test_data[i].str != NULL; i++) {
|
||||||
host = port = NULL;
|
host = port = NULL;
|
||||||
|
tls = false;
|
||||||
free(copy);
|
free(copy);
|
||||||
if ((copy = strdup(test_data[i].str)) == NULL)
|
if ((copy = strdup(test_data[i].str)) == NULL)
|
||||||
sudo_fatal_nodebug(NULL);
|
sudo_fatal_nodebug(NULL);
|
||||||
|
|
||||||
ntests++;
|
ntests++;
|
||||||
ret = sudo_parse_host_port(copy, &host, &port, test_data[i].defport);
|
ret = sudo_parse_host_port(copy, &host, &port, &tls,
|
||||||
|
test_data[i].defport, test_data[i].defport_tls);
|
||||||
if (ret != test_data[i].ret) {
|
if (ret != test_data[i].ret) {
|
||||||
sudo_warnx_nodebug("test #%d: %s: returned %s, expected %s",
|
sudo_warnx_nodebug("test #%d: %s: returned %s, expected %s",
|
||||||
ntests, test_data[i].str, ret ? "true" : "false",
|
ntests, test_data[i].str, ret ? "true" : "false",
|
||||||
@@ -117,6 +131,13 @@ main(int argc, char *argv[])
|
|||||||
errors++;
|
errors++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (tls != test_data[i].tls) {
|
||||||
|
sudo_warnx_nodebug("test #%d: %s: bad tls, expected %s, got %s",
|
||||||
|
ntests, test_data[i].str, test_data[i].tls ? "true" : "false",
|
||||||
|
tls ? "true" : "false");
|
||||||
|
errors++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(copy);
|
free(copy);
|
||||||
if (ntests != 0) {
|
if (ntests != 0) {
|
||||||
|
@@ -379,7 +379,7 @@ cb_listen_address(struct logsrvd_config *config, const char *str)
|
|||||||
{
|
{
|
||||||
struct addrinfo hints, *res, *res0 = NULL;
|
struct addrinfo hints, *res, *res0 = NULL;
|
||||||
char *copy, *host, *port;
|
char *copy, *host, *port;
|
||||||
bool ret = false;
|
bool tls, ret = false;
|
||||||
int error;
|
int error;
|
||||||
debug_decl(cb_iolog_mode, SUDO_DEBUG_UTIL);
|
debug_decl(cb_iolog_mode, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
@@ -389,7 +389,8 @@ cb_listen_address(struct logsrvd_config *config, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse host[:port] */
|
/* Parse host[:port] */
|
||||||
if (!sudo_parse_host_port(copy, &host, &port, DEFAULT_PORT_STR))
|
if (!sudo_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT_STR,
|
||||||
|
DEFAULT_PORT_STR))
|
||||||
goto done;
|
goto done;
|
||||||
if (host[0] == '*' && host[1] == '\0')
|
if (host[0] == '*' && host[1] == '\0')
|
||||||
host = NULL;
|
host = NULL;
|
||||||
|
@@ -215,11 +215,13 @@ log_server_connect(struct sudoers_str_list *servers, bool tcp_keepalive,
|
|||||||
char *copy, *host, *port;
|
char *copy, *host, *port;
|
||||||
const char *cause = NULL;
|
const char *cause = NULL;
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
|
bool tls;
|
||||||
debug_decl(restore_nproc, SUDOERS_DEBUG_UTIL);
|
debug_decl(restore_nproc, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
STAILQ_FOREACH(server, servers, entries) {
|
STAILQ_FOREACH(server, servers, entries) {
|
||||||
copy = strdup(server->str);
|
copy = strdup(server->str);
|
||||||
if (!sudo_parse_host_port(copy, &host, &port, DEFAULT_PORT_STR)) {
|
if (!sudo_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT_STR,
|
||||||
|
DEFAULT_PORT_STR)) {
|
||||||
free(copy);
|
free(copy);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user