Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
312 lines
8.2 KiB
312 lines
8.2 KiB
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) |
|
}
|
|
|