Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
2f11db4b
Commit
2f11db4b
authored
Sep 20, 2017
by
Michael Kozono
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adapt DN class for Gitlab
parent
7bc4278e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
207 additions
and
195 deletions
+207
-195
lib/gitlab/ldap/dn.rb
lib/gitlab/ldap/dn.rb
+207
-195
No files found.
lib/gitlab/ldap/dn.rb
View file @
2f11db4b
# -*- ruby encoding: utf-8 -*-
# -*- 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
# Objects of this class represent an LDAP DN ("Distinguished Name"). A DN
# ("Distinguished Name") is a unique identifier for an entry within an LDAP
# ("Distinguished Name") is a unique identifier for an entry within an LDAP
...
@@ -11,214 +19,218 @@
...
@@ -11,214 +19,218 @@
#
#
# A fully escaped DN needs to be unescaped when analysing its contents. This
# A fully escaped DN needs to be unescaped when analysing its contents. This
# class also helps take care of that.
# class also helps take care of that.
class
Net::LDAP::DN
module
Gitlab
##
module
LDAP
# Initialize a DN, escaping as required. Pass in attributes in name/value
class
DN
# pairs. If there is a left over argument, it will be appended to the dn
##
# without escaping (useful for a base string).
# 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
# Most uses of this class will be to escape a DN, rather than to parse it,
# without escaping (useful for a base string).
# so storing the dn as an escaped String and parsing parts as required
#
# with a state machine seems sensible.
# Most uses of this class will be to escape a DN, rather than to parse it,
def
initialize
(
*
args
)
# so storing the dn as an escaped String and parsing parts as required
buffer
=
StringIO
.
new
# with a state machine seems sensible.
def
initialize
(
*
args
)
buffer
=
StringIO
.
new
args
.
each_index
do
|
index
|
args
.
each_index
do
|
index
|
buffer
<<
"="
if
index
%
2
==
1
buffer
<<
"="
if
index
%
2
==
1
buffer
<<
","
if
index
%
2
==
0
&&
index
!=
0
buffer
<<
","
if
index
%
2
==
0
&&
index
!=
0
if
index
<
args
.
length
-
1
||
index
%
2
==
1
if
index
<
args
.
length
-
1
||
index
%
2
==
1
buffer
<<
Net
::
LDAP
::
DN
.
escape
(
args
[
index
])
buffer
<<
Net
::
LDAP
::
DN
.
escape
(
args
[
index
])
else
else
buffer
<<
args
[
index
]
buffer
<<
args
[
index
]
end
end
end
end
@dn
=
buffer
.
string
@dn
=
buffer
.
string
end
end
##
##
# 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
value
=
StringIO
.
new
value
=
StringIO
.
new
hex_buffer
=
""
hex_buffer
=
""
@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
when
:key_normal
then
case
char
case
char
when
'='
then
state
=
:value
when
'='
then
state
=
:value
when
'a'
..
'z'
,
'A'
..
'Z'
,
'0'
..
'9'
,
'-'
,
' '
then
key
<<
char
when
'a'
..
'z'
,
'A'
..
'Z'
,
'0'
..
'9'
,
'-'
,
' '
then
key
<<
char
else
raise
"DN badly formed"
else
raise
"DN badly formed"
end
end
when
:key_oid
then
when
:key_oid
then
case
char
case
char
when
'='
then
state
=
:value
when
'='
then
state
=
:value
when
'0'
..
'9'
,
'.'
,
' '
then
key
<<
char
when
'0'
..
'9'
,
'.'
,
' '
then
key
<<
char
else
raise
"DN badly formed"
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
when
:value_normal_escape
then
case
char
case
char
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
state
=
:value_normal_escape_hex
state
=
:value_normal_escape_hex
hex_buffer
=
char
hex_buffer
=
char
else
state
=
:value_normal
;
value
<<
char
else
state
=
:value_normal
;
value
<<
char
end
end
when
:value_normal_escape_hex
then
when
:value_normal_escape_hex
then
case
char
case
char
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
state
=
:value_normal
state
=
:value_normal
value
<<
"
#{
hex_buffer
}#{
char
}
"
.
to_i
(
16
).
chr
value
<<
"
#{
hex_buffer
}#{
char
}
"
.
to_i
(
16
).
chr
else
raise
"DN badly formed"
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
when
:value_quoted_escape
then
case
char
case
char
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
when
'0'
..
'9'
,
'a'
..
'f'
,
'A'
..
'F'
then
state
=
:value_quoted_escape_hex
state
=
:value_quoted_escape_hex
hex_buffer
=
char
hex_buffer
=
char
else
else
state
=
:value_quoted
;
state
=
:value_quoted
;
value
<<
char
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
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
# Last pair
raise
"DN badly formed"
unless
raise
"DN badly formed"
unless
[
:value
,
:value_normal
,
:value_hexstring
,
:value_end
].
include?
state
[
:value
,
:value_normal
,
:value_hexstring
,
:value_end
].
include?
state
yield
key
.
string
.
strip
,
value
.
string
.
rstrip
yield
key
.
string
.
strip
,
value
.
string
.
rstrip
end
end
##
##
# Returns the DN as an array in the form expected by the constructor.
# Returns the DN as an array in the form expected by the constructor.
def
to_a
def
to_a
a
=
[]
a
=
[]
self
.
each_pair
{
|
key
,
value
|
a
<<
key
<<
value
}
self
.
each_pair
{
|
key
,
value
|
a
<<
key
<<
value
}
a
a
end
end
##
##
# Return the DN as an escaped string.
# Return the DN as an escaped string.
def
to_s
def
to_s
@dn
@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 string
# for dn values. All of the following must be escaped in any normal string
# using a single backslash ('\') as escape.
# using a single backslash ('\') as escape.
ESCAPES
=
{
ESCAPES
=
{
','
=>
','
,
','
=>
','
,
'+'
=>
'+'
,
'+'
=>
'+'
,
'"'
=>
'"'
,
'"'
=>
'"'
,
'\\'
=>
'\\'
,
'\\'
=>
'\\'
,
'<'
=>
'<'
,
'<'
=>
'<'
,
'>'
=>
'>'
,
'>'
=>
'>'
,
';'
=>
';'
,
';'
=>
';'
,
}
}
# 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
def
self
.
escape
(
string
)
def
self
.
escape
(
string
)
string
.
gsub
(
ESCAPE_RE
)
{
|
char
|
"
\\
"
+
ESCAPES
[
char
]
}
string
.
gsub
(
ESCAPE_RE
)
{
|
char
|
"
\\
"
+
ESCAPES
[
char
]
}
end
end
##
##
# Proxy all other requests to the string object, because a DN is mainly
# Proxy all other requests to the string object, because a DN is mainly
# used within the library as a string
# used within the library as a string
def
method_missing
(
method
,
*
args
,
&
block
)
def
method_missing
(
method
,
*
args
,
&
block
)
@dn
.
send
(
method
,
*
args
,
&
block
)
@dn
.
send
(
method
,
*
args
,
&
block
)
end
end
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment