summaryrefslogtreecommitdiff
path: root/lib/gitlab
diff options
context:
space:
mode:
authorMichael Kozono <mkozono@gmail.com>2017-09-20 11:01:11 -0700
committerMichael Kozono <mkozono@gmail.com>2017-10-07 10:28:12 -0700
commit2f11db4b005f67fe7687dd15267062556e8431ad (patch)
tree1e31eb5b10225c2106609e8453cc71070f2702c7 /lib/gitlab
parent7bc4278e07e2386fa35039e23af027a092623b32 (diff)
downloadgitlab-ce-2f11db4b005f67fe7687dd15267062556e8431ad.tar.gz
Adapt DN class for Gitlab
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/ldap/dn.rb402
1 files changed, 207 insertions, 195 deletions
diff --git a/lib/gitlab/ldap/dn.rb b/lib/gitlab/ldap/dn.rb
index e314b80e578..038476b2d2a 100644
--- a/lib/gitlab/ldap/dn.rb
+++ b/lib/gitlab/ldap/dn.rb
@@ -1,5 +1,13 @@
# -*- ruby encoding: utf-8 -*-
+# Based on the `ruby-net-ldap` gem's `Net::LDAP::DN`
+#
+# For our purposes, this class is used to normalize DNs in order to allow proper
+# comparison.
+#
+# E.g. DNs should be compared case-insensitively (in basically all LDAP
+# implementations or setups), therefore we downcase every 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
@@ -11,214 +19,218 @@
#
# A fully escaped DN needs to be unescaped when analysing its contents. This
# class also helps take care of that.
-class Net::LDAP::DN
- ##
- # 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
- # without escaping (useful for a base string).
- #
- # 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 a state machine seems sensible.
- def initialize(*args)
- buffer = StringIO.new
+module Gitlab
+ module LDAP
+ class DN
+ ##
+ # 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
+ # without escaping (useful for a base string).
+ #
+ # 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 a state machine seems sensible.
+ def initialize(*args)
+ buffer = StringIO.new
- args.each_index do |index|
- buffer << "=" if index % 2 == 1
- buffer << "," if index % 2 == 0 && index != 0
+ args.each_index do |index|
+ buffer << "=" if index % 2 == 1
+ buffer << "," if index % 2 == 0 && index != 0
- if index < args.length - 1 || index % 2 == 1
- buffer << Net::LDAP::DN.escape(args[index])
- else
- buffer << args[index]
- end
- end
+ if index < args.length - 1 || index % 2 == 1
+ buffer << Net::LDAP::DN.escape(args[index])
+ else
+ buffer << args[index]
+ end
+ end
- @dn = buffer.string
- end
+ @dn = buffer.string
+ end
- ##
- # Parse a DN into key value pairs using ASN from
- # http://tools.ietf.org/html/rfc2253 section 3.
- def each_pair
- state = :key
- key = StringIO.new
- value = StringIO.new
- hex_buffer = ""
+ ##
+ # Parse a DN into key value pairs using ASN from
+ # http://tools.ietf.org/html/rfc2253 section 3.
+ def each_pair
+ state = :key
+ key = StringIO.new
+ value = StringIO.new
+ hex_buffer = ""
- @dn.each_char do |char|
- case state
- when :key then
- case char
- when 'a'..'z', 'A'..'Z' then
- state = :key_normal
- key << char
- when '0'..'9' then
- state = :key_oid
- key << char
- when ' ' then state = :key
- else raise "DN badly formed"
- end
- when :key_normal then
- case char
- when '=' then state = :value
- when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
- else raise "DN badly formed"
- end
- when :key_oid then
- case char
- when '=' then state = :value
- when '0'..'9', '.', ' ' then key << char
- else raise "DN badly formed"
- end
- when :value then
- case char
- when '\\' then state = :value_normal_escape
- when '"' then state = :value_quoted
- when ' ' then state = :value
- when '#' then
- state = :value_hexstring
- value << char
- when ',' then
- state = :key
- yield key.string.strip, value.string.rstrip
- key = StringIO.new
- value = StringIO.new;
- else
- state = :value_normal
- value << char
- end
- when :value_normal then
- case char
- when '\\' then state = :value_normal_escape
- when ',' then
- state = :key
- yield key.string.strip, value.string.rstrip
- key = StringIO.new
- value = StringIO.new;
- else value << char
- end
- when :value_normal_escape then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_normal_escape_hex
- hex_buffer = char
- else state = :value_normal; value << char
- end
- when :value_normal_escape_hex then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_normal
- value << "#{hex_buffer}#{char}".to_i(16).chr
- else raise "DN badly formed"
- end
- when :value_quoted then
- case char
- when '\\' then state = :value_quoted_escape
- when '"' then state = :value_end
- else value << char
- end
- when :value_quoted_escape then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_quoted_escape_hex
- hex_buffer = char
- else
- state = :value_quoted;
- value << char
+ @dn.each_char do |char|
+ case state
+ when :key then
+ case char
+ when 'a'..'z', 'A'..'Z' then
+ state = :key_normal
+ key << char
+ when '0'..'9' then
+ state = :key_oid
+ key << char
+ when ' ' then state = :key
+ else raise "DN badly formed"
+ end
+ when :key_normal then
+ case char
+ when '=' then state = :value
+ when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
+ else raise "DN badly formed"
+ end
+ when :key_oid then
+ case char
+ when '=' then state = :value
+ when '0'..'9', '.', ' ' then key << char
+ else raise "DN badly formed"
+ end
+ when :value then
+ case char
+ when '\\' then state = :value_normal_escape
+ when '"' then state = :value_quoted
+ when ' ' then state = :value
+ when '#' then
+ state = :value_hexstring
+ value << char
+ when ',' then
+ state = :key
+ yield key.string.strip, value.string.rstrip
+ key = StringIO.new
+ value = StringIO.new;
+ else
+ state = :value_normal
+ value << char
+ end
+ when :value_normal then
+ case char
+ when '\\' then state = :value_normal_escape
+ when ',' then
+ state = :key
+ yield key.string.strip, value.string.rstrip
+ key = StringIO.new
+ value = StringIO.new;
+ else value << char
+ end
+ when :value_normal_escape then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_normal_escape_hex
+ hex_buffer = char
+ else state = :value_normal; value << char
+ end
+ when :value_normal_escape_hex then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_normal
+ value << "#{hex_buffer}#{char}".to_i(16).chr
+ else raise "DN badly formed"
+ end
+ when :value_quoted then
+ case char
+ when '\\' then state = :value_quoted_escape
+ when '"' then state = :value_end
+ else value << char
+ end
+ when :value_quoted_escape then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_quoted_escape_hex
+ hex_buffer = char
+ else
+ state = :value_quoted;
+ value << char
+ end
+ when :value_quoted_escape_hex then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_quoted
+ value << "#{hex_buffer}#{char}".to_i(16).chr
+ else raise "DN badly formed"
+ end
+ when :value_hexstring then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_hexstring_hex
+ value << char
+ when ' ' then state = :value_end
+ when ',' then
+ state = :key
+ yield key.string.strip, value.string.rstrip
+ key = StringIO.new
+ value = StringIO.new;
+ else raise "DN badly formed"
+ end
+ when :value_hexstring_hex then
+ case char
+ when '0'..'9', 'a'..'f', 'A'..'F' then
+ state = :value_hexstring
+ value << char
+ else raise "DN badly formed"
+ end
+ when :value_end then
+ case char
+ when ' ' then state = :value_end
+ when ',' then
+ state = :key
+ yield key.string.strip, value.string.rstrip
+ key = StringIO.new
+ value = StringIO.new;
+ else raise "DN badly formed"
+ end
+ else raise "Fell out of state machine"
+ end
end
- when :value_quoted_escape_hex then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_quoted
- value << "#{hex_buffer}#{char}".to_i(16).chr
- else raise "DN badly formed"
- end
- when :value_hexstring then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_hexstring_hex
- value << char
- when ' ' then state = :value_end
- when ',' then
- state = :key
- yield key.string.strip, value.string.rstrip
- key = StringIO.new
- value = StringIO.new;
- else raise "DN badly formed"
- end
- when :value_hexstring_hex then
- case char
- when '0'..'9', 'a'..'f', 'A'..'F' then
- state = :value_hexstring
- value << char
- else raise "DN badly formed"
- end
- when :value_end then
- case char
- when ' ' then state = :value_end
- when ',' then
- state = :key
- yield key.string.strip, value.string.rstrip
- key = StringIO.new
- value = StringIO.new;
- else raise "DN badly formed"
- end
- else raise "Fell out of state machine"
- end
- end
- # Last pair
- raise "DN badly formed" unless
- [:value, :value_normal, :value_hexstring, :value_end].include? state
+ # Last pair
+ raise "DN badly formed" unless
+ [:value, :value_normal, :value_hexstring, :value_end].include? state
- yield key.string.strip, value.string.rstrip
- end
+ yield key.string.strip, value.string.rstrip
+ end
- ##
- # Returns the DN as an array in the form expected by the constructor.
- def to_a
- a = []
- self.each_pair { |key, value| a << key << value }
- a
- end
+ ##
+ # Returns the DN as an array in the form expected by the constructor.
+ def to_a
+ a = []
+ self.each_pair { |key, value| a << key << value }
+ a
+ end
- ##
- # Return the DN as an escaped string.
- def to_s
- @dn
- end
+ ##
+ # Return the DN as an escaped string.
+ def to_s
+ @dn
+ end
- # 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 string
- # using a single backslash ('\') as escape.
- ESCAPES = {
- ',' => ',',
- '+' => '+',
- '"' => '"',
- '\\' => '\\',
- '<' => '<',
- '>' => '>',
- ';' => ';',
- }
+ # 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 string
+ # using a single backslash ('\') as escape.
+ ESCAPES = {
+ ',' => ',',
+ '+' => '+',
+ '"' => '"',
+ '\\' => '\\',
+ '<' => '<',
+ '>' => '>',
+ ';' => ';',
+ }
- # 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
- # string.
- ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
- ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
- "])")
+ # 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
+ # string.
+ ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
+ ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
+ "])")
- ##
- # Escape a string for use in a DN value
- def self.escape(string)
- string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
- end
+ ##
+ # Escape a string for use in a DN value
+ def self.escape(string)
+ string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
+ end
- ##
- # Proxy all other requests to the string object, because a DN is mainly
- # used within the library as a string
- def method_missing(method, *args, &block)
- @dn.send(method, *args, &block)
+ ##
+ # Proxy all other requests to the string object, because a DN is mainly
+ # used within the library as a string
+ def method_missing(method, *args, &block)
+ @dn.send(method, *args, &block)
+ end
+ end
end
end