net-ldap 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of net-ldap might be problematic. Click here for more details.
- data/History.txt +7 -6
- data/LICENSE +3 -2
- data/Manifest.txt +13 -5
- data/README.txt +34 -28
- data/Rakefile +115 -11
- data/lib/net-ldap.rb +1 -0
- data/lib/net/ber.rb +52 -514
- data/lib/net/ber/ber_parser.rb +112 -0
- data/lib/net/ldap.rb +486 -540
- data/lib/net/ldap/core_ext/all.rb +43 -0
- data/lib/net/ldap/core_ext/array.rb +42 -0
- data/lib/net/ldap/core_ext/bignum.rb +25 -0
- data/lib/net/ldap/core_ext/false_class.rb +11 -0
- data/lib/net/ldap/core_ext/fixnum.rb +64 -0
- data/lib/net/ldap/core_ext/string.rb +40 -0
- data/lib/net/ldap/core_ext/true_class.rb +11 -0
- data/lib/net/ldap/dataset.rb +64 -73
- data/lib/net/ldap/entry.rb +0 -9
- data/lib/net/ldap/filter.rb +1 -8
- data/lib/net/ldap/pdu.rb +2 -3
- data/lib/net/ldap/psw.rb +31 -38
- data/lib/net/ldif.rb +2 -7
- data/lib/net/snmp.rb +2 -4
- data/spec/integration/ssl_ber_spec.rb +36 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/unit/ber/ber_spec.rb +18 -0
- data/test/common.rb +0 -4
- data/test/test_ber.rb +73 -95
- data/test/test_filter.rb +1 -1
- data/test/test_ldif.rb +1 -1
- data/test/test_snmp.rb +61 -78
- data/testserver/ldapserver.rb +0 -19
- metadata +118 -24
- data/Release-Announcement +0 -95
- data/pre-setup.rb +0 -45
- data/setup.rb +0 -1366
- data/tests/NOTICE.txt +0 -6
- data/tests/testldap.rb +0 -190
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'net/ldap/core_ext/array'
|
2
|
+
require 'net/ldap/core_ext/string'
|
3
|
+
require 'net/ldap/core_ext/bignum'
|
4
|
+
require 'net/ldap/core_ext/fixnum'
|
5
|
+
require 'net/ldap/core_ext/false_class'
|
6
|
+
require 'net/ldap/core_ext/true_class'
|
7
|
+
|
8
|
+
class Array
|
9
|
+
include Net::LDAP::Extensions::Array
|
10
|
+
end
|
11
|
+
|
12
|
+
class String
|
13
|
+
include Net::BER::BERParser
|
14
|
+
include Net::LDAP::Extensions::String
|
15
|
+
end
|
16
|
+
|
17
|
+
class Bignum
|
18
|
+
include Net::LDAP::Extensions::Bignum
|
19
|
+
end
|
20
|
+
|
21
|
+
class Fixnum
|
22
|
+
include Net::LDAP::Extensions::Fixnum
|
23
|
+
end
|
24
|
+
|
25
|
+
class FalseClass
|
26
|
+
include Net::LDAP::Extensions::FalseClass
|
27
|
+
end
|
28
|
+
|
29
|
+
class TrueClass
|
30
|
+
include Net::LDAP::Extensions::TrueClass
|
31
|
+
end
|
32
|
+
|
33
|
+
class IO
|
34
|
+
include Net::BER::BERParser
|
35
|
+
end
|
36
|
+
|
37
|
+
class StringIO
|
38
|
+
include Net::BER::BERParser
|
39
|
+
end
|
40
|
+
|
41
|
+
class OpenSSL::SSL::SSLSocket
|
42
|
+
include Net::BER::BERParser
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Net
|
2
|
+
class LDAP
|
3
|
+
module Extensions
|
4
|
+
module Array
|
5
|
+
#
|
6
|
+
# to_ber_appsequence
|
7
|
+
# An application-specific sequence usually gets assigned
|
8
|
+
# a tag that is meaningful to the particular protocol being used.
|
9
|
+
# This is different from the universal sequence, which usually
|
10
|
+
# gets a tag value of 16.
|
11
|
+
# Now here's an interesting thing: We're adding the X.690
|
12
|
+
# "application constructed" code at the top of the tag byte (0x60),
|
13
|
+
# but some clients, notably ldapsearch, send "context-specific
|
14
|
+
# constructed" (0xA0). The latter would appear to violate RFC-1777,
|
15
|
+
# but what do I know? We may need to change this.
|
16
|
+
#
|
17
|
+
|
18
|
+
def to_ber id = 0; to_ber_seq_internal( 0x30 + id ); end
|
19
|
+
def to_ber_set id = 0; to_ber_seq_internal( 0x31 + id ); end
|
20
|
+
def to_ber_sequence id = 0; to_ber_seq_internal( 0x30 + id ); end
|
21
|
+
def to_ber_appsequence id = 0; to_ber_seq_internal( 0x60 + id ); end
|
22
|
+
def to_ber_contextspecific id = 0; to_ber_seq_internal( 0xA0 + id ); end
|
23
|
+
|
24
|
+
def to_ber_oid
|
25
|
+
ary = self.dup
|
26
|
+
first = ary.shift
|
27
|
+
raise Net::BER::BerError.new( "invalid OID" ) unless [0,1,2].include?(first)
|
28
|
+
first = first * 40 + ary.shift
|
29
|
+
ary.unshift first
|
30
|
+
oid = ary.pack("w*")
|
31
|
+
[6, oid.length].pack("CC") + oid
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def to_ber_seq_internal code
|
36
|
+
s = self.join
|
37
|
+
[code].pack('C') + s.length.to_ber_length_encoding + s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end # class Array
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Net
|
2
|
+
class LDAP
|
3
|
+
module Extensions
|
4
|
+
module Bignum
|
5
|
+
|
6
|
+
def to_ber
|
7
|
+
# NOTE: Array#pack's 'w' is a BER _compressed_ integer. We need uncompressed
|
8
|
+
# BER integers, so we're not using that.
|
9
|
+
# See also: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/228864
|
10
|
+
result = []
|
11
|
+
|
12
|
+
n = self
|
13
|
+
while n>0
|
14
|
+
b = n & 0xff
|
15
|
+
result << b
|
16
|
+
n = n >> 8
|
17
|
+
end
|
18
|
+
|
19
|
+
"\002" + ([result.size] + result.reverse).pack('C*')
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Net
|
2
|
+
class LDAP
|
3
|
+
module Extensions
|
4
|
+
module Fixnum
|
5
|
+
#
|
6
|
+
# to_ber
|
7
|
+
#
|
8
|
+
def to_ber
|
9
|
+
"\002" + to_ber_internal
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# to_ber_enumerated
|
14
|
+
#
|
15
|
+
def to_ber_enumerated
|
16
|
+
"\012" + to_ber_internal
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# to_ber_length_encoding
|
21
|
+
#
|
22
|
+
def to_ber_length_encoding
|
23
|
+
if self <= 127
|
24
|
+
[self].pack('C')
|
25
|
+
else
|
26
|
+
i = [self].pack('N').sub(/^[\0]+/,"")
|
27
|
+
[0x80 + i.length].pack('C') + i
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Generate a BER-encoding for an application-defined INTEGER.
|
32
|
+
# Example: SNMP's Counter, Gauge, and TimeTick types.
|
33
|
+
#
|
34
|
+
def to_ber_application tag
|
35
|
+
[0x40 + tag].pack("C") + to_ber_internal
|
36
|
+
end
|
37
|
+
|
38
|
+
#--
|
39
|
+
# Called internally to BER-encode the length and content bytes of a Fixnum.
|
40
|
+
# The caller will prepend the tag byte.
|
41
|
+
MAX_SIZE = 0.size
|
42
|
+
def to_ber_internal
|
43
|
+
size = MAX_SIZE
|
44
|
+
while size>1
|
45
|
+
break if (self & (0xff << (size-1)*8)) > 0
|
46
|
+
size -= 1
|
47
|
+
end
|
48
|
+
|
49
|
+
result = [size]
|
50
|
+
|
51
|
+
while size>0
|
52
|
+
# right shift size-1 bytes, mask with 0xff
|
53
|
+
result << ((self >> ((size-1)*8)) & 0xff)
|
54
|
+
|
55
|
+
size -= 1
|
56
|
+
end
|
57
|
+
|
58
|
+
result.pack('C*')
|
59
|
+
end
|
60
|
+
private :to_ber_internal
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class LDAP
|
5
|
+
module Extensions
|
6
|
+
module String
|
7
|
+
#
|
8
|
+
# to_ber
|
9
|
+
# A universal octet-string is tag number 4,
|
10
|
+
# but others are possible depending on the context, so we
|
11
|
+
# let the caller give us one.
|
12
|
+
# The preferred way to do this in user code is via to_ber_application_sring
|
13
|
+
# and to_ber_contextspecific.
|
14
|
+
#
|
15
|
+
def to_ber code = 4
|
16
|
+
[code].pack('C') + length.to_ber_length_encoding + self
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# to_ber_application_string
|
21
|
+
#
|
22
|
+
def to_ber_application_string code
|
23
|
+
to_ber( 0x40 + code )
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# to_ber_contextspecific
|
28
|
+
#
|
29
|
+
def to_ber_contextspecific code
|
30
|
+
to_ber( 0x80 + code )
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_ber syntax=nil
|
34
|
+
StringIO.new(self).
|
35
|
+
read_ber(syntax)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/net/ldap/dataset.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
# $Id$
|
2
|
-
#
|
3
|
-
#
|
4
1
|
#----------------------------------------------------------------------------
|
5
2
|
#
|
6
3
|
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
@@ -22,87 +19,81 @@
|
|
22
19
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
23
20
|
#
|
24
21
|
#---------------------------------------------------------------------------
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
22
|
|
31
23
|
module Net
|
32
|
-
class LDAP
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
attr_reader :comments
|
37
|
-
|
38
|
-
|
39
|
-
def Dataset::read_ldif io
|
40
|
-
ds = Dataset.new
|
41
|
-
|
42
|
-
line = io.gets && chomp
|
43
|
-
dn = nil
|
44
|
-
|
45
|
-
while line
|
46
|
-
io.gets and chomp
|
47
|
-
if $_ =~ /^[\s]+/
|
48
|
-
line << " " << $'
|
49
|
-
else
|
50
|
-
nextline = $_
|
24
|
+
class LDAP
|
25
|
+
class Dataset < Hash
|
26
|
+
attr_reader :comments
|
51
27
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
elsif line =~ /^([^:]+):([\:]?)[\s]*/
|
60
|
-
# $1 is the attribute name
|
61
|
-
# $2 is a colon iff the attr-value is base-64 encoded
|
62
|
-
# $' is the attr-value
|
63
|
-
# Avoid the Base64 class because not all Ruby versions have it.
|
64
|
-
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
|
65
|
-
ds[dn][$1.downcase.intern] << attrvalue
|
28
|
+
class IOFilter
|
29
|
+
def initialize(io)
|
30
|
+
@io = io
|
31
|
+
end
|
32
|
+
def gets
|
33
|
+
s = @io.gets
|
34
|
+
s.chomp if s
|
66
35
|
end
|
67
|
-
|
68
|
-
line = nextline
|
69
36
|
end
|
70
|
-
end
|
71
|
-
|
72
|
-
ds
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
def initialize
|
77
|
-
@comments = []
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
def to_ldif
|
82
|
-
ary = []
|
83
|
-
ary += (@comments || [])
|
84
37
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
38
|
+
def self.read_ldif io
|
39
|
+
ds = Dataset.new
|
40
|
+
io = IOFilter.new(io)
|
41
|
+
|
42
|
+
line = io.gets
|
43
|
+
dn = nil
|
44
|
+
|
45
|
+
while line
|
46
|
+
new_line = io.gets
|
47
|
+
if new_line =~ /^[\s]+/
|
48
|
+
line << " " << $'
|
49
|
+
else
|
50
|
+
nextline = new_line
|
51
|
+
|
52
|
+
if line =~ /^\#/
|
53
|
+
ds.comments << line
|
54
|
+
elsif line =~ /^dn:[\s]*/i
|
55
|
+
dn = $'
|
56
|
+
ds[dn] = Hash.new {|k,v| k[v] = []}
|
57
|
+
elsif line.length == 0
|
58
|
+
dn = nil
|
59
|
+
elsif line =~ /^([^:]+):([\:]?)[\s]*/
|
60
|
+
# $1 is the attribute name
|
61
|
+
# $2 is a colon iff the attr-value is base-64 encoded
|
62
|
+
# $' is the attr-value
|
63
|
+
# Avoid the Base64 class because not all Ruby versions have it.
|
64
|
+
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
|
65
|
+
ds[dn][$1.downcase.intern] << attrvalue
|
66
|
+
end
|
67
|
+
|
68
|
+
line = nextline
|
69
|
+
end
|
70
|
+
end
|
93
71
|
|
94
|
-
|
95
|
-
|
72
|
+
ds
|
73
|
+
end
|
96
74
|
|
97
|
-
block_given? and ary.each {|line| yield line}
|
98
75
|
|
99
|
-
|
100
|
-
|
76
|
+
def initialize
|
77
|
+
@comments = []
|
78
|
+
end
|
101
79
|
|
102
80
|
|
103
|
-
|
81
|
+
def to_ldif
|
82
|
+
ary = []
|
83
|
+
ary += (@comments || [])
|
84
|
+
keys.sort.each do |dn|
|
85
|
+
ary << "dn: #{dn}"
|
104
86
|
|
105
|
-
|
106
|
-
|
87
|
+
self[dn].keys.map {|sym| sym.to_s}.sort.each do |attr|
|
88
|
+
self[dn][attr.intern].each {|val| ary << "#{attr}: #{val}" }
|
89
|
+
end
|
107
90
|
|
91
|
+
ary << ""
|
92
|
+
end
|
93
|
+
block_given? and ary.each {|line| yield line}
|
94
|
+
ary
|
95
|
+
end
|
108
96
|
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/net/ldap/entry.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
# $Id$
|
2
|
-
#
|
3
1
|
# LDAP Entry (search-result) support classes
|
4
2
|
#
|
5
|
-
#
|
6
3
|
#----------------------------------------------------------------------------
|
7
4
|
#
|
8
5
|
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
@@ -26,10 +23,6 @@
|
|
26
23
|
#---------------------------------------------------------------------------
|
27
24
|
#
|
28
25
|
|
29
|
-
|
30
|
-
require 'base64'
|
31
|
-
|
32
|
-
|
33
26
|
module Net
|
34
27
|
class LDAP
|
35
28
|
|
@@ -265,5 +258,3 @@ class LDAP
|
|
265
258
|
|
266
259
|
end # class LDAP
|
267
260
|
end # module Net
|
268
|
-
|
269
|
-
|
data/lib/net/ldap/filter.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
# $Id$
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#----------------------------------------------------------------------------
|
5
|
-
#
|
6
1
|
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
7
2
|
#
|
8
3
|
# Gmail: garbagecat10
|
@@ -25,6 +20,7 @@
|
|
25
20
|
#
|
26
21
|
#
|
27
22
|
|
23
|
+
require 'strscan'
|
28
24
|
|
29
25
|
module Net
|
30
26
|
class LDAP
|
@@ -408,7 +404,6 @@ class FilterParser #:nodoc:
|
|
408
404
|
attr_reader :filter
|
409
405
|
|
410
406
|
def initialize str
|
411
|
-
require 'strscan'
|
412
407
|
@filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" )
|
413
408
|
end
|
414
409
|
|
@@ -495,5 +490,3 @@ end # class Net::LDAP::FilterParser
|
|
495
490
|
|
496
491
|
end # class Net::LDAP
|
497
492
|
end # module Net
|
498
|
-
|
499
|
-
|