173 lines
6.6 KiB
C#
173 lines
6.6 KiB
C#
using DSInternals.Common.Cryptography;
|
|
using DSInternals.Common.Exceptions;
|
|
using DSInternals.Common.Interop;
|
|
using DSInternals.Common.Properties;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.DirectoryServices.ActiveDirectory;
|
|
using System.IO;
|
|
using System.Security;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace DSInternals.Common
|
|
{
|
|
public static class Validator
|
|
{
|
|
private const string hexPattern = "^([0-9a-fA-F][0-9a-fA-F])+$";
|
|
|
|
public static void AssertSuccess(NtStatus status)
|
|
{
|
|
Win32ErrorCode code = NativeMethods.RtlNtStatusToDosError(status);
|
|
AssertSuccess(code);
|
|
}
|
|
public static void AssertSuccess(Win32ErrorCode code)
|
|
{
|
|
switch(code)
|
|
{
|
|
case Win32ErrorCode.Success:
|
|
case Win32ErrorCode.MORE_DATA:
|
|
// No error occured, so exit gracefully.
|
|
return;
|
|
}
|
|
|
|
var genericException = new Win32Exception((int)code);
|
|
Exception exceptionToThrow;
|
|
// We will try to translate the generic Win32 exception to a more specific built-in exception.
|
|
switch(code)
|
|
{
|
|
case Win32ErrorCode.DS_INVALID_DN_SYNTAX:
|
|
exceptionToThrow = new ArgumentException(genericException.Message, genericException);
|
|
break;
|
|
case Win32ErrorCode.ACCESS_DENIED:
|
|
case Win32ErrorCode.DS_DRA_ACCESS_DENIED:
|
|
case Win32ErrorCode.WRONG_PASSWORD:
|
|
case Win32ErrorCode.PASSWORD_EXPIRED:
|
|
exceptionToThrow = new UnauthorizedAccessException(genericException.Message, genericException);
|
|
break;
|
|
case Win32ErrorCode.NOT_ENOUGH_MEMORY:
|
|
case Win32ErrorCode.OUTOFMEMORY:
|
|
case Win32ErrorCode.DS_DRA_OUT_OF_MEM:
|
|
case Win32ErrorCode.RPC_S_OUT_OF_RESOURCES:
|
|
exceptionToThrow = new OutOfMemoryException(genericException.Message, genericException);
|
|
break;
|
|
case Win32ErrorCode.NO_LOGON_SERVERS:
|
|
case Win32ErrorCode.NO_SUCH_DOMAIN:
|
|
case Win32ErrorCode.RPC_S_SERVER_UNAVAILABLE:
|
|
case Win32ErrorCode.RPC_S_CALL_FAILED:
|
|
exceptionToThrow = new ActiveDirectoryServerDownException(genericException.Message, genericException);
|
|
break;
|
|
case Win32ErrorCode.DS_OBJ_NOT_FOUND:
|
|
// This error code means either a non-existing DN or Access Denied.
|
|
case Win32ErrorCode.DS_DRA_BAD_DN:
|
|
exceptionToThrow = new DirectoryObjectNotFoundException(null, genericException);
|
|
break;
|
|
// TODO: Add translation for ActiveDirectoryOperationException and for other exception types.
|
|
default:
|
|
// We were not able to translate the Win32Exception to a more specific type.
|
|
exceptionToThrow = genericException;
|
|
break;
|
|
}
|
|
throw exceptionToThrow;
|
|
}
|
|
|
|
public static void AssertIsHex(string value, string paramName)
|
|
{
|
|
bool isHexString = Regex.IsMatch(value, hexPattern);
|
|
if (!isHexString)
|
|
{
|
|
var exception = new ArgumentException(Resources.NotHexStringMessage, paramName);
|
|
exception.Data.Add("Value", value);
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
public static void AssertNotNull(object value, string paramName)
|
|
{
|
|
if(value == null)
|
|
{
|
|
throw new ArgumentNullException(paramName);
|
|
}
|
|
}
|
|
public static void AssertNotNullOrWhiteSpace(string value, string paramName)
|
|
{
|
|
if(string.IsNullOrWhiteSpace(value))
|
|
{
|
|
throw new ArgumentNullException(paramName);
|
|
}
|
|
}
|
|
public static void AssertLength(string value, int length, string paramName)
|
|
{
|
|
AssertNotNull(value, paramName);
|
|
if(value.Length != length)
|
|
{
|
|
throw new ArgumentOutOfRangeException(paramName, value.Length, Resources.UnexpectedLengthMessage);
|
|
}
|
|
}
|
|
|
|
public static void AssertMaxLength(SecureString password, int maxLength, string paramName)
|
|
{
|
|
AssertNotNull(password, paramName);
|
|
if (password.Length > maxLength)
|
|
{
|
|
throw new ArgumentOutOfRangeException(paramName, password.Length, Resources.InputLongerThanMaxMessage);
|
|
}
|
|
}
|
|
|
|
public static void AssertMaxLength(string input, int maxLength, string paramName)
|
|
{
|
|
AssertNotNull(input, paramName);
|
|
if (input.Length > maxLength)
|
|
{
|
|
throw new ArgumentOutOfRangeException(paramName, input.Length, Resources.InputLongerThanMaxMessage);
|
|
}
|
|
}
|
|
|
|
public static void AssertMinLength(byte[] data, int minLength, string paramName)
|
|
{
|
|
AssertNotNull(data, paramName);
|
|
if (data.Length < minLength)
|
|
{
|
|
var exception = new ArgumentOutOfRangeException(paramName, data.Length, Resources.InputShorterThanMinMessage);
|
|
// DEBUG: exception.Data.Add("BinaryBlob", data.ToHex());
|
|
throw exception;
|
|
}
|
|
}
|
|
|
|
public static void AssertLength(byte[] value, long length, string paramName)
|
|
{
|
|
AssertNotNull(value, paramName);
|
|
if (value.Length != length)
|
|
{
|
|
throw new ArgumentOutOfRangeException(paramName, value.Length, Resources.UnexpectedLengthMessage);
|
|
}
|
|
}
|
|
|
|
public static void AssertFileExists(string filePath)
|
|
{
|
|
bool exists = File.Exists(filePath);
|
|
if(!exists)
|
|
{
|
|
throw new FileNotFoundException(Resources.PathNotFoundMessage, filePath);
|
|
}
|
|
}
|
|
|
|
public static void AssertDirectoryExists(string directoryPath)
|
|
{
|
|
bool exists = Directory.Exists(directoryPath);
|
|
if (!exists)
|
|
{
|
|
throw new DirectoryNotFoundException(Resources.PathNotFoundMessage);
|
|
}
|
|
}
|
|
|
|
public static void AssertCrcMatches(byte[] buffer, uint expectedCrc)
|
|
{
|
|
uint actualCrc = Crc32.Calculate(buffer);
|
|
if(actualCrc != expectedCrc)
|
|
{
|
|
throw new Exception(Resources.InvalidCRCMessage);
|
|
}
|
|
}
|
|
}
|
|
}
|