Created
April 10, 2015 23:51
-
-
Save davetransom/e9c58b96afa46d4c75a0 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 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