fakeldap 0.0.1 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +7 -1
  3. data/lib/fakeldap.rb +133 -10
  4. data/lib/fakeldap/version.rb +1 -1
  5. metadata +50 -191
  6. data/vendor/ruby-ldapserver/COPYING +0 -27
  7. data/vendor/ruby-ldapserver/ChangeLog +0 -83
  8. data/vendor/ruby-ldapserver/Manifest.txt +0 -32
  9. data/vendor/ruby-ldapserver/README +0 -222
  10. data/vendor/ruby-ldapserver/Rakefile +0 -22
  11. data/vendor/ruby-ldapserver/doc/LDAP.html +0 -104
  12. data/vendor/ruby-ldapserver/doc/LDAP/Abandon.html +0 -112
  13. data/vendor/ruby-ldapserver/doc/LDAP/Error.html +0 -115
  14. data/vendor/ruby-ldapserver/doc/LDAP/ResultError.html +0 -241
  15. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AdminLimitExceeded.html +0 -158
  16. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AffectsMultipleDSAs.html +0 -158
  17. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AliasDereferencingProblem.html +0 -158
  18. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AliasProblem.html +0 -158
  19. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AttributeOrValueExists.html +0 -158
  20. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AuthMethodNotSupported.html +0 -158
  21. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Busy.html +0 -158
  22. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/CompareFalse.html +0 -158
  23. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/CompareTrue.html +0 -158
  24. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ConfidentialityRequired.html +0 -158
  25. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ConstraintViolation.html +0 -158
  26. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/EntryAlreadyExists.html +0 -158
  27. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InappropriateAuthentication.html +0 -158
  28. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InappropriateMatching.html +0 -158
  29. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InsufficientAccessRights.html +0 -158
  30. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidAttributeSyntax.html +0 -158
  31. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidCredentials.html +0 -158
  32. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidDNSyntax.html +0 -158
  33. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/IsLeaf.html +0 -158
  34. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/LoopDetect.html +0 -158
  35. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NamingViolation.html +0 -158
  36. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NoSuchAttribute.html +0 -158
  37. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NoSuchObject.html +0 -158
  38. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NotAllowedOnNonLeaf.html +0 -158
  39. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NotAllowedOnRDN.html +0 -158
  40. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ObjectClassModsProhibited.html +0 -158
  41. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ObjectClassViolation.html +0 -158
  42. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/OperationsError.html +0 -158
  43. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Other.html +0 -158
  44. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ProtocolError.html +0 -158
  45. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Referral.html +0 -158
  46. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/SaslBindInProgress.html +0 -158
  47. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/SizeLimitExceeded.html +0 -158
  48. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/StrongAuthRequired.html +0 -158
  49. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Success.html +0 -158
  50. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/TimeLimitExceeded.html +0 -158
  51. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Unavailable.html +0 -158
  52. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UnavailableCriticalExtension.html +0 -158
  53. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UndefinedAttributeType.html +0 -158
  54. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UnwillingToPerform.html +0 -158
  55. data/vendor/ruby-ldapserver/doc/LDAP/Server.html +0 -1056
  56. data/vendor/ruby-ldapserver/doc/LDAP/Server/Connection.html +0 -1353
  57. data/vendor/ruby-ldapserver/doc/LDAP/Server/Filter.html +0 -634
  58. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule.html +0 -1132
  59. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/DefaultMatchingClass.html +0 -219
  60. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Equality.html +0 -170
  61. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/IA5Downcase.html +0 -143
  62. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/IA5Trim.html +0 -155
  63. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Integer.html +0 -143
  64. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Ordering.html +0 -212
  65. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/StringDowncase.html +0 -143
  66. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/StringTrim.html +0 -154
  67. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Substrings.html +0 -177
  68. data/vendor/ruby-ldapserver/doc/LDAP/Server/Operation.html +0 -2994
  69. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema.html +0 -2024
  70. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema/AttributeType.html +0 -1462
  71. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema/ObjectClass.html +0 -1097
  72. data/vendor/ruby-ldapserver/doc/LDAP/Server/Syntax.html +0 -1254
  73. data/vendor/ruby-ldapserver/doc/LDAP/Server/VERSION.html +0 -134
  74. data/vendor/ruby-ldapserver/doc/_index.html +0 -662
  75. data/vendor/ruby-ldapserver/doc/class_list.html +0 -36
  76. data/vendor/ruby-ldapserver/doc/css/common.css +0 -1
  77. data/vendor/ruby-ldapserver/doc/css/full_list.css +0 -50
  78. data/vendor/ruby-ldapserver/doc/css/style.css +0 -303
  79. data/vendor/ruby-ldapserver/doc/file.README.html +0 -399
  80. data/vendor/ruby-ldapserver/doc/file_list.html +0 -38
  81. data/vendor/ruby-ldapserver/doc/frames.html +0 -13
  82. data/vendor/ruby-ldapserver/doc/index.html +0 -399
  83. data/vendor/ruby-ldapserver/doc/js/app.js +0 -204
  84. data/vendor/ruby-ldapserver/doc/js/full_list.js +0 -112
  85. data/vendor/ruby-ldapserver/doc/js/jquery.js +0 -154
  86. data/vendor/ruby-ldapserver/doc/method_list.html +0 -1571
  87. data/vendor/ruby-ldapserver/doc/top-level-namespace.html +0 -88
  88. data/vendor/ruby-ldapserver/examples/README +0 -89
  89. data/vendor/ruby-ldapserver/examples/mkcert.rb +0 -31
  90. data/vendor/ruby-ldapserver/examples/rbslapd1.rb +0 -111
  91. data/vendor/ruby-ldapserver/examples/rbslapd2.rb +0 -161
  92. data/vendor/ruby-ldapserver/examples/rbslapd3.rb +0 -172
  93. data/vendor/ruby-ldapserver/examples/speedtest.rb +0 -37
  94. data/vendor/ruby-ldapserver/lib/ldap/server.rb +0 -4
  95. data/vendor/ruby-ldapserver/lib/ldap/server/connection.rb +0 -276
  96. data/vendor/ruby-ldapserver/lib/ldap/server/filter.rb +0 -223
  97. data/vendor/ruby-ldapserver/lib/ldap/server/match.rb +0 -283
  98. data/vendor/ruby-ldapserver/lib/ldap/server/operation.rb +0 -487
  99. data/vendor/ruby-ldapserver/lib/ldap/server/preforkserver.rb +0 -93
  100. data/vendor/ruby-ldapserver/lib/ldap/server/result.rb +0 -71
  101. data/vendor/ruby-ldapserver/lib/ldap/server/schema.rb +0 -592
  102. data/vendor/ruby-ldapserver/lib/ldap/server/server.rb +0 -89
  103. data/vendor/ruby-ldapserver/lib/ldap/server/syntax.rb +0 -235
  104. data/vendor/ruby-ldapserver/lib/ldap/server/tcpserver.rb +0 -91
  105. data/vendor/ruby-ldapserver/lib/ldap/server/util.rb +0 -88
  106. data/vendor/ruby-ldapserver/lib/ldap/server/version.rb +0 -11
  107. data/vendor/ruby-ldapserver/test/core.schema +0 -582
  108. data/vendor/ruby-ldapserver/test/encoding_test.rb +0 -279
  109. data/vendor/ruby-ldapserver/test/filter_test.rb +0 -107
  110. data/vendor/ruby-ldapserver/test/match_test.rb +0 -59
  111. data/vendor/ruby-ldapserver/test/schema_test.rb +0 -113
  112. data/vendor/ruby-ldapserver/test/syntax_test.rb +0 -40
  113. data/vendor/ruby-ldapserver/test/test_helper.rb +0 -2
  114. data/vendor/ruby-ldapserver/test/util_test.rb +0 -51
