/* Copyright (C) 2014 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, * either version 3 of the License, or (at your option) any later version. */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; namespace SMBLibrary.Authentication.Win32 { public enum SecBufferType { SECBUFFER_VERSION = 0, SECBUFFER_EMPTY = 0, SECBUFFER_DATA = 1, SECBUFFER_TOKEN = 2 } [StructLayout(LayoutKind.Sequential)] public struct SecBuffer { public int cbBuffer; public int BufferType; public IntPtr pvBuffer; public SecBuffer(int bufferSize) { cbBuffer = bufferSize; BufferType = (int)SecBufferType.SECBUFFER_TOKEN; pvBuffer = Marshal.AllocHGlobal(bufferSize); } public SecBuffer(byte[] secBufferBytes) { cbBuffer = secBufferBytes.Length; BufferType = (int)SecBufferType.SECBUFFER_TOKEN; pvBuffer = Marshal.AllocHGlobal(cbBuffer); Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); } public SecBuffer(byte[] secBufferBytes, SecBufferType bufferType) { cbBuffer = secBufferBytes.Length; BufferType = (int)bufferType; pvBuffer = Marshal.AllocHGlobal(cbBuffer); Marshal.Copy(secBufferBytes, 0, pvBuffer, cbBuffer); } public void Dispose() { if (pvBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pvBuffer); pvBuffer = IntPtr.Zero; } } public byte[] GetBytes() { byte[] buffer = null; if (cbBuffer > 0) { buffer = new byte[cbBuffer]; Marshal.Copy(pvBuffer, buffer, 0, cbBuffer); } return buffer; } } /// /// Simplified SecBufferDesc struct with only one SecBuffer /// [StructLayout(LayoutKind.Sequential)] public struct SecBufferDesc { public int ulVersion; public int cBuffers; public IntPtr pBuffers; public SecBufferDesc(int bufferSize) { ulVersion = (int)SecBufferType.SECBUFFER_VERSION; cBuffers = 1; SecBuffer secBuffer = new SecBuffer(bufferSize); pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(secBuffer)); Marshal.StructureToPtr(secBuffer, pBuffers, false); } public SecBufferDesc(byte[] secBufferBytes) { ulVersion = (int)SecBufferType.SECBUFFER_VERSION; cBuffers = 1; SecBuffer secBuffer = new SecBuffer(secBufferBytes); pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(secBuffer)); Marshal.StructureToPtr(secBuffer, pBuffers, false); } public void Dispose() { if (pBuffers != IntPtr.Zero) { SecBuffer secBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer)); secBuffer.Dispose(); Marshal.FreeHGlobal(pBuffers); pBuffers = IntPtr.Zero; } } public byte[] GetSecBufferBytes() { if (pBuffers == IntPtr.Zero) throw new ObjectDisposedException("SecBufferDesc"); SecBuffer secBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers, typeof(SecBuffer)); return secBuffer.GetBytes(); } } }