-
-
Save dsibiski/4e42cffe8e587a6bbfb5efb6a386fdcf to your computer and use it in GitHub Desktop.
Implementation of LDAP Distinguished Name parser, based on http://stackoverflow.com/a/25335936/137854. Also trims leading whitespace from attribute names and handles quoted values e.g. the `O="VeriSign, Inc."` in `CN=VeriSign Class 3 Secure Server CA - G3, OU=Terms of use at https://www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O="VeriS…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DistinguishedName | |
{ | |
/// <summary> | |
/// Represents a name/value pair within a distinguished name, including the index of the part. | |
/// </summary> | |
public struct Part | |
{ | |
public Part(string name, string value, int index = -1) | |
: this() | |
{ | |
Name = name; | |
Value = value; | |
Index = index; | |
} | |
public string Name { get; private set; } | |
public string Value { get; private set; } | |
public int Index { get; private set; } | |
/// <summary> | |
/// Performs a case-insensitive name comparison | |
/// </summary> | |
/// <param name="name"></param> | |
/// <returns></returns> | |
public bool IsNamed(string name) | |
{ | |
return string.Equals(name, this.Name, StringComparison.OrdinalIgnoreCase); | |
} | |
} | |
/// <summary> | |
/// Parses the given distinguished name into parts | |
/// </summary> | |
/// <param name="dn"></param> | |
/// <returns></returns> | |
public static IEnumerable<Part> Parse(string dn) | |
{ | |
int i = 0; | |
int a = 0; | |
int v = 0; | |
int index = -1; | |
bool inNamePart = true; | |
bool isQuoted = false; | |
var namePart = new char[50]; | |
var valuePart = new char[200]; | |
string attrName, attrValue; | |
while (i < dn.Length) | |
{ | |
char ch = dn[i++]; | |
if (!inNamePart && ch == '"') | |
{ | |
isQuoted = !isQuoted; | |
continue; | |
} | |
if (!isQuoted) | |
{ | |
if (ch == '\\') | |
{ | |
valuePart[v++] = ch; | |
valuePart[v++] = dn[i++]; | |
continue; | |
} | |
if (ch == '=') | |
{ | |
inNamePart = false; | |
isQuoted = false; | |
continue; | |
} | |
if (ch == ',') | |
{ | |
inNamePart = true; | |
attrName = new string(namePart, 0, a); | |
attrValue = new string(valuePart, 0, v); | |
yield return new Part(attrName, attrValue, ++index); | |
isQuoted = false; | |
a = v = 0; | |
continue; | |
} | |
} | |
if (inNamePart && a == 0 && char.IsWhiteSpace(ch)) // skip whitespace | |
continue; | |
else if (inNamePart) | |
namePart[a++] = ch; | |
else | |
valuePart[v++] = ch; | |
} | |
attrName = new string(namePart, 0, a); | |
attrValue = new string(valuePart, 0, v); | |
yield return new Part(attrName, attrValue, ++index); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment