Test code for parsing and creating ACE conditions. Used in examples on my blog: https://rohnspowershellblog.wordpress.com/2015/08/29/reading-and-creating-conditional-aces-with-powershell-kind-of/
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
/* | |
This is meant to be saved as a .cs file, and called with Add-Type inside PowerShell: | |
Add-Type -Path c:\path\to\this\gist.cs | |
*/ | |
using System; | |
using System.Security.Principal; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Testing { | |
public enum ConditionalAceTokenLiteralBaseType : byte { | |
Octal = 0x01, | |
Decimal = 0x02, | |
Hexadecimal = 0x03 | |
} | |
public enum ConditionalAceTokenLiteralSignType : byte { | |
Positive = 0x01, | |
Negative = 0x02, | |
None = 0x03 | |
} | |
public enum ConditionalAceTokenByteCode : byte { | |
Padding = 0x00, | |
Int8 = 0x01, | |
Int16 = 0x02, | |
Int32 = 0x03, | |
Int64 = 0x04, | |
UnicodeString = 0x10, | |
OctetString = 0x18, | |
Composite = 0x50, | |
Sid = 0x51, | |
Equals = 0x80, | |
NotEquals = 0x81, | |
LessThan = 0x82, | |
LessThanOrEqualTo = 0x83, | |
GreaterThan = 0x84, | |
GreaterThanOrEqualTo = 0x85, | |
Contains = 0x86, | |
Exists = 0x87, | |
AnyOf = 0x88, | |
Member_of = 0x89, | |
Device_Member_of = 0x8a, | |
Member_of_Any = 0x8b, | |
Device_Member_of_Any = 0x8c, | |
Not_Exists = 0x8d, | |
NotContains = 0x8e, | |
NotAnyOf = 0x8f, | |
Not_Member_of = 0x90, | |
Not_Device_Member_of = 0x91, | |
Not_Member_of_Any = 0x92, | |
Not_Device_Member_of_Any = 0x93, | |
And = 0xa0, | |
Or = 0xa1, | |
Not = 0xa2, | |
LocalAttribute = 0xf8, | |
UserAttribute = 0xf9, | |
ResourceAttribute = 0xfa, | |
DeviceAttribute = 0xfb | |
} | |
internal enum ConditionalAceOperatorTokenType { | |
Unary, | |
Binary | |
} | |
public abstract class ConditionalAceConditionOperand { | |
internal abstract byte[] _BinaryForm { get; } | |
public int BinaryLength { | |
get { | |
return _BinaryForm.Length; | |
} | |
} | |
public void GetBinaryForm(byte[] binaryForm, int offset) { | |
_BinaryForm.CopyTo(binaryForm, offset); | |
} | |
} | |
public class ConditionalAceConditionalLiteralOperand : ConditionalAceConditionOperand { | |
public ConditionalAceConditionalLiteralOperand(ConditionalAceLiteralToken token) { | |
this.LiteralToken = token; | |
} | |
public ConditionalAceLiteralToken LiteralToken { get; set; } | |
internal override byte[] _BinaryForm { | |
get { | |
return this.LiteralToken._BinaryForm; | |
} | |
} | |
public override string ToString() { | |
return this.LiteralToken.ToString(); | |
} | |
} | |
public abstract class ConditionalAceCondition : ConditionalAceConditionOperand { | |
public ConditionalAceCondition(ConditionalAceOperatorToken operatorToken) { | |
this.Operator = operatorToken; | |
} | |
public ConditionalAceOperatorToken Operator { get; set; } | |
public static ConditionalAceCondition GetConditionalAceCondition(byte[] binaryForm) { | |
// Check signature here | |
int offset = 4; | |
int length = binaryForm.Length - 4; | |
var stack = new Stack<ConditionalAceConditionOperand>(); | |
// https://msdn.microsoft.com/en-us/library/hh877855.aspx | |
foreach (var token in ConditionalAceToken.GetTokens(binaryForm, offset, length)) { | |
if (token is ConditionalAceLiteralToken) { | |
if (!(token is ConditionalAcePaddingToken)) { | |
stack.Push(new ConditionalAceConditionalLiteralOperand((ConditionalAceLiteralToken) token)); | |
} | |
} | |
else if (token is ConditionalAceOperatorToken) { | |
var operatorToken = (ConditionalAceOperatorToken) token; | |
if (operatorToken.OperatorType == ConditionalAceOperatorTokenType.Unary) { | |
var unaryOperation = new ConditionalAceUnaryCondition(operatorToken); | |
unaryOperation.Operand = stack.Pop(); | |
stack.Push(unaryOperation); | |
} | |
else if (operatorToken.OperatorType == ConditionalAceOperatorTokenType.Binary) { | |
var binaryOperation = new ConditionalAceBinaryCondition(operatorToken); | |
binaryOperation.RightOperand = stack.Pop(); | |
binaryOperation.LeftOperand = stack.Pop(); | |
stack.Push(binaryOperation); | |
} | |
else { | |
throw new Exception(string.Format("token is ConditionalAceOperatorToken, but is of unknown OperatorType '{0}'", operatorToken.OperatorType)); | |
} | |
} | |
else { | |
throw new Exception(string.Format("Unknown token type: {0}", token.GetType().Name)); | |
} | |
} | |
if (stack.Count != 1) { | |
throw new Exception(string.Format("Stack contains {0} elements (it should contain 1)", stack.Count)); | |
} | |
return (stack.Pop() as ConditionalAceCondition); | |
} | |
public byte[] GetApplicationData() { | |
int paddedSize = 0; | |
int binarySize = 0; | |
int signatureSize = System.Runtime.InteropServices.Marshal.SizeOf(ConditionalAceToken.ApplicationDataSignature); | |
binarySize = this.BinaryLength + signatureSize; | |
// Must align on DWORD (4 bytes) | |
paddedSize = binarySize; | |
int remainder = binarySize % 4; | |
if (remainder != 0) { | |
paddedSize += 4 - remainder; | |
} | |
byte[] binaryApplicationData = new byte[paddedSize]; | |
// Put signature in byte array: | |
byte[] signature = BitConverter.GetBytes(ConditionalAceToken.ApplicationDataSignature); | |
signature.CopyTo(binaryApplicationData, 0); | |
this.GetBinaryForm(binaryApplicationData, signature.Length); | |
for (int i = paddedSize - (paddedSize - binarySize); i < paddedSize; i++) { | |
binaryApplicationData[i] = 0; | |
} | |
return binaryApplicationData; | |
} | |
internal override byte[] _BinaryForm { get { return new byte[0]; } } | |
} | |
public class ConditionalAceUnaryCondition : ConditionalAceCondition { | |
public ConditionalAceUnaryCondition(ConditionalAceOperatorToken operatorToken) : base(operatorToken) { | |
if (operatorToken.OperatorType != ConditionalAceOperatorTokenType.Unary) { | |
throw new Exception(string.Format("Can't create ConditionalAceUnaryCondition with non-unary operator '{0}'", operatorToken)); | |
} | |
} | |
public ConditionalAceConditionOperand Operand { get; set; } | |
internal override byte[] _BinaryForm { | |
get { | |
int size = base.Operator.BinaryLength + this.Operand.BinaryLength; | |
byte[] binaryForm = new byte[size]; | |
int offset = 0; | |
this.Operand.GetBinaryForm(binaryForm, offset); | |
offset += this.Operand.BinaryLength; | |
base.Operator.GetBinaryForm(binaryForm, offset); | |
return binaryForm; | |
} | |
} | |
public override string ToString() { | |
return string.Format("({0} {1})", base.Operator.ToString(), this.Operand.ToString()); | |
} | |
} | |
public class ConditionalAceBinaryCondition : ConditionalAceCondition { | |
public ConditionalAceBinaryCondition(ConditionalAceOperatorToken operatorToken) : base(operatorToken) { | |
if (operatorToken.OperatorType != ConditionalAceOperatorTokenType.Binary) { | |
throw new Exception(string.Format("Can't create ConditionalAceBinaryCondition with non-binary operator '{0}'", operatorToken)); | |
} | |
} | |
public ConditionalAceConditionOperand LeftOperand { get; set; } | |
public ConditionalAceConditionOperand RightOperand { get; set; } | |
internal override byte[] _BinaryForm { | |
get { | |
int size = base.Operator.BinaryLength + this.LeftOperand.BinaryLength + this.RightOperand.BinaryLength; | |
byte[] binaryForm = new byte[size]; | |
int offset = 0; | |
this.LeftOperand.GetBinaryForm(binaryForm, offset); | |
offset += this.LeftOperand.BinaryLength; | |
this.RightOperand.GetBinaryForm(binaryForm, offset); | |
offset += this.RightOperand.BinaryLength; | |
base.Operator.GetBinaryForm(binaryForm, offset); | |
return binaryForm; | |
} | |
} | |
public override string ToString() { | |
return string.Format("({0} {1} {2})", this.LeftOperand.ToString(), base.Operator.ToString(), this.RightOperand.ToString()); | |
} | |
} | |
public abstract class ConditionalAceToken { | |
public const Int32 ApplicationDataSignature = 2020897377; | |
public ConditionalAceToken(ConditionalAceTokenByteCode byteCode) { | |
this.TokenByteCode = byteCode; | |
} | |
internal ConditionalAceTokenByteCode TokenByteCode { get; private set; } | |
internal abstract byte[] _BinaryForm { get; } | |
public int BinaryLength { | |
get { | |
return _BinaryForm.Length; | |
} | |
} | |
public void GetBinaryForm(byte[] binaryForm, int offset) { | |
_BinaryForm.CopyTo(binaryForm, offset); | |
} | |
internal static string GetString(byte[] binaryForm, int offset, int length, System.Text.Encoding encoding) { | |
if (BitConverter.IsLittleEndian == false) { | |
// Data is stored little endian. Method isn't set up to | |
// handle a big endian architecture | |
throw new Exception("Unsupported architecture (GetString())"); | |
} | |
return encoding.GetString(binaryForm, offset, length); | |
} | |
public static List<ConditionalAceToken> GetTokens(byte[] binaryForm, int offset, int length) { | |
int maxOffset = offset + length; | |
List<ConditionalAceToken> tokenList = new List<ConditionalAceToken>(); | |
ConditionalAceTokenByteCode tokenByteCode; | |
while (offset < maxOffset) { | |
tokenByteCode = (ConditionalAceTokenByteCode) binaryForm[offset++]; | |
//Console.WriteLine("offset = {0}; maxOffset = {1}: {2}", offset - 1, maxOffset, tokenByteCode); | |
switch (tokenByteCode) { | |
case ConditionalAceTokenByteCode.Padding: // Padding | |
tokenList.Add(new ConditionalAcePaddingToken()); | |
break; | |
case ConditionalAceTokenByteCode.UnicodeString: | |
case ConditionalAceTokenByteCode.OctetString: | |
tokenList.Add(ConditionalAceStringToken.FromBytes(binaryForm, offset, tokenByteCode)); | |
break; | |
case ConditionalAceTokenByteCode.ResourceAttribute: | |
case ConditionalAceTokenByteCode.LocalAttribute: | |
case ConditionalAceTokenByteCode.DeviceAttribute: | |
case ConditionalAceTokenByteCode.UserAttribute: | |
tokenList.Add(ConditionalAceAttributeToken.FromBytes(binaryForm, offset, tokenByteCode)); | |
break; | |
case ConditionalAceTokenByteCode.Composite: // Composite | |
tokenList.Add(ConditionalAceCompositeToken.FromBytes(binaryForm, offset)); | |
break; | |
case ConditionalAceTokenByteCode.Sid: // SID | |
tokenList.Add(ConditionalAceSecurityIdentifierToken.FromBytes(binaryForm, offset)); | |
break; | |
case ConditionalAceTokenByteCode.Exists: | |
case ConditionalAceTokenByteCode.Member_of: | |
case ConditionalAceTokenByteCode.Device_Member_of: | |
case ConditionalAceTokenByteCode.Member_of_Any: | |
case ConditionalAceTokenByteCode.Device_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not_Exists: | |
case ConditionalAceTokenByteCode.Not_Member_of: | |
case ConditionalAceTokenByteCode.Not_Device_Member_of: | |
case ConditionalAceTokenByteCode.Not_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not_Device_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not: | |
case ConditionalAceTokenByteCode.Equals: | |
case ConditionalAceTokenByteCode.NotEquals: | |
case ConditionalAceTokenByteCode.LessThan: | |
case ConditionalAceTokenByteCode.LessThanOrEqualTo: | |
case ConditionalAceTokenByteCode.GreaterThan: | |
case ConditionalAceTokenByteCode.GreaterThanOrEqualTo: | |
case ConditionalAceTokenByteCode.Contains: | |
case ConditionalAceTokenByteCode.AnyOf: | |
case ConditionalAceTokenByteCode.NotContains: | |
case ConditionalAceTokenByteCode.NotAnyOf: | |
case ConditionalAceTokenByteCode.And: | |
case ConditionalAceTokenByteCode.Or: | |
tokenList.Add(new ConditionalAceOperatorToken(tokenByteCode)); | |
break; | |
default: | |
throw new Exception(string.Format("Unknown token byte code: 0x{0:x2}", (byte)tokenByteCode)); | |
} | |
offset += tokenList.Last().BinaryLength - 1; // -1 b/c offset was already incremented | |
} | |
return tokenList; | |
} | |
} | |
public class ConditionalAcePaddingToken : ConditionalAceLiteralToken { | |
public ConditionalAcePaddingToken() : base(ConditionalAceTokenByteCode.Padding) {} | |
internal override byte[] _BinaryForm { | |
get { | |
byte[] binaryForm = new byte[1]; | |
binaryForm[0] = (byte) base.TokenByteCode; | |
return binaryForm; | |
} | |
} | |
public override string ToString() { return string.Empty; } | |
} | |
public abstract class ConditionalAceLiteralToken : ConditionalAceToken { | |
internal ConditionalAceLiteralToken(ConditionalAceTokenByteCode byteCode) : base(byteCode) {} | |
internal override byte[] _BinaryForm { get { return new byte[0]; } } | |
} | |
public class ConditionalAceAttributeToken : ConditionalAceLiteralToken { | |
public ConditionalAceAttributeToken(ConditionalAceTokenByteCode attributeType, string attributeName) : base(attributeType) { | |
switch (attributeType) { | |
case ConditionalAceTokenByteCode.UserAttribute: | |
case ConditionalAceTokenByteCode.DeviceAttribute: | |
case ConditionalAceTokenByteCode.LocalAttribute: | |
case ConditionalAceTokenByteCode.ResourceAttribute: | |
// Do nothing | |
break; | |
default: | |
throw new Exception(string.Format("TokenByteCode '{0}' is not an attribute type", attributeType)); | |
} | |
// Create a unicode string token: | |
this.UnicodeStringToken = new ConditionalAceStringToken(attributeName, attributeType, true); | |
} | |
internal ConditionalAceStringToken UnicodeStringToken { get; private set; } | |
public string AttributeName { | |
get { | |
return this.UnicodeStringToken.StringValue; | |
} | |
set { | |
this.UnicodeStringToken.StringValue = value; | |
} | |
} | |
public override string ToString() { | |
return string.Format("@{0}.{1}", base.TokenByteCode.ToString().Replace("Attribute","").ToUpper(), this.AttributeName); | |
} | |
public static ConditionalAceAttributeToken FromBytes(byte[] binaryForm, int offset, ConditionalAceTokenByteCode tokenType) { | |
int length = BitConverter.ToInt32(binaryForm, offset); | |
if (length >= (binaryForm.Length - offset)) { | |
throw new Exception("Unable to create ConditionalAceStringToken from byte array; length is too long"); | |
} | |
string attributeName = Encoding.Unicode.GetString(binaryForm, offset + 4, length); | |
return new ConditionalAceAttributeToken(tokenType, attributeName); | |
} | |
internal override byte[] _BinaryForm { | |
get { | |
return this.UnicodeStringToken._BinaryForm; | |
} | |
} | |
} | |
public class ConditionalAceStringToken : ConditionalAceLiteralToken { | |
public ConditionalAceStringToken() : this(string.Empty) {} | |
public ConditionalAceStringToken(string stringValue) : this(string.Empty, ConditionalAceTokenByteCode.UnicodeString) {} | |
public ConditionalAceStringToken(string stringValue, ConditionalAceTokenByteCode tokenType) : this(stringValue, tokenType, false) { } | |
internal ConditionalAceStringToken(string stringValue, ConditionalAceTokenByteCode tokenType, bool allowAttributeType) : base(tokenType) { | |
// Hidden constructor that allows token types other than Unicode and Octet strings | |
this.Encoding = GetEncodingFromByteCode(tokenType, allowAttributeType); | |
this.StringValue = stringValue; | |
} | |
private static Encoding GetEncodingFromByteCode(ConditionalAceTokenByteCode tokenType, bool allowAttributeType) { | |
switch (tokenType) { | |
case ConditionalAceTokenByteCode.UnicodeString: | |
return Encoding.Unicode; | |
case ConditionalAceTokenByteCode.ResourceAttribute: | |
case ConditionalAceTokenByteCode.UserAttribute: | |
case ConditionalAceTokenByteCode.LocalAttribute: | |
case ConditionalAceTokenByteCode.DeviceAttribute: | |
if (allowAttributeType) { | |
return Encoding.Unicode; | |
} | |
else { | |
goto default; | |
} | |
case ConditionalAceTokenByteCode.OctetString: | |
return Encoding.UTF8; | |
default: | |
throw new Exception(string.Format("Unable to determine encoding from byte code '{0}", tokenType)); | |
} | |
} | |
public Encoding Encoding { get; private set; } | |
public string StringValue { get; set; } | |
public static ConditionalAceStringToken FromBytes(byte[] binaryForm, int offset, ConditionalAceTokenByteCode tokenType) { | |
int length = BitConverter.ToInt32(binaryForm, offset); | |
if (length >= (binaryForm.Length - offset)) { | |
throw new Exception("Unable to create ConditionalAceStringToken from byte array; length is too long"); | |
} | |
var stringToken = new ConditionalAceStringToken(string.Empty, tokenType); | |
stringToken.StringValue = stringToken.Encoding.GetString(binaryForm, offset + 4, length); | |
return stringToken; | |
} | |
public override string ToString() { | |
return string.Format("\"{0}\"", this.StringValue); | |
} | |
internal override byte[] _BinaryForm { | |
get { | |
byte[] binaryForm; | |
int contentSize = 1; // Token byte code | |
contentSize += 4; // DWORD for size of string | |
byte[] stringBytes = this.Encoding.GetBytes(this.StringValue); | |
contentSize += stringBytes.Length; | |
binaryForm = new byte[contentSize]; | |
binaryForm[0] = (byte) base.TokenByteCode; | |
BitConverter.GetBytes(stringBytes.Length).CopyTo(binaryForm, 1); | |
// Copy binary form of string: | |
stringBytes.CopyTo(binaryForm, 5); | |
return binaryForm; | |
} | |
} | |
} | |
public class ConditionalAceCompositeToken : ConditionalAceLiteralToken { | |
public ConditionalAceCompositeToken() : base(ConditionalAceTokenByteCode.Composite) { | |
this.Tokens = new List<ConditionalAceToken>(); | |
} | |
public static ConditionalAceCompositeToken FromBytes(byte[] binaryForm, int offset) { | |
var returnToken = new ConditionalAceCompositeToken(); | |
int compositeLength = BitConverter.ToInt32(binaryForm, offset); | |
foreach (var currentToken in GetTokens(binaryForm, offset + 4, compositeLength)) { | |
returnToken.Tokens.Add(currentToken); | |
} | |
return returnToken; | |
} | |
public List<ConditionalAceToken> Tokens { get; set; } | |
internal override byte[] _BinaryForm { | |
get { | |
byte[] binaryForm; | |
int contentSize = 1; // Token byte code | |
contentSize += 4; // DWORD for size of list | |
if (this.Tokens == null) { | |
throw new Exception("No Tokens!"); | |
} | |
int listLength = 0; | |
foreach (var token in this.Tokens) { | |
listLength += token.BinaryLength; | |
} | |
contentSize += listLength; | |
binaryForm = new byte[contentSize]; | |
binaryForm[0] = (byte) base.TokenByteCode; | |
BitConverter.GetBytes(listLength).CopyTo(binaryForm, 1); | |
int index = 5; | |
foreach (var token in this.Tokens) { | |
token.GetBinaryForm(binaryForm, index); | |
index += token.BinaryLength; | |
} | |
return binaryForm; | |
} | |
} | |
public override string ToString() { | |
return string.Format("({0})", string.Join(", ", this.Tokens)); | |
} | |
} | |
public class ConditionalAceSecurityIdentifierToken : ConditionalAceLiteralToken { | |
public ConditionalAceSecurityIdentifierToken(SecurityIdentifier sid) : base(ConditionalAceTokenByteCode.Sid) { | |
this.SecurityIdentifier = sid; | |
} | |
public static ConditionalAceSecurityIdentifierToken FromBytes(byte[] binaryForm, int offset) { | |
int sidLength = BitConverter.ToInt32(binaryForm, offset); | |
byte[] sidBinaryForm = new byte[sidLength]; | |
Array.Copy(binaryForm, offset + 4, sidBinaryForm, 0, sidLength); | |
return new ConditionalAceSecurityIdentifierToken(new SecurityIdentifier(sidBinaryForm, 0)); | |
} | |
public SecurityIdentifier SecurityIdentifier { get; private set; } | |
// This will be PacPrincipal in final code...didn't want to deal with reference right now | |
public IdentityReference TranslatedAccount { | |
get { | |
return this.SecurityIdentifier.Translate(typeof(NTAccount)); | |
} | |
} | |
internal override byte[] _BinaryForm { | |
get { | |
byte[] binaryForm; | |
int contentSize = 1; | |
contentSize += 4; // DWORD for SID size | |
if (this.SecurityIdentifier != null) { | |
contentSize += this.SecurityIdentifier.BinaryLength; | |
} | |
else { | |
throw new Exception("No SID"); | |
} | |
binaryForm = new byte[contentSize]; | |
binaryForm[0] = (byte) base.TokenByteCode; | |
BitConverter.GetBytes(this.SecurityIdentifier.BinaryLength).CopyTo(binaryForm, 1); | |
this.SecurityIdentifier.GetBinaryForm(binaryForm, 5); | |
return binaryForm; | |
} | |
} | |
public override string ToString() { | |
IdentityReference translatedAccount = this.TranslatedAccount; | |
if (translatedAccount is SecurityIdentifier) { | |
// Account couldn't be translated | |
return string.Format("SID[{0}]", translatedAccount.ToString()); | |
} | |
else { | |
return translatedAccount.ToString(); | |
} | |
} | |
} | |
public class ConditionalAceOperatorToken : ConditionalAceToken { | |
public ConditionalAceOperatorToken(ConditionalAceTokenByteCode byteCode) : base(byteCode) { | |
switch ((ConditionalAceTokenByteCode) byteCode) { | |
case ConditionalAceTokenByteCode.Exists: | |
case ConditionalAceTokenByteCode.Member_of: | |
case ConditionalAceTokenByteCode.Device_Member_of: | |
case ConditionalAceTokenByteCode.Member_of_Any: | |
case ConditionalAceTokenByteCode.Device_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not_Exists: | |
case ConditionalAceTokenByteCode.Not_Member_of: | |
case ConditionalAceTokenByteCode.Not_Device_Member_of: | |
case ConditionalAceTokenByteCode.Not_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not_Device_Member_of_Any: | |
case ConditionalAceTokenByteCode.Not: | |
this.OperatorType = ConditionalAceOperatorTokenType.Unary; | |
break; | |
case ConditionalAceTokenByteCode.Equals: | |
case ConditionalAceTokenByteCode.NotEquals: | |
case ConditionalAceTokenByteCode.LessThan: | |
case ConditionalAceTokenByteCode.LessThanOrEqualTo: | |
case ConditionalAceTokenByteCode.GreaterThan: | |
case ConditionalAceTokenByteCode.GreaterThanOrEqualTo: | |
case ConditionalAceTokenByteCode.Contains: | |
case ConditionalAceTokenByteCode.AnyOf: | |
case ConditionalAceTokenByteCode.NotContains: | |
case ConditionalAceTokenByteCode.NotAnyOf: | |
case ConditionalAceTokenByteCode.And: | |
case ConditionalAceTokenByteCode.Or: | |
this.OperatorType = ConditionalAceOperatorTokenType.Binary; | |
break; | |
default: | |
//throw new Exception(string.Format("Unknown operator byte code: 0x{0:x2}", byteCode)); | |
throw new Exception(string.Format("Invalid operator byte code: {0}", byteCode)); | |
} | |
} | |
internal ConditionalAceOperatorTokenType OperatorType { get; private set; } | |
internal override byte[] _BinaryForm { | |
get { | |
byte[] binaryForm = new byte[1]; | |
binaryForm[0] = (byte) base.TokenByteCode; | |
return binaryForm; | |
} | |
} | |
public override string ToString() { | |
string returnString; | |
switch (base.TokenByteCode) { | |
case ConditionalAceTokenByteCode.And: | |
case ConditionalAceTokenByteCode.Or: | |
case ConditionalAceTokenByteCode.Not: | |
case ConditionalAceTokenByteCode.Contains: | |
case ConditionalAceTokenByteCode.NotContains: | |
returnString = "-" + base.TokenByteCode.ToString().ToLower(); | |
break; | |
case ConditionalAceTokenByteCode.AnyOf: | |
case ConditionalAceTokenByteCode.NotAnyOf: | |
returnString = "-" + base.TokenByteCode.ToString().ToLower().Replace("anyof", "in"); | |
break; | |
case ConditionalAceTokenByteCode.Equals: | |
returnString = "-eq"; | |
break; | |
case ConditionalAceTokenByteCode.NotEquals: | |
returnString = "-ne"; | |
break; | |
case ConditionalAceTokenByteCode.LessThan: | |
returnString = "-lt"; | |
break; | |
case ConditionalAceTokenByteCode.LessThanOrEqualTo: | |
returnString = "-le"; | |
break; | |
case ConditionalAceTokenByteCode.GreaterThan: | |
returnString = "-gt"; | |
break; | |
case ConditionalAceTokenByteCode.GreaterThanOrEqualTo: | |
returnString = "-ge"; | |
break; | |
case ConditionalAceTokenByteCode.Member_of_Any: | |
// Considering changing this to show that a user is a member of a group. If so, will need to | |
// handle other operators (both user and device)... | |
//returnString = "@USER -in"; | |
returnString = base.TokenByteCode.ToString(); | |
break; | |
default: | |
returnString = base.TokenByteCode.ToString(); | |
break; | |
} | |
return returnString; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment