[client] add --server-resolve-ipv4 to only accept IPv4 addresses from DNS for the SPA server
This commit is contained in:
parent
a4309ad768
commit
b03c007c44
@ -49,6 +49,7 @@ enum {
|
||||
RC_FILE_PATH,
|
||||
RESOLVE_HTTP_ONLY,
|
||||
RESOLVE_URL,
|
||||
SERVER_RESOLVE_IPV4,
|
||||
USE_HMAC,
|
||||
USE_WGET_USER_AGENT,
|
||||
SPA_ICMP_TYPE,
|
||||
@ -139,6 +140,7 @@ static struct option cmd_opts[] =
|
||||
{"resolve-ip-https", 0, NULL, 'R'}, /* synonym, default is HTTPS */
|
||||
{"resolve-http-only", 0, NULL, RESOLVE_HTTP_ONLY},
|
||||
{"resolve-url", 1, NULL, RESOLVE_URL},
|
||||
{"server-resolve-ipv4", 0, NULL, SERVER_RESOLVE_IPV4},
|
||||
{"show-last", 0, NULL, SHOW_LAST_ARGS},
|
||||
{"source-ip", 0, NULL, 's'},
|
||||
{"source-port", 1, NULL, 'S'},
|
||||
|
||||
@ -124,6 +124,7 @@ enum
|
||||
FWKNOP_CLI_ARG_NAT_ACCESS,
|
||||
FWKNOP_CLI_ARG_HTTP_USER_AGENT,
|
||||
FWKNOP_CLI_ARG_RESOLVE_URL,
|
||||
FWKNOP_CLI_ARG_SERVER_RESOLVE_IPV4,
|
||||
FWKNOP_CLI_ARG_NAT_LOCAL,
|
||||
FWKNOP_CLI_ARG_NAT_RAND_PORT,
|
||||
FWKNOP_CLI_ARG_NAT_PORT,
|
||||
@ -172,6 +173,7 @@ static fko_var_t fko_var_array[FWKNOP_CLI_LAST_ARG] =
|
||||
{ "NAT_ACCESS", FWKNOP_CLI_ARG_NAT_ACCESS },
|
||||
{ "HTTP_USER_AGENT", FWKNOP_CLI_ARG_HTTP_USER_AGENT },
|
||||
{ "RESOLVE_URL", FWKNOP_CLI_ARG_RESOLVE_URL },
|
||||
{ "SERVER_RESOLVE_IPV4", FWKNOP_CLI_ARG_SERVER_RESOLVE_IPV4 },
|
||||
{ "NAT_LOCAL", FWKNOP_CLI_ARG_NAT_LOCAL },
|
||||
{ "NAT_RAND_PORT", FWKNOP_CLI_ARG_NAT_RAND_PORT },
|
||||
{ "NAT_PORT", FWKNOP_CLI_ARG_NAT_PORT },
|
||||
@ -1195,6 +1197,14 @@ parse_rc_param(fko_cli_options_t *options, const char *var_name, char * val)
|
||||
}
|
||||
strlcpy(options->resolve_url, val, tmpint);
|
||||
}
|
||||
/* Resolve the SPA server (via DNS) - accept IPv4 addresses only ? */
|
||||
else if (var->pos == FWKNOP_CLI_ARG_SERVER_RESOLVE_IPV4)
|
||||
{
|
||||
if (is_yes_str(val))
|
||||
{
|
||||
options->spa_server_resolve_ipv4 = 1;
|
||||
}
|
||||
}
|
||||
/* wget command */
|
||||
else if (var->pos == FWKNOP_CLI_ARG_WGET_CMD)
|
||||
{
|
||||
@ -1417,6 +1427,9 @@ add_single_var_to_rc(FILE* fhandle, short var_pos, fko_cli_options_t *options)
|
||||
strlcpy(val, options->resolve_url, sizeof(val));
|
||||
else;
|
||||
break;
|
||||
case FWKNOP_CLI_ARG_SERVER_RESOLVE_IPV4:
|
||||
bool_to_yesno(options->spa_server_resolve_ipv4, val, sizeof(val));
|
||||
break;
|
||||
case FWKNOP_CLI_ARG_NAT_LOCAL :
|
||||
bool_to_yesno(options->nat_local, val, sizeof(val));
|
||||
break;
|
||||
@ -2266,6 +2279,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
|
||||
strlcpy(options->resolve_url, optarg, rlen);
|
||||
add_var_to_bitmask(FWKNOP_CLI_ARG_RESOLVE_URL, &var_bitmask);
|
||||
break;
|
||||
case SERVER_RESOLVE_IPV4:
|
||||
options->spa_server_resolve_ipv4 = 1;
|
||||
break;
|
||||
case 'w':
|
||||
if(options->wget_bin != NULL)
|
||||
free(options->wget_bin);
|
||||
@ -2563,6 +2579,8 @@ usage(void)
|
||||
" $HOME/fwknop.run file\n"
|
||||
" --rc-file Specify path to the fwknop rc file (default\n"
|
||||
" is $HOME/.fwknoprc)\n"
|
||||
" --server-resolve-ipv4 Force IPv4 address resolution from DNS for\n"
|
||||
" SPA server when using a hostname.\n"
|
||||
" --save-rc-stanza Save command line arguments to the\n"
|
||||
" $HOME/.fwknoprc stanza specified with the\n"
|
||||
" -n option.\n"
|
||||
|
||||
@ -899,7 +899,8 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc
|
||||
* family to either AF_INET or AF_INET6 */
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (resolve_dest_adr(hostname, &hints, dst_ip_str, sizeof(dst_ip_str)) != 0)
|
||||
if (resolve_dst_addr(hostname, &hints,
|
||||
dst_ip_str, sizeof(dst_ip_str), options) != 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR, "[*] Unable to resolve %s as an ip address",
|
||||
hostname);
|
||||
|
||||
@ -164,6 +164,7 @@ typedef struct fko_cli_options
|
||||
unsigned char save_rc_stanza;
|
||||
unsigned char force_save_rc_stanza;
|
||||
unsigned char stanza_list;
|
||||
int spa_server_resolve_ipv4;
|
||||
|
||||
int input_fd;
|
||||
|
||||
|
||||
@ -136,6 +136,17 @@ send_spa_packet_tcp_or_udp(const char *spa_data, const int sd_len,
|
||||
}
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
/* Apply --server-resolve-ipv4 criteria
|
||||
*/
|
||||
if(options->spa_server_resolve_ipv4)
|
||||
{
|
||||
if(rp->ai_family != AF_INET)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_DEBUG, "Non-IPv4 resolution");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sock = socket(rp->ai_family, rp->ai_socktype,
|
||||
rp->ai_protocol);
|
||||
if (sock < 0)
|
||||
@ -703,7 +714,8 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
|
||||
return res;
|
||||
#endif
|
||||
|
||||
if (resolve_dest_adr(options->spa_server_str, &hints, ip_str, sizeof(ip_str)) != 0)
|
||||
if (resolve_dst_addr(options->spa_server_str,
|
||||
&hints, ip_str, sizeof(ip_str), options) != 0)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_ERROR, "[*] Unable to resolve %s as an ip address",
|
||||
options->spa_server_str);
|
||||
|
||||
@ -148,17 +148,19 @@ get_in_addr(struct sockaddr *sa)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resolve a domain name as an ip adress.
|
||||
* @brief Resolve a domain name as an IP address.
|
||||
*
|
||||
* @param dns_str Name of the host to resolve.
|
||||
* @param hints Hints to reduce the number of result from getaddrinfo()
|
||||
* @param ip_str String where to store the resolve ip address
|
||||
* @param ip_bufsize Number of bytes available in the ip_str buffer
|
||||
* @param opts Client command line options
|
||||
*
|
||||
* @return 0 if successful, 1 if an error occured.
|
||||
*/
|
||||
int
|
||||
resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize)
|
||||
resolve_dst_addr(const char *dns_str, struct addrinfo *hints,
|
||||
char *ip_str, size_t ip_bufsize, fko_cli_options_t *opts)
|
||||
{
|
||||
int error; /* Function error return code */
|
||||
struct addrinfo *result; /* Result of getaddrinfo() */
|
||||
@ -173,7 +175,7 @@ resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size
|
||||
/* Try to resolve the host name */
|
||||
error = getaddrinfo(dns_str, NULL, hints, &result);
|
||||
if (error != 0)
|
||||
fprintf(stderr, "resolve_dest_adr() : %s\n", gai_strerror(error));
|
||||
fprintf(stderr, "resolve_dst_addr() : %s\n", gai_strerror(error));
|
||||
|
||||
else
|
||||
{
|
||||
@ -182,6 +184,17 @@ resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size
|
||||
/* Go through the linked list of addrinfo structures */
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next)
|
||||
{
|
||||
/* Apply --server-resolve-ipv4 criteria
|
||||
*/
|
||||
if(opts->spa_server_resolve_ipv4)
|
||||
{
|
||||
if(rp->ai_family != AF_INET)
|
||||
{
|
||||
log_msg(LOG_VERBOSITY_DEBUG, "Non-IPv4 resolution");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
memset(ip_str, 0, ip_bufsize);
|
||||
#if WIN32 && WINVER <= 0x0600
|
||||
/* On older Windows systems (anything before Vista?),
|
||||
@ -195,12 +208,12 @@ resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size
|
||||
sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr));
|
||||
if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL)
|
||||
#endif
|
||||
{
|
||||
{
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
log_msg(LOG_VERBOSITY_ERROR, "resolve_dest_adr() : inet_ntop (%d) - %s",
|
||||
log_msg(LOG_VERBOSITY_ERROR, "resolve_dst_addr() : inet_ntop (%d) - %s",
|
||||
errno, strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,8 @@
|
||||
void hex_dump(const unsigned char *data, const int size);
|
||||
int set_file_perms(const char *file);
|
||||
int verify_file_perms_ownership(const char *file);
|
||||
int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize);
|
||||
int resolve_dst_addr(const char *dns_str, struct addrinfo *hints,
|
||||
char *ip_str, size_t ip_bufsize, fko_cli_options_t *opts);
|
||||
short proto_inttostr(int proto, char *proto_str, size_t proto_size);
|
||||
short proto_strtoint(const char *pr_str);
|
||||
int strtoargv(char *args_str, char **argv_new, int *argc_new, fko_cli_options_t *opts);
|
||||
|
||||
@ -462,6 +462,11 @@ SPA OPTIONS
|
||||
*-S, --source-port*='<port>'::
|
||||
Set the source port for outgoing SPA packet.
|
||||
|
||||
*--server-resolve-ipv4*::
|
||||
This option forces the *fwknop* client to only accept an IPv4 address from
|
||||
DNS when a hostname is used for the SPA server. This is necessary in some
|
||||
cases where DNS may return both IPv6 and IPv4 addresses.
|
||||
|
||||
*-f, --fw-timeout*='<seconds>'::
|
||||
Specify the length of time (seconds) that the remote firewall rule that
|
||||
grants access to a service is to remain active. The default maintained by
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user