! Fixes tests for everything BUT the number conversion
This commit removes read_ber! since no one seems to be using it. YAGNI.
This commit is contained in:
parent
4c24cf239a
commit
75f37c58b9
0
Manifest.txt
Normal file
0
Manifest.txt
Normal file
85
Rakefile
85
Rakefile
|
@ -1,24 +1,69 @@
|
||||||
# -*- ruby -*-
|
require "rubygems"
|
||||||
|
require "rake/gempackagetask"
|
||||||
|
require "rake/rdoctask"
|
||||||
|
|
||||||
require 'rubygems'
|
require "rake/testtask"
|
||||||
require 'hoe'
|
Rake::TestTask.new do |t|
|
||||||
|
t.libs << "test"
|
||||||
# Add 'lib' to load path.
|
t.test_files = FileList["test/test_*.rb"]
|
||||||
$LOAD_PATH.unshift( "#{File.dirname(__FILE__)}/lib" )
|
t.verbose = true
|
||||||
|
|
||||||
# Pull in local 'net/ldap' as opposed to an installed version.
|
|
||||||
require 'net'
|
|
||||||
|
|
||||||
Hoe.spec "net-ldap" do
|
|
||||||
developer 'Francis Cianfrocca', 'garbagecat10@gmail.com'
|
|
||||||
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|
|
require 'spec/rake/spectask'
|
||||||
# p.rubyforge_name = 'net-ldap'
|
Spec::Rake::SpecTask.new
|
||||||
# p.developer('Francis Cianfrocca', 'garbagecat10@gmail.com')
|
|
||||||
# p.developer('Emiel van de Laar', 'gemiel@gmail.com')
|
|
||||||
# end
|
|
||||||
|
|
||||||
# vim: syntax=Ruby
|
task :default => ["test", 'spec']
|
||||||
|
|
||||||
|
# This builds the actual gem. For details of what all these options
|
||||||
|
# mean, and other ones you can add, check the documentation here:
|
||||||
|
#
|
||||||
|
# http://rubygems.org/read/chapter/20
|
||||||
|
#
|
||||||
|
spec = Gem::Specification.new do |s|
|
||||||
|
|
||||||
|
# Change these as appropriate
|
||||||
|
s.name = "net-ldap"
|
||||||
|
s.version = "0.1.0"
|
||||||
|
s.summary = "What this thing does"
|
||||||
|
s.author = "Francis Cianfrocca", 'garbagecat10@gmail.com'
|
||||||
|
s.author = 'Emiel van de Laar', 'gemiel@gmail.com'
|
||||||
|
s.author = "Rory O'Connell", 'rory.ocon@gmail.com'
|
||||||
|
s.author = "Kaspar Schiess", 'kaspar.schiess@absurd.li'
|
||||||
|
|
||||||
|
s.description = "Pure Ruby LDAP library"
|
||||||
|
|
||||||
|
# s.has_rdoc = true
|
||||||
|
# s.extra_rdoc_files = %w(README.txt)
|
||||||
|
# s.rdoc_options = %w(--main README.txt)
|
||||||
|
|
||||||
|
# Add any extra files to include in the gem
|
||||||
|
s.files = %w(COPYING History.txt LICENSE Manifest.txt pre-setup.rb Rakefile README.txt Release-Announcement setup.rb) + Dir.glob("{test,lib/**/*}")
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
end
|
||||||
|
|
||||||
|
# This task actually builds the gem. We also regenerate a static
|
||||||
|
# .gemspec file, which is useful if something (i.e. GitHub) will
|
||||||
|
# be automatically building a gem for this project. If you're not
|
||||||
|
# using GitHub, edit as appropriate.
|
||||||
|
#
|
||||||
|
# To publish your gem online, install the 'gemcutter' gem; Read more
|
||||||
|
# about that here: http://gemcutter.org/pages/gem_docs
|
||||||
|
Rake::GemPackageTask.new(spec) do |pkg|
|
||||||
|
pkg.gem_spec = spec
|
||||||
|
|
||||||
|
# Generate the gemspec file for github.
|
||||||
|
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
||||||
|
File.open(file, "w") {|f| f << spec.to_ruby }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate documentation
|
||||||
|
Rake::RDocTask.new do |rd|
|
||||||
|
rd.main = "README.txt"
|
||||||
|
rd.rdoc_files.include("README.txt", "lib/**/*.rb")
|
||||||
|
rd.rdoc_dir = "rdoc"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Clear out RDoc and generated packages'
|
||||||
|
task :clean => [:clobber_rdoc, :clobber_package] do
|
||||||
|
rm "#{spec.name}.gemspec"
|
||||||
|
end
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
# NET::BER
|
# NET::BER
|
||||||
# Mixes ASN.1/BER convenience methods into several standard classes.
|
# Mixes ASN.1/BER convenience methods into several standard classes.
|
||||||
# Also provides BER parsing functionality.
|
# Also provides BER parsing functionality.
|
||||||
|
@ -25,8 +23,6 @@
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#
|
#
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
module Net
|
module Net
|
||||||
module BER
|
module BER
|
||||||
|
@ -105,3 +101,4 @@ module Net
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require 'net/ber/ber_parser'
|
|
@ -28,38 +28,24 @@ module Net
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
#
|
def read_ber syntax=nil
|
||||||
# read_ber
|
|
||||||
# TODO: clean this up so it works properly with partial
|
# TODO: clean this up so it works properly with partial
|
||||||
# packets coming from streams that don't block when
|
# packets coming from streams that don't block when
|
||||||
# we ask for more data (like StringIOs). At it is,
|
# we ask for more data (like StringIOs). At it is,
|
||||||
# this can throw TypeErrors and other nasties.
|
# this can throw TypeErrors and other nasties.
|
||||||
#--
|
|
||||||
# BEWARE, this violates DRY and is largely equal in functionality to
|
|
||||||
# read_ber_from_string. Eventually that method may subsume the functionality
|
|
||||||
# of this one.
|
|
||||||
#
|
|
||||||
def read_ber syntax=nil
|
|
||||||
# don't bother with this line, since IO#getc by definition returns nil on eof.
|
|
||||||
#return nil if eof?
|
|
||||||
|
|
||||||
# here we'll create two different procs, one for 1.8 and one for 1.9
|
# We might have been included in two kinds of things: IO-like
|
||||||
# the reason being getc doesn't return a byte value in 1.9, so we need to
|
# (answering to getbyte) and String-like (answering to to_s). Have
|
||||||
# get the byte code out of the 1.9 encoded string
|
# stream be a stream that is IO-like in both cases.
|
||||||
|
if respond_to? :getbyte
|
||||||
if RUBY_VERSION =~ /^1\.9/
|
stream = self
|
||||||
fetch_byte = Proc.new { getc.bytes.first }
|
else
|
||||||
elsif RUBY_VERSION =~ /^1\.8/
|
stream = StringIO.new(self.to_s)
|
||||||
fetch_byte = Proc.new { getc }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
id = fetch_byte.call or return nil # don't trash this value, we'll use it later
|
id = stream.getbyte 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
|
n = stream.getbyte
|
||||||
lengthlength,contentlength = if n <= 127
|
lengthlength,contentlength = if n <= 127
|
||||||
[1,n]
|
[1,n]
|
||||||
else
|
else
|
||||||
|
@ -70,7 +56,7 @@ module Net
|
||||||
[1 + (n & 127), j]
|
[1 + (n & 127), j]
|
||||||
end
|
end
|
||||||
|
|
||||||
newobj = read contentlength
|
newobj = stream.read contentlength
|
||||||
|
|
||||||
# This exceptionally clever and clear bit of code is verrrry slow.
|
# This exceptionally clever and clear bit of code is verrrry slow.
|
||||||
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
|
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
|
||||||
|
@ -121,101 +107,10 @@ module Net
|
||||||
n.ber_identifier = id
|
n.ber_identifier = id
|
||||||
n
|
n
|
||||||
else
|
else
|
||||||
#raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
|
|
||||||
raise BerError.new( "unsupported object type: id=#{id}" )
|
raise BerError.new( "unsupported object type: id=#{id}" )
|
||||||
end
|
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
|
obj
|
||||||
end
|
|
||||||
|
|
||||||
#--
|
|
||||||
# Violates DRY! This replicates the functionality of #read_ber.
|
|
||||||
# Eventually this method may replace that one.
|
|
||||||
# This version of #read_ber behaves properly in the face of incomplete
|
|
||||||
# data packets. If a full BER object is detected, we return an array containing
|
|
||||||
# the detected object and the number of bytes consumed from the string.
|
|
||||||
# If we don't detect a complete packet, return nil.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
def read_ber_from_string str, syntax=nil
|
|
||||||
id = str[0].ord or return nil
|
|
||||||
n = str[1].ord or return nil
|
|
||||||
n_consumed = 2
|
|
||||||
lengthlength,contentlength = if n <= 127
|
|
||||||
[1,n]
|
|
||||||
else
|
|
||||||
n1 = n & 127
|
|
||||||
return nil unless str.length >= (n_consumed + n1)
|
|
||||||
j = 0
|
|
||||||
n1.times {
|
|
||||||
j = (j << 8) + str[n_consumed]
|
|
||||||
n_consumed += 1
|
|
||||||
}
|
|
||||||
[1 + (n1), j]
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil unless str.length >= (n_consumed + contentlength)
|
|
||||||
newobj = str[n_consumed...(n_consumed + contentlength)]
|
|
||||||
n_consumed += contentlength
|
|
||||||
|
|
||||||
objtype = (syntax && syntax[id]) || BuiltinSyntax[id]
|
|
||||||
|
|
||||||
# == is expensive so sort this if/else so the common cases are at the top.
|
|
||||||
obj = if objtype == :array
|
|
||||||
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!
|
|
||||||
# Also, we can use the standard read_ber method because
|
|
||||||
# we know for sure we have enough data. (Although this
|
|
||||||
# might be faster than the standard method.)
|
|
||||||
while (e = sio.read_ber(syntax)) != nil
|
|
||||||
seq << e
|
|
||||||
end
|
|
||||||
seq
|
|
||||||
elsif objtype == :string
|
|
||||||
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 == :boolean
|
|
||||||
newobj != "\000"
|
|
||||||
elsif objtype == :null
|
|
||||||
n = BerIdentifiedNull.new
|
|
||||||
n.ber_identifier = id
|
|
||||||
n
|
|
||||||
else
|
|
||||||
raise BerError.new( "unsupported object type: id=#{id}" )
|
|
||||||
end
|
|
||||||
|
|
||||||
[obj, n_consumed]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,12 @@
|
||||||
# $Id$
|
require 'openssl'
|
||||||
#
|
|
||||||
# Net::LDAP for Ruby
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Written and maintained by Francis Cianfrocca, gmail: garbagecat10.
|
|
||||||
#
|
|
||||||
# This program is free software.
|
|
||||||
# You may re-distribute and/or modify this program under the same terms
|
|
||||||
# as Ruby itself: Ruby Distribution License or GNU General Public License.x
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# See Net::LDAP for documentation and usage samples.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
require 'net/ber'
|
||||||
require 'net/ldap/pdu'
|
require 'net/ldap/pdu'
|
||||||
require 'net/ldap/filter'
|
require 'net/ldap/filter'
|
||||||
require 'net/ldap/dataset'
|
require 'net/ldap/dataset'
|
||||||
require 'net/ldap/psw'
|
require 'net/ldap/psw'
|
||||||
require 'net/ldap/entry'
|
require 'net/ldap/entry'
|
||||||
|
require 'net/ldap/core_ext/all'
|
||||||
|
|
||||||
module Net
|
module Net
|
||||||
|
|
||||||
|
@ -258,7 +245,7 @@ module Net
|
||||||
SearchScope_WholeSubtree = 2
|
SearchScope_WholeSubtree = 2
|
||||||
SearchScopes = [SearchScope_BaseObject, SearchScope_SingleLevel, SearchScope_WholeSubtree]
|
SearchScopes = [SearchScope_BaseObject, SearchScope_SingleLevel, SearchScope_WholeSubtree]
|
||||||
|
|
||||||
AsnSyntax = BER.compile_syntax({
|
AsnSyntax = Net::BER.compile_syntax({
|
||||||
:application => {
|
:application => {
|
||||||
:primitive => {
|
:primitive => {
|
||||||
2 => :null # UnbindRequest body
|
2 => :null # UnbindRequest body
|
||||||
|
|
|
@ -32,16 +32,15 @@ module Net
|
||||||
StringIO.new(self).read_ber(syntax)
|
StringIO.new(self).read_ber(syntax)
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_ber! syntax=nil
|
# def read_ber! syntax=nil
|
||||||
obj,n_consumed = read_ber_from_string(self, syntax)
|
# obj,n_consumed = read_ber_from_string(self, syntax)
|
||||||
if n_consumed
|
# if n_consumed
|
||||||
self.slice!(0...n_consumed)
|
# self.slice!(0...n_consumed)
|
||||||
obj
|
# obj
|
||||||
else
|
# else
|
||||||
nil
|
# nil
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,11 +32,11 @@ module Net
|
||||||
class LDAP
|
class LDAP
|
||||||
class Dataset < Hash
|
class Dataset < Hash
|
||||||
attr_reader :comments
|
attr_reader :comments
|
||||||
|
|
||||||
class IOFilter
|
class IOFilter
|
||||||
def initialize(io)
|
def initialize(io)
|
||||||
@io = io
|
@io = io
|
||||||
end
|
end
|
||||||
|
|
||||||
def gets
|
def gets
|
||||||
s = @io.gets
|
s = @io.gets
|
||||||
s.chomp if s
|
s.chomp if s
|
||||||
|
@ -45,12 +45,13 @@ module Net
|
||||||
|
|
||||||
def self.read_ldif io
|
def self.read_ldif io
|
||||||
ds = Dataset.new
|
ds = Dataset.new
|
||||||
|
io = IOFilter.new(io)
|
||||||
|
|
||||||
line = io.gets
|
line = io.gets
|
||||||
dn = nil
|
dn = nil
|
||||||
|
|
||||||
while line
|
while line
|
||||||
io.gets and chomp
|
new_line = io.gets
|
||||||
if new_line =~ /^[\s]+/
|
if new_line =~ /^[\s]+/
|
||||||
line << " " << $'
|
line << " " << $'
|
||||||
else
|
else
|
||||||
|
|
25
net-ldap.gemspec
Normal file
25
net-ldap.gemspec
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = %q{net-ldap}
|
||||||
|
s.version = "0.1.0"
|
||||||
|
|
||||||
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
|
s.authors = [["Kaspar Schiess", "kaspar.schiess@absurd.li"]]
|
||||||
|
s.date = %q{2010-02-12}
|
||||||
|
s.description = %q{Pure Ruby LDAP library}
|
||||||
|
s.files = ["COPYING", "History.txt", "LICENSE", "Manifest.txt", "pre-setup.rb", "Rakefile", "README.txt", "Release-Announcement", "setup.rb", "test", "lib/net", "lib/net/ber", "lib/net/ber/ber_parser.rb", "lib/net/ber.rb", "lib/net/ldap", "lib/net/ldap/core_ext", "lib/net/ldap/core_ext/all.rb", "lib/net/ldap/core_ext/array.rb", "lib/net/ldap/core_ext/bignum.rb", "lib/net/ldap/core_ext/false_class.rb", "lib/net/ldap/core_ext/fixnum.rb", "lib/net/ldap/core_ext/string.rb", "lib/net/ldap/core_ext/true_class.rb", "lib/net/ldap/dataset.rb", "lib/net/ldap/entry.rb", "lib/net/ldap/filter.rb", "lib/net/ldap/pdu.rb", "lib/net/ldap/psw.rb", "lib/net/ldap.rb", "lib/net/ldif.rb", "lib/net/snmp.rb", "lib/net.rb"]
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
s.rubygems_version = %q{1.3.5}
|
||||||
|
s.summary = %q{What this thing does}
|
||||||
|
|
||||||
|
if s.respond_to? :specification_version then
|
||||||
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||||
|
s.specification_version = 3
|
||||||
|
|
||||||
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||||
|
else
|
||||||
|
end
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
|
@ -25,23 +25,6 @@ class TestSnmp < Test::Unit::TestCase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# The method String#read_ber! added by Net::BER consumes a well-formed BER object
|
|
||||||
# from the head of a string. If it doesn't find a complete, well-formed BER object,
|
|
||||||
# it returns nil and leaves the string unchanged. If it finds an object, it returns
|
|
||||||
# the object and removes it from the head of the string. This is good for handling
|
|
||||||
# partially-received data streams, such as from network connections.
|
|
||||||
def test_consume_string
|
|
||||||
data = "xxx"
|
|
||||||
assert_equal( data.read_ber!, nil )
|
|
||||||
assert_equal( "xxx", data )
|
|
||||||
|
|
||||||
data = SnmpGetRequest + "!!!"
|
|
||||||
ary = data.read_ber!( Net::SNMP::AsnSyntax )
|
|
||||||
assert_equal( "!!!", data )
|
|
||||||
assert ary.is_a?(Array)
|
|
||||||
assert ary.is_a?(Net::BER::BerIdentifiedArray)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_weird_packet
|
def test_weird_packet
|
||||||
assert_raise( Net::SnmpPdu::Error ) {
|
assert_raise( Net::SnmpPdu::Error ) {
|
||||||
Net::SnmpPdu.parse("aaaaaaaaaaaaaa")
|
Net::SnmpPdu.parse("aaaaaaaaaaaaaa")
|
||||||
|
|
|
@ -17,22 +17,6 @@ require 'stringio'
|
||||||
|
|
||||||
#------------------------------------------------
|
#------------------------------------------------
|
||||||
|
|
||||||
class String
|
|
||||||
def read_ber! syntax=nil
|
|
||||||
s = StringIO.new self
|
|
||||||
pdu = s.read_ber(syntax)
|
|
||||||
if pdu
|
|
||||||
if s.eof?
|
|
||||||
slice!(0, length)
|
|
||||||
else
|
|
||||||
slice!(0, length - s.read.length)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
pdu
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module LdapServer
|
module LdapServer
|
||||||
|
|
||||||
LdapServerAsnSyntax = {
|
LdapServerAsnSyntax = {
|
||||||
|
|
Loading…
Reference in a new issue