Add a test for BIO_ADDR_copy()
authorMatt Caswell <matt@openssl.org>
Thu, 21 Sep 2023 15:28:58 +0000 (16:28 +0100)
committerPauli <pauli@openssl.org>
Sun, 24 Sep 2023 21:46:45 +0000 (07:46 +1000)
We also add a test for BIO_ADDR_dup() which was also added in 3.2

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22164)

test/bio_addr_test.c [new file with mode: 0644]
test/build.info
test/recipes/61-test_bio_addr.t [new file with mode: 0644]

diff --git a/test/bio_addr_test.c b/test/bio_addr_test.c
new file mode 100644 (file)
index 0000000..a985d03
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/bio.h>
+#include "internal/e_os.h"
+#include "internal/sockets.h"
+#include "testutil.h"
+
+static int families[] = {
+    AF_INET,
+#if OPENSSL_USE_IPV6
+    AF_INET6,
+#endif
+#ifndef OPENSSL_NO_UNIX_SOCK
+    AF_UNIX
+#endif
+};
+
+static BIO_ADDR *make_dummy_addr(int family)
+{
+    BIO_ADDR *addr;
+    union {
+        struct sockaddr_in sin;
+#if OPENSSL_USE_IPV6
+        struct sockaddr_in6 sin6;
+#endif
+#ifndef OPENSSL_NO_UNIX_SOCK
+        struct sockaddr_un sun;
+#endif
+    } sa;
+    void *where;
+    size_t wherelen;
+
+    /* Fill with a dummy address */
+    switch(family) {
+    case AF_INET:
+        where = &(sa.sin.sin_addr);
+        wherelen = sizeof(sa.sin.sin_addr);
+        break;
+#if OPENSSL_USE_IPV6
+    case AF_INET6:
+        where = &(sa.sin6.sin6_addr);
+        wherelen = sizeof(sa.sin6.sin6_addr);
+        break;
+#endif
+#ifndef OPENSSL_NO_UNIX_SOCK
+    case AF_UNIX:
+        where = &(sa.sun.sun_path);
+        /* BIO_ADDR_rawmake needs an extra byte for a NUL-terminator*/
+        wherelen = sizeof(sa.sun.sun_path) - 1;
+        break;
+#endif
+    default:
+        TEST_error("Unsupported address family");
+        return 0;
+    }
+    /*
+     * Could be any data, but we make it printable because BIO_ADDR_rawmake
+     * expects the AF_UNIX address to be a string.
+     */
+    memset(where, 'a', wherelen);
+
+    addr = BIO_ADDR_new();
+    if (!TEST_ptr(addr))
+        return NULL;
+
+    if (!TEST_true(BIO_ADDR_rawmake(addr, family, where, wherelen, 1000))) {
+        BIO_ADDR_free(addr);
+        return NULL;
+    }
+
+    return addr;
+}
+
+static int bio_addr_is_eq(const BIO_ADDR *a, const BIO_ADDR *b)
+{
+    struct sockaddr_storage adata, bdata;
+    size_t alen, blen;
+
+    /* True even if a and b are NULL */
+    if (a == b)
+        return 1;
+
+    /* If one is NULL the other cannot be due to the test above */
+    if (a == NULL || b == NULL)
+        return 0;
+
+    if (BIO_ADDR_family(a) != BIO_ADDR_family(b))
+        return 0;
+
+    /* Works even with AF_UNIX/AF_UNSPEC which just returns 0 */
+    if (BIO_ADDR_rawport(a) != BIO_ADDR_rawport(b))
+        return 0;
+
+    if (!BIO_ADDR_rawaddress(a, NULL, &alen)
+            || alen > sizeof(adata)
+            || !BIO_ADDR_rawaddress(a, &adata, &alen))
+        return 0;
+
+    if (!BIO_ADDR_rawaddress(a, NULL, &blen)
+            || blen > sizeof(bdata)
+            || !BIO_ADDR_rawaddress(a, &bdata, &blen))
+        return 0;
+
+    if (alen != blen)
+        return 0;
+
+    if (alen == 0)
+        return 1;
+
+    return memcmp(&adata, &bdata, alen) == 0;
+}
+
+static int test_bio_addr_copy_dup(int idx)
+{
+    BIO_ADDR *src = NULL, *dst = NULL;
+    int ret = 0;
+    int docopy = idx & 1;
+
+    idx >>= 1;
+
+    src = make_dummy_addr(families[idx]);
+    if (!TEST_ptr(src))
+        return 0;
+
+    if (docopy) {
+        dst = BIO_ADDR_new();
+        if (!TEST_ptr(dst))
+            goto err;
+
+        if (!TEST_true(BIO_ADDR_copy(dst, src)))
+            goto err;
+    } else {
+        dst = BIO_ADDR_dup(src);
+        if (!TEST_ptr(dst))
+            goto err;
+    }
+
+    if (!TEST_true(bio_addr_is_eq(src, dst)))
+        goto err;
+
+    ret = 1;
+ err:
+    BIO_ADDR_free(src);
+    BIO_ADDR_free(dst);
+    return ret;
+}
+
+int setup_tests(void)
+{
+    if (!test_skip_common_options()) {
+        TEST_error("Error parsing test options\n");
+        return 0;
+    }
+
+    ADD_ALL_TESTS(test_bio_addr_copy_dup, OSSL_NELEM(families) * 2);
+    return 1;
+}
index 4c81a2b77984c708217a39f3de11ff809a041f6d..73f8de1f7a125b96eba58b2a4ca3382bc987d7af 100644 (file)
@@ -522,6 +522,12 @@ IF[{- !$disabled{tests} -}]
       INCLUDE[http_test]=../include ../apps/include
       DEPEND[http_test]=../libcrypto libtestutil.a
     ENDIF
+
+    PROGRAMS{noinst}=bio_addr_test
+
+    SOURCE[bio_addr_test]=bio_addr_test.c
+    INCLUDE[bio_addr_test]=../include ../apps/include
+    DEPEND[bio_addr_test]=../libcrypto libtestutil.a
   ENDIF
 
   SOURCE[dtlstest]=dtlstest.c helpers/ssltestlib.c
diff --git a/test/recipes/61-test_bio_addr.t b/test/recipes/61-test_bio_addr.t
new file mode 100644 (file)
index 0000000..bd4c23a
--- /dev/null
@@ -0,0 +1,20 @@
+#! /usr/bin/env perl
+# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+use OpenSSL::Test;
+use OpenSSL::Test::Utils;
+
+setup("test_bio_addr");
+
+plan skip_all => "No sockets in this configuration"
+    if disabled("sock");
+
+plan tests => 1;
+
+ok(run(test(["bio_addr_test"])), "running bio_addr_test");