Skip to content

Commit

Permalink
Add k5_parse_host_string()
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
SaharahSarah authored and greghudson committed Jun 1, 2016
1 parent 24452cd commit c2d843a
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/include/k5-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/lib/krb5/krb/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ STLIBOBJS= \
pac.o \
pac_sign.o \
parse.o \
parse_host_string.o \
plugin.o \
pr_to_salt.o \
preauth2.o \
Expand Down Expand Up @@ -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) \
Expand Down Expand Up @@ -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 \
Expand Down
124 changes: 124 additions & 0 deletions src/lib/krb5/krb/parse_host_string.c
Original file line number Diff line number Diff line change
@@ -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 <ctype.h>

/* 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;
}
1 change: 1 addition & 0 deletions src/lib/krb5/libkrb5.exports
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c2d843a

Please sign in to comment.