/*1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2019-2020 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <config.h>1920#ifdef HAVE_STDBOOL_H21# include <stdbool.h>22#else23# include <compat/stdbool.h>24#endif /* HAVE_STDBOOL_H */25#include <stdio.h>26#include <string.h>27#include <time.h>2829#include <sudo_compat.h>30#include <sudo_debug.h>31#include <sudo_gettext.h>32#include <sudo_util.h>33#include <sudo_iolog.h>3435/*36* Parse a string in the form host[:port] where host can also be37* an IPv4 address or an IPv6 address in square brackets.38* Fills in hostp and portp which may point within str, which is modified.39*/40bool41iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp,42const char *defport, const char *defport_tls)43{44char *flags, *port, *host = str;45bool ret = false;46bool tls = false;47debug_decl(iolog_parse_host_port, SUDO_DEBUG_UTIL);4849/* Check for IPv6 address like [::0] followed by optional port */50if (*host == '[') {51host++;52port = strchr(host, ']');53if (port == NULL) {54sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,55"invalid IPv6 address %s", str);56goto done;57}58*port++ = '\0';59switch (*port) {60case ':':61port++;62break;63case '\0':64port = NULL; /* no port specified */65break;66case '(':67/* flag, handled below */68break;69default:70sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,71"invalid IPv6 address %s", str);72goto done;73}74} else {75port = strrchr(host, ':');76if (port != NULL)77*port++ = '\0';78}7980/* Check for optional tls flag at the end. */81flags = strchr(port ? port : host, '(');82if (flags != NULL) {83if (strcasecmp(flags, "(tls)") == 0)84tls = true;85*flags = '\0';86if (port == flags)87port = NULL;88}8990if (port == NULL)91port = tls ? (char *)defport_tls : (char *)defport;92else if (*port == '\0')93goto done;9495*hostp = host;96*portp = port;97*tlsp = tls;9899ret = true;100101done:102debug_return_bool(ret);103}104105106