Import fixes from kschiess
This commit is contained in:
parent
d37c3b3ae6
commit
4c24cf239a
16
Rakefile
16
Rakefile
|
@ -7,12 +7,18 @@ require 'hoe'
|
||||||
$LOAD_PATH.unshift( "#{File.dirname(__FILE__)}/lib" )
|
$LOAD_PATH.unshift( "#{File.dirname(__FILE__)}/lib" )
|
||||||
|
|
||||||
# Pull in local 'net/ldap' as opposed to an installed version.
|
# Pull in local 'net/ldap' as opposed to an installed version.
|
||||||
require 'net/ldap'
|
require 'net'
|
||||||
|
|
||||||
Hoe.new('net-ldap', Net::LDAP::VERSION) do |p|
|
Hoe.spec "net-ldap" do
|
||||||
p.rubyforge_name = 'net-ldap'
|
developer 'Francis Cianfrocca', 'garbagecat10@gmail.com'
|
||||||
p.developer('Francis Cianfrocca', 'garbagecat10@gmail.com')
|
developer 'Emiel van de Laar', 'gemiel@gmail.com'
|
||||||
p.developer('Emiel van de Laar', 'gemiel@gmail.com')
|
developer "Rory O'Connell", 'rory.ocon@gmail.com'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Hoe.new('net-ldap', Net::LDAP::VERSION) do |p|
|
||||||
|
# p.rubyforge_name = 'net-ldap'
|
||||||
|
# p.developer('Francis Cianfrocca', 'garbagecat10@gmail.com')
|
||||||
|
# p.developer('Emiel van de Laar', 'gemiel@gmail.com')
|
||||||
|
# end
|
||||||
|
|
||||||
# vim: syntax=Ruby
|
# vim: syntax=Ruby
|
||||||
|
|
|
@ -40,100 +40,97 @@ module Net
|
||||||
# of this one.
|
# of this one.
|
||||||
#
|
#
|
||||||
def read_ber syntax=nil
|
def read_ber syntax=nil
|
||||||
# don't bother with this line, since IO#getc by definition returns nil on eof.
|
# don't bother with this line, since IO#getc by definition returns nil on eof.
|
||||||
#return nil if eof?
|
#return nil if eof?
|
||||||
|
|
||||||
# here we'll create two different procs, one for 1.8 and one for 1.9
|
# here we'll create two different procs, one for 1.8 and one for 1.9
|
||||||
# the reason being getc doesn't return a byte value in 1.9, so we need to
|
# the reason being getc doesn't return a byte value in 1.9, so we need to
|
||||||
# get the byte code out of the 1.9 encoded string
|
# get the byte code out of the 1.9 encoded string
|
||||||
|
|
||||||
if RUBY_VERSION =~ /^1\.9/
|
if RUBY_VERSION =~ /^1\.9/
|
||||||
fetch_byte = Proc.new { getc.bytes.first }
|
fetch_byte = Proc.new { getc.bytes.first }
|
||||||
elsif RUBY_VERSION =~ /^1\.8/
|
elsif RUBY_VERSION =~ /^1\.8/
|
||||||
fetch_byte = Proc.new { getc }
|
fetch_byte = Proc.new { getc }
|
||||||
end
|
|
||||||
|
|
||||||
id = fetch_byte.call or return nil # don't trash this value, we'll use it later
|
|
||||||
#tag = id & 31
|
|
||||||
#tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
|
|
||||||
#tagclass = TagClasses[ id >> 6 ]
|
|
||||||
#encoding = (id & 0x20 != 0) ? :constructed : :primitive
|
|
||||||
|
|
||||||
n = fetch_byte.call
|
|
||||||
lengthlength,contentlength = if n <= 127
|
|
||||||
[1,n]
|
|
||||||
else
|
|
||||||
# Replaced the inject because it profiles hot.
|
|
||||||
#j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
|
|
||||||
j = 0
|
|
||||||
read( n & 127 ).each_byte {|n1| j = (j << 8) + n1}
|
|
||||||
[1 + (n & 127), j]
|
|
||||||
end
|
|
||||||
|
|
||||||
newobj = read contentlength
|
|
||||||
|
|
||||||
# This exceptionally clever and clear bit of code is verrrry slow.
|
|
||||||
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
|
|
||||||
|
|
||||||
|
|
||||||
# == is expensive so sort this if/else so the common cases are at the top.
|
|
||||||
obj = if objtype == :string
|
|
||||||
#(newobj || "").dup
|
|
||||||
s = BerIdentifiedString.new( newobj || "" )
|
|
||||||
s.ber_identifier = id
|
|
||||||
s
|
|
||||||
elsif objtype == :integer
|
|
||||||
j = 0
|
|
||||||
newobj.each_byte {|b| j = (j << 8) + b}
|
|
||||||
j
|
|
||||||
elsif objtype == :oid
|
|
||||||
# cf X.690 pgh 8.19 for an explanation of this algorithm.
|
|
||||||
# Potentially not good enough. We may need a BerIdentifiedOid
|
|
||||||
# as a subclass of BerIdentifiedArray, to get the ber identifier
|
|
||||||
# and also a to_s method that produces the familiar dotted notation.
|
|
||||||
oid = newobj.unpack("w*")
|
|
||||||
f = oid.shift
|
|
||||||
g = if f < 40
|
|
||||||
[0, f]
|
|
||||||
elsif f < 80
|
|
||||||
[1, f-40]
|
|
||||||
else
|
|
||||||
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
|
|
||||||
end
|
end
|
||||||
oid.unshift g.last
|
|
||||||
oid.unshift g.first
|
|
||||||
oid
|
|
||||||
elsif objtype == :array
|
|
||||||
#seq = []
|
|
||||||
seq = BerIdentifiedArray.new
|
|
||||||
seq.ber_identifier = id
|
|
||||||
sio = StringIO.new( newobj || "" )
|
|
||||||
# Interpret the subobject, but note how the loop
|
|
||||||
# is built: nil ends the loop, but false (a valid
|
|
||||||
# BER value) does not!
|
|
||||||
while (e = sio.read_ber(syntax)) != nil
|
|
||||||
seq << e
|
|
||||||
end
|
|
||||||
seq
|
|
||||||
elsif objtype == :boolean
|
|
||||||
newobj != "\000"
|
|
||||||
elsif objtype == :null
|
|
||||||
n = BerIdentifiedNull.new
|
|
||||||
n.ber_identifier = id
|
|
||||||
n
|
|
||||||
else
|
|
||||||
#raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
|
|
||||||
raise BerError.new( "unsupported object type: id=#{id}" )
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add the identifier bits into the object if it's a String or an Array.
|
id = fetch_byte.call or return nil # don't trash this value, we'll use it later
|
||||||
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
|
#tag = id & 31
|
||||||
# Replaced this mechanism with subclasses because the instance_eval profiled too hot.
|
#tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
|
||||||
#obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
|
#tagclass = TagClasses[ id >> 6 ]
|
||||||
#obj.ber_identifier = id if obj.respond_to?(:ber_identifier)
|
#encoding = (id & 0x20 != 0) ? :constructed : :primitive
|
||||||
obj
|
|
||||||
|
|
||||||
end
|
n = fetch_byte.call
|
||||||
|
lengthlength,contentlength = if n <= 127
|
||||||
|
[1,n]
|
||||||
|
else
|
||||||
|
# Replaced the inject because it profiles hot.
|
||||||
|
#j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
|
||||||
|
j = 0
|
||||||
|
read( n & 127 ).each_byte {|n1| j = (j << 8) + n1}
|
||||||
|
[1 + (n & 127), j]
|
||||||
|
end
|
||||||
|
|
||||||
|
newobj = read contentlength
|
||||||
|
|
||||||
|
# This exceptionally clever and clear bit of code is verrrry slow.
|
||||||
|
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
|
||||||
|
|
||||||
|
# == is expensive so sort this if/else so the common cases are at the top.
|
||||||
|
obj = if objtype == :string
|
||||||
|
#(newobj || "").dup
|
||||||
|
s = BerIdentifiedString.new( newobj || "" )
|
||||||
|
s.ber_identifier = id
|
||||||
|
s
|
||||||
|
elsif objtype == :integer
|
||||||
|
j = 0
|
||||||
|
newobj.each_byte {|b| j = (j << 8) + b}
|
||||||
|
j
|
||||||
|
elsif objtype == :oid
|
||||||
|
# cf X.690 pgh 8.19 for an explanation of this algorithm.
|
||||||
|
# Potentially not good enough. We may need a BerIdentifiedOid
|
||||||
|
# as a subclass of BerIdentifiedArray, to get the ber identifier
|
||||||
|
# and also a to_s method that produces the familiar dotted notation.
|
||||||
|
oid = newobj.unpack("w*")
|
||||||
|
f = oid.shift
|
||||||
|
g = if f < 40
|
||||||
|
[0, f]
|
||||||
|
elsif f < 80
|
||||||
|
[1, f-40]
|
||||||
|
else
|
||||||
|
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
|
||||||
|
end
|
||||||
|
oid.unshift g.last
|
||||||
|
oid.unshift g.first
|
||||||
|
oid
|
||||||
|
elsif objtype == :array
|
||||||
|
#seq = []
|
||||||
|
seq = BerIdentifiedArray.new
|
||||||
|
seq.ber_identifier = id
|
||||||
|
sio = StringIO.new( newobj || "" )
|
||||||
|
# Interpret the subobject, but note how the loop
|
||||||
|
# is built: nil ends the loop, but false (a valid
|
||||||
|
# BER value) does not!
|
||||||
|
while (e = sio.read_ber(syntax)) != nil
|
||||||
|
seq << e
|
||||||
|
end
|
||||||
|
seq
|
||||||
|
elsif objtype == :boolean
|
||||||
|
newobj != "\000"
|
||||||
|
elsif objtype == :null
|
||||||
|
n = BerIdentifiedNull.new
|
||||||
|
n.ber_identifier = id
|
||||||
|
n
|
||||||
|
else
|
||||||
|
#raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
|
||||||
|
raise BerError.new( "unsupported object type: id=#{id}" )
|
||||||
|
end
|
||||||
|
# Add the identifier bits into the object if it's a String or an Array.
|
||||||
|
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
|
||||||
|
# Replaced this mechanism with subclasses because the instance_eval profiled too hot.
|
||||||
|
#obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
|
||||||
|
#obj.ber_identifier = id if obj.respond_to?(:ber_identifier)
|
||||||
|
obj
|
||||||
|
end
|
||||||
|
|
||||||
#--
|
#--
|
||||||
# Violates DRY! This replicates the functionality of #read_ber.
|
# Violates DRY! This replicates the functionality of #read_ber.
|
||||||
|
@ -145,24 +142,24 @@ module Net
|
||||||
#
|
#
|
||||||
# Observe that weirdly we recursively call the original #read_ber in here.
|
# Observe that weirdly we recursively call the original #read_ber in here.
|
||||||
# That needs to be fixed if we ever obsolete the original method in favor of this one.
|
# That needs to be fixed if we ever obsolete the original method in favor of this one.
|
||||||
def read_ber_from_string str, syntax=nil
|
def read_ber_from_string str, syntax=nil
|
||||||
id = str[0] or return nil
|
id = str[0].ord or return nil
|
||||||
n = str[1] or return nil
|
n = str[1].ord or return nil
|
||||||
n_consumed = 2
|
n_consumed = 2
|
||||||
lengthlength,contentlength = if n <= 127
|
lengthlength,contentlength = if n <= 127
|
||||||
[1,n]
|
[1,n]
|
||||||
else
|
else
|
||||||
n1 = n & 127
|
n1 = n & 127
|
||||||
return nil unless str.length >= (n_consumed + n1)
|
return nil unless str.length >= (n_consumed + n1)
|
||||||
j = 0
|
j = 0
|
||||||
n1.times {
|
n1.times {
|
||||||
j = (j << 8) + str[n_consumed]
|
j = (j << 8) + str[n_consumed]
|
||||||
n_consumed += 1
|
n_consumed += 1
|
||||||
}
|
}
|
||||||
[1 + (n1), j]
|
[1 + (n1), j]
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil unless str.length >= (n_consumed + contentlength)
|
return nil unless str.length >= (n_consumed + contentlength)
|
||||||
newobj = str[n_consumed...(n_consumed + contentlength)]
|
newobj = str[n_consumed...(n_consumed + contentlength)]
|
||||||
n_consumed += contentlength
|
n_consumed += contentlength
|
||||||
|
|
||||||
|
@ -170,52 +167,52 @@ module Net
|
||||||
|
|
||||||
# == is expensive so sort this if/else so the common cases are at the top.
|
# == is expensive so sort this if/else so the common cases are at the top.
|
||||||
obj = if objtype == :array
|
obj = if objtype == :array
|
||||||
seq = BerIdentifiedArray.new
|
seq = BerIdentifiedArray.new
|
||||||
seq.ber_identifier = id
|
seq.ber_identifier = id
|
||||||
sio = StringIO.new( newobj || "" )
|
sio = StringIO.new( newobj || "" )
|
||||||
# Interpret the subobject, but note how the loop
|
# Interpret the subobject, but note how the loop
|
||||||
# is built: nil ends the loop, but false (a valid
|
# is built: nil ends the loop, but false (a valid
|
||||||
# BER value) does not!
|
# BER value) does not!
|
||||||
# Also, we can use the standard read_ber method because
|
# Also, we can use the standard read_ber method because
|
||||||
# we know for sure we have enough data. (Although this
|
# we know for sure we have enough data. (Although this
|
||||||
# might be faster than the standard method.)
|
# might be faster than the standard method.)
|
||||||
while (e = sio.read_ber(syntax)) != nil
|
while (e = sio.read_ber(syntax)) != nil
|
||||||
seq << e
|
seq << e
|
||||||
end
|
end
|
||||||
seq
|
seq
|
||||||
elsif objtype == :string
|
elsif objtype == :string
|
||||||
s = BerIdentifiedString.new( newobj || "" )
|
s = BerIdentifiedString.new( newobj || "" )
|
||||||
s.ber_identifier = id
|
s.ber_identifier = id
|
||||||
s
|
s
|
||||||
elsif objtype == :integer
|
elsif objtype == :integer
|
||||||
j = 0
|
j = 0
|
||||||
newobj.each_byte {|b| j = (j << 8) + b}
|
newobj.each_byte {|b| j = (j << 8) + b}
|
||||||
j
|
j
|
||||||
elsif objtype == :oid
|
elsif objtype == :oid
|
||||||
# cf X.690 pgh 8.19 for an explanation of this algorithm.
|
# cf X.690 pgh 8.19 for an explanation of this algorithm.
|
||||||
# Potentially not good enough. We may need a BerIdentifiedOid
|
# Potentially not good enough. We may need a BerIdentifiedOid
|
||||||
# as a subclass of BerIdentifiedArray, to get the ber identifier
|
# as a subclass of BerIdentifiedArray, to get the ber identifier
|
||||||
# and also a to_s method that produces the familiar dotted notation.
|
# and also a to_s method that produces the familiar dotted notation.
|
||||||
oid = newobj.unpack("w*")
|
oid = newobj.unpack("w*")
|
||||||
f = oid.shift
|
f = oid.shift
|
||||||
g = if f < 40
|
g = if f < 40
|
||||||
[0,f]
|
[0,f]
|
||||||
elsif f < 80
|
elsif f < 80
|
||||||
[1, f-40]
|
[1, f-40]
|
||||||
else
|
else
|
||||||
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
|
[2, f-80] # f-80 can easily be > 80. What a weird optimization.
|
||||||
end
|
end
|
||||||
oid.unshift g.last
|
oid.unshift g.last
|
||||||
oid.unshift g.first
|
oid.unshift g.first
|
||||||
oid
|
oid
|
||||||
elsif objtype == :boolean
|
elsif objtype == :boolean
|
||||||
newobj != "\000"
|
newobj != "\000"
|
||||||
elsif objtype == :null
|
elsif objtype == :null
|
||||||
n = BerIdentifiedNull.new
|
n = BerIdentifiedNull.new
|
||||||
n.ber_identifier = id
|
n.ber_identifier = id
|
||||||
n
|
n
|
||||||
else
|
else
|
||||||
raise BerError.new( "unsupported object type: id=#{id}" )
|
raise BerError.new( "unsupported object type: id=#{id}" )
|
||||||
end
|
end
|
||||||
|
|
||||||
[obj, n_consumed]
|
[obj, n_consumed]
|
||||||
|
|
|
@ -29,80 +29,78 @@
|
||||||
|
|
||||||
|
|
||||||
module Net
|
module Net
|
||||||
class LDAP
|
class LDAP
|
||||||
|
class Dataset < Hash
|
||||||
class Dataset < Hash
|
attr_reader :comments
|
||||||
|
class IOFilter
|
||||||
attr_reader :comments
|
def initialize(io)
|
||||||
|
@io = io
|
||||||
|
end
|
||||||
def Dataset::read_ldif io
|
|
||||||
ds = Dataset.new
|
def gets
|
||||||
|
s = @io.gets
|
||||||
line = io.gets && chomp
|
s.chomp if s
|
||||||
dn = nil
|
|
||||||
|
|
||||||
while line
|
|
||||||
io.gets and chomp
|
|
||||||
if $_ =~ /^[\s]+/
|
|
||||||
line << " " << $'
|
|
||||||
else
|
|
||||||
nextline = $_
|
|
||||||
|
|
||||||
if line =~ /^\#/
|
|
||||||
ds.comments << line
|
|
||||||
elsif line =~ /^dn:[\s]*/i
|
|
||||||
dn = $'
|
|
||||||
ds[dn] = Hash.new {|k,v| k[v] = []}
|
|
||||||
elsif line.length == 0
|
|
||||||
dn = nil
|
|
||||||
elsif line =~ /^([^:]+):([\:]?)[\s]*/
|
|
||||||
# $1 is the attribute name
|
|
||||||
# $2 is a colon iff the attr-value is base-64 encoded
|
|
||||||
# $' is the attr-value
|
|
||||||
# Avoid the Base64 class because not all Ruby versions have it.
|
|
||||||
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
|
|
||||||
ds[dn][$1.downcase.intern] << attrvalue
|
|
||||||
end
|
end
|
||||||
|
|
||||||
line = nextline
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
def self.read_ldif io
|
||||||
|
ds = Dataset.new
|
||||||
|
|
||||||
|
line = io.gets
|
||||||
|
dn = nil
|
||||||
|
|
||||||
|
while line
|
||||||
|
io.gets and chomp
|
||||||
|
if new_line =~ /^[\s]+/
|
||||||
|
line << " " << $'
|
||||||
|
else
|
||||||
|
nextline = new_line
|
||||||
|
|
||||||
|
if line =~ /^\#/
|
||||||
|
ds.comments << line
|
||||||
|
elsif line =~ /^dn:[\s]*/i
|
||||||
|
dn = $'
|
||||||
|
ds[dn] = Hash.new {|k,v| k[v] = []}
|
||||||
|
elsif line.length == 0
|
||||||
|
dn = nil
|
||||||
|
elsif line =~ /^([^:]+):([\:]?)[\s]*/
|
||||||
|
# $1 is the attribute name
|
||||||
|
# $2 is a colon iff the attr-value is base-64 encoded
|
||||||
|
# $' is the attr-value
|
||||||
|
# Avoid the Base64 class because not all Ruby versions have it.
|
||||||
|
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $'
|
||||||
|
ds[dn][$1.downcase.intern] << attrvalue
|
||||||
|
end
|
||||||
|
|
||||||
|
line = nextline
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
ds
|
ds
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@comments = []
|
@comments = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def to_ldif
|
def to_ldif
|
||||||
ary = []
|
ary = []
|
||||||
ary += (@comments || [])
|
ary += (@comments || [])
|
||||||
|
keys.sort.each do |dn|
|
||||||
|
ary << "dn: #{dn}"
|
||||||
|
|
||||||
keys.sort.each {|dn|
|
self[dn].keys.map {|sym| sym.to_s}.sort.each do |attr|
|
||||||
ary << "dn: #{dn}"
|
self[dn][attr.intern].each {|val| ary << "#{attr}: #{val}" }
|
||||||
|
end
|
||||||
self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr|
|
|
||||||
self[dn][attr.intern].each {|val|
|
|
||||||
ary << "#{attr}: #{val}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ary << ""
|
|
||||||
}
|
|
||||||
|
|
||||||
block_given? and ary.each {|line| yield line}
|
|
||||||
|
|
||||||
ary
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end # Dataset
|
|
||||||
|
|
||||||
end # LDAP
|
|
||||||
end # Net
|
|
||||||
|
|
||||||
|
ary << ""
|
||||||
|
end
|
||||||
|
block_given? and ary.each {|line| yield line}
|
||||||
|
ary
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -27,36 +27,36 @@
|
||||||
|
|
||||||
|
|
||||||
module Net
|
module Net
|
||||||
class LDAP
|
class LDAP
|
||||||
|
class Password
|
||||||
|
class << self
|
||||||
|
|
||||||
|
# Generate a password-hash suitable for inclusion in an LDAP attribute.
|
||||||
class Password
|
# Pass a hash type (currently supported: :md5 and :sha) and a plaintext
|
||||||
class << self
|
# password. This function will return a hashed representation.
|
||||||
|
# STUB: This is here to fulfill the requirements of an RFC, which one?
|
||||||
# Generate a password-hash suitable for inclusion in an LDAP attribute.
|
# TODO, gotta do salted-sha and (maybe) salted-md5.
|
||||||
# Pass a hash type (currently supported: :md5 and :sha) and a plaintext
|
# Should we provide sha1 as a synonym for sha1? I vote no because then
|
||||||
# password. This function will return a hashed representation.
|
# should you also provide ssha1 for symmetry?
|
||||||
# STUB: This is here to fulfill the requirements of an RFC, which one?
|
def generate( type, str )
|
||||||
# TODO, gotta do salted-sha and (maybe) salted-md5.
|
digest, digest_name = case type
|
||||||
# Should we provide sha1 as a synonym for sha1? I vote no because then
|
when :md5
|
||||||
# should you also provide ssha1 for symmetry?
|
[Digest::MD5.new, 'MD5']
|
||||||
def generate( type, str )
|
when :sha
|
||||||
case type
|
[Digest::SHA1.new, 'sha']
|
||||||
when :md5
|
# when ssha
|
||||||
"{MD5}#{ [MD5.new( str.to_s ).digest].pack("m").chomp }"
|
else
|
||||||
when :sha
|
raise Net::LDAP::LdapError.new( "unsupported password-hash type (#{type})" )
|
||||||
"{SHA}#{ [SHA1.new( str.to_s ).digest].pack("m").chomp }"
|
end
|
||||||
# when ssha
|
|
||||||
else
|
digest << str.to_s
|
||||||
raise Net::LDAP::LdapError.new( "unsupported password-hash type (#{type})" )
|
return "{#{digest_name}}#{[digest.digest].pack('m').chomp }"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end # class LDAP
|
|
||||||
end # module Net
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ class TestLdif < Test::Unit::TestCase
|
||||||
TestLdifFilename = "#{File.dirname(__FILE__)}/testdata.ldif"
|
TestLdifFilename = "#{File.dirname(__FILE__)}/testdata.ldif"
|
||||||
|
|
||||||
def test_empty_ldif
|
def test_empty_ldif
|
||||||
ds = Net::LDAP::Dataset::read_ldif( StringIO.new )
|
ds = Net::LDAP::Dataset.read_ldif( StringIO.new )
|
||||||
assert_equal( true, ds.empty? )
|
assert_equal( true, ds.empty? )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class TestSnmp < Test::Unit::TestCase
|
||||||
# partially-received data streams, such as from network connections.
|
# partially-received data streams, such as from network connections.
|
||||||
def test_consume_string
|
def test_consume_string
|
||||||
data = "xxx"
|
data = "xxx"
|
||||||
assert_equal( nil, data.read_ber! )
|
assert_equal( data.read_ber!, nil )
|
||||||
assert_equal( "xxx", data )
|
assert_equal( "xxx", data )
|
||||||
|
|
||||||
data = SnmpGetRequest + "!!!"
|
data = SnmpGetRequest + "!!!"
|
||||||
|
|
Loading…
Reference in a new issue