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
data/lib/net/ldap/pdu.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# $Id$
|
2
1
|
#
|
3
2
|
# LDAP PDU support classes
|
4
3
|
#
|
@@ -24,12 +23,12 @@
|
|
24
23
|
#
|
25
24
|
#---------------------------------------------------------------------------
|
26
25
|
|
27
|
-
|
26
|
+
require 'ostruct'
|
28
27
|
|
28
|
+
module Net
|
29
29
|
class LdapPduError < StandardError; end
|
30
30
|
|
31
31
|
class LdapPdu
|
32
|
-
|
33
32
|
BindRequest = 0
|
34
33
|
BindResult = 1
|
35
34
|
UnbindRequest = 2
|
data/lib/net/ldap/psw.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,43 +19,39 @@
|
|
22
19
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
23
20
|
#
|
24
21
|
#---------------------------------------------------------------------------
|
25
|
-
#
|
26
|
-
#
|
27
22
|
|
23
|
+
require 'digest/sha1'
|
24
|
+
require 'digest/md5'
|
28
25
|
|
29
26
|
module Net
|
30
|
-
class LDAP
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
27
|
+
class LDAP
|
28
|
+
class Password
|
29
|
+
class << self
|
30
|
+
# Generate a password-hash suitable for inclusion in an LDAP
|
31
|
+
# attribute. Pass a hash type (currently supported: :md5 and :sha)
|
32
|
+
# and a plaintext password. This function will return a hashed
|
33
|
+
# representation.
|
34
|
+
#
|
35
|
+
# STUB: This is here to fulfill the requirements of an RFC, which
|
36
|
+
# one?
|
37
|
+
#
|
38
|
+
# TODO, gotta do salted-sha and (maybe) salted-md5.
|
39
|
+
# Should we provide sha1 as a synonym for sha1? I vote no because
|
40
|
+
# then should you also provide ssha1 for symmetry?
|
41
|
+
def generate(type, str)
|
42
|
+
digest, digest_name = case type
|
43
|
+
when :md5
|
44
|
+
[Digest::MD5.new, 'MD5']
|
45
|
+
when :sha
|
46
|
+
[Digest::SHA1.new, 'SHA']
|
47
|
+
else
|
48
|
+
raise Net::LDAP::LdapError.new("unsupported password-hash type (#{type})")
|
49
|
+
end
|
50
|
+
|
51
|
+
digest << str.to_s
|
52
|
+
return "{#{digest_name}}#{[digest.digest].pack('m').chomp }"
|
53
|
+
end
|
54
|
+
end
|
54
55
|
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
56
|
+
end
|
58
57
|
end
|
59
|
-
|
60
|
-
|
61
|
-
end # class LDAP
|
62
|
-
end # module Net
|
63
|
-
|
64
|
-
|
data/lib/net/ldif.rb
CHANGED
data/lib/net/snmp.rb
CHANGED
@@ -26,14 +26,12 @@
|
|
26
26
|
#
|
27
27
|
#
|
28
28
|
|
29
|
-
require 'net/ber'
|
30
|
-
|
31
|
-
|
32
29
|
module Net
|
33
30
|
|
34
31
|
class SNMP
|
32
|
+
VERSION = '0.1.0'
|
35
33
|
|
36
|
-
AsnSyntax = BER.compile_syntax({
|
34
|
+
AsnSyntax = Net::BER.compile_syntax({
|
37
35
|
:application => {
|
38
36
|
:primitive => {
|
39
37
|
1 => :integer, # Counter32, (RFC2578 sec 2)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'openssl'
|
5
|
+
|
6
|
+
require 'net/ldap'
|
7
|
+
|
8
|
+
describe "BER serialisation (SSL)" do
|
9
|
+
# Transmits str to #to and reads it back from #from.
|
10
|
+
#
|
11
|
+
def transmit(str)
|
12
|
+
to.write(str)
|
13
|
+
to.close
|
14
|
+
|
15
|
+
from.read
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :to, :from
|
19
|
+
before(:each) do
|
20
|
+
@from, @to = IO.pipe
|
21
|
+
|
22
|
+
flexmock(OpenSSL::SSL::SSLSocket).
|
23
|
+
new_instances.should_receive(:connect => nil)
|
24
|
+
|
25
|
+
@to = Net::LDAP::Connection.wrap_with_ssl(to)
|
26
|
+
@from = Net::LDAP::Connection.wrap_with_ssl(from)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should transmit strings" do
|
30
|
+
transmit('foo').should == 'foo'
|
31
|
+
end
|
32
|
+
it "should correctly transmit numbers" do
|
33
|
+
to.write 1234.to_ber
|
34
|
+
from.read_ber.should == 1234
|
35
|
+
end
|
36
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'net/ber'
|
4
|
+
require 'net/ldap'
|
5
|
+
|
6
|
+
describe "Ber encoding of various types" do
|
7
|
+
def properly_encode_and_decode
|
8
|
+
simple_matcher('properly encode and decode') do |given|
|
9
|
+
given.to_ber.read_ber.should == given
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "array" do
|
14
|
+
it "should properly encode []" do
|
15
|
+
[].should properly_encode_and_decode
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/test/common.rb
CHANGED
data/test/test_ber.rb
CHANGED
@@ -1,100 +1,78 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# encoding: ASCII-8BIT
|
3
2
|
require 'common'
|
4
3
|
|
5
4
|
class TestBer < Test::Unit::TestCase
|
6
5
|
|
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
|
-
assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax ))
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_ber_parser_on_ldap_bind_request
|
83
|
-
require 'stringio'
|
84
|
-
|
85
|
-
s = StringIO.new(
|
86
|
-
"0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus" )
|
87
|
-
|
88
|
-
assert_equal(
|
89
|
-
[1, [3, "Administrator", "ad_is_bogus"]],
|
90
|
-
s.read_ber( Net::LDAP::AsnSyntax ))
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_oid
|
94
|
-
oid = Net::BER::BerIdentifiedOid.new( [1,3,6,1,2,1,1,1,0] )
|
95
|
-
assert_equal( "\006\b+\006\001\002\001\001\001\000", oid.to_ber )
|
96
|
-
|
97
|
-
oid = Net::BER::BerIdentifiedOid.new( "1.3.6.1.2.1.1.1.0" )
|
98
|
-
assert_equal( "\006\b+\006\001\002\001\001\001\000", oid.to_ber )
|
99
|
-
end
|
6
|
+
def test_encode_boolean
|
7
|
+
assert_equal( "\x01\x01\x01", true.to_ber ) # should actually be: 01 01 ff
|
8
|
+
assert_equal( "\x01\x01\x00", false.to_ber )
|
9
|
+
end
|
10
|
+
|
11
|
+
#def test_encode_nil
|
12
|
+
# assert_equal( "\x05\x00", nil.to_ber )
|
13
|
+
#end
|
14
|
+
|
15
|
+
def test_encode_integer
|
16
|
+
|
17
|
+
# Fixnum
|
18
|
+
#
|
19
|
+
#assert_equal( "\x02\x02\x96\x46", -27_066.to_ber )
|
20
|
+
#assert_equal( "\x02\x02\xFF\x7F", -129.to_ber )
|
21
|
+
#assert_equal( "\x02\x01\x80", -128.to_ber )
|
22
|
+
#assert_equal( "\x02\x01\xFF", -1.to_ber )
|
23
|
+
|
24
|
+
assert_equal( "\x02\x01\x00", 0.to_ber )
|
25
|
+
assert_equal( "\x02\x01\x01", 1.to_ber )
|
26
|
+
assert_equal( "\x02\x01\x7F", 127.to_ber )
|
27
|
+
assert_equal( "\x02\x01\x80", 128.to_ber )
|
28
|
+
assert_equal( "\x02\x01\xFF", 255.to_ber )
|
29
|
+
|
30
|
+
assert_equal( "\x02\x02\x01\x00", 256.to_ber )
|
31
|
+
assert_equal( "\x02\x02\xFF\xFF", 65535.to_ber )
|
32
|
+
|
33
|
+
assert_equal( "\x02\x03\x01\x00\x00", 65536.to_ber )
|
34
|
+
assert_equal( "\x02\x03\xFF\xFF\xFF", 16_777_215.to_ber )
|
35
|
+
|
36
|
+
assert_equal( "\x02\x04\x01\x00\x00\x00", 0x01000000.to_ber )
|
37
|
+
assert_equal( "\x02\x04\x3F\xFF\xFF\xFF", 0x3FFFFFFF.to_ber )
|
38
|
+
|
39
|
+
# Bignum
|
40
|
+
#
|
41
|
+
assert_equal( "\x02\x04\x4F\xFF\xFF\xFF", 0x4FFFFFFF.to_ber )
|
42
|
+
#assert_equal( "\x02\x05\x00\xFF\xFF\xFF\xFF", 0xFFFFFFFF.to_ber )
|
43
|
+
end
|
44
|
+
|
45
|
+
# TOD Add some much bigger numbers
|
46
|
+
# 5000000000 is a Bignum, which hits different code.
|
47
|
+
def test_ber_integers
|
48
|
+
assert_equal( "\002\001\005", 5.to_ber )
|
49
|
+
assert_equal( "\002\002\001\364", 500.to_ber )
|
50
|
+
assert_equal( "\x02\x02\xC3P", 50000.to_ber )
|
51
|
+
assert_equal( "\002\005\001*\005\362\000", 5000000000.to_ber )
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_ber_bignums
|
55
|
+
# Some of these values are Fixnums and some are Bignums. Different BER code.
|
56
|
+
100.times do |p|
|
57
|
+
n = 2 << p
|
58
|
+
assert_equal(n, n.to_ber.read_ber, "2**#{p} could not be read back")
|
59
|
+
|
60
|
+
n = 5 * 10**p
|
61
|
+
assert_equal(n, n.to_ber.read_ber)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_ber_parsing
|
66
|
+
assert_equal( 6, "\002\001\006".read_ber( Net::LDAP::AsnSyntax ))
|
67
|
+
assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax ))
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_ber_parser_on_ldap_bind_request
|
71
|
+
s = StringIO.new(
|
72
|
+
"0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus" )
|
73
|
+
|
74
|
+
assert_equal(
|
75
|
+
[1, [3, "Administrator", "ad_is_bogus"]],
|
76
|
+
s.read_ber( Net::LDAP::AsnSyntax ))
|
77
|
+
end
|
100
78
|
end
|
data/test/test_filter.rb
CHANGED
@@ -74,7 +74,7 @@ class TestFilter < Test::Unit::TestCase
|
|
74
74
|
Net::LDAP::Filter.construct("objectclass=aaa*bbb*"),
|
75
75
|
Net::LDAP::Filter.construct("objectclass=aaa*bbb*ccc*"),
|
76
76
|
].each {|ber|
|
77
|
-
|
77
|
+
f = Net::LDAP::Filter.parse_ber( ber.to_ber.read_ber( Net::LDAP::AsnSyntax) )
|
78
78
|
assert( f == ber )
|
79
79
|
assert_equal( f.to_ber, ber.to_ber )
|
80
80
|
}
|
data/test/test_ldif.rb
CHANGED
@@ -11,7 +11,7 @@ class TestLdif < Test::Unit::TestCase
|
|
11
11
|
TestLdifFilename = "#{File.dirname(__FILE__)}/testdata.ldif"
|
12
12
|
|
13
13
|
def test_empty_ldif
|
14
|
-
ds = Net::LDAP::Dataset
|
14
|
+
ds = Net::LDAP::Dataset.read_ldif( StringIO.new )
|
15
15
|
assert_equal( true, ds.empty? )
|
16
16
|
end
|
17
17
|
|
data/test/test_snmp.rb
CHANGED
@@ -18,111 +18,94 @@ class TestSnmp < Test::Unit::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_invalid_packet
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
data = "xxxx"
|
22
|
+
assert_raise( Net::BER::BerError ) {
|
23
|
+
ary = data.read_ber(Net::SNMP::AsnSyntax)
|
24
|
+
}
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
-
# The method String#read_ber! added by Net::BER consumes a well-formed BER object
|
29
|
-
# from the head of a string. If it doesn't find a complete, well-formed BER object,
|
30
|
-
# it returns nil and leaves the string unchanged. If it finds an object, it returns
|
31
|
-
# the object and removes it from the head of the string. This is good for handling
|
32
|
-
# partially-received data streams, such as from network connections.
|
33
|
-
def test_consume_string
|
34
|
-
data = "xxx"
|
35
|
-
assert_equal( nil, data.read_ber! )
|
36
|
-
assert_equal( "xxx", data )
|
37
|
-
|
38
|
-
data = SnmpGetRequest + "!!!"
|
39
|
-
ary = data.read_ber!( Net::SNMP::AsnSyntax )
|
40
|
-
assert_equal( "!!!", data )
|
41
|
-
assert ary.is_a?(Array)
|
42
|
-
assert ary.is_a?(Net::BER::BerIdentifiedArray)
|
43
|
-
end
|
44
|
-
|
45
28
|
def test_weird_packet
|
46
|
-
|
47
|
-
|
48
|
-
|
29
|
+
assert_raise( Net::SnmpPdu::Error ) {
|
30
|
+
Net::SnmpPdu.parse("aaaaaaaaaaaaaa")
|
31
|
+
}
|
49
32
|
end
|
50
33
|
|
51
34
|
def test_get_request
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
35
|
+
data = SnmpGetRequest.dup
|
36
|
+
pkt = data.read_ber(Net::SNMP::AsnSyntax)
|
37
|
+
assert pkt.is_a?(Net::BER::BerIdentifiedArray)
|
38
|
+
assert_equal( 48, pkt.ber_identifier) # Constructed [0], signifies GetRequest
|
56
39
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
40
|
+
pdu = Net::SnmpPdu.parse(pkt)
|
41
|
+
assert_equal(:get_request, pdu.pdu_type )
|
42
|
+
assert_equal(16170, pdu.request_id ) # whatever was in the test data. 16170 is not magic.
|
43
|
+
assert_equal( [[[1,3,6,1,2,1,1,1,0],nil]], pdu.variables )
|
61
44
|
|
62
|
-
|
45
|
+
assert_equal( pdu.to_ber_string, SnmpGetRequest )
|
63
46
|
end
|
64
47
|
|
65
48
|
def test_empty_pdu
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
49
|
+
pdu = Net::SnmpPdu.new
|
50
|
+
assert_raise( Net::SnmpPdu::Error ) {
|
51
|
+
pdu.to_ber_string
|
52
|
+
}
|
70
53
|
end
|
71
54
|
|
72
55
|
def test_malformations
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
56
|
+
pdu = Net::SnmpPdu.new
|
57
|
+
pdu.version = 0
|
58
|
+
pdu.version = 2
|
59
|
+
assert_raise( Net::SnmpPdu::Error ) {
|
60
|
+
pdu.version = 100
|
61
|
+
}
|
62
|
+
|
63
|
+
pdu.pdu_type = :get_request
|
64
|
+
pdu.pdu_type = :get_next_request
|
65
|
+
pdu.pdu_type = :get_response
|
66
|
+
pdu.pdu_type = :set_request
|
67
|
+
pdu.pdu_type = :trap
|
68
|
+
assert_raise( Net::SnmpPdu::Error ) {
|
69
|
+
pdu.pdu_type = :something_else
|
70
|
+
}
|
88
71
|
end
|
89
72
|
|
90
73
|
def test_make_response
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
74
|
+
pdu = Net::SnmpPdu.new
|
75
|
+
pdu.version = 0
|
76
|
+
pdu.community = "public"
|
77
|
+
pdu.pdu_type = :get_response
|
78
|
+
pdu.request_id = 9999
|
79
|
+
pdu.error_status = 0
|
80
|
+
pdu.error_index = 0
|
81
|
+
pdu.add_variable_binding [1,3,6,1,2,1,1,1,0], "test"
|
82
|
+
|
83
|
+
assert_equal( SnmpGetResponse, pdu.to_ber_string )
|
101
84
|
end
|
102
85
|
|
103
86
|
def test_make_bad_response
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
87
|
+
pdu = Net::SnmpPdu.new
|
88
|
+
assert_raise(Net::SnmpPdu::Error) {pdu.to_ber_string}
|
89
|
+
pdu.pdu_type = :get_response
|
90
|
+
pdu.request_id = 999
|
91
|
+
pdu.to_ber_string
|
92
|
+
# Not specifying variables doesn't create an error. (Maybe it should?)
|
110
93
|
end
|
111
94
|
|
112
95
|
def test_snmp_integers
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
96
|
+
c32 = Net::SNMP::Counter32.new(100)
|
97
|
+
assert_equal( "A\001d", c32.to_ber )
|
98
|
+
g32 = Net::SNMP::Gauge32.new(100)
|
99
|
+
assert_equal( "B\001d", g32.to_ber )
|
100
|
+
t32 = Net::SNMP::TimeTicks32.new(100)
|
101
|
+
assert_equal( "C\001d", t32.to_ber )
|
119
102
|
end
|
120
103
|
|
121
104
|
def test_community
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
105
|
+
data = SnmpGetRequestXXX.dup
|
106
|
+
ary = data.read_ber(Net::SNMP::AsnSyntax)
|
107
|
+
pdu = Net::SnmpPdu.parse( ary )
|
108
|
+
assert_equal( "xxxxxx", pdu.community )
|
126
109
|
end
|
127
110
|
|
128
111
|
end
|