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.

win32_windows.go 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. package websspi
  2. import (
  3. "syscall"
  4. "unsafe"
  5. "golang.org/x/sys/windows"
  6. )
  7. // secur32.dll
  8. type SECURITY_STATUS syscall.Errno
  9. const (
  10. SEC_E_OK = SECURITY_STATUS(0)
  11. SEC_E_INCOMPLETE_MESSAGE = SECURITY_STATUS(0x80090318)
  12. SEC_E_INSUFFICIENT_MEMORY = SECURITY_STATUS(0x80090300)
  13. SEC_E_INTERNAL_ERROR = SECURITY_STATUS(0x80090304)
  14. SEC_E_INVALID_HANDLE = SECURITY_STATUS(0x80090301)
  15. SEC_E_INVALID_TOKEN = SECURITY_STATUS(0x80090308)
  16. SEC_E_LOGON_DENIED = SECURITY_STATUS(0x8009030C)
  17. SEC_E_NO_AUTHENTICATING_AUTHORITY = SECURITY_STATUS(0x80090311)
  18. SEC_E_NO_CREDENTIALS = SECURITY_STATUS(0x8009030E)
  19. SEC_E_UNSUPPORTED_FUNCTION = SECURITY_STATUS(0x80090302)
  20. SEC_I_COMPLETE_AND_CONTINUE = SECURITY_STATUS(0x00090314)
  21. SEC_I_COMPLETE_NEEDED = SECURITY_STATUS(0x00090313)
  22. SEC_I_CONTINUE_NEEDED = SECURITY_STATUS(0x00090312)
  23. SEC_E_NOT_OWNER = SECURITY_STATUS(0x80090306)
  24. SEC_E_SECPKG_NOT_FOUND = SECURITY_STATUS(0x80090305)
  25. SEC_E_UNKNOWN_CREDENTIALS = SECURITY_STATUS(0x8009030D)
  26. NEGOSSP_NAME = "Negotiate"
  27. SECPKG_CRED_INBOUND = 1
  28. SECURITY_NATIVE_DREP = 16
  29. ASC_REQ_DELEGATE = 1
  30. ASC_REQ_MUTUAL_AUTH = 2
  31. ASC_REQ_REPLAY_DETECT = 4
  32. ASC_REQ_SEQUENCE_DETECT = 8
  33. ASC_REQ_CONFIDENTIALITY = 16
  34. ASC_REQ_USE_SESSION_KEY = 32
  35. ASC_REQ_ALLOCATE_MEMORY = 256
  36. ASC_REQ_USE_DCE_STYLE = 512
  37. ASC_REQ_DATAGRAM = 1024
  38. ASC_REQ_CONNECTION = 2048
  39. ASC_REQ_EXTENDED_ERROR = 32768
  40. ASC_REQ_STREAM = 65536
  41. ASC_REQ_INTEGRITY = 131072
  42. SECPKG_ATTR_SIZES = 0
  43. SECPKG_ATTR_NAMES = 1
  44. SECPKG_ATTR_LIFESPAN = 2
  45. SECPKG_ATTR_DCE_INFO = 3
  46. SECPKG_ATTR_STREAM_SIZES = 4
  47. SECPKG_ATTR_KEY_INFO = 5
  48. SECPKG_ATTR_AUTHORITY = 6
  49. SECPKG_ATTR_PROTO_INFO = 7
  50. SECPKG_ATTR_PASSWORD_EXPIRY = 8
  51. SECPKG_ATTR_SESSION_KEY = 9
  52. SECPKG_ATTR_PACKAGE_INFO = 10
  53. SECPKG_ATTR_USER_FLAGS = 11
  54. SECPKG_ATTR_NEGOTIATION_INFO = 12
  55. SECPKG_ATTR_NATIVE_NAMES = 13
  56. SECPKG_ATTR_FLAGS = 14
  57. SECBUFFER_VERSION = 0
  58. SECBUFFER_TOKEN = 2
  59. )
  60. type CredHandle struct {
  61. Lower uintptr
  62. Upper uintptr
  63. }
  64. type CtxtHandle struct {
  65. Lower uintptr
  66. Upper uintptr
  67. }
  68. type SecBuffer struct {
  69. BufferSize uint32
  70. BufferType uint32
  71. Buffer *byte
  72. }
  73. type SecBufferDesc struct {
  74. Version uint32
  75. BuffersCount uint32
  76. Buffers *SecBuffer
  77. }
  78. type LUID struct {
  79. LowPart uint32
  80. HighPart int32
  81. }
  82. type SecPkgContext_Names struct {
  83. UserName *uint16
  84. }
  85. type SecPkgContext_Flags struct {
  86. Flags uint32
  87. }
  88. // netapi32.dll
  89. const (
  90. NERR_Success = 0x0
  91. NERR_InternalError = 0x85C
  92. NERR_UserNotFound = 0x8AD
  93. ERROR_ACCESS_DENIED = 0x5
  94. ERROR_BAD_NETPATH = 0x35
  95. ERROR_INVALID_LEVEL = 0x7C
  96. ERROR_INVALID_NAME = 0x7B
  97. ERROR_MORE_DATA = 0xEA
  98. ERROR_NOT_ENOUGH_MEMORY = 0x8
  99. MAX_PREFERRED_LENGTH = 0xFFFFFFFF
  100. MAX_GROUP_NAME_LENGTH = 256
  101. SE_GROUP_MANDATORY = 0x1
  102. SE_GROUP_ENABLED_BY_DEFAULT = 0x2
  103. SE_GROUP_ENABLED = 0x4
  104. SE_GROUP_OWNER = 0x8
  105. SE_GROUP_USE_FOR_DENY_ONLY = 0x10
  106. SE_GROUP_INTEGRITY = 0x20
  107. SE_GROUP_INTEGRITY_ENABLED = 0x40
  108. SE_GROUP_LOGON_ID = 0xC0000000
  109. SE_GROUP_RESOURCE = 0x20000000
  110. )
  111. type GroupUsersInfo0 struct {
  112. Grui0_name *uint16
  113. }
  114. type GroupUsersInfo1 struct {
  115. Grui1_name *uint16
  116. Grui1_attributes uint32
  117. }
  118. // The API interface describes the Win32 functions used in this package and
  119. // its primary purpose is to allow replacing them with stub functions in unit tests.
  120. type API interface {
  121. AcquireCredentialsHandle(
  122. principal *uint16,
  123. _package *uint16,
  124. credentialUse uint32,
  125. logonID *LUID,
  126. authData *byte,
  127. getKeyFn uintptr,
  128. getKeyArgument uintptr,
  129. credHandle *CredHandle,
  130. expiry *syscall.Filetime,
  131. ) SECURITY_STATUS
  132. AcceptSecurityContext(
  133. credential *CredHandle,
  134. context *CtxtHandle,
  135. input *SecBufferDesc,
  136. contextReq uint32,
  137. targDataRep uint32,
  138. newContext *CtxtHandle,
  139. output *SecBufferDesc,
  140. contextAttr *uint32,
  141. expiry *syscall.Filetime,
  142. ) SECURITY_STATUS
  143. QueryContextAttributes(context *CtxtHandle, attribute uint32, buffer *byte) SECURITY_STATUS
  144. DeleteSecurityContext(context *CtxtHandle) SECURITY_STATUS
  145. FreeContextBuffer(buffer *byte) SECURITY_STATUS
  146. FreeCredentialsHandle(handle *CredHandle) SECURITY_STATUS
  147. NetUserGetGroups(
  148. serverName *uint16,
  149. userName *uint16,
  150. level uint32,
  151. buf **byte,
  152. prefmaxlen uint32,
  153. entriesread *uint32,
  154. totalentries *uint32,
  155. ) (neterr error)
  156. NetApiBufferFree(buf *byte) (neterr error)
  157. }
  158. // Win32 implements the API interface by calling the relevant system functions
  159. // from secur32.dll and netapi32.dll
  160. type Win32 struct{}
  161. var (
  162. secur32dll = windows.NewLazySystemDLL("secur32.dll")
  163. netapi32dll = windows.NewLazySystemDLL("netapi32.dll")
  164. procAcquireCredentialsHandleW = secur32dll.NewProc("AcquireCredentialsHandleW")
  165. procAcceptSecurityContext = secur32dll.NewProc("AcceptSecurityContext")
  166. procQueryContextAttributesW = secur32dll.NewProc("QueryContextAttributesW")
  167. procDeleteSecurityContext = secur32dll.NewProc("DeleteSecurityContext")
  168. procFreeContextBuffer = secur32dll.NewProc("FreeContextBuffer")
  169. procFreeCredentialsHandle = secur32dll.NewProc("FreeCredentialsHandle")
  170. procNetUserGetGroups = netapi32dll.NewProc("NetUserGetGroups")
  171. )
  172. func (w *Win32) AcquireCredentialsHandle(
  173. principal *uint16,
  174. _package *uint16,
  175. credentialUse uint32,
  176. logonId *LUID,
  177. authData *byte,
  178. getKeyFn uintptr,
  179. getKeyArgument uintptr,
  180. credHandle *CredHandle,
  181. expiry *syscall.Filetime,
  182. ) SECURITY_STATUS {
  183. r1, _, _ := syscall.Syscall9(
  184. procAcquireCredentialsHandleW.Addr(), 9,
  185. uintptr(unsafe.Pointer(principal)),
  186. uintptr(unsafe.Pointer(_package)),
  187. uintptr(credentialUse),
  188. uintptr(unsafe.Pointer(logonId)),
  189. uintptr(unsafe.Pointer(authData)),
  190. uintptr(getKeyFn),
  191. uintptr(getKeyArgument),
  192. uintptr(unsafe.Pointer(credHandle)),
  193. uintptr(unsafe.Pointer(expiry)),
  194. )
  195. return SECURITY_STATUS(r1)
  196. }
  197. func (w *Win32) AcceptSecurityContext(
  198. credential *CredHandle,
  199. context *CtxtHandle,
  200. input *SecBufferDesc,
  201. contextReq uint32,
  202. targDataRep uint32,
  203. newContext *CtxtHandle,
  204. output *SecBufferDesc,
  205. contextAttr *uint32,
  206. expiry *syscall.Filetime,
  207. ) SECURITY_STATUS {
  208. r1, _, _ := syscall.Syscall9(
  209. procAcceptSecurityContext.Addr(), 9,
  210. uintptr(unsafe.Pointer(credential)),
  211. uintptr(unsafe.Pointer(context)),
  212. uintptr(unsafe.Pointer(input)),
  213. uintptr(contextReq),
  214. uintptr(targDataRep),
  215. uintptr(unsafe.Pointer(newContext)),
  216. uintptr(unsafe.Pointer(output)),
  217. uintptr(unsafe.Pointer(contextAttr)),
  218. uintptr(unsafe.Pointer(expiry)),
  219. )
  220. return SECURITY_STATUS(r1)
  221. }
  222. func (w *Win32) QueryContextAttributes(
  223. context *CtxtHandle,
  224. attribute uint32,
  225. buffer *byte,
  226. ) SECURITY_STATUS {
  227. r1, _, _ := syscall.Syscall(
  228. procQueryContextAttributesW.Addr(), 3,
  229. uintptr(unsafe.Pointer(context)),
  230. uintptr(attribute),
  231. uintptr(unsafe.Pointer(buffer)),
  232. )
  233. return SECURITY_STATUS(r1)
  234. }
  235. func (w *Win32) DeleteSecurityContext(context *CtxtHandle) SECURITY_STATUS {
  236. r1, _, _ := syscall.Syscall(
  237. procDeleteSecurityContext.Addr(), 1,
  238. uintptr(unsafe.Pointer(context)),
  239. 0, 0,
  240. )
  241. return SECURITY_STATUS(r1)
  242. }
  243. func (w *Win32) FreeContextBuffer(buffer *byte) SECURITY_STATUS {
  244. r1, _, _ := syscall.Syscall(
  245. procFreeContextBuffer.Addr(), 1,
  246. uintptr(unsafe.Pointer(buffer)),
  247. 0, 0,
  248. )
  249. return SECURITY_STATUS(r1)
  250. }
  251. func (w *Win32) FreeCredentialsHandle(handle *CredHandle) SECURITY_STATUS {
  252. r1, _, _ := syscall.Syscall(
  253. procFreeCredentialsHandle.Addr(), 1,
  254. uintptr(unsafe.Pointer(handle)),
  255. 0, 0,
  256. )
  257. return SECURITY_STATUS(r1)
  258. }
  259. func (w *Win32) NetUserGetGroups(
  260. serverName *uint16,
  261. userName *uint16,
  262. level uint32,
  263. buf **byte,
  264. prefmaxlen uint32,
  265. entriesread *uint32,
  266. totalentries *uint32,
  267. ) (neterr error) {
  268. 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)
  269. if r0 != 0 {
  270. neterr = syscall.Errno(r0)
  271. }
  272. return
  273. }
  274. func (w *Win32) NetApiBufferFree(buf *byte) (neterr error) {
  275. return syscall.NetApiBufferFree(buf)
  276. }