| /* 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_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; |
| } |
| |