-
Notifications
You must be signed in to change notification settings - Fork 31
/
LDAPS.pm
219 lines (156 loc) · 6.06 KB
/
LDAPS.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# Copyright (c) 2000-2001 Chris Ridd <chris.ridd@messagingdirect.com> and
# Graham Barr <gbarr@pobox.com>. All rights reserved. This program is
# free software; you can redistribute it and/or modify it under the
# same terms as Perl itself.
package Net::LDAPS;
@Net::LDAPS::ISA = ( 'Net::LDAP' );
$Net::LDAPS::VERSION = "0.03";
use strict;
use Net::LDAP;
use IO::Socket::SSL;
# Different OpenSSL verify modes.
my %verify = qw(none 0 optional 1 require 3);
sub _connect {
my ($ldap, $host, $arg) = @_;
$ldap->{'net_ldap_socket'} = IO::Socket::SSL->new(
PeerAddr => $host,
PeerPort => $arg->{'port'} || '636',
Proto => 'tcp',
Timeout => defined $arg->{'timeout'} ? $arg->{'timeout'} : 120,
SSL_context_init_args($arg)
);
}
sub SSL_context_init_args {
my $arg = shift;
my $verify = 0;
my ($clientcert,$clientkey);
if (exists $arg->{'verify'}) {
my $v = lc $arg->{'verify'};
$verify = 0 + (exists $verify{$v} ? $verify{$v} : $verify);
}
if (exists $arg->{'clientcert'}) {
$clientcert = $arg->{'clientcert'};
if (exists $arg->{'clientkey'}) {
$clientkey = $arg->{'clientkey'};
} else {
require Carp;
Carp::croak("Setting client public key but not client private key");
}
}
(
SSL_cipher_list => defined $arg->{'ciphers'} ? $arg->{'ciphers'} : 'ALL',
SSL_ca_file => exists $arg->{'cafile'} ? $arg->{'cafile'} : '',
SSL_ca_path => exists $arg->{'capath'} ? $arg->{'capath'} : '',
SSL_key_file => $clientcert ? $clientkey : undef,
SSL_use_cert => $clientcert ? 1 : 0,
SSL_cert_file => $clientcert,
SSL_verify_mode => $verify,
SSL_version => defined $arg->{'sslversion'} ? $arg->{'sslversion'} :
'sslv2/3',
);
}
1;
__END__
=head1 NAME
Net::LDAPS - use LDAP over an SSL connection
=head1 SYNOPSIS
use Net::LDAPS;
$ldaps = new Net::LDAPS('myhost.example.com',
port => '10000',
verify => 'require',
capath => '/usr/local/cacerts/');
=head1 DESCRIPTION
Communicate using the LDAP protocol to a directory server using a
potentially encrypted (SSL) network connection.
This class is a subclass of Net::LDAP so all the normal Net::LDAP
methods can be used with a Net::LDAPS object; see the documentation
for Net::LDAP to find out how to query a directory server using the
LDAP protocol.
Note that the use of LDAPS is not recommended, because it is not
described by any IETF documents. Instead, you should consider using
LDAPv3 with the TLS extension defined in RFC 2830. This will give you
the same functionality as LDAPS, but using recognized standards. See
L<Net::LDAP/start_tls>.
=head1 CONSTRUCTOR
=over 4
=item new ( HOST [, OPTIONS ] )
Create a new connection. HOST is the hostname to contact. OPTIONS is a
number of key/value pairs - additional keys to those understood by
Net::LDAP::new are:
=over 4
=item verify
How to verify the server's certificate, either 'none' (the server may
provide a certificate but it will not be checked - this may mean you
are be connected to the wrong server), 'optional' (verify if the
server offers a certificate), or 'require' (the server must provide a
certificate, and it must be valid.) If you set verify to optional or
require, you must also set either cafile or capath. The most secure
option is 'require'.
=item sslversion
This defines the version of the SSL/TLS protocol to use. Defaults to
'sslv2/3', other possible values are 'sslv2', 'sslv3', and 'tlsv1'.
=item ciphers
Specify which subset of cipher suites are permissible for this
connection, using the standard OpenSSL string format. The default
value for ciphers is 'ALL', which permits all ciphers, even those that
don't encrypt!
=item clientcert
=item clientkey
If you want to use the client to offer a certificate to the server for
SSL authentication (which is not the same as for the LDAP Bind
operation) then set clientcert to the user's certificate file, and
clientkey to the user's private key file. These files must be in PEM
format.
=item capath
=item cafile
When verifying the server's certificate, either set capath to the
pathname of the directory containing CA certificates, or set cafile to
the filename containing the certificate of the CA who signed the
server's certificate. These certificates must all be in PEM format.
The directory in 'capath' must contain certificates named using the
hash value of themselves. To generate these names, use OpenSSL like
this in Unix:
ln -s cacert.pem `openssl x509 -hash -noout < cacert.pem`.0
(assuming that the certificate of the CA is in cacert.pem.)
=back
=back
=head1 ADDITIONAL METHODS
=over 4
=item cipher
Returns the cipher mode being used by the connection, in the string
format used by OpenSSL.
=item certificate
Returns an X509_Certificate object containing the server's
certificate. See the IO::Socket::SSL documentation for information
about this class.
For example, to get the subject name (in a peculiar OpenSSL-specific
format, different from RFC 1779 and RFC 2253) from the server's
certificate, do this:
print "Subject DN: " . $ldaps->certificate->subject_name . "\n";
=back
=head1 SEE ALSO
L<Net::LDAP>,
L<IO::Socket::SSL>
=head1 BUGS
Several apparently bogus warnings are emitted when initializing the
two underlying modules used by Net::LDAPS, namely IO::Socket::SSL and
Net::SSLeay. To avoid these, don't initialize via 'use Net::LDAPS' and
instead try initializing Net::LDAPS like this:
BEGIN {
# Turn off all warnings etc whilst initializing
# IO::Socket::SSL and Net::SSLeay.
local $^W = 0;
no strict;
require Net::SSLeay;
# The /dev/urandom is a device on Linux that returns
# random data.
Net::SSLeay::randomize('/dev/urandom');
require Net::LDAPS;
}
=head1 AUTHOR
Chris Ridd <chris.ridd@messagingdirect.com>
=head1 COPYRIGHT
Copyright (c) 2000-2001, Chris Ridd and Graham Barr. All rights reserved. This
library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut