xref: /openbsd-src/lib/libtls/tls_util.c (revision 5b859c19fe53bbea08f5c342e0a4470e99f883e1)
1 /* $OpenBSD: tls_util.c,v 1.1 2014/10/31 13:46:17 jsing Exp $ */
2 /*
3  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <stdlib.h>
19 
20 #include "tls_internal.h"
21 
22 /*
23  * Extract the host and port from a colon separated value. For a literal IPv6
24  * address the address must be contained with square braces. If a host and
25  * port are successfully extracted, the function will return 0 and the
26  * caller is responsible for freeing the host and port. If no port is found
27  * then the function will return 1, with both host and port being NULL.
28  * On memory allocation failure -1 will be returned.
29  */
30 int
31 tls_host_port(const char *hostport, char **host, char **port)
32 {
33 	char *h, *p, *s;
34 	int rv = 1;
35 
36 	*host = NULL;
37 	*port = NULL;
38 
39 	if ((s = strdup(hostport)) == NULL)
40 		goto fail;
41 
42 	h = p = s;
43 
44 	/* See if this is an IPv6 literal with square braces. */
45 	if (p[0] == '[') {
46 		h++;
47 		if ((p = strchr(s, ']')) == NULL)
48 			goto done;
49 		*p++ = '\0';
50 	}
51 
52 	/* Find the port seperator. */
53 	if ((p = strchr(p, ':')) == NULL)
54 		goto done;
55 
56 	/* If there is another separator then we have issues. */
57 	if (strchr(p + 1, ':') != NULL)
58 		goto done;
59 
60 	*p++ = '\0';
61 
62 	if (asprintf(host, "%s", h) == -1)
63 		goto fail;
64 	if (asprintf(port, "%s", p) == -1)
65 		goto fail;
66 
67 	rv = 0;
68 	goto done;
69 
70 fail:
71 	free(*host);
72 	*host = NULL;
73 	free(*port);
74 	*port = NULL;
75 	rv = -1;
76 
77 done:
78 	free(s);
79 
80 	return (rv);
81 }
82