From 87692b3cc6b9c954cc96ce9c67b9ba48b1928436 Mon Sep 17 00:00:00 2001 From: antiduh Date: Wed, 18 Jun 2014 21:26:43 +0000 Subject: [PATCH] New project to interface with the Microsoft Windows SSPI integration authentication API. --- Credential.cs | 70 ++++++++++++++++++++++++++++++++++++++ CredentialPackage.cs | 15 ++++++++ CredentialType.cs | 14 ++++++++ NSspi.csproj | 53 +++++++++++++++++++++++++++++ NSspi.sln | 20 +++++++++++ NativeMethods.cs | 51 +++++++++++++++++++++++++++ PackageNames.cs | 17 +++++++++ Properties/AssemblyInfo.cs | 36 ++++++++++++++++++++ SSPIException.cs | 53 +++++++++++++++++++++++++++++ 9 files changed, 329 insertions(+) create mode 100644 Credential.cs create mode 100644 CredentialPackage.cs create mode 100644 CredentialType.cs create mode 100644 NSspi.csproj create mode 100644 NSspi.sln create mode 100644 NativeMethods.cs create mode 100644 PackageNames.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 SSPIException.cs diff --git a/Credential.cs b/Credential.cs new file mode 100644 index 0000000..d089b72 --- /dev/null +++ b/Credential.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + public class Credential : IDisposable + { + private bool disposed; + + private SecurityPackage securityPackage; + + public Credential(SecurityPackage package, CredentialType credentialType) + { + this.disposed = false; + + Init(); + } + + ~Credential() + { + Dispose( false ); + } + + public SecurityPackage SecurityPackage + { + get + { + if( this.disposed ) + { + throw new ObjectDisposedException( base.GetType().Name ); + } + + return this.securityPackage; + } + } + + public string GetName() + { + return null; + } + + // TODO use safe handle ... + public IntPtr CredentialHandle + { + get + { + return IntPtr.Zero; + } + } + + public void Dispose() + { + Dispose( true ); + GC.SuppressFinalize( this ); + } + + protected virtual void Dispose( bool disposing ) + { + this.disposed = true; + } + + private void Init() + { + } + + } +} diff --git a/CredentialPackage.cs b/CredentialPackage.cs new file mode 100644 index 0000000..a309d7a --- /dev/null +++ b/CredentialPackage.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + public enum SecurityPackage + { + Negotiate = 0, + Kerberos = 1, + NTLM = 2 + } +} diff --git a/CredentialType.cs b/CredentialType.cs new file mode 100644 index 0000000..e4961e2 --- /dev/null +++ b/CredentialType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + public enum CredentialType + { + Client = 0, + Server = 1 + } +} diff --git a/NSspi.csproj b/NSspi.csproj new file mode 100644 index 0000000..8a4d938 --- /dev/null +++ b/NSspi.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {4B4CD933-BF62-4F92-B8FA-6771758C5197} + Library + Properties + NSspi + NSspi + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NSspi.sln b/NSspi.sln new file mode 100644 index 0000000..aeaff87 --- /dev/null +++ b/NSspi.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NSspi", "NSspi.csproj", "{4B4CD933-BF62-4F92-B8FA-6771758C5197}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B4CD933-BF62-4F92-B8FA-6771758C5197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B4CD933-BF62-4F92-B8FA-6771758C5197}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B4CD933-BF62-4F92-B8FA-6771758C5197}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B4CD933-BF62-4F92-B8FA-6771758C5197}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/NativeMethods.cs b/NativeMethods.cs new file mode 100644 index 0000000..8678072 --- /dev/null +++ b/NativeMethods.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + public class NativeMethods + { + /* + SECURITY_STATUS sResult = AcquireCredentialsHandle( + NULL, // [in] name of principal. NULL = principal of current security context + pszPackageName, // [in] name of package + fCredentialUse, // [in] flags indicating use. + NULL, // [in] pointer to logon identifier. NULL = we're not specifying the id of another logon session + NULL, // [in] package-specific data. NULL = default credentials for security package + NULL, // [in] pointer to GetKey function. NULL = we're not using a callback to retrieve the credentials + NULL, // [in] value to pass to GetKey + this->credentialHandle, // [out] credential handle (this must be already allocated) + &tsExpiry // [out] lifetime of the returned credentials + ); + + SECURITY_STATUS SEC_Entry AcquireCredentialsHandle( + _In_ SEC_CHAR *pszPrincipal, + _In_ SEC_CHAR *pszPackage, + _In_ ULONG fCredentialUse, + _In_ PLUID pvLogonID, + _In_ PVOID pAuthData, + _In_ SEC_GET_KEY_FN pGetKeyFn, + _In_ PVOID pvGetKeyArgument, + _Out_ PCredHandle phCredential, + _Out_ PTimeStamp ptsExpiry + ); + */ + + [DllImport( "Secur32.dll", CallingConvention = CallingConvention.Winapi, SetLastError=false)] + public extern int AcquireCredentialHandle( + string principleName, + string packageName, + int credentialUse, + IntPtr loginId, + IntPtr packageData, + IntPtr getKeyFunc, + IntPtr getKeyData, + IntPtr credentialHandle, + long expiry + ); + } +} diff --git a/PackageNames.cs b/PackageNames.cs new file mode 100644 index 0000000..1b0eee9 --- /dev/null +++ b/PackageNames.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + public static sealed class PackageNames + { + public const string Negotiate = "Negotiate"; + + public const string Kerberos = "Kerberos"; + + public const string Ntlm = "NTLM"; + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a326160 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("NSspi")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Kevin Thompson")] +[assembly: AssemblyProduct("NSspi")] +[assembly: AssemblyCopyright("Copyright © Kevin Thompson 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9abf710c-c646-42aa-8183-76bfa141a07b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SSPIException.cs b/SSPIException.cs new file mode 100644 index 0000000..21bbd9e --- /dev/null +++ b/SSPIException.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi +{ + [Serializable] + public class SSPIException : Exception + { + private int errorCode; + private string message; + + public SSPIException( SerializationInfo info, StreamingContext context ) + : base( info, context ) + { + this.message = info.GetString( "messsage" ); + this.errorCode = info.GetInt32( "errorCode" ); + } + + public SSPIException( string message, int errorCode ) + { + this.message = message; + this.errorCode = errorCode; + } + + public override void GetObjectData( SerializationInfo info, StreamingContext context ) + { + base.GetObjectData( info, context ); + + info.AddValue( "message", this.message ); + info.AddValue( "errorCode", this.errorCode ); + } + + public int ErrorCode + { + get + { + return this.errorCode; + } + } + + public override string Message + { + get + { + return string.Format( "{0}. Error Code = '{1:X}'.", this.message, this.errorCode ); + } + } + } +}