From: Sarah Day Date: Tue, 19 Jan 2016 14:47:10 +0000 (-0500) Subject: Add k5_parse_host_string() X-Git-Tag: krb5-1.15-beta1~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2d843ab133324e23007a8a5bc0bde05d3934ae7;p=thirdparty%2Fkrb5.git Add k5_parse_host_string() Add a helper function k5_parse_host_string() containing the hostname-and-port parsing logic currently inlined into locate_srv_conf_1(). The new function will also accept a port number without hostname, for parsing listener addresses. [ghudson@mit.edu: simplified parsing code and better handle edge cases; split into two commits] --- diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 1706790abb..1d3667dfb0 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1747,6 +1747,10 @@ krb5_encode_kdc_rep(krb5_context, krb5_msgtype, const krb5_enc_kdc_rep_part *, int using_subkey, const krb5_keyblock *, krb5_kdc_rep *, krb5_data ** ); +krb5_error_code +k5_parse_host_string(const char *address, int default_port, char **host_out, + int *port_out); + /* * [De]Serialization Handle and operations. */ diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index 63b8c9c931..81eebb4d0b 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -75,6 +75,7 @@ STLIBOBJS= \ pac.o \ pac_sign.o \ parse.o \ + parse_host_string.o \ plugin.o \ pr_to_salt.o \ preauth2.o \ @@ -184,6 +185,7 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \ $(OUTPRE)pac.$(OBJEXT) \ $(OUTPRE)pac_sign.$(OBJEXT) \ $(OUTPRE)parse.$(OBJEXT) \ + $(OUTPRE)parse_host_string.$(OBJEXT) \ $(OUTPRE)plugin.$(OBJEXT) \ $(OUTPRE)pr_to_salt.$(OBJEXT) \ $(OUTPRE)preauth2.$(OBJEXT) \ @@ -293,6 +295,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/pac.c \ $(srcdir)/pac_sign.c \ $(srcdir)/parse.c \ + $(srcdir)/parse_host_string.c \ $(srcdir)/plugin.c \ $(srcdir)/pr_to_salt.c \ $(srcdir)/preauth2.c \ diff --git a/src/lib/krb5/krb/parse_host_string.c b/src/lib/krb5/krb/parse_host_string.c new file mode 100644 index 0000000000..7eaa27a6cb --- /dev/null +++ b/src/lib/krb5/krb/parse_host_string.c @@ -0,0 +1,124 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/krb5/krb/parse_host_string.c - Parse host strings into host and port */ +/* + * Copyright (C) 2016 by the Massachusetts Institute of Technology. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "k5-int.h" +#include + +/* Return true if s is composed solely of digits. */ +static krb5_boolean +is_string_numeric(const char *s) +{ + if (*s == '\0') + return FALSE; + + for (; *s != '\0'; s++) { + if (!isdigit(*s)) + return FALSE; + } + + return TRUE; +} + +/* + * Parse a string containing a host specifier. The expected format for the + * string is: + * + * host[:port] or port + * + * host and port are optional, though one must be present. host may have + * brackets around it for IPv6 addresses. + * + * Arguments: + * address - The address string that should be parsed. + * default_port - The default port to use if no port is found. + * host_out - An output pointer for the parsed host, or NULL if no host was + * specified or an error occured. Must be freed. + * port_out - An output pointer for the parsed port. Will be 0 on error. + * + * Returns 0 on success, otherwise an error. + */ +krb5_error_code +k5_parse_host_string(const char *address, int default_port, char **host_out, + int *port_out) +{ + krb5_error_code ret; + int port_num; + const char *p, *host = NULL, *port = NULL; + char *endptr, *hostname = NULL; + size_t hostlen = 0; + unsigned long l; + + *host_out = NULL; + *port_out = 0; + + if (address == NULL || *address == '\0') + return EINVAL; + if (default_port < 0 || default_port > 65535) + return EINVAL; + + /* Find the bounds of the host string and the start of the port string. */ + if (is_string_numeric(address)) { + port = address; + } else if (*address == '[' && (p = strchr(address, ']')) != NULL) { + host = address + 1; + hostlen = p - host; + if (*(p + 1) == ':') + port = p + 2; + } else { + host = address; + hostlen = strcspn(host, " \t:"); + if (host[hostlen] == ':') + port = host + hostlen + 1; + } + + /* Parse the port number, or use the default port. */ + if (port != NULL) { + errno = 0; + l = strtoul(port, &endptr, 10); + if (errno || endptr == port || *endptr != '\0' || l > 65535) + return EINVAL; + port_num = l; + } else { + port_num = default_port; + } + + /* Copy the host if it was specified. */ + if (host != NULL) { + hostname = k5memdup0(host, hostlen, &ret); + if (hostname == NULL) + return ENOMEM; + } + + *host_out = hostname; + *port_out = port_num; + return 0; +} diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index eeb1146165..2c5f1815c1 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -137,6 +137,7 @@ k5_marshal_cred k5_marshal_princ k5_os_free_context k5_os_init_context +k5_parse_host_string k5_plugin_free_modules k5_plugin_load k5_plugin_load_all