diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:30:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:30:05 +0000 |
commit | a1e354165254cd9e346751e6c2ddc554feeb0e6d (patch) | |
tree | 5fd273cc604fd00efd630eb387a6f79ce102f4e3 /test/testldap.c | |
parent | Initial commit. (diff) | |
download | apr-util-a1e354165254cd9e346751e6c2ddc554feeb0e6d.tar.xz apr-util-a1e354165254cd9e346751e6c2ddc554feeb0e6d.zip |
Adding upstream version 1.6.3.upstream/1.6.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/testldap.c')
-rw-r--r-- | test/testldap.c | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/test/testldap.c b/test/testldap.c new file mode 100644 index 0000000..4f4fef9 --- /dev/null +++ b/test/testldap.c @@ -0,0 +1,250 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* Setup: + * - Create or edit the file data/host.data and add an + * ldap server DN. Multiple DNs may be listed on + * a single line. + * - Copy the server certificates to the data/ directory. + * All DER type certificates must have the .der extention. + * All BASE64 or PEM certificates must have the .b64 + * extension. All certificate files copied to the /data + * directory will be added to the ldap certificate store. + */ + + /* This test covers the following three types of connections: + * - Unsecure ldap:// + * - Secure ldaps:// + * - Secure ldap://+Start_TLS + * + * - (TBD) Mutual authentication + * + * There are other variations that should be tested: + * - All of the above with multiple redundant LDAP servers + * This can be done by listing more than one server DN + * in the host.data file. The DNs should all be listed + * on one line separated by a space. + * - All of the above with multiple certificates + * If more than one certificate is found in the data/ + * directory, each certificate found will be added + * to the certificate store. + * - All of the above on alternate ports + * An alternate port can be specified as part of the + * host in the host.data file. The ":port" should + * follow each DN listed. Default is 389 and 636. + * - Secure connections with mutual authentication + */ + +#include "testutil.h" + +#include "apr.h" +#include "apr_general.h" +#include "apr_ldap.h" +#include "apr_file_io.h" +#include "apr_file_info.h" +#include "apr_strings.h" +#if APR_HAVE_STDLIB_H +#include <stdlib.h> +#endif +#define APR_WANT_STDIO +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#define DIRNAME "data" +#define FILENAME DIRNAME "/host.data" +#define CERTFILEDER DIRNAME "/*.der" +#define CERTFILEB64 DIRNAME "/*.b64" + +#if APR_HAS_LDAP + +static char ldap_host[256]; + +static int get_ldap_host(void) +{ + apr_status_t rv; + apr_file_t *thefile = NULL; + char *ptr; + + ldap_host[0] = '\0'; + rv = apr_file_open(&thefile, FILENAME, + APR_FOPEN_READ, + APR_UREAD | APR_UWRITE | APR_GREAD, p); + if (rv != APR_SUCCESS) { + return 0; + } + + rv = apr_file_gets(ldap_host, sizeof(ldap_host), thefile); + if (rv != APR_SUCCESS) { + return 0; + } + + ptr = strstr (ldap_host, "\r\n"); + if (ptr) { + *ptr = '\0'; + } + apr_file_close(thefile); + + return 1; + +} + +static int add_ldap_certs(abts_case *tc) +{ + apr_status_t status; + apr_dir_t *thedir; + apr_finfo_t dirent; + apr_ldap_err_t *result = NULL; + + if ((status = apr_dir_open(&thedir, DIRNAME, p)) == APR_SUCCESS) { + apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_pcalloc(p, sizeof(apr_ldap_opt_tls_cert_t)); + + do { + status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir); + if (APR_STATUS_IS_INCOMPLETE(status)) { + continue; /* ignore un-stat()able files */ + } + else if (status != APR_SUCCESS) { + break; + } + + if (strstr(dirent.name, ".der")) { + cert->type = APR_LDAP_CA_TYPE_DER; + cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); + apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); + ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); + } + if (strstr(dirent.name, ".b64")) { + cert->type = APR_LDAP_CA_TYPE_BASE64; + cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); + apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); + ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); + } + + } while (1); + + apr_dir_close(thedir); + } + return 0; +} + +static void test_ldap_connection(abts_case *tc, LDAP *ldap) +{ + int version = LDAP_VERSION3; + int failures, result; + + /* always default to LDAP V3 */ + ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &version); + + for (failures=0; failures<10; failures++) + { + result = ldap_simple_bind_s(ldap, + (char *)NULL, + (char *)NULL); + if (LDAP_SERVER_DOWN != result) + break; + } + + ABTS_TRUE(tc, result == LDAP_SUCCESS); + if (result != LDAP_SUCCESS) { + abts_log_message("%s\n", ldap_err2string(result)); + } + + ldap_unbind_s(ldap); + + return; +} + +static void test_ldap(abts_case *tc, void *data) +{ + apr_pool_t *pool = p; + LDAP *ldap; + apr_ldap_err_t *result = NULL; + + + ABTS_ASSERT(tc, "failed to get host", ldap_host[0] != '\0'); + + apr_ldap_init(pool, &ldap, + ldap_host, LDAP_PORT, + APR_LDAP_NONE, &(result)); + + ABTS_TRUE(tc, ldap != NULL); + ABTS_PTR_NOTNULL(tc, result); + + if (result->rc == LDAP_SUCCESS) { + test_ldap_connection(tc, ldap); + } +} + +static void test_ldaps(abts_case *tc, void *data) +{ + apr_pool_t *pool = p; + LDAP *ldap; + apr_ldap_err_t *result = NULL; + + apr_ldap_init(pool, &ldap, + ldap_host, LDAPS_PORT, + APR_LDAP_SSL, &(result)); + + ABTS_TRUE(tc, ldap != NULL); + ABTS_PTR_NOTNULL(tc, result); + + if (result->rc == LDAP_SUCCESS) { + add_ldap_certs(tc); + + test_ldap_connection(tc, ldap); + } +} + +static void test_ldap_tls(abts_case *tc, void *data) +{ + apr_pool_t *pool = p; + LDAP *ldap; + apr_ldap_err_t *result = NULL; + + apr_ldap_init(pool, &ldap, + ldap_host, LDAP_PORT, + APR_LDAP_STARTTLS, &(result)); + + ABTS_TRUE(tc, ldap != NULL); + ABTS_PTR_NOTNULL(tc, result); + + if (result->rc == LDAP_SUCCESS) { + add_ldap_certs(tc); + + test_ldap_connection(tc, ldap); + } +} + +#endif /* APR_HAS_LDAP */ + +abts_suite *testldap(abts_suite *suite) +{ +#if APR_HAS_LDAP + apr_ldap_err_t *result = NULL; + suite = ADD_SUITE(suite); + + apr_ldap_ssl_init(p, NULL, 0, &result); + + if (get_ldap_host()) { + abts_run_test(suite, test_ldap, NULL); + abts_run_test(suite, test_ldaps, NULL); + abts_run_test(suite, test_ldap_tls, NULL); + } +#endif /* APR_HAS_LDAP */ + + return suite; +} + |