Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Net / System / Net / _SSPIWrapper.cs / 1 / _SSPIWrapper.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net {
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.ComponentModel;
using System.Net.Sockets;
using System.Security.Permissions;
using System.Globalization;
using System.Net.Security;
internal static class SSPIWrapper {
internal static SecurityPackageInfoClass[] EnumerateSecurityPackages(SSPIInterface SecModule) {
GlobalLog.Enter("EnumerateSecurityPackages");
if (SecModule.SecurityPackages==null) {
lock (SecModule) {
if (SecModule.SecurityPackages==null) {
int moduleCount = 0;
SafeFreeContextBuffer arrayBaseHandle = null;
try {
int errorCode = SecModule.EnumerateSecurityPackages(out moduleCount, out arrayBaseHandle);
GlobalLog.Print("SSPIWrapper::arrayBase: " + (arrayBaseHandle.DangerousGetHandle().ToString("x")));
if (errorCode != 0) {
throw new Win32Exception(errorCode);
}
SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount];
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_enumerating_security_packages));
int i;
for (i = 0; i < moduleCount; i++) {
securityPackages[i] = new SecurityPackageInfoClass(arrayBaseHandle, i);
if (Logging.On) Logging.PrintInfo(Logging.Web, " " + securityPackages[i].Name);
}
SecModule.SecurityPackages = securityPackages;
}
finally {
if (arrayBaseHandle != null) {
arrayBaseHandle.Close();
}
}
}
}
}
GlobalLog.Leave("EnumerateSecurityPackages");
return SecModule.SecurityPackages;
}
internal static SecurityPackageInfoClass GetVerifyPackageInfo(SSPIInterface secModule, string packageName) {
return GetVerifyPackageInfo(secModule, packageName, false);
}
internal static SecurityPackageInfoClass GetVerifyPackageInfo(SSPIInterface secModule, string packageName, bool throwIfMissing) {
SecurityPackageInfoClass[] supportedSecurityPackages = EnumerateSecurityPackages(secModule);
if (supportedSecurityPackages != null) {
for (int i = 0; i < supportedSecurityPackages.Length; i++) {
if (string.Compare(supportedSecurityPackages[i].Name, packageName, StringComparison.OrdinalIgnoreCase) == 0) {
return supportedSecurityPackages[i];
}
}
}
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_package_not_found, packageName));
// error
if (throwIfMissing) {
throw new NotSupportedException(SR.GetString(SR.net_securitypackagesupport));
}
return null;
}
public static SafeFreeCredentials AcquireDefaultCredential(SSPIInterface SecModule, string package, CredentialUse intent) {
GlobalLog.Print("SSPIWrapper::AcquireDefaultCredential(): using " + package);
if (Logging.On) Logging.PrintInfo(Logging.Web,
"AcquireDefaultCredential(" +
"package = " + package + ", " +
"intent = " + intent + ")");
SafeFreeCredentials outCredential = null;
int errorCode = SecModule.AcquireDefaultCredential(package, intent, out outCredential );
if (errorCode != 0) {
#if TRAVE
GlobalLog.Print("SSPIWrapper::AcquireDefaultCredential(): error " + SecureChannel.MapSecurityStatus((uint)errorCode));
#endif
if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireDefaultCredential()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
throw new Win32Exception(errorCode);
}
return outCredential;
}
public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface SecModule, string package, CredentialUse intent, ref AuthIdentity authdata) {
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#2(): using " + package);
if (Logging.On) Logging.PrintInfo(Logging.Web,
"AcquireCredentialsHandle(" +
"package = " + package + ", " +
"intent = " + intent + ", " +
"authdata = " + authdata + ")");
SafeFreeCredentials credentialsHandle = null;
int errorCode = SecModule.AcquireCredentialsHandle(package,
intent,
ref authdata,
out credentialsHandle
);
if (errorCode != 0) {
#if TRAVE
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#2(): error " + SecureChannel.MapSecurityStatus((uint)errorCode));
#endif
if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireCredentialsHandle()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
throw new Win32Exception(errorCode);
}
return credentialsHandle;
}
public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface SecModule, string package, CredentialUse intent, SecureCredential scc) {
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): using " + package);
if (Logging.On) Logging.PrintInfo(Logging.Web,
"AcquireCredentialsHandle(" +
"package = " + package + ", " +
"intent = " + intent + ", " +
"scc = " + scc + ")");
SafeFreeCredentials outCredential = null;
int errorCode = SecModule.AcquireCredentialsHandle(
package,
intent,
ref scc,
out outCredential
);
if (errorCode != 0) {
#if TRAVE
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): error " + SecureChannel.MapSecurityStatus((uint)errorCode));
#endif
if (Logging.On) Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireCredentialsHandle()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
throw new Win32Exception(errorCode);
}
#if TRAVE
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): cred handle = " + outCredential.ToString());
#endif
return outCredential;
}
internal static int InitializeSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlags outFlags) {
if (Logging.On) Logging.PrintInfo(Logging.Web,
"InitializeSecurityContext(" +
"credential = " + credential.ToString() + ", " +
"context = " + ValidationHelper.ToString(context) + ", " +
"targetName = " + targetName + ", " +
"inFlags = " + inFlags + ")");
int errorCode = SecModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffer, outputBuffer, ref outFlags);
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffer, "InitializeSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (SecurityStatus) errorCode));
return errorCode;
}
internal static int InitializeSecurityContext(SSPIInterface SecModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags) {
if (Logging.On) Logging.PrintInfo(Logging.Web,
"InitializeSecurityContext(" +
"credential = " + credential.ToString() + ", " +
"context = " + ValidationHelper.ToString(context) + ", " +
"targetName = " + targetName + ", " +
"inFlags = " + inFlags + ")");
int errorCode = SecModule.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffers, outputBuffer, ref outFlags);
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffers, "InitializeSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (SecurityStatus) errorCode));
return errorCode;
}
internal static int AcceptSecurityContext(SSPIInterface SecModule, ref SafeFreeCredentials credential, ref SafeDeleteContext context, ContextFlags inFlags, Endianness datarep, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
{
if (Logging.On) Logging.PrintInfo(Logging.Web,
"AcceptSecurityContext(" +
"credential = " + credential.ToString() + ", " +
"context = " + ValidationHelper.ToString(context) + ", " +
"inFlags = " + inFlags + ")");
int errorCode = SecModule.AcceptSecurityContext(ref credential, ref context, inputBuffer, inFlags, datarep, outputBuffer, ref outFlags);
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffer, "AcceptSecurityContext", (inputBuffer == null ? 0 : inputBuffer.size), outputBuffer.size, (SecurityStatus) errorCode));
return errorCode;
}
internal static int AcceptSecurityContext(SSPIInterface SecModule, SafeFreeCredentials credential, ref SafeDeleteContext context, ContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
{
if (Logging.On) Logging.PrintInfo(Logging.Web,
"AcceptSecurityContext(" +
"credential = " + credential.ToString() + ", " +
"context = " + ValidationHelper.ToString(context) + ", " +
"inFlags = " + inFlags + ")");
int errorCode = SecModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags);
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffers, "AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (SecurityStatus) errorCode));
return errorCode;
}
internal static int CompleteAuthToken(SSPIInterface SecModule, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers) {
int errorCode = SecModule.CompleteAuthToken(ref context, inputBuffers);
if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_operation_returned_something, "CompleteAuthToken()", (SecurityStatus) errorCode));
return errorCode;
}
public static int QuerySecurityContextToken(SSPIInterface SecModule, SafeDeleteContext context, out SafeCloseHandle token) {
return SecModule.QuerySecurityContextToken(context, out token);
}
public static int EncryptMessage(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) {
return EncryptDecryptHelper(OP.Encrypt, secModule, context, input, sequenceNumber);
}
public static int DecryptMessage(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) {
return EncryptDecryptHelper(OP.Decrypt, secModule, context, input, sequenceNumber);
}
internal static int MakeSignature(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) {
return EncryptDecryptHelper(OP.MakeSignature, secModule, context, input, sequenceNumber);
}
public static int VerifySignature(SSPIInterface secModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) {
return EncryptDecryptHelper(OP.VerifySignature, secModule, context, input, sequenceNumber);
}
private enum OP {
Encrypt = 1,
Decrypt,
MakeSignature,
VerifySignature
}
//
private unsafe static int EncryptDecryptHelper(OP op, SSPIInterface SecModule, SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
{
SecurityBufferDescriptor sdcInOut = new SecurityBufferDescriptor(input.Length);
SecurityBufferStruct[] unmanagedBuffer = new SecurityBufferStruct[input.Length];
fixed (SecurityBufferStruct* unmanagedBufferPtr = unmanagedBuffer)
{
sdcInOut.UnmanagedPointer = unmanagedBufferPtr;
GCHandle[] pinnedBuffers = new GCHandle[input.Length];
byte[][] buffers = new byte[input.Length][];
try
{
for (int i = 0; i < input.Length; i++)
{
SecurityBuffer iBuffer = input[i];
unmanagedBuffer[i].count = iBuffer.size;
unmanagedBuffer[i].type = iBuffer.type;
if (iBuffer.token == null || iBuffer.token.Length == 0)
{
unmanagedBuffer[i].token = IntPtr.Zero;
}
else
{
pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned);
unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset);
buffers[i] = iBuffer.token;
}
}
// The result is written in the input Buffer passed as type=BufferType.Data.
int errorCode;
switch (op)
{
case OP.Encrypt:
errorCode = SecModule.EncryptMessage(context, sdcInOut, sequenceNumber);
break;
case OP.Decrypt:
errorCode = SecModule.DecryptMessage(context, sdcInOut, sequenceNumber);
break;
case OP.MakeSignature:
errorCode = SecModule.MakeSignature(context, sdcInOut, sequenceNumber);
break;
case OP.VerifySignature:
errorCode = SecModule.VerifySignature(context, sdcInOut, sequenceNumber);
break;
default: throw ExceptionHelper.MethodNotImplementedException;
}
// Marshalling back returned sizes / data.
for (int i = 0; i < input.Length; i++)
{
SecurityBuffer iBuffer = input[i];
iBuffer.size = unmanagedBuffer[i].count;
iBuffer.type = unmanagedBuffer[i].type;
if (iBuffer.size == 0)
{
iBuffer.offset = 0;
iBuffer.token = null;
}
else checked
{
// Find the buffer this is inside of. Usually they all point inside buffer 0.
int j;
for (j = 0; j < input.Length; j++)
{
if (buffers[j] == null)
{
continue;
}
byte* bufferAddress = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0);
if ((byte*) unmanagedBuffer[i].token >= bufferAddress &&
(byte*) unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length)
{
iBuffer.offset = (int) ((byte*) unmanagedBuffer[i].token - bufferAddress);
iBuffer.token = buffers[j];
break;
}
}
if (j >= input.Length)
{
GlobalLog.Assert("SSPIWrapper::EncryptDecryptHelper", "Output buffer out of range.");
iBuffer.size = 0;
iBuffer.offset = 0;
iBuffer.token = null;
}
}
// Backup validate the new sizes.
GlobalLog.Assert(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length), "SSPIWrapper::EncryptDecryptHelper|'offset' out of range. [{0}]", iBuffer.offset);
GlobalLog.Assert(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset), "SSPIWrapper::EncryptDecryptHelper|'size' out of range. [{0}]", iBuffer.size);
}
if (errorCode !=0)
if (Logging.On)
{
if (errorCode == 0x90321)
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_returned_something, op, "SEC_I_RENEGOTIATE"));
else
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, op, String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
}
return errorCode;
}
finally {
for (int i = 0; i < pinnedBuffers.Length; ++i) {
if (pinnedBuffers[i].IsAllocated) {
pinnedBuffers[i].Free();
}
}
}
}
}
public static object QueryContextAttributes(SSPIInterface SecModule, SafeDeleteContext securityContext, ContextAttribute contextAttribute) {
GlobalLog.Enter("QueryContextAttributes", contextAttribute.ToString());
int nativeBlockSize = IntPtr.Size;
Type handleType = null;
switch (contextAttribute) {
case ContextAttribute.Sizes:
nativeBlockSize = SecSizes.SizeOf;
break;
case ContextAttribute.StreamSizes:
nativeBlockSize = StreamSizes.SizeOf;
break;
case ContextAttribute.Names:
handleType = typeof(SafeFreeContextBuffer);
break;
case ContextAttribute.PackageInfo:
handleType = typeof(SafeFreeContextBuffer);
break;
case ContextAttribute.NegotiationInfo:
handleType = typeof(SafeFreeContextBuffer);
nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo));
break;
case ContextAttribute.RemoteCertificate:
handleType = typeof(SafeFreeCertContext);
break;
case ContextAttribute.LocalCertificate:
handleType = typeof(SafeFreeCertContext);
break;
case ContextAttribute.IssuerListInfoEx:
nativeBlockSize = Marshal.SizeOf(typeof(IssuerListInfoEx));
handleType = typeof(SafeFreeContextBuffer);
break;
case ContextAttribute.ConnectionInfo:
nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo));
break;
default:
throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "ContextAttribute"), "contextAttribute");
}
SafeHandle SspiHandle = null;
object attribute = null;
try {
byte[] nativeBuffer = new byte[nativeBlockSize];
int errorCode = SecModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out SspiHandle);
if (errorCode != 0) {
GlobalLog.Leave("Win32:QueryContextAttributes", "ERROR = " + ErrorDescription(errorCode));
return null;
}
switch (contextAttribute) {
case ContextAttribute.Sizes:
attribute = new SecSizes(nativeBuffer);
break;
case ContextAttribute.StreamSizes:
attribute = new StreamSizes(nativeBuffer);
break;
case ContextAttribute.Names:
if (ComNetOS.IsWin9x) {
attribute = Marshal.PtrToStringAnsi(SspiHandle.DangerousGetHandle());
}
else {
attribute = Marshal.PtrToStringUni(SspiHandle.DangerousGetHandle());
}
break;
case ContextAttribute.PackageInfo:
attribute = new SecurityPackageInfoClass(SspiHandle, 0);
break;
case ContextAttribute.NegotiationInfo:
unsafe {
fixed (void* ptr=nativeBuffer) {
attribute = new NegotiationInfoClass(SspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffest));
}
}
break;
case ContextAttribute.LocalCertificate:
goto case ContextAttribute.RemoteCertificate;
case ContextAttribute.RemoteCertificate:
attribute = SspiHandle;
SspiHandle = null;
break;
case ContextAttribute.IssuerListInfoEx:
attribute = new IssuerListInfoEx(SspiHandle, nativeBuffer);
SspiHandle = null;
break;
case ContextAttribute.ConnectionInfo:
attribute = new SslConnectionInfo(nativeBuffer);
break;
default:
// will return null
break;
}
}
finally {
if (SspiHandle != null) {
SspiHandle.Close();
}
}
GlobalLog.Leave("QueryContextAttributes", ValidationHelper.ToString(attribute));
return attribute;
}
public static string ErrorDescription(int errorCode) {
if (errorCode == -1) {
return "An exception when invoking Win32 API";
}
switch ((SecurityStatus)errorCode) {
case SecurityStatus.InvalidHandle:
return "Invalid handle";
case SecurityStatus.InvalidToken:
return "Invalid token";
case SecurityStatus.ContinueNeeded:
return "Continue needed";
case SecurityStatus.IncompleteMessage:
return "Message incomplete";
case SecurityStatus.WrongPrincipal:
return "Wrong principal";
case SecurityStatus.TargetUnknown:
return "Target unknown";
case SecurityStatus.PackageNotFound:
return "Package not found";
case SecurityStatus.BufferNotEnough:
return "Buffer not enough";
case SecurityStatus.MessageAltered:
return "Message altered";
case SecurityStatus.UntrustedRoot:
return "Untrusted root";
default:
return "0x"+errorCode.ToString("x", NumberFormatInfo.InvariantInfo);
}
}
} // class SSPIWrapper
[StructLayout(LayoutKind.Sequential)]
internal class StreamSizes {
public int header;
public int trailer;
public int maximumMessage;
public int buffersCount;
public int blockSize;
internal unsafe StreamSizes(byte[] memory) {
fixed(void* voidPtr = memory) {
IntPtr unmanagedAddress = new IntPtr(voidPtr);
try
{
header = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress));
trailer = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 4));
maximumMessage = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 8));
buffersCount = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 12));
blockSize = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 16));
}
catch (OverflowException)
{
GlobalLog.Assert(false, "StreamSizes::.ctor", "Negative size.");
throw;
}
}
}
public static readonly int SizeOf = Marshal.SizeOf(typeof(StreamSizes));
}
[StructLayout(LayoutKind.Sequential)]
internal class SecSizes {
public readonly int MaxToken;
public readonly int MaxSignature;
public readonly int BlockSize;
public readonly int SecurityTrailer;
internal unsafe SecSizes(byte[] memory) {
fixed(void* voidPtr = memory) {
IntPtr unmanagedAddress = new IntPtr(voidPtr);
try
{
MaxToken = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress));
MaxSignature = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 4));
BlockSize = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 8));
SecurityTrailer = (int) checked((uint) Marshal.ReadInt32(unmanagedAddress, 12));
}
catch (OverflowException)
{
GlobalLog.Assert(false, "SecSizes::.ctor", "Negative size.");
throw;
}
}
}
public static readonly int SizeOf = Marshal.SizeOf(typeof(SecSizes));
}
//From Schannel.h
internal enum SchProtocols {
Zero = 0,
PctClient = 0x00000002,
PctServer = 0x00000001,
Pct = (PctClient | PctServer),
Ssl2Client = 0x00000008,
Ssl2Server = 0x00000004,
Ssl2 = (Ssl2Client | Ssl2Server),
Ssl3Client = 0x00000020,
Ssl3Server = 0x00000010,
Ssl3 = (Ssl3Client | Ssl3Server),
TlsClient = 0x00000080,
TlsServer = 0x00000040,
Tls = (TlsClient | TlsServer),
Ssl3Tls = (Ssl3 | Tls),
UniClient = unchecked((int)0x80000000),
UniServer = 0x40000000,
Unified = (UniClient | UniServer),
ClientMask = (PctClient | Ssl2Client | Ssl3Client | TlsClient |UniClient),
ServerMask = (PctServer | Ssl2Server | Ssl3Server | TlsServer |UniServer)
};
//From WinCrypt.h
[Flags]
internal enum Alg {
Any = 0,
ClassSignture = (1 << 13),
ClassEncrypt = (3 << 13),
ClassHash = (4 << 13),
ClassKeyXch = (5 << 13),
TypeRSA = (2 << 9),
TypeBlock = (3 << 9),
TypeStream = (4 << 9),
TypeDH = (5 << 9),
NameDES = 1,
NameRC2 = 2,
Name3DES = 3,
NameAES_128 = 14,
NameAES_192 = 15,
NameAES_256 = 16,
NameAES = 17,
NameRC4 = 1,
NameMD5 = 3,
NameSHA = 4,
NameDH_Ephem = 2,
}
//From Schannel.h
[StructLayout(LayoutKind.Sequential)]
internal class SslConnectionInfo {
public readonly int Protocol;
public readonly int DataCipherAlg;
public readonly int DataKeySize;
public readonly int DataHashAlg;
public readonly int DataHashKeySize;
public readonly int KeyExchangeAlg;
public readonly int KeyExchKeySize;
internal unsafe SslConnectionInfo(byte[] nativeBuffer) {
fixed(void* voidPtr = nativeBuffer) {
IntPtr unmanagedAddress = new IntPtr(voidPtr);
Protocol = Marshal.ReadInt32(unmanagedAddress);
DataCipherAlg = Marshal.ReadInt32(unmanagedAddress, 4);
DataKeySize = Marshal.ReadInt32(unmanagedAddress, 8);
DataHashAlg = Marshal.ReadInt32(unmanagedAddress, 12);
DataHashKeySize = Marshal.ReadInt32(unmanagedAddress, 16);
KeyExchangeAlg = Marshal.ReadInt32(unmanagedAddress, 20);
KeyExchKeySize = Marshal.ReadInt32(unmanagedAddress, 24);
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct NegotiationInfo {
// see SecPkgContext_NegotiationInfoW in
// [MarshalAs(UnmanagedType.LPStruct)] internal SecurityPackageInfo PackageInfo;
internal IntPtr PackageInfo;
internal uint NegotiationState;
internal static readonly int Size = Marshal.SizeOf(typeof(NegotiationInfo));
internal static readonly int NegotiationStateOffest = (int)Marshal.OffsetOf(typeof(NegotiationInfo), "NegotiationState");
}
// we keep it simple since we use this only to know if NTLM or
// Kerberos are used in the context of a Negotiate handshake
internal class NegotiationInfoClass {
internal const string NTLM = "NTLM";
internal const string Kerberos = "Kerberos";
internal const string WDigest = "WDigest";
internal const string Negotiate = "Negotiate";
internal string AuthenticationPackage;
internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState) {
if (safeHandle.IsInvalid) {
GlobalLog.Print("NegotiationInfoClass::.ctor() the handle is invalid:" + (safeHandle.DangerousGetHandle()).ToString("x"));
return;
}
IntPtr packageInfo = safeHandle.DangerousGetHandle();
GlobalLog.Print("NegotiationInfoClass::.ctor() packageInfo:" + packageInfo.ToString("x8") + " negotiationState:" + negotiationState.ToString("x8"));
const int SECPKG_NEGOTIATION_COMPLETE = 0;
const int SECPKG_NEGOTIATION_OPTIMISTIC = 1;
// const int SECPKG_NEGOTIATION_IN_PROGRESS = 2;
// const int SECPKG_NEGOTIATION_DIRECT = 3;
// const int SECPKG_NEGOTIATION_TRY_MULTICRED = 4;
if (negotiationState==SECPKG_NEGOTIATION_COMPLETE || negotiationState==SECPKG_NEGOTIATION_OPTIMISTIC) {
IntPtr unmanagedString = Marshal.ReadIntPtr(packageInfo, SecurityPackageInfo.NameOffest);
string name = null;
if (unmanagedString!=IntPtr.Zero) {
name = ComNetOS.IsWin9x ? Marshal.PtrToStringAnsi(unmanagedString) : Marshal.PtrToStringUni(unmanagedString);
}
GlobalLog.Print("NegotiationInfoClass::.ctor() packageInfo:" + packageInfo.ToString("x8") + " negotiationState:" + negotiationState.ToString("x8") + " name:" + ValidationHelper.ToString(name));
// an optimization for future string comparisons
if (string.Compare(name, Kerberos, StringComparison.OrdinalIgnoreCase)==0) {
AuthenticationPackage = Kerberos;
}
else if (string.Compare(name, NTLM, StringComparison.OrdinalIgnoreCase)==0) {
AuthenticationPackage = NTLM;
}
else if (string.Compare(name, WDigest, StringComparison.OrdinalIgnoreCase)==0) {
AuthenticationPackage = WDigest;
}
else {
AuthenticationPackage = name;
}
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct SecurityPackageInfo {
// see SecPkgInfoW in
internal int Capabilities;
internal short Version;
internal short RPCID;
internal int MaxToken;
internal IntPtr Name;
internal IntPtr Comment;
internal static readonly int Size = Marshal.SizeOf(typeof(SecurityPackageInfo));
internal static readonly int NameOffest = (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name");
}
internal class SecurityPackageInfoClass {
internal int Capabilities = 0;
internal short Version = 0;
internal short RPCID = 0;
internal int MaxToken = 0;
internal string Name = null;
internal string Comment = null;
/*
* This is to support SSL under semi trusted enviornment.
* Note that it is only for SSL with no client cert
*/
internal SecurityPackageInfoClass(SafeHandle safeHandle, int index) {
if (safeHandle.IsInvalid) {
GlobalLog.Print("SecurityPackageInfoClass::.ctor() the pointer is invalid: " + (safeHandle.DangerousGetHandle()).ToString("x"));
return;
}
IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index);
GlobalLog.Print("SecurityPackageInfoClass::.ctor() unmanagedPointer: " + ((long)unmanagedAddress).ToString("x"));
Capabilities = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"Capabilities"));
Version = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"Version"));
RPCID = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"RPCID"));
MaxToken = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"MaxToken"));
IntPtr unmanagedString;
unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"Name"));
if (unmanagedString != IntPtr.Zero) {
if (ComNetOS.IsWin9x) {
Name = Marshal.PtrToStringAnsi(unmanagedString);
}
else {
Name = Marshal.PtrToStringUni(unmanagedString);
}
GlobalLog.Print("Name: " + Name);
}
unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo),"Comment"));
if (unmanagedString != IntPtr.Zero) {
if (ComNetOS.IsWin9x) {
Comment = Marshal.PtrToStringAnsi(unmanagedString);
}
else {
Comment = Marshal.PtrToStringUni(unmanagedString);
}
GlobalLog.Print("Comment: " + Comment);
}
GlobalLog.Print("SecurityPackageInfoClass::.ctor(): " + ToString());
}
public override string ToString() {
return "Capabilities:" + String.Format(CultureInfo.InvariantCulture, "0x{0:x}", Capabilities)
+ " Version:" + Version.ToString(NumberFormatInfo.InvariantInfo)
+ " RPCID:" + RPCID.ToString(NumberFormatInfo.InvariantInfo)
+ " MaxToken:" + MaxToken.ToString(NumberFormatInfo.InvariantInfo)
+ " Name:" + ((Name==null)?"(null)":Name)
+ " Comment:" + ((Comment==null)?"(null)":Comment
);
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PresentationTraceSources.cs
- BatchParser.cs
- OptionalRstParameters.cs
- DbProviderFactory.cs
- MissingSatelliteAssemblyException.cs
- ReflectionUtil.cs
- DefaultSection.cs
- XmlSchemaComplexContent.cs
- DateTimeFormatInfo.cs
- ToolConsole.cs
- LayoutTable.cs
- ErrorStyle.cs
- securitycriticaldata.cs
- SourceLocationProvider.cs
- PopupControlService.cs
- MailWriter.cs
- StoreItemCollection.Loader.cs
- ReadOnlyTernaryTree.cs
- TextBoxAutoCompleteSourceConverter.cs
- WebControlAdapter.cs
- CheckBoxStandardAdapter.cs
- AuthenticateEventArgs.cs
- IgnoreFlushAndCloseStream.cs
- StringPropertyBuilder.cs
- EntitySetBase.cs
- ComponentDispatcher.cs
- ReliableDuplexSessionChannel.cs
- ActiveXContainer.cs
- GroupBox.cs
- UncommonField.cs
- RelationshipNavigation.cs
- EqualityComparer.cs
- ConfigurationFileMap.cs
- DecimalKeyFrameCollection.cs
- SerializationException.cs
- ActivatableWorkflowsQueryResult.cs
- Symbol.cs
- IsolatedStorageSecurityState.cs
- XamlClipboardData.cs
- CodeGotoStatement.cs
- SortDescriptionCollection.cs
- PlaceHolder.cs
- ConfigurationFileMap.cs
- SqlServices.cs
- ImportException.cs
- XsltException.cs
- ToolBarTray.cs
- EntityDataReader.cs
- DnsCache.cs
- UserControlBuildProvider.cs
- ViewCellSlot.cs
- OleDbConnection.cs
- MemoryMappedView.cs
- RequestNavigateEventArgs.cs
- HtmlElement.cs
- ExpressionTable.cs
- DataServiceRequest.cs
- SimpleColumnProvider.cs
- CodeDOMProvider.cs
- CAGDesigner.cs
- FunctionNode.cs
- CursorInteropHelper.cs
- DataList.cs
- IntranetCredentialPolicy.cs
- URIFormatException.cs
- DefaultPrintController.cs
- LinkButton.cs
- SecurityAppliedMessage.cs
- HandlerWithFactory.cs
- Error.cs
- ProgressBarAutomationPeer.cs
- FunctionOverloadResolver.cs
- DesignerActionGlyph.cs
- ButtonChrome.cs
- PathGeometry.cs
- ShutDownListener.cs
- GatewayIPAddressInformationCollection.cs
- XmlAutoDetectWriter.cs
- ImpersonateTokenRef.cs
- ReachSerializationCacheItems.cs
- DataListItem.cs
- Membership.cs
- DeadCharTextComposition.cs
- ApplicationCommands.cs
- FormsIdentity.cs
- FrameworkElementAutomationPeer.cs
- TabControlEvent.cs
- ValidationException.cs
- GridItemProviderWrapper.cs
- QilLoop.cs
- WpfPayload.cs
- GroupAggregateExpr.cs
- SimpleParser.cs
- XsltQilFactory.cs
- XmlEnumAttribute.cs
- HtmlForm.cs
- LOSFormatter.cs
- AutoSizeComboBox.cs
- HealthMonitoringSection.cs
- Query.cs