Formatting changes to the DN class.
This commit is contained in:
parent
f50ba57e99
commit
393b57405d
|
@ -1,12 +1,10 @@
|
||||||
# LDAP DN support classes
|
# -*- ruby encoding: utf-8 -*-
|
||||||
#
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Objects of this class represent an LDAP DN.
|
# Objects of this class represent an LDAP DN ("Distinguished Name"). A DN
|
||||||
#
|
# ("Distinguished Name") is a unique identifier for an entry within an LDAP
|
||||||
# In LDAP-land, a DN ("Distinguished Name") is a unique identifier for an
|
# directory. It is made up of a number of other attributes strung together,
|
||||||
# entry within an LDAP directory. It is made up of a number of other
|
# to identify the entry in the tree.
|
||||||
# attributes strung together, to identify the entry in the tree.
|
|
||||||
#
|
#
|
||||||
# Each attribute that makes up a DN needs to have its value escaped so that
|
# Each attribute that makes up a DN needs to have its value escaped so that
|
||||||
# the DN is valid. This class helps take care of that.
|
# the DN is valid. This class helps take care of that.
|
||||||
|
@ -18,10 +16,10 @@ class Net::LDAP::DN
|
||||||
# Initialize a DN, escaping as required. Pass in attributes in name/value
|
# Initialize a DN, escaping as required. Pass in attributes in name/value
|
||||||
# pairs. If there is a left over argument, it will be appended to the dn
|
# pairs. If there is a left over argument, it will be appended to the dn
|
||||||
# without escaping (useful for a base string).
|
# without escaping (useful for a base string).
|
||||||
#
|
#
|
||||||
# Most uses of this class will be to escape a DN, rather than to parse it,
|
# Most uses of this class will be to escape a DN, rather than to parse it,
|
||||||
# so storing the dn as an escaped String and parsing parts as required with
|
# so storing the dn as an escaped String and parsing parts as required
|
||||||
# a state machine seems sensible.
|
# with a state machine seems sensible.
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
buffer = StringIO.new
|
buffer = StringIO.new
|
||||||
|
|
||||||
|
@ -42,7 +40,6 @@ class Net::LDAP::DN
|
||||||
##
|
##
|
||||||
# Parse a DN into key value pairs using ASN from
|
# Parse a DN into key value pairs using ASN from
|
||||||
# http://tools.ietf.org/html/rfc2253 section 3.
|
# http://tools.ietf.org/html/rfc2253 section 3.
|
||||||
#
|
|
||||||
def each_pair
|
def each_pair
|
||||||
state = :key
|
state = :key
|
||||||
key = StringIO.new
|
key = StringIO.new
|
||||||
|
@ -51,118 +48,126 @@ class Net::LDAP::DN
|
||||||
|
|
||||||
@dn.each_char do |char|
|
@dn.each_char do |char|
|
||||||
case state
|
case state
|
||||||
|
when :key then
|
||||||
when :key then case char
|
case char
|
||||||
when 'a'..'z','A'..'Z' then
|
when 'a'..'z', 'A'..'Z' then
|
||||||
state = :key_normal
|
state = :key_normal
|
||||||
key << char
|
key << char
|
||||||
when '0'..'9' then
|
when '0'..'9' then
|
||||||
state = :key_oid
|
state = :key_oid
|
||||||
key << char
|
key << char
|
||||||
when ' ' then state = :key
|
when ' ' then state = :key
|
||||||
else raise "DN badly formed"
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
when :key_normal then case char
|
when :key_normal then
|
||||||
when '=' then state = :value
|
case char
|
||||||
when 'a'..'z','A'..'Z','0'..'9','-',' ' then key << char
|
when '=' then state = :value
|
||||||
else raise "DN badly formed"
|
when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
|
||||||
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
when :key_oid then case char
|
when :key_oid then
|
||||||
when '=' then state = :value
|
case char
|
||||||
when '0'..'9','.',' ' then key << char
|
when '=' then state = :value
|
||||||
else raise "DN badly formed"
|
when '0'..'9', '.', ' ' then key << char
|
||||||
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
|
when :value then
|
||||||
when :value then case char
|
case char
|
||||||
when '\\' then state = :value_normal_escape
|
when '\\' then state = :value_normal_escape
|
||||||
when '"' then state = :value_quoted
|
when '"' then state = :value_quoted
|
||||||
when ' ' then state = :value
|
when ' ' then state = :value
|
||||||
when '#' then
|
when '#' then
|
||||||
state = :value_hexstring
|
state = :value_hexstring
|
||||||
value << char
|
value << char
|
||||||
when ',' then
|
when ',' then
|
||||||
state = :key
|
state = :key
|
||||||
yield key.string.strip, value.string.rstrip
|
yield key.string.strip, value.string.rstrip
|
||||||
key = StringIO.new
|
key = StringIO.new
|
||||||
value = StringIO.new;
|
value = StringIO.new;
|
||||||
else
|
else
|
||||||
state = :value_normal
|
state = :value_normal
|
||||||
value << char
|
value << char
|
||||||
end
|
end
|
||||||
|
when :value_normal then
|
||||||
when :value_normal then case char
|
case char
|
||||||
when '\\' then state = :value_normal_escape
|
when '\\' then state = :value_normal_escape
|
||||||
when ',' then
|
when ',' then
|
||||||
state = :key
|
state = :key
|
||||||
yield key.string.strip, value.string.rstrip
|
yield key.string.strip, value.string.rstrip
|
||||||
key = StringIO.new
|
key = StringIO.new
|
||||||
value = StringIO.new;
|
value = StringIO.new;
|
||||||
else value << char
|
else value << char
|
||||||
end
|
end
|
||||||
when :value_normal_escape then case char
|
when :value_normal_escape then
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
case char
|
||||||
state = :value_normal_escape_hex
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
hex_buffer = char
|
state = :value_normal_escape_hex
|
||||||
else state = :value_normal; value << char
|
hex_buffer = char
|
||||||
|
else state = :value_normal; value << char
|
||||||
end
|
end
|
||||||
when :value_normal_escape_hex then case char
|
when :value_normal_escape_hex then
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
case char
|
||||||
state = :value_normal
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
value << "#{hex_buffer}#{char}".to_i(16).chr
|
state = :value_normal
|
||||||
else raise "DN badly formed"
|
value << "#{hex_buffer}#{char}".to_i(16).chr
|
||||||
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
|
when :value_quoted then
|
||||||
when :value_quoted then case char
|
case char
|
||||||
when '\\' then state = :value_quoted_escape
|
when '\\' then state = :value_quoted_escape
|
||||||
when '"' then state = :value_end
|
when '"' then state = :value_end
|
||||||
else value << char
|
else value << char
|
||||||
end
|
end
|
||||||
when :value_quoted_escape then case char
|
when :value_quoted_escape then
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
case char
|
||||||
state = :value_quoted_escape_hex
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
hex_buffer = char
|
state = :value_quoted_escape_hex
|
||||||
else state = :value_quoted; value << char
|
hex_buffer = char
|
||||||
|
else
|
||||||
|
state = :value_quoted;
|
||||||
|
value << char
|
||||||
end
|
end
|
||||||
when :value_quoted_escape_hex then case char
|
when :value_quoted_escape_hex then
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
case char
|
||||||
state = :value_quoted
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
value << "#{hex_buffer}#{char}".to_i(16).chr
|
state = :value_quoted
|
||||||
else raise "DN badly formed"
|
value << "#{hex_buffer}#{char}".to_i(16).chr
|
||||||
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
|
when :value_hexstring then
|
||||||
when :value_hexstring then case char
|
case char
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
state = :value_hexstring_hex
|
state = :value_hexstring_hex
|
||||||
value << char
|
value << char
|
||||||
when ' ' then state = :value_end
|
when ' ' then state = :value_end
|
||||||
when ',' then
|
when ',' then
|
||||||
state = :key
|
state = :key
|
||||||
yield key.string.strip, value.string.rstrip
|
yield key.string.strip, value.string.rstrip
|
||||||
key = StringIO.new
|
key = StringIO.new
|
||||||
value = StringIO.new;
|
value = StringIO.new;
|
||||||
else raise "DN badly formed"
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
when :value_hexstring_hex then case char
|
when :value_hexstring_hex then
|
||||||
when '0'..'9', 'a'..'f', 'A'..'F' then
|
case char
|
||||||
state = :value_hexstring
|
when '0'..'9', 'a'..'f', 'A'..'F' then
|
||||||
value << char
|
state = :value_hexstring
|
||||||
else raise "DN badly formed"
|
value << char
|
||||||
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
|
when :value_end then
|
||||||
when :value_end then case char
|
case char
|
||||||
when ' ' then state = :value_end
|
when ' ' then state = :value_end
|
||||||
when ',' then
|
when ',' then
|
||||||
state = :key
|
state = :key
|
||||||
yield key.string.strip, value.string.rstrip
|
yield key.string.strip, value.string.rstrip
|
||||||
key = StringIO.new
|
key = StringIO.new
|
||||||
value = StringIO.new;
|
value = StringIO.new;
|
||||||
else raise "DN badly formed"
|
else raise "DN badly formed"
|
||||||
end
|
end
|
||||||
|
else raise "Fell out of state machine"
|
||||||
else raise "Fell out of state machine"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Last pair
|
# Last pair
|
||||||
if [:value, :value_normal, :value_hexstring, :value_end].include? state
|
if [:value, :value_normal, :value_hexstring, :value_end].include? state
|
||||||
yield key.string.strip, value.string.rstrip
|
yield key.string.strip, value.string.rstrip
|
||||||
|
@ -186,9 +191,8 @@ class Net::LDAP::DN
|
||||||
end
|
end
|
||||||
|
|
||||||
# http://tools.ietf.org/html/rfc2253 section 2.4 lists these exceptions
|
# http://tools.ietf.org/html/rfc2253 section 2.4 lists these exceptions
|
||||||
# for dn values. All of the following must be escaped in any normal
|
# for dn values. All of the following must be escaped in any normal string
|
||||||
# string using a single backslash ('\') as escape.
|
# using a single backslash ('\') as escape.
|
||||||
#
|
|
||||||
ESCAPES = {
|
ESCAPES = {
|
||||||
',' => ',',
|
',' => ',',
|
||||||
'+' => '+',
|
'+' => '+',
|
||||||
|
@ -198,13 +202,13 @@ class Net::LDAP::DN
|
||||||
'>' => '>',
|
'>' => '>',
|
||||||
';' => ';',
|
';' => ';',
|
||||||
}
|
}
|
||||||
|
|
||||||
# Compiled character class regexp using the keys from the above hash, and
|
# Compiled character class regexp using the keys from the above hash, and
|
||||||
# checking for a space or # at the start, or space at the end, of the
|
# checking for a space or # at the start, or space at the end, of the
|
||||||
# string.
|
# string.
|
||||||
ESCAPE_RE = Regexp.new(
|
ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
|
||||||
"(^ |^#| $|[" +
|
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
|
||||||
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
|
"])")
|
||||||
"])")
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Escape a string for use in a DN value
|
# Escape a string for use in a DN value
|
||||||
|
|
|
@ -4,16 +4,20 @@ require 'net/ldap/dn'
|
||||||
describe Net::LDAP::DN do
|
describe Net::LDAP::DN do
|
||||||
describe "<- .construct" do
|
describe "<- .construct" do
|
||||||
attr_reader :dn
|
attr_reader :dn
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@dn = Net::LDAP::DN.new('cn', ',+"\\<>;', 'ou=company')
|
@dn = Net::LDAP::DN.new('cn', ',+"\\<>;', 'ou=company')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should construct a Net::LDAP::DN" do
|
it "should construct a Net::LDAP::DN" do
|
||||||
dn.should be_an_instance_of(Net::LDAP::DN)
|
dn.should be_an_instance_of(Net::LDAP::DN)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should escape all the required characters" do
|
it "should escape all the required characters" do
|
||||||
dn.to_s.should == 'cn=\\,\\+\\"\\\\\\<\\>\\;,ou=company'
|
dn.to_s.should == 'cn=\\,\\+\\"\\\\\\<\\>\\;,ou=company'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "<- .to_a" do
|
describe "<- .to_a" do
|
||||||
context "parsing" do
|
context "parsing" do
|
||||||
{
|
{
|
||||||
|
@ -23,12 +27,15 @@ describe Net::LDAP::DN do
|
||||||
}.each do |key, value|
|
}.each do |key, value|
|
||||||
context "(#{key})" do
|
context "(#{key})" do
|
||||||
attr_reader :dn
|
attr_reader :dn
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@dn = Net::LDAP::DN.new(key)
|
@dn = Net::LDAP::DN.new(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should decode into a Net::LDAP::DN" do
|
it "should decode into a Net::LDAP::DN" do
|
||||||
dn.should be_an_instance_of(Net::LDAP::DN)
|
dn.should be_an_instance_of(Net::LDAP::DN)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return the correct array" do
|
it "should return the correct array" do
|
||||||
dn.to_a.should == value
|
dn.to_a.should == value
|
||||||
end
|
end
|
||||||
|
@ -48,12 +55,15 @@ describe Net::LDAP::DN do
|
||||||
].each do |value|
|
].each do |value|
|
||||||
context "(#{value})" do
|
context "(#{value})" do
|
||||||
attr_reader :dn
|
attr_reader :dn
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@dn = Net::LDAP::DN.new(value)
|
@dn = Net::LDAP::DN.new(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should decode into a Net::LDAP::DN" do
|
it "should decode into a Net::LDAP::DN" do
|
||||||
dn.should be_an_instance_of(Net::LDAP::DN)
|
dn.should be_an_instance_of(Net::LDAP::DN)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise an error on parsing" do
|
it "should raise an error on parsing" do
|
||||||
lambda { dn.to_a }.should raise_error
|
lambda { dn.to_a }.should raise_error
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue