1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * - Create or edit the file data/host.data and add an
19 * ldap server DN. Multiple DNs may be listed on
21 * - Copy the server certificates to the data/ directory.
22 * All DER type certificates must have the .der extention.
23 * All BASE64 or PEM certificates must have the .b64
24 * extension. All certificate files copied to the /data
25 * directory will be added to the ldap certificate store.
28 /* This test covers the following three types of connections:
31 * - Secure ldap://+Start_TLS
33 * - (TBD) Mutual authentication
35 * There are other variations that should be tested:
36 * - All of the above with multiple redundant LDAP servers
37 * This can be done by listing more than one server DN
38 * in the host.data file. The DNs should all be listed
39 * on one line separated by a space.
40 * - All of the above with multiple certificates
41 * If more than one certificate is found in the data/
42 * directory, each certificate found will be added
43 * to the certificate store.
44 * - All of the above on alternate ports
45 * An alternate port can be specified as part of the
46 * host in the host.data file. The ":port" should
47 * follow each DN listed. Default is 389 and 636.
48 * - Secure connections with mutual authentication
54 #include "apr_general.h"
56 #include "apr_file_io.h"
57 #include "apr_file_info.h"
58 #include "apr_strings.h"
62 #define APR_WANT_STDIO
63 #define APR_WANT_STRFUNC
66 #define DIRNAME "data"
67 #define FILENAME DIRNAME "/host.data"
68 #define CERTFILEDER DIRNAME "/*.der"
69 #define CERTFILEB64 DIRNAME "/*.b64"
73 static char ldap_host
[256];
75 static int get_ldap_host(void)
78 apr_file_t
*thefile
= NULL
;
82 rv
= apr_file_open(&thefile
, FILENAME
,
84 APR_UREAD
| APR_UWRITE
| APR_GREAD
, p
);
85 if (rv
!= APR_SUCCESS
) {
89 rv
= apr_file_gets(ldap_host
, sizeof(ldap_host
), thefile
);
90 if (rv
!= APR_SUCCESS
) {
94 ptr
= strstr (ldap_host
, "\r\n");
98 apr_file_close(thefile
);
104 static int add_ldap_certs(abts_case
*tc
)
109 apr_ldap_err_t
*result
= NULL
;
111 if ((status
= apr_dir_open(&thedir
, DIRNAME
, p
)) == APR_SUCCESS
) {
112 apr_ldap_opt_tls_cert_t
*cert
= (apr_ldap_opt_tls_cert_t
*)apr_pcalloc(p
, sizeof(apr_ldap_opt_tls_cert_t
));
115 status
= apr_dir_read(&dirent
, APR_FINFO_MIN
| APR_FINFO_NAME
, thedir
);
116 if (APR_STATUS_IS_INCOMPLETE(status
)) {
117 continue; /* ignore un-stat()able files */
119 else if (status
!= APR_SUCCESS
) {
123 if (strstr(dirent
.name
, ".der")) {
124 cert
->type
= APR_LDAP_CA_TYPE_DER
;
125 cert
->path
= apr_pstrcat (p
, DIRNAME
, "/", dirent
.name
, NULL
);
126 apr_ldap_set_option(p
, NULL
, APR_LDAP_OPT_TLS_CERT
, (void *)cert
, &result
);
127 ABTS_TRUE(tc
, result
->rc
== LDAP_SUCCESS
);
129 if (strstr(dirent
.name
, ".b64")) {
130 cert
->type
= APR_LDAP_CA_TYPE_BASE64
;
131 cert
->path
= apr_pstrcat (p
, DIRNAME
, "/", dirent
.name
, NULL
);
132 apr_ldap_set_option(p
, NULL
, APR_LDAP_OPT_TLS_CERT
, (void *)cert
, &result
);
133 ABTS_TRUE(tc
, result
->rc
== LDAP_SUCCESS
);
138 apr_dir_close(thedir
);
143 static void test_ldap_connection(abts_case
*tc
, LDAP
*ldap
)
145 int version
= LDAP_VERSION3
;
146 int failures
, result
;
148 /* always default to LDAP V3 */
149 ldap_set_option(ldap
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
151 for (failures
=0; failures
<10; failures
++)
153 result
= ldap_simple_bind_s(ldap
,
156 if (LDAP_SERVER_DOWN
!= result
)
160 ABTS_TRUE(tc
, result
== LDAP_SUCCESS
);
161 if (result
!= LDAP_SUCCESS
) {
162 abts_log_message("%s\n", ldap_err2string(result
));
170 static void test_ldap(abts_case
*tc
, void *data
)
172 apr_pool_t
*pool
= p
;
174 apr_ldap_err_t
*result
= NULL
;
177 ABTS_ASSERT(tc
, "failed to get host", ldap_host
[0] != '\0');
179 apr_ldap_init(pool
, &ldap
,
180 ldap_host
, LDAP_PORT
,
181 APR_LDAP_NONE
, &(result
));
183 ABTS_TRUE(tc
, ldap
!= NULL
);
184 ABTS_PTR_NOTNULL(tc
, result
);
186 if (result
->rc
== LDAP_SUCCESS
) {
187 test_ldap_connection(tc
, ldap
);
191 static void test_ldaps(abts_case
*tc
, void *data
)
193 apr_pool_t
*pool
= p
;
195 apr_ldap_err_t
*result
= NULL
;
197 apr_ldap_init(pool
, &ldap
,
198 ldap_host
, LDAPS_PORT
,
199 APR_LDAP_SSL
, &(result
));
201 ABTS_TRUE(tc
, ldap
!= NULL
);
202 ABTS_PTR_NOTNULL(tc
, result
);
204 if (result
->rc
== LDAP_SUCCESS
) {
207 test_ldap_connection(tc
, ldap
);
211 static void test_ldap_tls(abts_case
*tc
, void *data
)
213 apr_pool_t
*pool
= p
;
215 apr_ldap_err_t
*result
= NULL
;
217 apr_ldap_init(pool
, &ldap
,
218 ldap_host
, LDAP_PORT
,
219 APR_LDAP_STARTTLS
, &(result
));
221 ABTS_TRUE(tc
, ldap
!= NULL
);
222 ABTS_PTR_NOTNULL(tc
, result
);
224 if (result
->rc
== LDAP_SUCCESS
) {
227 test_ldap_connection(tc
, ldap
);
231 #endif /* APR_HAS_LDAP */
233 abts_suite
*testldap(abts_suite
*suite
)
236 apr_ldap_err_t
*result
= NULL
;
237 suite
= ADD_SUITE(suite
);
239 apr_ldap_ssl_init(p
, NULL
, 0, &result
);
241 if (get_ldap_host()) {
242 abts_run_test(suite
, test_ldap
, NULL
);
243 abts_run_test(suite
, test_ldaps
, NULL
);
244 abts_run_test(suite
, test_ldap_tls
, NULL
);
246 #endif /* APR_HAS_LDAP */