Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/lib/iolog/host_port.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2019-2020 Todd C. Miller <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include <config.h>
20
21
#ifdef HAVE_STDBOOL_H
22
# include <stdbool.h>
23
#else
24
# include <compat/stdbool.h>
25
#endif /* HAVE_STDBOOL_H */
26
#include <stdio.h>
27
#include <string.h>
28
#include <time.h>
29
30
#include <sudo_compat.h>
31
#include <sudo_debug.h>
32
#include <sudo_gettext.h>
33
#include <sudo_util.h>
34
#include <sudo_iolog.h>
35
36
/*
37
* Parse a string in the form host[:port] where host can also be
38
* an IPv4 address or an IPv6 address in square brackets.
39
* Fills in hostp and portp which may point within str, which is modified.
40
*/
41
bool
42
iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp,
43
const char *defport, const char *defport_tls)
44
{
45
char *flags, *port, *host = str;
46
bool ret = false;
47
bool tls = false;
48
debug_decl(iolog_parse_host_port, SUDO_DEBUG_UTIL);
49
50
/* Check for IPv6 address like [::0] followed by optional port */
51
if (*host == '[') {
52
host++;
53
port = strchr(host, ']');
54
if (port == NULL) {
55
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
56
"invalid IPv6 address %s", str);
57
goto done;
58
}
59
*port++ = '\0';
60
switch (*port) {
61
case ':':
62
port++;
63
break;
64
case '\0':
65
port = NULL; /* no port specified */
66
break;
67
case '(':
68
/* flag, handled below */
69
break;
70
default:
71
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
72
"invalid IPv6 address %s", str);
73
goto done;
74
}
75
} else {
76
port = strrchr(host, ':');
77
if (port != NULL)
78
*port++ = '\0';
79
}
80
81
/* Check for optional tls flag at the end. */
82
flags = strchr(port ? port : host, '(');
83
if (flags != NULL) {
84
if (strcasecmp(flags, "(tls)") == 0)
85
tls = true;
86
*flags = '\0';
87
if (port == flags)
88
port = NULL;
89
}
90
91
if (port == NULL)
92
port = tls ? (char *)defport_tls : (char *)defport;
93
else if (*port == '\0')
94
goto done;
95
96
*hostp = host;
97
*portp = port;
98
*tlsp = tls;
99
100
ret = true;
101
102
done:
103
debug_return_bool(ret);
104
}
105
106