fakeldap 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +3 -0
  3. data/lib/fakeldap.rb +46 -0
  4. data/lib/fakeldap/version.rb +4 -0
  5. data/vendor/ruby-ldapserver/COPYING +27 -0
  6. data/vendor/ruby-ldapserver/ChangeLog +83 -0
  7. data/vendor/ruby-ldapserver/Manifest.txt +32 -0
  8. data/vendor/ruby-ldapserver/README +222 -0
  9. data/vendor/ruby-ldapserver/Rakefile +22 -0
  10. data/vendor/ruby-ldapserver/examples/README +89 -0
  11. data/vendor/ruby-ldapserver/examples/mkcert.rb +31 -0
  12. data/vendor/ruby-ldapserver/examples/rbslapd1.rb +111 -0
  13. data/vendor/ruby-ldapserver/examples/rbslapd2.rb +161 -0
  14. data/vendor/ruby-ldapserver/examples/rbslapd3.rb +172 -0
  15. data/vendor/ruby-ldapserver/examples/speedtest.rb +37 -0
  16. data/vendor/ruby-ldapserver/lib/ldap/server.rb +4 -0
  17. data/vendor/ruby-ldapserver/lib/ldap/server/connection.rb +276 -0
  18. data/vendor/ruby-ldapserver/lib/ldap/server/filter.rb +223 -0
  19. data/vendor/ruby-ldapserver/lib/ldap/server/match.rb +283 -0
  20. data/vendor/ruby-ldapserver/lib/ldap/server/operation.rb +487 -0
  21. data/vendor/ruby-ldapserver/lib/ldap/server/preforkserver.rb +93 -0
  22. data/vendor/ruby-ldapserver/lib/ldap/server/result.rb +71 -0
  23. data/vendor/ruby-ldapserver/lib/ldap/server/schema.rb +592 -0
  24. data/vendor/ruby-ldapserver/lib/ldap/server/server.rb +89 -0
  25. data/vendor/ruby-ldapserver/lib/ldap/server/syntax.rb +235 -0
  26. data/vendor/ruby-ldapserver/lib/ldap/server/tcpserver.rb +91 -0
  27. data/vendor/ruby-ldapserver/lib/ldap/server/util.rb +88 -0
  28. data/vendor/ruby-ldapserver/lib/ldap/server/version.rb +11 -0
  29. data/vendor/ruby-ldapserver/test/core.schema +582 -0
  30. data/vendor/ruby-ldapserver/test/encoding_test.rb +279 -0
  31. data/vendor/ruby-ldapserver/test/filter_test.rb +107 -0
  32. data/vendor/ruby-ldapserver/test/match_test.rb +59 -0
  33. data/vendor/ruby-ldapserver/test/schema_test.rb +113 -0
  34. data/vendor/ruby-ldapserver/test/syntax_test.rb +40 -0
  35. data/vendor/ruby-ldapserver/test/test_helper.rb +2 -0
  36. data/vendor/ruby-ldapserver/test/util_test.rb +51 -0
  37. metadata +130 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Aanand Prasad
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ Only supports bind operations for now.
2
+
3
+ Have a look at [server_spec.rb](http://github.com/aanand/fakeldap/blob/master/spec/server_spec.rb) for usage.
@@ -0,0 +1,46 @@
1
+ $:.unshift(File.expand_path('../../vendor/ruby-ldapserver/lib', __FILE__))
2
+ require 'ldap/server'
3
+
4
+ module FakeLDAP
5
+ class Server < LDAP::Server
6
+ def initialize(options={})
7
+ @users = {}
8
+ super(default_options.merge(options))
9
+ end
10
+
11
+ def add_user(user, pass)
12
+ @users[user] = pass
13
+ end
14
+
15
+ def valid_credentials?(user, pass)
16
+ @users.has_key?(user) && @users[user] == pass
17
+ end
18
+
19
+ def default_options
20
+ {
21
+ :operation_class => ::FakeLDAP::Operation,
22
+ :operation_args => [self]
23
+ }
24
+ end
25
+ end
26
+
27
+ class Operation < LDAP::Server::Operation
28
+ def initialize(connection, messageID, server)
29
+ super(connection, messageID)
30
+ @server = server
31
+ end
32
+
33
+ def simple_bind(version, dn, password)
34
+ unless dn
35
+ raise LDAP::ResultError::InappropriateAuthentication,
36
+ "This server does not support anonymous bind"
37
+ end
38
+
39
+ unless @server.valid_credentials?(dn, password)
40
+ raise LDAP::ResultError::InvalidCredentials,
41
+ "Invalid credentials"
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,4 @@
1
+ module FakeLDAP
2
+ VERSION = "0.0.0"
3
+ end
4
+
@@ -0,0 +1,27 @@
1
+ The file 'test/core.schema' is Copyrighted by the OpenLDAP project. See the
2
+ comments in that file for full details.
3
+
4
+ All other files in this distribution are subject to the following copyright
5
+ notice:
6
+
7
+ COPYING
8
+ =======
9
+ Copyright (c) 2005 Brian Candler
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to
13
+ deal in the Software without restriction, including without limitation the
14
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
15
+ sell copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27
+ IN THE SOFTWARE.
@@ -0,0 +1,83 @@
1
+ 0.3.1 - 2008-01-16
2
+ * First release as a gem [Brandon Keepers]
3
+
4
+ RELEASE_0_3
5
+
6
+ Filters now return nil instead of LDAP::Server::MatchingRule::DefaultMatch
7
+ in the case that there's no schema.
8
+ Minor changes to syntax.rb to support OpenLDAP extensions.
9
+
10
+ 20050722
11
+
12
+ Change the 'validate' API so it works for updates too.
13
+ Change the 'modify' API so it sends a hash of attr=>[:op,data] which makes
14
+ it easier to determine which entries have been modified.
15
+ Fix modify, add and compare to normalise attribute names using the schema if
16
+ there is one.
17
+
18
+ 20050721
19
+
20
+ Added a whole loada Schema stuff.
21
+ Moved exceptions under LDAP::ResultError for consistency with ruby-ldap.
22
+ Changed the parsed [filter] format to include a MatchingRule object always
23
+ (even if no schema is present)
24
+
25
+ 20050711
26
+
27
+ Changed LDAPserver to LDAP::Server and rejigged the repository to match.
28
+ In your code you will have to change:
29
+ require 'ldapserver/foo' -> require 'ldap/server/foo'
30
+ LDAPserver::bar -> LDAP::Server::bar
31
+
32
+ I have added require 'ldap/server' which pulls in the things a basic server
33
+ will need (minus schema)
34
+
35
+ 20050626
36
+
37
+ Factored out the SSL stuff into Connection, which should also allow the
38
+ STARTTLS extension to be implemented later
39
+
40
+ Added a Server class, with methods run_tcpserver and run_prefork.
41
+
42
+ Created an explicit preforkserver method.
43
+
44
+ 20050625
45
+
46
+ tcpserver: add ability to drop privileges
47
+
48
+ examples/rbslapd3.rb: make work if ldapdb.yaml does not exist. Also bind
49
+ explicitly to 0.0.0.0; it seems that TCPSocket doesn't work properly in
50
+ some circumstances without it (FreeBSD 5.4 with IPv6 disabled in kernel)
51
+
52
+ 20050620
53
+
54
+ RELEASE_0_2
55
+
56
+ Implemented SSL support in tcpserver, just by copying examples from
57
+ openssl module.
58
+
59
+ Tweak split_dn so that it should work properly with UTF-8 encoded strings
60
+
61
+ Added examples/rbslapd3.rb, a preforking LDAP server
62
+
63
+ Added :listen option to tcpserver to set listen queue size. With the default
64
+ of 5, and 100 children trying to connect, a few connections get dropped.
65
+
66
+ Added :nodelay option to tcpserver to set TCP_NODELAY socket option. This
67
+ removes 100ms of latency in responses.
68
+
69
+ Added examples/speedtest.rb
70
+
71
+ 20050619
72
+
73
+ Modify connection.rb to ensure no memory leak in the event of exceptions
74
+ being raised in operation threads.
75
+
76
+ Fix examples/rbslapd2.rb SQLPool so that it always puts connections back
77
+ into the pool (using 'ensure' this time :-)
78
+
79
+ 20050618
80
+
81
+ RELEASE_0_1
82
+
83
+ 20050616
@@ -0,0 +1,32 @@
1
+ COPYING
2
+ ChangeLog
3
+ Manifest.txt
4
+ README
5
+ Rakefile
6
+ examples/README
7
+ examples/mkcert.rb
8
+ examples/rbslapd1.rb
9
+ examples/rbslapd2.rb
10
+ examples/rbslapd3.rb
11
+ examples/speedtest.rb
12
+ lib/ldap/server.rb
13
+ lib/ldap/server/connection.rb
14
+ lib/ldap/server/filter.rb
15
+ lib/ldap/server/match.rb
16
+ lib/ldap/server/operation.rb
17
+ lib/ldap/server/preforkserver.rb
18
+ lib/ldap/server/result.rb
19
+ lib/ldap/server/schema.rb
20
+ lib/ldap/server/server.rb
21
+ lib/ldap/server/syntax.rb
22
+ lib/ldap/server/tcpserver.rb
23
+ lib/ldap/server/util.rb
24
+ lib/ldap/server/version.rb
25
+ test/core.schema
26
+ test/encoding_test.rb
27
+ test/filter_test.rb
28
+ test/match_test.rb
29
+ test/schema_test.rb
30
+ test/syntax_test.rb
31
+ test/test_helper.rb
32
+ test/util_test.rb
@@ -0,0 +1,222 @@
1
+ CHANGES FROM VERSION 0.2 TO VERSION 0.3
2
+ ---------------------------------------
3
+
4
+ There have been substantial changes to ruby-ldapserver between version 0.2
5
+ and version 0.3. If you have not been using 0.2, you can skip this section.
6
+
7
+ Major API changes:
8
+
9
+ * I have renamed module LDAPServer to module LDAP::Server, This means e.g.
10
+ require 'ldapserver/connection' becomes require 'ldap/server/connection'
11
+
12
+ * I have moved the result exceptions to be subclasses of LDAP::ResultError,
13
+ for consistency with ruby-ldap, and named under LDAP::ResultError::<name> to
14
+ group them together. Everything else remains under LDAP::Server.
15
+
16
+ * The format of the parsed 'filter' parameter to Operation#search has
17
+ changed. See filter.rb. In particular, the format of a :substrings filter
18
+ has been changed (simplified).
19
+
20
+ * The format of the 'modinfo' parameter to Operation#modify has changed. See
21
+ the comment above 'def modify' in operation.rb
22
+
23
+ * Attribute names are no longer automatically downcased. If you are running
24
+ with a schema, however, then they will be converted into their preferred
25
+ forms. That is, "OBJECTCLASS" will become "objectClass", "CommonName" will
26
+ become "cn", and so on.
27
+
28
+ Improvements include:
29
+
30
+ * There is now an explicit object representing a server instance:
31
+ "LDAP::Server". This bundles together the root DSE, the schema (if used),
32
+ the subclass of Operation which you wish to use, and various other
33
+ parameters such as ssl certificate data. It has methods run_tcpserver and
34
+ run_prefork, making it straightforward to start a server. Both support SSL
35
+ on connect. You can do require 'ldap/server' to get all the essential
36
+ libraries for a server.
37
+
38
+ * LDAP::Server :user and :group settings let you drop privileges after
39
+ binding to port 389.
40
+
41
+ * Schema support. Can load schemas in OpenLDAP format, publish them via
42
+ LDAP, validate add/modify operations, use them to map attribute names to
43
+ their 'standard' versions (e.g. "commonname" becomes "cn"), and perform
44
+ case-insensitive comparisons where the schema mandates this. See classes
45
+ LDAP::Server::Schema, LDAP::Server::ObjectClass, LDAP::Server::AttributeType,
46
+ LDAP::Server::Syntax, LDAP::Server::MatchingRule, and examples/rbslapd3.rb.
47
+
48
+ What is it?
49
+ -----------
50
+
51
+ ruby-ldapserver is a lightweight, pure Ruby skeleton for implementing LDAP
52
+ server applications. It is intended primarily for when you wish to build a
53
+ gateway from LDAP queries into some other protocol or database; it does not
54
+ attempt to be a full implementation of the standard LDAP data model itself
55
+ (although you could build one using this as a frontend)
56
+
57
+ The Connection class handles incoming connections, decodes ASN1-formatted
58
+ LDAP requests, and creates an Operation object for each request. The
59
+ Operation object further parses the ASN1 request and invokes methods which
60
+ you override to perform useful work. Responses and exceptions are converted
61
+ back into ASN1 and returned to the client. Optionally, a collection of
62
+ objects can be used to implement a Schema (e.g. normalize attribute names,
63
+ validate add and modify operations, perform appropriate matching operations)
64
+
65
+ Since it's written entirely in Ruby, it benefits from Ruby's threading
66
+ engine.
67
+
68
+ Target audience
69
+ ---------------
70
+
71
+ Technically-savvy Ruby applications developers; the sort of people who are
72
+ happy to read RFCs and read code to work out what it does :-)
73
+
74
+ The examples/ directory contains a few minimal LDAP servers which you can
75
+ use as a starting point.
76
+
77
+ Status
78
+ ------
79
+
80
+ This is an early release. It works for me as an LDAP protocol convertor; the
81
+ Schema stuff has not been heavily tested by me.
82
+
83
+ Libraries
84
+ ---------
85
+
86
+ ASN1 encoding and decoding is done using the 'openssl' extension, which is
87
+ standard in the Ruby 1.8.2 base distribution. To check you have it, you
88
+ should be able to run `ruby -ropenssl -e puts` with no error.
89
+
90
+ However, I've found in the past that Linux machines don't always build the
91
+ openssl extension when compiling Ruby from source. With Red Hat 9, the
92
+ solution for me was, when building Ruby itself:
93
+
94
+ # export CPPFLAGS="-I/usr/kerberos/include"
95
+ # export LDFLAGS="-L/usr/kerberos/lib"
96
+ # ./configure ...etc
97
+
98
+ If you want to run the test suite then you'll need to install the ruby-ldap
99
+ client library, and if you want to run examples/rbslapd3.rb then you'll need
100
+ the prefork library. Both are available from <http://raa.ruby-lang.org/>.
101
+
102
+ Protocol implementation
103
+ -----------------------
104
+
105
+ ruby-ldapserver tries to be a reasonably complete implementation of the
106
+ message decoding and encoding components of LDAP. However, it does not
107
+ synthesise or directly enforce the LDAP data model. It will advertise a
108
+ schema in the root DSE if you configure one, and it provides helper
109
+ functions which allow you to validate add and modify operations against a
110
+ schema; but it's up to you to use them, if you wish. If you're just using
111
+ LDAP as a convenient query interface into some other database, you probably
112
+ don't care about schemas.
113
+
114
+ If your clients permit it, you can violate the LDAP specification further,
115
+ eliminating some of the gross design flaws of LDAP. For example, you can
116
+ ditch the LDAP idea that a Distinguished Name must consist of
117
+ attr=val,attr=val,attr=val... and use whatever is convenient as a primary
118
+ key (e.g. "val1,val2,val3" or "id,table_name"). The 'add' operation could
119
+ allocate DNs automatically from a sequence. There's no need for the data
120
+ duplication where an LDAP entry must contain the same attr=val pair which is
121
+ also the entry's RDN. Violations of the LDAP spec in this way are at your
122
+ own risk.
123
+
124
+ Threading issues
125
+ ----------------
126
+
127
+ The core of this library is the LDAP::Server::Connection object which handles
128
+ communication with a single client, and the LDAP::Server::Operation object
129
+ which handles a single request. Because the LDAP protocol allows a client to
130
+ send multiple overlapping requests down the same TCP connection, I start a
131
+ new Ruby thread for each Operation.
132
+
133
+ If your Operation object deals with any global shared data, then it needs to
134
+ do so in a thread-safe way. If this is new to you then see
135
+ <http://www.rubycentral.com/book/tut_threads.html>
136
+ <http://www.rubygarden.org/ruby?MultiThreading>
137
+
138
+ For incoming client connections, I have supplied a simple tcpserver method
139
+ which starts a new Ruby thread for each client. This works fine, but in a
140
+ multi-CPU system, all LDAP server operations will be processed on one CPU;
141
+ also with a very large number of concurrent client connections, you may find
142
+ you hit the a max-filedescriptors-per-process limit.
143
+
144
+ I have also provided a preforking server; see examples/rbslapd3.rb. In this
145
+ case, your connections are handled in separate processes so they cannot
146
+ share data directly in RAM.
147
+
148
+ If you are using the default threading tcpserver, then beware that a number
149
+ of Ruby extension libraries block the threading interpreter. In particular,
150
+ the client library "ruby-ldap" blocks when waiting for a response from a
151
+ remote server, since it's a wrapper around a C library which is unaware of
152
+ Ruby's threading engine. This can cause your application to 'freeze'
153
+ periodically. Either choose client libraries which play well with threading,
154
+ or make sure each client is handled in a different process.
155
+
156
+ For example, when talking to a MySQL database, you might want to choose
157
+ "ruby-mysql" (which is a pure Ruby implementation of the MySQL protocol)
158
+ rather than "mysql-ruby" (which is a wrapper around the C API, and blocks
159
+ while waiting for responses from the server)
160
+
161
+ Even with something like ruby-mysql, beware DNS lookups: resolver libraries
162
+ can block too. There is a pure Ruby resolver replacement in the standard
163
+ library: if you do
164
+
165
+ require 'resolv-replace'
166
+
167
+ this changes TCPSocket and friends to use it instead of the default C
168
+ resolver. Or you could just hard-code IP addresses, or put entries in
169
+ /etc/hosts for the machines you want to contact.
170
+
171
+ Another threading issue to think about is abandoned and timed-out LDAP
172
+ operations. The Connection object handles these by raising an
173
+ LDAP::Server::Abandon or LDAP::Server::TimeLimitExceeded exception in the
174
+ Operation thread, which you can either ignore or rescue. However, if in
175
+ rescuing it you end up putting (say) a SQL connection back into a pool, you
176
+ should beware that the SQL connection may still be mid-query, so it's
177
+ probably better to discard it and use a fresh one next time.
178
+
179
+ Performance
180
+ -----------
181
+
182
+ examples/speedtest.rb is a simple client which forks N processes, and in
183
+ each process opens an LDAP connection, binds, and sends M search requests
184
+ down it.
185
+
186
+ Using speedtest.rb and rbslapd1.rb, running on the *same* machine
187
+ (single-processor AMD Athlon 2500+) I achieve around 800 searches per second
188
+ with N=1,M=1000 and 300-400 searches per second with N=10,M=100.
189
+
190
+ To-do list
191
+ ----------
192
+
193
+ - handle and test generation of LDAP referrals properly
194
+ - more cases in test suite: abandon, concurrency, performance tests, error
195
+ handling
196
+ - extensible match filters
197
+ - extended operations
198
+ RFC 2830 - Start TLS
199
+ RFC 3062 - password modify
200
+ RFC 2839 - whoami
201
+ RFC 3909 - cancel
202
+
203
+ References
204
+ ----------
205
+
206
+ - ftp://ftp.isi.edu/in-notes/rfc2251.txt (base protocol)
207
+ - ftp://ftp.isi.edu/in-notes/rfc2252.txt (schema)
208
+ - ftp://ftp.isi.edu/in-notes/rfc2253.txt (DN encoding)
209
+ - http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
210
+ - http://www.itu.int/ITU-T/studygroups/com10/languages/X.690_1297.pdf
211
+
212
+ Contact
213
+ -------
214
+
215
+ You are very welcome to E-mail me with bug reports, patches, comments and
216
+ suggestions for this software. However, please DON'T send me any general
217
+ questions about LDAP, how LDAP works, how to apply LDAP in your particular
218
+ situation, or questions about any other LDAP software. The `ldap@umich.edu`
219
+ mailing list is probably the correct place to ask such questions. See:
220
+ <http://listserver.itd.umich.edu/cgi-bin/lyris.pl?enter=ldap>
221
+
222
+ Brian Candler <B.Candler@pobox.com>
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require File.join(File.dirname(__FILE__), 'lib', 'ldap', 'server', 'version')
4
+
5
+ RDOC_OPTS = ['--quiet', '--title', "ruby-ldapserver",
6
+ "--opname", "index.html",
7
+ "--line-numbers",
8
+ "--main", "README",
9
+ "--inline-source"]
10
+
11
+ # Generate all the Rake tasks
12
+ hoe = Hoe.new('ruby-ldapserver', ENV['VERSION'] || LDAP::Server::VERSION::STRING) do |p|
13
+ p.rubyforge_name = 'ruby-ldapserver'
14
+ p.summary = "A pure-Ruby framework for building LDAP servers"
15
+ p.description = "ruby-ldapserver is a lightweight, pure-Ruby skeleton for implementing LDAP
16
+ server applications."
17
+ p.author = 'Brian Candler'
18
+ p.email = 'B.Candler@pobox.com'
19
+ p.url = 'http://rubyforge.org/projects/ruby-ldapserver'
20
+ p.test_globs = ["test/**/*_test.rb"]
21
+ p.changes = p.paragraphs_of('ChangeLog', 0..1).join("\n\n")
22
+ end