summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-07-28 15:05:37 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-07-28 15:18:33 +0200
commit410970f8777f2fe7a421e94999e542d023f35229 (patch)
tree32ad17647805b706fa9fbdc2e22dbe820268a239
parentcd1a89fcae6d1462a396b5a434086621ff54e0f1 (diff)
downloadgnutls-410970f8777f2fe7a421e94999e542d023f35229.tar.gz
Added replacements of inet_aton and inet_pton on systems they are not present
gnulib is avoided due to keep the gnulib network replacements out of the library
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/inet_pton.c266
-rw-r--r--lib/system.h11
-rw-r--r--lib/x509/rfc2818_hostname.c6
4 files changed, 279 insertions, 6 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c161ebc2d3..3e75d882f7 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -79,7 +79,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \
gnutls_rsa_export.c gnutls_helper.c gnutls_supplemental.c \
random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c \
gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \
- crypto-backend.c verify-tofu.c pin.c tpm.c
+ crypto-backend.c verify-tofu.c pin.c tpm.c inet_pton.c
if ENABLE_PKCS11
COBJECTS += pkcs11.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c \
diff --git a/lib/inet_pton.c b/lib/inet_pton.c
new file mode 100644
index 0000000000..cc9254fd4c
--- /dev/null
+++ b/lib/inet_pton.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h> /* needed to define AF_ values on UNIX */
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h> /* needed to define AF_ values on Windows */
+#if _MSC_VER < 1600 /* errno.h defines EAFNOSUPPORT in Windows VC10 (and presumably eventually in VC11 ...) */
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#endif
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+
+#include <system.h>
+
+#ifndef HAVE_INET_PTON
+
+#ifndef NS_INADDRSZ
+#define NS_INADDRSZ 4
+#endif
+#ifndef NS_IN6ADDRSZ
+#define NS_IN6ADDRSZ 16
+#endif
+#ifndef NS_INT16SZ
+#define NS_INT16SZ 2
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 (const char *src, u_char *dst);
+static int inet_pton6 (const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+ int af;
+ const char *src;
+ void *dst;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+#endif
+
+#ifdef _WIN32
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+ return inet_pton(AF_INET, cp, inp);
+}
+#endif
+
+#ifndef HAVE_INET_PTON
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ size_t new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = (u_char) new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return (0);
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = (int) (tp - colonp);
+ int i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
+
+#endif /* HAVE_INET_PTON */
diff --git a/lib/system.h b/lib/system.h
index d2e695a40c..0e7bcfbcc8 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -98,4 +98,15 @@ int _gnutls_ucs2_to_utf8(const void *data, size_t size,
int gnutls_system_global_init(void);
void gnutls_system_global_deinit(void);
+#include <arpa/inet.h>
+#ifdef _WIN32
+# define inet_aton _gnutls_inet_aton
+int inet_aton(const char *cp, struct in_addr *inp);
+#endif
+
+#ifndef HAVE_INET_PTON
+# define inet_pton _gnutls_inet_pton
+int inet_pton(int af, const char *src, void *dst);
+#endif
+
#endif /* SYSTEM_H */
diff --git a/lib/x509/rfc2818_hostname.c b/lib/x509/rfc2818_hostname.c
index 5fb7535961..ea3e858a4a 100644
--- a/lib/x509/rfc2818_hostname.c
+++ b/lib/x509/rfc2818_hostname.c
@@ -24,7 +24,7 @@
#include <x509_int.h>
#include <common.h>
#include <gnutls_errors.h>
-#include <arpa/inet.h>
+#include <system.h>
static int
check_ip(gnutls_x509_crt_t cert, const void *ip, unsigned ip_size)
@@ -103,7 +103,6 @@ gnutls_x509_crt_check_hostname(gnutls_x509_crt_t cert,
if ((p=strchr(hostname, ':')) != NULL || inet_aton(hostname, &ipv4) != 0) {
if (p != NULL) {
-#ifdef HAVE_INET_PTON
struct in6_addr ipv6;
ret = inet_pton(AF_INET6, hostname, &ipv6);
@@ -112,9 +111,6 @@ gnutls_x509_crt_check_hostname(gnutls_x509_crt_t cert,
goto hostname_fallback;
}
ret = check_ip(cert, &ipv6, 16);
-#else
- ret = 0;
-#endif
} else {
ret = check_ip(cert, &ipv4, 4);
}