1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter */ 16251876Speter 17251876Speter /* Setup: 18251876Speter * - Create or edit the file data/host.data and add an 19251876Speter * ldap server DN. Multiple DNs may be listed on 20251876Speter * a single line. 21251876Speter * - Copy the server certificates to the data/ directory. 22251876Speter * All DER type certificates must have the .der extention. 23251876Speter * All BASE64 or PEM certificates must have the .b64 24251876Speter * extension. All certificate files copied to the /data 25251876Speter * directory will be added to the ldap certificate store. 26251876Speter */ 27251876Speter 28251876Speter /* This test covers the following three types of connections: 29251876Speter * - Unsecure ldap:// 30251876Speter * - Secure ldaps:// 31251876Speter * - Secure ldap://+Start_TLS 32251876Speter * 33251876Speter * - (TBD) Mutual authentication 34251876Speter * 35251876Speter * There are other variations that should be tested: 36251876Speter * - All of the above with multiple redundant LDAP servers 37251876Speter * This can be done by listing more than one server DN 38251876Speter * in the host.data file. The DNs should all be listed 39251876Speter * on one line separated by a space. 40251876Speter * - All of the above with multiple certificates 41251876Speter * If more than one certificate is found in the data/ 42251876Speter * directory, each certificate found will be added 43251876Speter * to the certificate store. 44251876Speter * - All of the above on alternate ports 45251876Speter * An alternate port can be specified as part of the 46251876Speter * host in the host.data file. The ":port" should 47251876Speter * follow each DN listed. Default is 389 and 636. 48251876Speter * - Secure connections with mutual authentication 49251876Speter */ 50251876Speter 51251876Speter#include "testutil.h" 52251876Speter 53251876Speter#include "apr.h" 54251876Speter#include "apr_general.h" 55251876Speter#include "apr_ldap.h" 56251876Speter#include "apr_file_io.h" 57251876Speter#include "apr_file_info.h" 58251876Speter#include "apr_strings.h" 59251876Speter#if APR_HAVE_STDLIB_H 60251876Speter#include <stdlib.h> 61251876Speter#endif 62251876Speter#define APR_WANT_STDIO 63251876Speter#define APR_WANT_STRFUNC 64251876Speter#include "apr_want.h" 65251876Speter 66251876Speter#define DIRNAME "data" 67251876Speter#define FILENAME DIRNAME "/host.data" 68251876Speter#define CERTFILEDER DIRNAME "/*.der" 69251876Speter#define CERTFILEB64 DIRNAME "/*.b64" 70251876Speter 71251876Speter#if APR_HAS_LDAP 72251876Speter 73251876Speterstatic char ldap_host[256]; 74251876Speter 75251876Speterstatic int get_ldap_host(void) 76251876Speter{ 77251876Speter apr_status_t rv; 78251876Speter apr_file_t *thefile = NULL; 79251876Speter char *ptr; 80251876Speter 81251876Speter ldap_host[0] = '\0'; 82251876Speter rv = apr_file_open(&thefile, FILENAME, 83251876Speter APR_FOPEN_READ, 84251876Speter APR_UREAD | APR_UWRITE | APR_GREAD, p); 85251876Speter if (rv != APR_SUCCESS) { 86251876Speter return 0; 87251876Speter } 88251876Speter 89251876Speter rv = apr_file_gets(ldap_host, sizeof(ldap_host), thefile); 90251876Speter if (rv != APR_SUCCESS) { 91251876Speter return 0; 92251876Speter } 93251876Speter 94251876Speter ptr = strstr (ldap_host, "\r\n"); 95251876Speter if (ptr) { 96251876Speter *ptr = '\0'; 97251876Speter } 98251876Speter apr_file_close(thefile); 99251876Speter 100251876Speter return 1; 101251876Speter 102251876Speter} 103251876Speter 104251876Speterstatic int add_ldap_certs(abts_case *tc) 105251876Speter{ 106251876Speter apr_status_t status; 107251876Speter apr_dir_t *thedir; 108251876Speter apr_finfo_t dirent; 109251876Speter apr_ldap_err_t *result = NULL; 110251876Speter 111251876Speter if ((status = apr_dir_open(&thedir, DIRNAME, p)) == APR_SUCCESS) { 112251876Speter apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_pcalloc(p, sizeof(apr_ldap_opt_tls_cert_t)); 113251876Speter 114251876Speter do { 115251876Speter status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir); 116251876Speter if (APR_STATUS_IS_INCOMPLETE(status)) { 117251876Speter continue; /* ignore un-stat()able files */ 118251876Speter } 119251876Speter else if (status != APR_SUCCESS) { 120251876Speter break; 121251876Speter } 122251876Speter 123251876Speter if (strstr(dirent.name, ".der")) { 124251876Speter cert->type = APR_LDAP_CA_TYPE_DER; 125251876Speter cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); 126251876Speter apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); 127251876Speter ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); 128251876Speter } 129251876Speter if (strstr(dirent.name, ".b64")) { 130251876Speter cert->type = APR_LDAP_CA_TYPE_BASE64; 131251876Speter cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); 132251876Speter apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); 133251876Speter ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); 134251876Speter } 135251876Speter 136251876Speter } while (1); 137251876Speter 138251876Speter apr_dir_close(thedir); 139251876Speter } 140251876Speter return 0; 141251876Speter} 142251876Speter 143251876Speterstatic void test_ldap_connection(abts_case *tc, LDAP *ldap) 144251876Speter{ 145251876Speter int version = LDAP_VERSION3; 146251876Speter int failures, result; 147251876Speter 148251876Speter /* always default to LDAP V3 */ 149251876Speter ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &version); 150251876Speter 151251876Speter for (failures=0; failures<10; failures++) 152251876Speter { 153251876Speter result = ldap_simple_bind_s(ldap, 154251876Speter (char *)NULL, 155251876Speter (char *)NULL); 156251876Speter if (LDAP_SERVER_DOWN != result) 157251876Speter break; 158251876Speter } 159251876Speter 160251876Speter ABTS_TRUE(tc, result == LDAP_SUCCESS); 161251876Speter if (result != LDAP_SUCCESS) { 162251876Speter abts_log_message("%s\n", ldap_err2string(result)); 163251876Speter } 164251876Speter 165251876Speter ldap_unbind_s(ldap); 166251876Speter 167251876Speter return; 168251876Speter} 169251876Speter 170251876Speterstatic void test_ldap(abts_case *tc, void *data) 171251876Speter{ 172251876Speter apr_pool_t *pool = p; 173251876Speter LDAP *ldap; 174251876Speter apr_ldap_err_t *result = NULL; 175251876Speter 176251876Speter 177251876Speter ABTS_ASSERT(tc, "failed to get host", ldap_host[0] != '\0'); 178251876Speter 179251876Speter apr_ldap_init(pool, &ldap, 180251876Speter ldap_host, LDAP_PORT, 181251876Speter APR_LDAP_NONE, &(result)); 182251876Speter 183251876Speter ABTS_TRUE(tc, ldap != NULL); 184251876Speter ABTS_PTR_NOTNULL(tc, result); 185251876Speter 186251876Speter if (result->rc == LDAP_SUCCESS) { 187251876Speter test_ldap_connection(tc, ldap); 188251876Speter } 189251876Speter} 190251876Speter 191251876Speterstatic void test_ldaps(abts_case *tc, void *data) 192251876Speter{ 193251876Speter apr_pool_t *pool = p; 194251876Speter LDAP *ldap; 195251876Speter apr_ldap_err_t *result = NULL; 196251876Speter 197251876Speter apr_ldap_init(pool, &ldap, 198251876Speter ldap_host, LDAPS_PORT, 199251876Speter APR_LDAP_SSL, &(result)); 200251876Speter 201251876Speter ABTS_TRUE(tc, ldap != NULL); 202251876Speter ABTS_PTR_NOTNULL(tc, result); 203251876Speter 204251876Speter if (result->rc == LDAP_SUCCESS) { 205251876Speter add_ldap_certs(tc); 206251876Speter 207251876Speter test_ldap_connection(tc, ldap); 208251876Speter } 209251876Speter} 210251876Speter 211251876Speterstatic void test_ldap_tls(abts_case *tc, void *data) 212251876Speter{ 213251876Speter apr_pool_t *pool = p; 214251876Speter LDAP *ldap; 215251876Speter apr_ldap_err_t *result = NULL; 216251876Speter 217251876Speter apr_ldap_init(pool, &ldap, 218251876Speter ldap_host, LDAP_PORT, 219251876Speter APR_LDAP_STARTTLS, &(result)); 220251876Speter 221251876Speter ABTS_TRUE(tc, ldap != NULL); 222251876Speter ABTS_PTR_NOTNULL(tc, result); 223251876Speter 224251876Speter if (result->rc == LDAP_SUCCESS) { 225251876Speter add_ldap_certs(tc); 226251876Speter 227251876Speter test_ldap_connection(tc, ldap); 228251876Speter } 229251876Speter} 230251876Speter 231251876Speter#endif /* APR_HAS_LDAP */ 232251876Speter 233251876Speterabts_suite *testldap(abts_suite *suite) 234251876Speter{ 235251876Speter#if APR_HAS_LDAP 236251876Speter apr_ldap_err_t *result = NULL; 237251876Speter suite = ADD_SUITE(suite); 238251876Speter 239251876Speter apr_ldap_ssl_init(p, NULL, 0, &result); 240251876Speter 241251876Speter if (get_ldap_host()) { 242251876Speter abts_run_test(suite, test_ldap, NULL); 243251876Speter abts_run_test(suite, test_ldaps, NULL); 244251876Speter abts_run_test(suite, test_ldap_tls, NULL); 245251876Speter } 246251876Speter#endif /* APR_HAS_LDAP */ 247251876Speter 248251876Speter return suite; 249251876Speter} 250251876Speter 251