scashin133-net-ldap 0.1.2

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.
data/Rakefile ADDED
@@ -0,0 +1,124 @@
1
+ require "rubygems"
2
+ require 'hanna/rdoctask'
3
+ require 'hoe'
4
+
5
+ $LOAD_PATH.unshift('lib')
6
+
7
+ require 'net/ldap'
8
+
9
+ PKG_NAME = 'scashin133-net-ldap'
10
+ PKG_VERSION = Net::LDAP::VERSION
11
+ PKG_DIST = "#{PKG_NAME}-#{PKG_VERSION}"
12
+ PKG_TAR = "pkg/#{PKG_DIST}.tar.gz"
13
+ MANIFEST = File.read("Manifest.txt").split
14
+ MINRUBY = "1.8.7"
15
+
16
+ Hoe.plugin :git
17
+ Hoe.spec PKG_NAME do
18
+ self.version = PKG_VERSION
19
+ self.rubyforge_name = PKG_NAME
20
+
21
+ developer "Francis Cianfrocca", "blackhedd@rubyforge.org"
22
+ developer "Emiel van de Laar", "gemiel@gmail.com"
23
+ developer "Rory O'Connell", "rory.ocon@gmail.com"
24
+ developer "Kaspar Schiess", "kaspar.schiess@absurd.li"
25
+ developer "Austin Ziegler", "austin@rubyforge.org"
26
+
27
+ self.remote_rdoc_dir = ''
28
+ rsync_args << ' --exclude=statsvn/'
29
+
30
+ self.url = %W(http://net-ldap.rubyforge.org/ http://github.com/RoryO/ruby-net-ldap)
31
+
32
+ self.summary = "Pure Ruby LDAP support library with most client features and some server features."
33
+ self.changes = paragraphs_of(self.history_file, 0..1).join("\n\n")
34
+ self.description = paragraphs_of(self.readme_file, 2..2).join("\n\n")
35
+
36
+ extra_rdoc_files << "Hacking.rdoc"
37
+
38
+ extra_dev_deps << [ "archive-tar-minitar", "~>0.5.1" ]
39
+ extra_dev_deps << [ "hanna", "~>0.1.2" ]
40
+ extra_dev_deps << [ "hoe-git", "~>1" ]
41
+ extra_dev_deps << [ "metaid", "~>1" ]
42
+ clean_globs << "coverage"
43
+
44
+ spec_extras[:required_ruby_version] = ">= #{MINRUBY}"
45
+ multiruby_skip << "1.8.6"
46
+ multiruby_skip << "1_8_6"
47
+
48
+ # This is a lie because I will continue to use Archive::Tar::Minitar.
49
+ self.need_tar = false
50
+ end
51
+
52
+ desc "Build a Net-LDAP .tar.gz distribution."
53
+ task :tar => [ PKG_TAR ]
54
+ file PKG_TAR => [ :test ] do |t|
55
+ require 'archive/tar/minitar'
56
+ require 'zlib'
57
+ files = MANIFEST.map { |f|
58
+ fn = File.join(PKG_DIST, f)
59
+ tm = File.stat(f).mtime
60
+
61
+ if File.directory?(f)
62
+ { :name => fn, :mode => 0755, :dir => true, :mtime => tm }
63
+ else
64
+ mode = if f =~ %r{^bin}
65
+ 0755
66
+ else
67
+ 0644
68
+ end
69
+ data = File.read(f)
70
+ { :name => fn, :mode => mode, :data => data, :size => data.size,
71
+ :mtime => tm }
72
+ end
73
+ }
74
+
75
+ begin
76
+ unless File.directory?(File.dirname(t.name))
77
+ require 'fileutils'
78
+ File.mkdir_p File.dirname(t.name)
79
+ end
80
+ tf = File.open(t.name, 'wb')
81
+ gz = Zlib::GzipWriter.new(tf)
82
+ tw = Archive::Tar::Minitar::Writer.new(gz)
83
+
84
+ files.each do |entry|
85
+ if entry[:dir]
86
+ tw.mkdir(entry[:name], entry)
87
+ else
88
+ tw.add_file_simple(entry[:name], entry) { |os|
89
+ os.write(entry[:data])
90
+ }
91
+ end
92
+ end
93
+ ensure
94
+ tw.close if tw
95
+ gz.close if gz
96
+ end
97
+ end
98
+ task :package => [ PKG_TAR ]
99
+
100
+ desc "Build the manifest file from the current set of files."
101
+ task :build_manifest do |t|
102
+ require 'find'
103
+
104
+ paths = []
105
+ Find.find(".") do |path|
106
+ next if File.directory?(path)
107
+ next if path =~ /\.svn/
108
+ next if path =~ /\.git/
109
+ next if path =~ /\.hoerc/
110
+ next if path =~ /\.swp$/
111
+ next if path =~ %r{coverage/}
112
+ next if path =~ /~$/
113
+ paths << path.sub(%r{^\./}, '')
114
+ end
115
+
116
+ File.open("Manifest.txt", "w") do |f|
117
+ f.puts paths.sort.join("\n")
118
+ end
119
+
120
+ puts paths.sort.join("\n")
121
+ end
122
+
123
+ desc "Run a full set of integration and unit tests"
124
+ task :cruise => [:test, :spec]
@@ -0,0 +1,168 @@
1
+ require 'stringio'
2
+
3
+ ##
4
+ # Implements Basic Encoding Rules parsing to be mixed into types as needed.
5
+ module Net::BER::BERParser
6
+ primitive = {
7
+ 1 => :boolean,
8
+ 2 => :integer,
9
+ 4 => :string,
10
+ 5 => :null,
11
+ 6 => :oid,
12
+ 10 => :integer,
13
+ 13 => :string # (relative OID)
14
+ }
15
+ constructed = {
16
+ 16 => :array,
17
+ 17 => :array
18
+ }
19
+ universal = { :primitive => primitive, :constructed => constructed }
20
+
21
+ primitive = { 10 => :integer }
22
+ context = { :primitive => primitive }
23
+
24
+ # The universal, built-in ASN.1 BER syntax.
25
+ BuiltinSyntax = Net::BER.compile_syntax(:universal => universal,
26
+ :context_specific => context)
27
+
28
+ ##
29
+ # This is an extract of our BER object parsing to simplify our
30
+ # understanding of how we parse basic BER object types.
31
+ def parse_ber_object(syntax, id, data)
32
+ # Find the object type from either the provided syntax lookup table or
33
+ # the built-in syntax lookup table.
34
+ #
35
+ # This exceptionally clever bit of code is verrrry slow.
36
+ object_type = (syntax && syntax[id]) || BuiltinSyntax[id]
37
+
38
+ # == is expensive so sort this so the common cases are at the top.
39
+ if object_type == :string
40
+ s = Net::BER::BerIdentifiedString.new(data || "")
41
+ s.ber_identifier = id
42
+ s
43
+ elsif object_type == :integer
44
+ j = 0
45
+ data.each_byte { |b| j = (j << 8) + b }
46
+ j
47
+ elsif object_type == :oid
48
+ # See X.690 pgh 8.19 for an explanation of this algorithm.
49
+ # This is potentially not good enough. We may need a
50
+ # BerIdentifiedOid as a subclass of BerIdentifiedArray, to
51
+ # get the ber identifier and also a to_s method that produces
52
+ # the familiar dotted notation.
53
+ oid = data.unpack("w*")
54
+ f = oid.shift
55
+ g = if f < 40
56
+ [0, f]
57
+ elsif f < 80
58
+ [1, f - 40]
59
+ else
60
+ # f - 80 can easily be > 80. What a weird optimization.
61
+ [2, f - 80]
62
+ end
63
+ oid.unshift g.last
64
+ oid.unshift g.first
65
+ # Net::BER::BerIdentifiedOid.new(oid)
66
+ oid
67
+ elsif object_type == :array
68
+ seq = Net::BER::BerIdentifiedArray.new
69
+ seq.ber_identifier = id
70
+ sio = StringIO.new(data || "")
71
+ # Interpret the subobject, but note how the loop is built:
72
+ # nil ends the loop, but false (a valid BER value) does not!
73
+ while (e = sio.read_ber(syntax)) != nil
74
+ seq << e
75
+ end
76
+ seq
77
+ elsif object_type == :boolean
78
+ data != "\000"
79
+ elsif object_type == :null
80
+ n = Net::BER::BerIdentifiedNull.new
81
+ n.ber_identifier = id
82
+ n
83
+ else
84
+ raise Net::BER::BerError, "Unsupported object type: id=#{id}"
85
+ end
86
+ end
87
+ private :parse_ber_object
88
+
89
+ ##
90
+ # This is an extract of how our BER object length parsing is done to
91
+ # simplify the primary call. This is defined in X.690 section 8.1.3.
92
+ #
93
+ # The BER length will either be a single byte or up to 126 bytes in
94
+ # length. There is a special case of a BER length indicating that the
95
+ # content-length is undefined and will be identified by the presence of
96
+ # two null values (0x00 0x00).
97
+ #
98
+ # <table>
99
+ # <tr>
100
+ # <th>Range</th>
101
+ # <th>Length</th>
102
+ # </tr>
103
+ # <tr>
104
+ # <th>0x00 -- 0x7f<br />0b00000000 -- 0b01111111</th>
105
+ # <td>0 - 127 bytes</td>
106
+ # </tr>
107
+ # <tr>
108
+ # <th>0x80<br />0b10000000</th>
109
+ # <td>Indeterminate (end-of-content marker required)</td>
110
+ # </tr>
111
+ # <tr>
112
+ # <th>0x81 -- 0xfe<br />0b10000001 -- 0b11111110</th>
113
+ # <td>1 - 126 bytes of length as an integer value</td>
114
+ # </tr>
115
+ # <tr>
116
+ # <th>0xff<br />0b11111111</th>
117
+ # <td>Illegal (reserved for future expansion)</td>
118
+ # </tr>
119
+ # </table>
120
+ #
121
+ #--
122
+ # This has been modified from the version that was previously inside
123
+ # #read_ber to handle both the indeterminate terminator case and the
124
+ # invalid BER length case. Because the "lengthlength" value was not used
125
+ # inside of #read_ber, we no longer return it.
126
+ def read_ber_length
127
+ n = getbyte
128
+
129
+ if n <= 0x7f
130
+ n
131
+ elsif n == 0x80
132
+ -1
133
+ elsif n == 0xff
134
+ raise Net::BER::BerError, "Invalid BER length 0xFF detected."
135
+ else
136
+ v = 0
137
+ read(n & 0x7f).each_byte do |b|
138
+ v = (v << 8) + b
139
+ end
140
+
141
+ v
142
+ end
143
+ end
144
+ private :read_ber_length
145
+
146
+ ##
147
+ # Reads a BER object from the including object. Requires that #getbyte is
148
+ # implemented on the including object and that it returns a Fixnum value.
149
+ # Also requires #read(bytes) to work.
150
+ #
151
+ # This does not work with non-blocking I/O.
152
+ def read_ber(syntax = nil)
153
+ # TODO: clean this up so it works properly with partial packets coming
154
+ # from streams that don't block when we ask for more data (like
155
+ # StringIOs). At it is, this can throw TypeErrors and other nasties.
156
+
157
+ id = getbyte or return nil # don't trash this value, we'll use it later
158
+ content_length = read_ber_length
159
+
160
+ if -1 == content_length
161
+ raise Net::BER::BerError, "Indeterminite BER content length not implemented."
162
+ else
163
+ data = read(content_length)
164
+ end
165
+
166
+ parse_ber_object(syntax, id, data)
167
+ end
168
+ end
@@ -0,0 +1,79 @@
1
+ module Net::BER::Extensions::Array
2
+ ##
3
+ # Converts an Array to a BER sequence. All values in the Array are
4
+ # expected to be in BER format prior to calling this method.
5
+ def to_ber(id = 0)
6
+ # The universal sequence tag 0x30 is composed of the base tag value
7
+ # (0x10) and the constructed flag (0x20).
8
+ to_ber_seq_internal(0x30 + id)
9
+ end
10
+ alias_method :to_ber_sequence, :to_ber
11
+
12
+ ##
13
+ # Converts an Array to a BER set. All values in the Array are expected to
14
+ # be in BER format prior to calling this method.
15
+ def to_ber_set(id = 0)
16
+ # The universal set tag 0x31 is composed of the base tag value (0x11)
17
+ # and the constructed flag (0x20).
18
+ to_ber_seq_internal(0x31 + id)
19
+ end
20
+
21
+ ##
22
+ # Converts an Array to an application-specific sequence, assigned a tag
23
+ # value that is meaningful to the particular protocol being used. All
24
+ # values in the Array are expected to be in BER format pr prior to calling
25
+ # this method.
26
+ #--
27
+ # Implementor's note 20100320(AZ): RFC 4511 (the LDAPv3 protocol) as well
28
+ # as earlier RFCs 1777 and 2559 seem to indicate that LDAP only has
29
+ # application constructed sequences (0x60). However, ldapsearch sends some
30
+ # context-specific constructed sequences (0xA0); other clients may do the
31
+ # same. This behaviour appears to violate the RFCs. In real-world
32
+ # practice, we may need to change calls of #to_ber_appsequence to
33
+ # #to_ber_contextspecific for full LDAP server compatibility.
34
+ #
35
+ # This note probably belongs elsewhere.
36
+ #++
37
+ def to_ber_appsequence(id = 0)
38
+ # The application sequence tag always starts from the application flag
39
+ # (0x40) and the constructed flag (0x20).
40
+ to_ber_seq_internal(0x60 + id)
41
+ end
42
+
43
+ ##
44
+ # Converts an Array to a context-specific sequence, assigned a tag value
45
+ # that is meaningful to the particular context of the particular protocol
46
+ # being used. All values in the Array are expected to be in BER format
47
+ # prior to calling this method.
48
+ def to_ber_contextspecific(id = 0)
49
+ # The application sequence tag always starts from the context flag
50
+ # (0x80) and the constructed flag (0x20).
51
+ to_ber_seq_internal(0xa0 + id)
52
+ end
53
+
54
+ ##
55
+ # The internal sequence packing routine. All values in the Array are
56
+ # expected to be in BER format prior to calling this method.
57
+ def to_ber_seq_internal(code)
58
+ s = self.join
59
+ [code].pack('C') + s.length.to_ber_length_encoding + s
60
+ end
61
+ private :to_ber_seq_internal
62
+
63
+ ##
64
+ # SNMP Object Identifiers (OID) are special arrays
65
+ #--
66
+ # 20100320 AZ: I do not think that this method should be in BER, since
67
+ # this appears to be SNMP-specific. This should probably be subsumed by a
68
+ # proper SNMP OID object.
69
+ #++
70
+ def to_ber_oid
71
+ ary = self.dup
72
+ first = ary.shift
73
+ raise Net::BER::BerError, "Invalid OID" unless [0, 1, 2].include?(first)
74
+ first = first * 40 + ary.shift
75
+ ary.unshift first
76
+ oid = ary.pack("w*")
77
+ [6, oid.length].pack("CC") + oid
78
+ end
79
+ end
@@ -0,0 +1,19 @@
1
+ module Net::BER::Extensions::Bignum
2
+ ##
3
+ # Converts a Bignum to an uncompressed BER integer.
4
+ def to_ber
5
+ result = []
6
+
7
+ # NOTE: Array#pack's 'w' is a BER _compressed_ integer. We need
8
+ # uncompressed BER integers, so we're not using that. See also:
9
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/228864
10
+ n = self
11
+ while n > 0
12
+ b = n & 0xff
13
+ result << b
14
+ n = n >> 8
15
+ end
16
+
17
+ "\002" + ([result.size] + result.reverse).pack('C*')
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module Net::BER::Extensions::FalseClass
2
+ ##
3
+ # Converts +false+ to the BER wireline representation of +false+.
4
+ def to_ber
5
+ "\001\001\000"
6
+ end
7
+ end
@@ -0,0 +1,63 @@
1
+ module Net::BER::Extensions::Fixnum
2
+ ##
3
+ # Converts the fixnum to BER format.
4
+ def to_ber
5
+ "\002#{to_ber_internal}"
6
+ end
7
+
8
+ ##
9
+ # Converts the fixnum to BER enumerated format.
10
+ def to_ber_enumerated
11
+ "\012#{to_ber_internal}"
12
+ end
13
+
14
+ ##
15
+ # Converts the fixnum to BER length encodining format.
16
+ def to_ber_length_encoding
17
+ if self <= 127
18
+ [self].pack('C')
19
+ else
20
+ i = [self].pack('N').sub(/^[\0]+/,"")
21
+ [0x80 + i.length].pack('C') + i
22
+ end
23
+ end
24
+
25
+ ##
26
+ # Generate a BER-encoding for an application-defined INTEGER. Examples of
27
+ # such integers are SNMP's Counter, Gauge, and TimeTick types.
28
+ def to_ber_application(tag)
29
+ [0x40 + tag].pack("C") + to_ber_internal
30
+ end
31
+
32
+ ##
33
+ # Used to BER-encode the length and content bytes of a Fixnum. Callers
34
+ # must prepend the tag byte for the contained value.
35
+ def to_ber_internal
36
+ # CAUTION: Bit twiddling ahead. You might want to shield your eyes or
37
+ # something.
38
+
39
+ # Looks for the first byte in the fixnum that is not all zeroes. It does
40
+ # this by masking one byte after another, checking the result for bits
41
+ # that are left on.
42
+ size = Net::BER::MAX_FIXNUM_SIZE
43
+ while size > 1
44
+ break if (self & (0xff << (size - 1) * 8)) > 0
45
+ size -= 1
46
+ end
47
+
48
+ # Store the size of the fixnum in the result
49
+ result = [size]
50
+
51
+ # Appends bytes to result, starting with higher orders first. Extraction
52
+ # of bytes is done by right shifting the original fixnum by an amount
53
+ # and then masking that with 0xff.
54
+ while size > 0
55
+ # right shift size - 1 bytes, mask with 0xff
56
+ result << ((self >> ((size - 1) * 8)) & 0xff)
57
+ size -= 1
58
+ end
59
+
60
+ result.pack('C*')
61
+ end
62
+ private :to_ber_internal
63
+ end
@@ -0,0 +1,45 @@
1
+ require 'stringio'
2
+
3
+ module Net::BER::Extensions::String
4
+ ##
5
+ # Converts a string to a BER string. Universal octet-strings are tagged
6
+ # with 0x04, but other values are possible depending on the context, so we
7
+ # let the caller give us one.
8
+ #
9
+ # User code should call either #to_ber_application_string or
10
+ # #to_ber_contextspecific.
11
+ def to_ber(code = 0x04)
12
+ [code].pack('C') + length.to_ber_length_encoding + self
13
+ end
14
+
15
+ ##
16
+ # Creates an application-specific BER string encoded value with the
17
+ # provided syntax code value.
18
+ def to_ber_application_string(code)
19
+ to_ber(0x40 + code)
20
+ end
21
+
22
+ ##
23
+ # Creates a context-specific BER string encoded value with the provided
24
+ # syntax code value.
25
+ def to_ber_contextspecific(code)
26
+ to_ber(0x80 + code)
27
+ end
28
+
29
+ ##
30
+ # Nondestructively reads a BER object from this string.
31
+ def read_ber(syntax = nil)
32
+ StringIO.new(self).read_ber(syntax)
33
+ end
34
+
35
+ ##
36
+ # Destructively reads a BER object from the string.
37
+ def read_ber!(syntax = nil)
38
+ io = StringIO.new(self)
39
+
40
+ result = io.read_ber(syntax)
41
+ self.slice!(0...io.pos)
42
+
43
+ return result
44
+ end
45
+ end
@@ -0,0 +1,9 @@
1
+ module Net::BER::Extensions::TrueClass
2
+ ##
3
+ # Converts +true+ to the BER wireline representation of +true+.
4
+ def to_ber
5
+ # 20100319 AZ: Note that this may not be the completely correct value,
6
+ # per some test documentation. We need to determine the truth of this.
7
+ "\001\001\001"
8
+ end
9
+ end
@@ -0,0 +1,72 @@
1
+ # NET::BER
2
+ # Mixes ASN.1/BER convenience methods into several standard classes. Also
3
+ # provides BER parsing functionality.
4
+ #
5
+ #--
6
+ # Copyright (C) 2006 by Francis Cianfrocca and other contributors. All
7
+ # Rights Reserved.
8
+ #
9
+ # Gmail: garbagecat10
10
+ #
11
+ # This program is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation; either version 2 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program; if not, write to the Free Software
23
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ #++
25
+
26
+ require 'net/ber/ber_parser'
27
+ class IO
28
+ include Net::BER::BERParser
29
+ end
30
+
31
+ class StringIO
32
+ include Net::BER::BERParser
33
+ end
34
+
35
+ if defined? ::OpenSSL
36
+ class OpenSSL::SSL::SSLSocket
37
+ include Net::BER::BERParser
38
+ end
39
+ end
40
+
41
+ module Net::BER::Extensions; end
42
+
43
+ require 'net/ber/core_ext/string'
44
+ class String
45
+ include Net::BER::BERParser
46
+ include Net::BER::Extensions::String
47
+ end
48
+
49
+ require 'net/ber/core_ext/array'
50
+ class Array
51
+ include Net::BER::Extensions::Array
52
+ end
53
+
54
+ require 'net/ber/core_ext/bignum'
55
+ class Bignum
56
+ include Net::BER::Extensions::Bignum
57
+ end
58
+
59
+ require 'net/ber/core_ext/fixnum'
60
+ class Fixnum
61
+ include Net::BER::Extensions::Fixnum
62
+ end
63
+
64
+ require 'net/ber/core_ext/true_class'
65
+ class TrueClass
66
+ include Net::BER::Extensions::TrueClass
67
+ end
68
+
69
+ require 'net/ber/core_ext/false_class'
70
+ class FalseClass
71
+ include Net::BER::Extensions::FalseClass
72
+ end