diff options
Diffstat (limited to 'vendor/github.com/quasoft/websspi/win32_windows.go')
-rw-r--r-- | vendor/github.com/quasoft/websspi/win32_windows.go | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/vendor/github.com/quasoft/websspi/win32_windows.go b/vendor/github.com/quasoft/websspi/win32_windows.go new file mode 100644 index 0000000000..7359a0909a --- /dev/null +++ b/vendor/github.com/quasoft/websspi/win32_windows.go @@ -0,0 +1,312 @@ +package websspi + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +// secur32.dll + +type SECURITY_STATUS syscall.Errno + +const ( + SEC_E_OK = SECURITY_STATUS(0) + + SEC_E_INCOMPLETE_MESSAGE = SECURITY_STATUS(0x80090318) + SEC_E_INSUFFICIENT_MEMORY = SECURITY_STATUS(0x80090300) + SEC_E_INTERNAL_ERROR = SECURITY_STATUS(0x80090304) + SEC_E_INVALID_HANDLE = SECURITY_STATUS(0x80090301) + SEC_E_INVALID_TOKEN = SECURITY_STATUS(0x80090308) + SEC_E_LOGON_DENIED = SECURITY_STATUS(0x8009030C) + SEC_E_NO_AUTHENTICATING_AUTHORITY = SECURITY_STATUS(0x80090311) + SEC_E_NO_CREDENTIALS = SECURITY_STATUS(0x8009030E) + SEC_E_UNSUPPORTED_FUNCTION = SECURITY_STATUS(0x80090302) + SEC_I_COMPLETE_AND_CONTINUE = SECURITY_STATUS(0x00090314) + SEC_I_COMPLETE_NEEDED = SECURITY_STATUS(0x00090313) + SEC_I_CONTINUE_NEEDED = SECURITY_STATUS(0x00090312) + SEC_E_NOT_OWNER = SECURITY_STATUS(0x80090306) + SEC_E_SECPKG_NOT_FOUND = SECURITY_STATUS(0x80090305) + SEC_E_UNKNOWN_CREDENTIALS = SECURITY_STATUS(0x8009030D) + + NEGOSSP_NAME = "Negotiate" + SECPKG_CRED_INBOUND = 1 + SECURITY_NATIVE_DREP = 16 + + ASC_REQ_DELEGATE = 1 + ASC_REQ_MUTUAL_AUTH = 2 + ASC_REQ_REPLAY_DETECT = 4 + ASC_REQ_SEQUENCE_DETECT = 8 + ASC_REQ_CONFIDENTIALITY = 16 + ASC_REQ_USE_SESSION_KEY = 32 + ASC_REQ_ALLOCATE_MEMORY = 256 + ASC_REQ_USE_DCE_STYLE = 512 + ASC_REQ_DATAGRAM = 1024 + ASC_REQ_CONNECTION = 2048 + ASC_REQ_EXTENDED_ERROR = 32768 + ASC_REQ_STREAM = 65536 + ASC_REQ_INTEGRITY = 131072 + + SECPKG_ATTR_SIZES = 0 + SECPKG_ATTR_NAMES = 1 + SECPKG_ATTR_LIFESPAN = 2 + SECPKG_ATTR_DCE_INFO = 3 + SECPKG_ATTR_STREAM_SIZES = 4 + SECPKG_ATTR_KEY_INFO = 5 + SECPKG_ATTR_AUTHORITY = 6 + SECPKG_ATTR_PROTO_INFO = 7 + SECPKG_ATTR_PASSWORD_EXPIRY = 8 + SECPKG_ATTR_SESSION_KEY = 9 + SECPKG_ATTR_PACKAGE_INFO = 10 + SECPKG_ATTR_USER_FLAGS = 11 + SECPKG_ATTR_NEGOTIATION_INFO = 12 + SECPKG_ATTR_NATIVE_NAMES = 13 + SECPKG_ATTR_FLAGS = 14 + + SECBUFFER_VERSION = 0 + SECBUFFER_TOKEN = 2 +) + +type CredHandle struct { + Lower uintptr + Upper uintptr +} + +type CtxtHandle struct { + Lower uintptr + Upper uintptr +} + +type SecBuffer struct { + BufferSize uint32 + BufferType uint32 + Buffer *byte +} + +type SecBufferDesc struct { + Version uint32 + BuffersCount uint32 + Buffers *SecBuffer +} + +type LUID struct { + LowPart uint32 + HighPart int32 +} + +type SecPkgContext_Names struct { + UserName *uint16 +} + +type SecPkgContext_Flags struct { + Flags uint32 +} + +// netapi32.dll + +const ( + NERR_Success = 0x0 + NERR_InternalError = 0x85C + NERR_UserNotFound = 0x8AD + + ERROR_ACCESS_DENIED = 0x5 + ERROR_BAD_NETPATH = 0x35 + ERROR_INVALID_LEVEL = 0x7C + ERROR_INVALID_NAME = 0x7B + ERROR_MORE_DATA = 0xEA + ERROR_NOT_ENOUGH_MEMORY = 0x8 + + MAX_PREFERRED_LENGTH = 0xFFFFFFFF + MAX_GROUP_NAME_LENGTH = 256 + + SE_GROUP_MANDATORY = 0x1 + SE_GROUP_ENABLED_BY_DEFAULT = 0x2 + SE_GROUP_ENABLED = 0x4 + SE_GROUP_OWNER = 0x8 + SE_GROUP_USE_FOR_DENY_ONLY = 0x10 + SE_GROUP_INTEGRITY = 0x20 + SE_GROUP_INTEGRITY_ENABLED = 0x40 + SE_GROUP_LOGON_ID = 0xC0000000 + SE_GROUP_RESOURCE = 0x20000000 +) + +type GroupUsersInfo0 struct { + Grui0_name *uint16 +} + +type GroupUsersInfo1 struct { + Grui1_name *uint16 + Grui1_attributes uint32 +} + +// The API interface describes the Win32 functions used in this package and +// its primary purpose is to allow replacing them with stub functions in unit tests. +type API interface { + AcquireCredentialsHandle( + principal *uint16, + _package *uint16, + credentialUse uint32, + logonID *LUID, + authData *byte, + getKeyFn uintptr, + getKeyArgument uintptr, + credHandle *CredHandle, + expiry *syscall.Filetime, + ) SECURITY_STATUS + AcceptSecurityContext( + credential *CredHandle, + context *CtxtHandle, + input *SecBufferDesc, + contextReq uint32, + targDataRep uint32, + newContext *CtxtHandle, + output *SecBufferDesc, + contextAttr *uint32, + expiry *syscall.Filetime, + ) SECURITY_STATUS + QueryContextAttributes(context *CtxtHandle, attribute uint32, buffer *byte) SECURITY_STATUS + DeleteSecurityContext(context *CtxtHandle) SECURITY_STATUS + FreeContextBuffer(buffer *byte) SECURITY_STATUS + FreeCredentialsHandle(handle *CredHandle) SECURITY_STATUS + NetUserGetGroups( + serverName *uint16, + userName *uint16, + level uint32, + buf **byte, + prefmaxlen uint32, + entriesread *uint32, + totalentries *uint32, + ) (neterr error) + NetApiBufferFree(buf *byte) (neterr error) +} + +// Win32 implements the API interface by calling the relevant system functions +// from secur32.dll and netapi32.dll +type Win32 struct{} + +var ( + secur32dll = windows.NewLazySystemDLL("secur32.dll") + netapi32dll = windows.NewLazySystemDLL("netapi32.dll") + + procAcquireCredentialsHandleW = secur32dll.NewProc("AcquireCredentialsHandleW") + procAcceptSecurityContext = secur32dll.NewProc("AcceptSecurityContext") + procQueryContextAttributesW = secur32dll.NewProc("QueryContextAttributesW") + procDeleteSecurityContext = secur32dll.NewProc("DeleteSecurityContext") + procFreeContextBuffer = secur32dll.NewProc("FreeContextBuffer") + procFreeCredentialsHandle = secur32dll.NewProc("FreeCredentialsHandle") + procNetUserGetGroups = netapi32dll.NewProc("NetUserGetGroups") +) + +func (w *Win32) AcquireCredentialsHandle( + principal *uint16, + _package *uint16, + credentialUse uint32, + logonId *LUID, + authData *byte, + getKeyFn uintptr, + getKeyArgument uintptr, + credHandle *CredHandle, + expiry *syscall.Filetime, +) SECURITY_STATUS { + r1, _, _ := syscall.Syscall9( + procAcquireCredentialsHandleW.Addr(), 9, + uintptr(unsafe.Pointer(principal)), + uintptr(unsafe.Pointer(_package)), + uintptr(credentialUse), + uintptr(unsafe.Pointer(logonId)), + uintptr(unsafe.Pointer(authData)), + uintptr(getKeyFn), + uintptr(getKeyArgument), + uintptr(unsafe.Pointer(credHandle)), + uintptr(unsafe.Pointer(expiry)), + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) AcceptSecurityContext( + credential *CredHandle, + context *CtxtHandle, + input *SecBufferDesc, + contextReq uint32, + targDataRep uint32, + newContext *CtxtHandle, + output *SecBufferDesc, + contextAttr *uint32, + expiry *syscall.Filetime, +) SECURITY_STATUS { + r1, _, _ := syscall.Syscall9( + procAcceptSecurityContext.Addr(), 9, + uintptr(unsafe.Pointer(credential)), + uintptr(unsafe.Pointer(context)), + uintptr(unsafe.Pointer(input)), + uintptr(contextReq), + uintptr(targDataRep), + uintptr(unsafe.Pointer(newContext)), + uintptr(unsafe.Pointer(output)), + uintptr(unsafe.Pointer(contextAttr)), + uintptr(unsafe.Pointer(expiry)), + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) QueryContextAttributes( + context *CtxtHandle, + attribute uint32, + buffer *byte, +) SECURITY_STATUS { + r1, _, _ := syscall.Syscall( + procQueryContextAttributesW.Addr(), 3, + uintptr(unsafe.Pointer(context)), + uintptr(attribute), + uintptr(unsafe.Pointer(buffer)), + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) DeleteSecurityContext(context *CtxtHandle) SECURITY_STATUS { + r1, _, _ := syscall.Syscall( + procDeleteSecurityContext.Addr(), 1, + uintptr(unsafe.Pointer(context)), + 0, 0, + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) FreeContextBuffer(buffer *byte) SECURITY_STATUS { + r1, _, _ := syscall.Syscall( + procFreeContextBuffer.Addr(), 1, + uintptr(unsafe.Pointer(buffer)), + 0, 0, + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) FreeCredentialsHandle(handle *CredHandle) SECURITY_STATUS { + r1, _, _ := syscall.Syscall( + procFreeCredentialsHandle.Addr(), 1, + uintptr(unsafe.Pointer(handle)), + 0, 0, + ) + return SECURITY_STATUS(r1) +} + +func (w *Win32) NetUserGetGroups( + serverName *uint16, + userName *uint16, + level uint32, + buf **byte, + prefmaxlen uint32, + entriesread *uint32, + totalentries *uint32, +) (neterr error) { + r0, _, _ := syscall.Syscall9(procNetUserGetGroups.Addr(), 7, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(prefmaxlen), uintptr(unsafe.Pointer(entriesread)), uintptr(unsafe.Pointer(totalentries)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) + } + return +} + +func (w *Win32) NetApiBufferFree(buf *byte) (neterr error) { + return syscall.NetApiBufferFree(buf) +} |