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/COPYING +272 -0
- data/Hacking.rdoc +16 -0
- data/History.txt +137 -0
- data/LICENSE +56 -0
- data/Manifest.txt +42 -0
- data/README.txt +70 -0
- data/Rakefile +124 -0
- data/lib/net/ber/ber_parser.rb +168 -0
- data/lib/net/ber/core_ext/array.rb +79 -0
- data/lib/net/ber/core_ext/bignum.rb +19 -0
- data/lib/net/ber/core_ext/false_class.rb +7 -0
- data/lib/net/ber/core_ext/fixnum.rb +63 -0
- data/lib/net/ber/core_ext/string.rb +45 -0
- data/lib/net/ber/core_ext/true_class.rb +9 -0
- data/lib/net/ber/core_ext.rb +72 -0
- data/lib/net/ber.rb +339 -0
- data/lib/net/ldap/dataset.rb +174 -0
- data/lib/net/ldap/entry.rb +208 -0
- data/lib/net/ldap/filter.rb +720 -0
- data/lib/net/ldap/password.rb +52 -0
- data/lib/net/ldap/pdu.rb +278 -0
- data/lib/net/ldap.rb +1536 -0
- data/lib/net/ldif.rb +34 -0
- data/lib/net/snmp.rb +295 -0
- data/lib/net-ldap.rb +1 -0
- data/spec/integration/ssl_ber_spec.rb +33 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/unit/ber/ber_spec.rb +93 -0
- data/spec/unit/ber/core_ext/string_spec.rb +51 -0
- data/spec/unit/ldap/entry_spec.rb +51 -0
- data/spec/unit/ldap/filter_spec.rb +48 -0
- data/spec/unit/ldap_spec.rb +48 -0
- data/test/common.rb +3 -0
- data/test/test_entry.rb +59 -0
- data/test/test_filter.rb +115 -0
- data/test/test_ldif.rb +68 -0
- data/test/test_password.rb +17 -0
- data/test/test_snmp.rb +114 -0
- data/test/testdata.ldif +101 -0
- data/testserver/ldapserver.rb +210 -0
- data/testserver/testdata.ldif +101 -0
- metadata +218 -0
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,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
|