net-ldap 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
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
|
-
|