1##
2## LDAP CONNECT AND BIND VALIDATION
3##
4## Here we can check the connection using sasl, tls and
5## just login + password credentials
6##
7## We need running LDAP server for that
8##
9
10use strict;
11use warnings;
12use utf8;
13use Test::More;
14use File::Spec;
15
16#--- check permission to run test
17my $test_directory = File::Spec->catfile( 't', '18_ldap');
18my $semaphore_file = File::Spec->catfile(
19			    $test_directory,
20                    	    'enable_talk_to_server',
21		     );
22if( !( -f $semaphore_file) ) {
23    plan skip_all => "No ldap server for testing";
24};
25
26use_ok( 'OpenXPKI::LdapUtils' );
27
28
29# --- get base realm options
30my $realm_generator =  File::Spec->catfile(
31			    $test_directory,
32                            'get_realm.pl',
33		     );
34require $realm_generator;
35our $realm;
36
37# ldap handle
38my $ldap=undef;
39
40# Array of connection configurations
41#
42# each tag ( [0] - comment) has four options
43# 1) tls
44# 2) sasl
45# 3) sasl mech
46# 4) login
47# 5) expected result ( 1 means Ok)
48my $connections=[
49                 [
50		    'no tls, no sasl',
51                    'no',
52		    'no',
53		    '',
54		    'cn=Manager,dc=openxpki,dc=org',
55		     1,
56		 ],
57                 [
58		    'tls, no sasl',
59                    'yes',
60		    'no',
61		    '',
62		    'cn=Manager,dc=openxpki,dc=org',
63		    1,
64		 ],
65                 [
66		    'no tls, sasl DIGEST-MD5',
67                    'no',
68		    'yes',
69		    'DIGEST-MD5',
70		    'sasl1',
71		    1,
72		 ],
73                 [
74		    'tls, sasl EXTERNAL',
75                    'yes',
76		    'yes',
77		    'EXTERNAL',
78		    'cn=Manager,dc=openxpki,dc=org',
79		    1,
80		 ],
81                 [
82		    'no tls, sasl CRAM-MD5',
83                    'no',
84		    'yes',
85		    'CRAM-MD5',
86		    'sasl1',
87		    1,
88		 ],
89                 [
90		    'no tls, bad sasl user CRAM-MD5',
91                    'no',
92		    'yes',
93		    'CRAM-MD5',
94		    'saslx',
95		    0,
96		 ],
97                 [
98            	    'no tls, bad sasl mechanism PLAIN',
99                    'no',
100		    'yes',
101		    'PLAIN',
102		    'sasl1',
103		    0,
104		 ],
105                 [
106		     'no tls, no sasl, bad user',
107                     'no',
108		     'no',
109		     'DIGEST-MD5',
110		     'sasl1',
111		     0,
112		 ],
113                 [
114            	    'no tls, EXTERNAL sasl mechanism',
115                    'no',
116		    'yes',
117		    'EXTERNAL',
118		    'sasl1',
119		    0,
120		 ],
121
122		];
123
124
125my $test_number = scalar @{$connections} ;
126if($ENV{DEBUG}){
127    diag( "NUMBER OF TESTS >" . ($test_number + 5) . "<\n");
128};
129my $utils=OpenXPKI::LdapUtils->new();
130
131#-------------- plan
132#
133#             connection   sasl+tls sasl+tls   utf8 FIXME
134#      	        types       some     bad      credentials
135#              	            user    certs     not done yet
136
137plan tests => $test_number + 2 +      2 +       1;
138
139diag "CONNECT TO LDAP SERVER VALIDATION\n" if $ENV{VERBOSE};
140
141#--------------------------------------------------REGULAR CONNECTIONS
142foreach my $connection_type ( @{$connections} ){
143    $realm->{ldap_tls}       = $connection_type->[1];
144    $realm->{ldap_sasl}      = $connection_type->[2];
145    $realm->{ldap_sasl_mech} = $connection_type->[3];
146    $realm->{ldap_login}     = $connection_type->[4];
147
148    my $test_name = $connection_type->[0];
149    if( $connection_type->[5] ){
150       $test_name = 'Check connect : ' . $test_name;
151    } else {
152       $test_name = 'Check deny : ' . $test_name;
153    };
154
155    $ldap = $utils->ldap_connect( $realm );
156    if( defined $ldap){
157	my $access_check = check_no_write_access($ldap);
158	$utils->ldap_disconnect($ldap);
159	ok(
160	   $connection_type->[5] && !$access_check ,
161	   $test_name
162	);
163    } else {
164	ok(
165	   1 - $connection_type->[5],
166	   $test_name
167	);
168    };
169}
170#--------------------------------------------- OTHER CERTIFICATES CONNECTIONS
171$realm->{ldap_client_cert} =
172    $realm->{'ldap_extra'}->{'badsasl_cert'};
173$realm->{ldap_client_key}  =
174    $realm->{'ldap_extra'}->{'badsasl_key'};
175
176    my $bad_connection_type  = $connections->[1];
177#   tls without sasl accepts all certificates
178    $realm->{ldap_tls}       = $bad_connection_type->[1];
179    $realm->{ldap_sasl}      = $bad_connection_type->[2];
180    $realm->{ldap_sasl_mech} = $bad_connection_type->[3];
181    $realm->{ldap_login}     = $bad_connection_type->[4];
182
183    $ldap = $utils->ldap_connect( $realm );
184    if( defined $ldap){
185        my $access_check = 1 - check_no_write_access($ldap);
186	$utils->ldap_disconnect($ldap);
187	ok(
188	   $access_check,
189	   'Check connect : ' . $bad_connection_type->[0] .
190	    " with some certificate"
191	);
192    } else {
193	ok(
194	   0,
195	   'Check connect : ' . $bad_connection_type->[0] .
196	   " with some certificate"
197	);
198    };
199
200    $bad_connection_type = $connections->[3];
201#   tls with sasl External mechanism accepts all certificates
202#   but the wrong one gives no rights
203    $realm->{ldap_tls}       = $bad_connection_type->[1];
204    $realm->{ldap_sasl}      = $bad_connection_type->[2];
205    $realm->{ldap_sasl_mech} = $bad_connection_type->[3];
206    $realm->{ldap_login}     = $bad_connection_type->[4];
207
208    $ldap = $utils->ldap_connect( $realm );
209    if( defined $ldap){
210        my $access_check = check_no_write_access($ldap);
211	$utils->ldap_disconnect($ldap);
212	ok(
213	   $access_check,
214	   'Check connect : ' . $bad_connection_type->[0] .
215	    " with a non registered user certificate"
216	);
217    } else {
218	ok(
219	   0,
220	   'Check connect : ' . $bad_connection_type->[0] .
221	    " with a non registered user certificate"
222	);
223    };
224
225
226#--------------------------------------------- NO CA CERTIFICATES CONNECTIONS
227$realm->{ldap_client_cert} =
228    $realm->{'ldap_extra'}->{'verybadsasl_cert'};
229$realm->{ldap_client_key}  =
230    $realm->{'ldap_extra'}->{'verybadsasl_key'};
231
232    $bad_connection_type  = $connections->[1];
233#   tls without sasl must die with non verifiable certificate
234    $realm->{ldap_tls}       = $bad_connection_type->[1];
235    $realm->{ldap_sasl}      = $bad_connection_type->[2];
236    $realm->{ldap_sasl_mech} = $bad_connection_type->[3];
237    $realm->{ldap_login}     = $bad_connection_type->[4];
238
239    $ldap = $utils->ldap_connect( $realm );
240    ok( !defined $ldap,
241	'Check deny : ' . $bad_connection_type->[0] .
242	" with a certificate signed by some CA"
243    );
244    if( defined $ldap){
245	$utils->ldap_disconnect($ldap);
246    };
247
248    $bad_connection_type = $connections->[3];
249#   tls with sasl External mechanism must die with
250#   non verifiable certificate
251    $realm->{ldap_tls}       = $bad_connection_type->[1];
252    $realm->{ldap_sasl}      = $bad_connection_type->[2];
253    $realm->{ldap_sasl_mech} = $bad_connection_type->[3];
254    $realm->{ldap_login}     = $bad_connection_type->[4];
255
256    $ldap = $utils->ldap_connect( $realm );
257    ok( !defined $ldap,
258	'Check deny : ' . $bad_connection_type->[0] .
259	" with a certificate signed by some CA"
260    );
261
262    if( defined $ldap){
263	$utils->ldap_disconnect($ldap);
264    };
265
266    TODO: {
267        todo_skip 'connect using utf8 credentials - not done yet', 1 if 1;
268	ok(1)
269    };
2701;
271
272
273sub check_no_write_access
274{
275    my $ldap = shift;
276    my $base_dn='dc=openxpki,dc=org';
277    my $ounit='xTESTxLDAPx';
278    my $addmsg = $ldap->add( 'ou=' . $ounit . ',' . $base_dn,
279	                    attr => [
280                          'ou'   => $ounit,
281                   'objectclass' => ['organizationalUnit'],
282		            ],
283               );
284    if ($addmsg->is_error()) {
285      return 1;
286    } else {
287	$ldap->delete( 'ou=' . $ounit . ',' . $base_dn);
288	return 0;
289    };
290}
291