@@ -1,89 +0,0 @@
1
- require 'ldap/server/connection'
2
- require 'ldap/server/operation'
3
- require 'openssl'
4
-
5
- module LDAP
6
- class Server
7
-
8
- attr_accessor :root_dse
9
-
10
- DEFAULT_OPT = {
11
- :port=>389,
12
- :nodelay=>true,
13
- }
14
-
15
- # Create a new server. Options include all those to tcpserver/preforkserver
16
- # plus:
17
- # :operation_class=>Class - set Operation handler class
18
- # :operation_args=>[...] - args to Operation.new
19
- # :ssl_key_file=>pem, :ssl_cert_file=>pem - enable SSL
20
- # :ssl_ca_path=>directory - verify peer certificates
21
- # :schema=>Schema - Schema object
22
- # :namingContexts=>[dn, ...] - base DN(s) we answer
23
-
24
- def initialize(opt = DEFAULT_OPT)
25
- @opt = opt
26
- @opt[:server] = self
27
- @opt[:operation_class] ||= LDAP::Server::Operation
28
- @opt[:operation_args] ||= []
29
- LDAP::Server.ssl_prepare(@opt)
30
- @schema = opt[:schema] # may be nil
31
- @root_dse = Hash.new { |h,k| h[k] = [] }.merge({
32
- 'objectClass' => ['top','openLDAProotDSE','extensibleObject'],
33
- 'supportedLDAPVersion' => ['3'],
34
- #'altServer' =>
35
- #'supportedExtension' =>
36
- #'supportedControl' =>
37
- #'supportedSASLMechanisms' =>
38
- })
39
- @root_dse['subschemaSubentry'] = [@schema.subschema_dn] if @schema
40
- @root_dse['namingContexts'] = opt[:namingContexts] if opt[:namingContexts]
41
- end
42
-
43
- # create opt[:ssl_ctx] from the other ssl options
44
-
45
- def self.ssl_prepare(opt) # :nodoc:
46
- if opt[:ssl_key_file] and opt[:ssl_cert_file]
47
- ctx = OpenSSL::SSL::SSLContext.new
48
- ctx.key = OpenSSL::PKey::RSA.new(File::read(opt[:ssl_key_file]))
49
- ctx.cert = OpenSSL::X509::Certificate.new(File::read(opt[:ssl_cert_file]))
50
- if opt[:ssl_ca_path]
51
- ctx.ca_path = opt[:ssl_ca_path]
52
- ctx.verify_mode =
53
- OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
54
- else
55
- $stderr.puts "Warning: SSL peer certificate won't be verified"
56
- end
57
- opt[:ssl_ctx] = ctx
58
- end
59
- end
60
-
61
- def run_tcpserver
62
- require 'ldap/server/tcpserver'
63
-
64
- opt = @opt
65
- @thread = LDAP::Server.tcpserver(@opt) do
66
- LDAP::Server::Connection::new(self,opt).handle_requests
67
- end
68
- end
69
-
70
- def run_prefork
71
- require 'ldap/server/preforkserver'
72
-
73
- opt = @opt
74
- @thread = LDAP::Server.preforkserver(@opt) do
75
- LDAP::Server::Connection::new(self,opt).handle_requests
76
- end
77
- end
78
-
79
- def join
80
- @thread.join
81
- end
82
-
83
- def stop
84
- @thread.raise Interrupt, "" # <= temporary fix for 1.8.6
85
- @thread.join
86
- end
87
-
88
- end # class Server
89
- end # module LDAP
@@ -1,235 +0,0 @@
1
- module LDAP
2
- class Server
3
-
4
- # A class which describes LDAP SyntaxDescriptions. For now there is
5
- # a global pool of Syntax objects (rather than each Schema object
6
- # having its own set)
7
-
8
- class Syntax
9
- attr_reader :oid, :nhr, :binary, :desc
10
-
11
- # Create a new Syntax object
12
-
13
- def initialize(oid, desc=nil, opt={}, &blk)
14
- @oid = oid
15
- @desc = desc
16
- @nhr = opt[:nhr] # not human-readable?
17
- @binary = opt[:binary] # binary encoding forced?
18
- @re = opt[:re] # regular expression for parsing
19
- @def = nil
20
- instance_eval(&blk) if blk
21
- end
22
-
23
- def to_s
24
- @oid
25
- end
26
-
27
- # Create a new Syntax object, given its description string
28
-
29
- def self.from_def(str, &blk)
30
- m = LDAPSyntaxDescription.match(str)
31
- raise LDAP::ResultError::InvalidAttributeSyntax,
32
- "Bad SyntaxTypeDescription #{str.inspect}" unless m
33
- new(m[1], m[2], :nhr=>(m[3] == 'TRUE'), :binary=>(m[4] == 'TRUE'), &blk)
34
- end
35
-
36
- # Convert this object to its description string
37
-
38
- def to_def
39
- return @def if @def
40
- ans = "( #@oid "
41
- ans << "DESC '#@desc' " if @desc
42
- # These are OpenLDAP extensions
43
- ans << "X-BINARY-TRANSFER-REQUIRED 'TRUE' " if @binary
44
- ans << "X-NOT-HUMAN-READABLE 'TRUE' " if @nhr
45
- ans << ")"
46
- @def = ans
47
- end
48
-
49
- # Return true or a MatchData object if the given value is allowed
50
- # by this syntax
51
-
52
- def match(val)
53
- return true if @re.nil?
54
- @re.match(value_to_s(val))
55
- end
56
-
57
- # Convert a value for this syntax into its canonical string representation
58
- # (not yet used, but seemed like a good idea)
59
-
60
- def value_to_s(val)
61
- val.to_s
62
- end
63
-
64
- # Convert a string value for this syntax into a Ruby-like value
65
- # (not yet used, but seemed like a good idea)
66
-
67
- def value_from_s(val)
68
- val
69
- end
70
-
71
- @@syntaxes = {}
72
-
73
- # Add a new syntax definition
74
-
75
- def self.add(*args, &blk)
76
- s = new(*args, &blk)
77
- @@syntaxes[s.oid] = s
78
- end
79
-
80
- # Find a Syntax object given an oid. If not known, return a new empty
81
- # Syntax object associated with this oid.
82
-
83
- def self.find(oid)
84
- return oid if oid.nil? or oid.is_a?(LDAP::Server::Syntax)
85
- return @@syntaxes[oid] if @@syntaxes[oid]
86
- add(oid)
87
- end
88
-
89
- # Return all known syntax objects
90
-
91
- def self.all_syntaxes
92
- @@syntaxes.values.uniq
93
- end
94
-
95
- # Shared constants for regexp-based syntax parsers
96
-
97
- KEYSTR = "[a-zA-Z][a-zA-Z0-9;-]*"
98
- NUMERICOID = "( \\d[\\d.]+\\d )"
99
- WOID = "\\s* ( #{KEYSTR} | \\d[\\d.]+\\d ) \\s*"
100
- _WOID = "\\s* (?: #{KEYSTR} | \\d[\\d.]+\\d ) \\s*"
101
- OIDS = "( #{_WOID} | \\s* \\( #{_WOID} (?: \\$ #{_WOID} )* \\) \\s* )"
102
- _QDESCR = "\\s* ' #{KEYSTR} ' \\s*"
103
- QDESCRS = "( #{_QDESCR} | \\s* \\( (?:#{_QDESCR})+ \\) \\s* )"
104
- QDSTRING = "\\s* ' (.*?) ' \\s*"
105
- NOIDLEN = "(\\d[\\d.]+\\d) (?: \\{ (\\d+) \\} )?"
106
- ATTRIBUTEUSAGE = "(userApplications|directoryOperation|distributedOperation|dSAOperation)"
107
-
108
- end
109
-
110
- class Syntax
111
-
112
- # These are the 'SHOULD' support syntaxes from RFC2252 section 6
113
-
114
- AttributeTypeDescription =
115
- add("1.3.6.1.4.1.1466.115.121.1.3", "Attribute Type Description", :re=>
116
- %r! \A \s* \( \s*
117
- #{NUMERICOID} \s*
118
- (?: NAME #{QDESCRS} )?
119
- (?: DESC #{QDSTRING} )?
120
- ( OBSOLETE \s* )?
121
- (?: SUP #{WOID} )?
122
- (?: EQUALITY #{WOID} )?
123
- (?: ORDERING #{WOID} )?
124
- (?: SUBSTR #{WOID} )?
125
- (?: SYNTAX \s* #{NOIDLEN} \s* )? # capture 2
126
- ( SINGLE-VALUE \s* )?
127
- ( COLLECTIVE \s* )?
128
- ( NO-USER-MODIFICATION \s* )?
129
- (?: USAGE \s* #{ATTRIBUTEUSAGE} )?
130
- \s* \) \s* \z !xu)
131
-
132
- add("1.3.6.1.4.1.1466.115.121.1.5", "Binary", :nhr=>true)
133
- # FIXME: value_to_s should BER-encode the value??
134
-
135
- add("1.3.6.1.4.1.1466.115.121.1.6", "Bit String", :re=>/\A'([01]*)'B\z/)
136
- # FIXME: convert to FixNum?
137
-
138
- add("1.3.6.1.4.1.1466.115.121.1.7", "Boolean", :re=>/\A(TRUE|FALSE)\z/) do
139
- def self.value_to_s(v)
140
- return v if v.is_a?(string)
141
- v ? "TRUE" : "FALSE"
142
- end
143
- def self.value_from_s(v)
144
- v.upcase == "TRUE"
145
- end
146
- end
147
-
148
- add("1.3.6.1.4.1.1466.115.121.1.8", "Certificate", :binary=>true, :nhr=>true)
149
- add("1.3.6.1.4.1.1466.115.121.1.9", "Certificate List", :binary=>true, :nhr=>true)
150
- add("1.3.6.1.4.1.1466.115.121.1.10", "Certificate Pair", :binary=>true, :nhr=>true)
151
- add("1.3.6.1.4.1.1466.115.121.1.11", "Country String", :re=>/\A[A-Z]{2}\z/i)
152
- add("1.3.6.1.4.1.1466.115.121.1.12", "Distinguished Name")
153
- # FIXME: validate DN?
154
- add("1.3.6.1.4.1.1466.115.121.1.15", "Directory String")
155
- # missed due to lack of interest: "DIT Content Rule Description"
156
- add("1.3.6.1.4.1.1466.115.121.1.22", "Facsimile Telephone Number")
157
- add(" 1.3.6.1.4.1.1466.115.121.1.23", "Fax", :nhr=>true)
158
- add("1.3.6.1.4.1.1466.115.121.1.24", "Generalized Time")
159
- # FIXME: Validate Generalized Time (find X.208) and convert to/from Ruby Time
160
- add("1.3.6.1.4.1.1466.115.121.1.26", "IA5 String")
161
- add("1.3.6.1.4.1.1466.115.121.1.27", "Integer", :re=>/\A\d+\z/) do
162
- def self.value_from_s(v)
163
- v.to_i
164
- end
165
- end
166
- add("1.3.6.1.4.1.1466.115.121.1.28", "JPEG", :nhr=>true)
167
- MatchingRuleDescription =
168
- add("1.3.6.1.4.1.1466.115.121.1.30", "Matching Rule Description", :re=>
169
- %r! \A \s* \( \s*
170
- #{NUMERICOID} \s*
171
- (?: NAME #{QDESCRS} )?
172
- (?: DESC #{QDSTRING} )?
173
- ( OBSOLETE \s* )?
174
- SYNTAX \s* #{NUMERICOID} \s*
175
- \s* \) \s* \z !xu)
176
- MatchingRuleUseDescription =
177
- add("1.3.6.1.4.1.1466.115.121.1.31", "Matching Rule Use Description", :re=>
178
- %r! \A \s* \( \s*
179
- #{NUMERICOID} \s*
180
- (?: NAME #{QDESCRS} )?
181
- (?: DESC #{QDSTRING} )?
182
- ( OBSOLETE \s* )?
183
- APPLIES \s* #{OIDS} \s*
184
- \s* \) \s* \z !xu)
185
- add("1.3.6.1.4.1.1466.115.121.1.33", "MHS OR Address")
186
- add("1.3.6.1.4.1.1466.115.121.1.34", "Name And Optional UID")
187
- # missed due to lack of interest: "Name Form Description"
188
- add("1.3.6.1.4.1.1466.115.121.1.36", "Numeric String", :re=>/\A\d+\z/)
189
- ObjectClassDescription =
190
- add("1.3.6.1.4.1.1466.115.121.1.37", "Object Class Description", :re=>
191
- %r! \A \s* \( \s*
192
- #{NUMERICOID} \s*
193
- (?: NAME #{QDESCRS} )?
194
- (?: DESC #{QDSTRING} )?
195
- ( OBSOLETE \s* )?
196
- (?: SUP #{OIDS} )?
197
- (?: ( ABSTRACT|STRUCTURAL|AUXILIARY ) \s* )?
198
- (?: MUST #{OIDS} )?
199
- (?: MAY #{OIDS} )?
200
- \s* \) \s* \z !xu)
201
- add("1.3.6.1.4.1.1466.115.121.1.38", "OID", :re=>/\A#{WOID}\z/xu)
202
- add("1.3.6.1.4.1.1466.115.121.1.39", "Other Mailbox")
203
- add("1.3.6.1.4.1.1466.115.121.1.41", "Postal Address") do
204
- def self.value_from_s(v)
205
- v.split(/\$/)
206
- end
207
- def self.value_to_s(v)
208
- return v.join("$") if v.is_a?(Array)
209
- return v
210
- end
211
- end
212
- add("1.3.6.1.4.1.1466.115.121.1.43", "Presentation Address")
213
- add("1.3.6.1.4.1.1466.115.121.1.44", "Printable String")
214
- add("1.3.6.1.4.1.1466.115.121.1.50", "Telephone Number")
215
- add("1.3.6.1.4.1.1466.115.121.1.53", "UTC Time")
216
-
217
- LDAPSyntaxDescription =
218
- add("1.3.6.1.4.1.1466.115.121.1.54", "LDAP Syntax Description", :re=>
219
- %r! \A \s* \( \s*
220
- #{NUMERICOID} \s*
221
- (?: DESC #{QDSTRING} )?
222
- (?: X-BINARY-TRANSFER-REQUIRED \s* ' (TRUE|FALSE) ' \s* )?
223
- (?: X-NOT-HUMAN-READABLE \s* ' (TRUE|FALSE) ' \s* )?
224
- \s* \) \s* \z !xu)
225
-
226
- # Missed due to lack of interest: "DIT Structure Rule Description"
227
-
228
- # A few others from RFC2252 section 4.3.2
229
- add("1.3.6.1.4.1.1466.115.121.1.4", "Audio", :nhr=>true)
230
- add("1.3.6.1.4.1.1466.115.121.1.40", "Octet String")
231
- add("1.3.6.1.4.1.1466.115.121.1.58", "Substring Assertion")
232
- end
233
-
234
- end # class Server
235
- end # module LDAP
@@ -1,91 +0,0 @@
1
- require 'socket'
2
-
3
- module LDAP
4
- class Server
5
-
6
- # Accept connections on a port, and for each one start a new thread
7
- # and run the given block. Returns the Thread object for the listener.
8
- #
9
- # FIXME:
10
- # - have a limit on total number of concurrent connects
11
- # - have a limit on connections from a single IP, or from a /24
12
- # (to avoid the trivial DoS that the first limit creates)
13
- # - ACL using source IP address (or perhaps that belongs in application)
14
- #
15
- # Options:
16
- # :port=>port number [required]
17
- # :bindaddr=>"IP address"
18
- # :user=>"username" - drop privileges after bind
19
- # :group=>"groupname" - ditto
20
- # :logger=>object - implements << method
21
- # :listen=>number - listen queue depth
22
- # :nodelay=>true - set TCP_NODELAY option
23
-
24
- def self.tcpserver(opt, &blk)
25
- logger = opt[:logger] || $stderr
26
- server = TCPServer.new(opt[:bindaddr] || "0.0.0.0", opt[:port])
27
-
28
- # Drop privileges if requested
29
- require 'etc' if opt[:group] or opt[:user]
30
- Process.gid = Process.egid = Etc.getgrnam(opt[:group]).gid if opt[:group]
31
- Process.uid = Process.euid = Etc.getpwnam(opt[:user]).uid if opt[:user]
32
-
33
- # Typically the O/S will buffer response data for 100ms before sending.
34
- # If the response is sent as a single write() then there's no need for it.
35
- if opt[:nodelay]
36
- begin
37
- server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
38
- rescue Exception
39
- end
40
- end
41
- # set queue size for incoming connections (default is 5)
42
- server.listen(opt[:listen]) if opt[:listen]
43
-
44
- Thread.new do
45
- while true
46
- begin
47
- session = server.accept
48
- # subtlety: copy 'session' into a block-local variable because
49
- # it will change when the next session is accepted
50
- Thread.new(session) do |s|
51
- begin
52
- s.instance_eval(&blk)
53
- rescue Exception => e
54
- logger << "[#{s.peeraddr[3]}]: #{e}: #{e.backtrace[0]}\n"
55
- #logger << "[#{s.peeraddr[3]}]: #{e}: #{e.backtrace.join("\n\tfrom ")}\n"
56
- ensure
57
- s.close
58
- end
59
- end
60
- rescue Interrupt
61
- # This exception can be raised to shut the server down
62
- server.close if server and not server.closed?
63
- break
64
- end
65
- end
66
- end
67
- end
68
-
69
- end # class Server
70
- end # module LDAP
71
-
72
- if __FILE__ == $0
73
- # simple test
74
- puts "Running a test POP3 server on port 1110"
75
- t = LDAP::Server.tcpserver(:port=>1110) do
76
- print "+OK I am a fake POP3 server\r\n"
77
- while line = gets
78
- case line
79
- when /^quit/i
80
- break
81
- when /^crash/i
82
- raise Errno::EPERM, "dammit!"
83
- else
84
- print "-ERR I don't understand #{line}"
85
- end
86
- end
87
- print "+OK bye\r\n"
88
- end
89
- #sleep 10; t.raise Interrupt # uncomment to run for fixed time period
90
- t.join
91
- end
@@ -1,88 +0,0 @@
1
- require 'ldap/server/result'
2
-
3
- module LDAP
4
- class Server
5
-
6
- class Operation
7
-
8
- # Return true if connection is not authenticated
9
-
10
- def anonymous?
11
- @connection.binddn.nil?
12
- end
13
-
14
- # Split dn string into its component parts, returning
15
- # [ {attr=>val}, {attr=>val}, ... ]
16
- #
17
- # This is pretty horrible legacy stuff from X500; see RFC2253 for the
18
- # full gore. It's stupid that the LDAP protocol sends the DN in string
19
- # form, rather than in ASN1 form (as it does with search filters, for
20
- # example), even though the DN syntax is defined in terms of ASN1!
21
- #
22
- # Attribute names are downcased, but values are not. For any
23
- # case-insensitive attributes it's up to you to downcase them.
24
- #
25
- # Note that only v2 clients should add extra space around the comma.
26
- # This is accepted, and so is semicolon instead of comma, but the
27
- # full RFC1779 backwards-compatibility rules (e.g. quoted values)
28
- # are not implemented.
29
- #
30
- # I *think* these functions will work correctly with UTF8-encoded
31
- # characters, given that a multibyte UTF8 character does not contain
32
- # the bytes 00-7F and therefore we cannot confuse '\', '+' etc
33
-
34
- def self.split_dn(dn)
35
- # convert \\ to \5c, \+ to \2b etc
36
- dn2 = dn.gsub(/\\([ #,+"\\<>;])/) { "\\%02x" % $1[0] }
37
-
38
- # Now we know that \\ and \, do not exist, it's safe to split
39
- parts = dn2.split(/\s*[,;]\s*/)
40
-
41
- parts.collect do |part|
42
- res = {}
43
-
44
- # Split each part into attr=val+attr=val
45
- avs = part.split(/\+/)
46
-
47
- avs.each do |av|
48
- # These should all be of form attr=value
49
- unless av =~ /^([^=]+)=(.*)$/
50
- raise LDAP::ResultError::ProtocolError, "Bad DN component: #{av}"
51
- end
52
- attr, val = $1.downcase, $2
53
- # Now we can decode those bits
54
- attr.gsub!(/\\([a-f0-9][a-f0-9])/i) { $1.hex.chr }
55
- val.gsub!(/\\([a-f0-9][a-f0-9])/i) { $1.hex.chr }
56
- res[attr] = val
57
- end
58
- res
59
- end
60
- end
61
-
62
- # Reverse of split_dn. Join [elements...]
63
- # where each element can be {attr=>val,...} or [[attr,val],...]
64
- # or just [attr,val]
65
-
66
- def self.join_dn(elements)
67
- dn = ""
68
- elements.each do |elem|
69
- av = ""
70
- elem = [elem] if elem[0].is_a?(String)
71
- elem.each do |attr,val|
72
- av << "+" unless av == ""
73
-
74
- av << attr << "=" <<
75
- val.sub(/^([# ])/, '\\\\\\1').
76
- sub(/( )$/, '\\\\\\1').
77
- gsub(/([,+"\\<>;])/, '\\\\\\1')
78
- end
79
- dn << "," unless dn == ""
80
- dn << av
81
- end
82
- dn
83
- end
84
-
85
- end # class Operation
86
-
87
- end # class Server
88
- end # module LDAP