1 // Code adapted from the NodeJS kerberos library:
2 //
3 //   https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.c
4 //
5 // Under the terms of the Apache License, Version 2.0:
6 //
7 //   http://www.apache.org/licenses/LICENSE-2.0
8 //
9 #include <stdlib.h>
10 
11 #include "sspi_windows.h"
12 
13 static HINSTANCE sspi_secur32_dll = NULL;
14 
load_secur32_dll()15 int load_secur32_dll()
16 {
17 	sspi_secur32_dll = LoadLibrary("secur32.dll");
18 	if (sspi_secur32_dll == NULL) {
19 		return GetLastError();
20 	}
21 	return 0;
22 }
23 
call_sspi_encrypt_message(PCtxtHandle phContext,unsigned long fQOP,PSecBufferDesc pMessage,unsigned long MessageSeqNo)24 SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo)
25 {
26 	if (sspi_secur32_dll == NULL) {
27 		return -1;
28 	}
29 	encryptMessage_fn pfn_encryptMessage = (encryptMessage_fn) GetProcAddress(sspi_secur32_dll, "EncryptMessage");
30 	if (!pfn_encryptMessage) {
31 		return -2;
32 	}
33 	return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo);
34 }
35 
call_sspi_acquire_credentials_handle(LPSTR pszPrincipal,LPSTR pszPackage,unsigned long fCredentialUse,void * pvLogonId,void * pAuthData,SEC_GET_KEY_FN pGetKeyFn,void * pvGetKeyArgument,PCredHandle phCredential,PTimeStamp ptsExpiry)36 SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle(
37 	LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse,
38         void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
39         PCredHandle phCredential, PTimeStamp ptsExpiry)
40 {
41 	if (sspi_secur32_dll == NULL) {
42 		return -1;
43 	}
44 	acquireCredentialsHandle_fn pfn_acquireCredentialsHandle;
45 #ifdef _UNICODE
46 	pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleW");
47 #else
48 	pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleA");
49 #endif
50 	if (!pfn_acquireCredentialsHandle) {
51 		return -2;
52 	}
53 	return (*pfn_acquireCredentialsHandle)(
54 		pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData,
55 	        pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
56 }
57 
call_sspi_initialize_security_context(PCredHandle phCredential,PCtxtHandle phContext,LPSTR pszTargetName,unsigned long fContextReq,unsigned long Reserved1,unsigned long TargetDataRep,PSecBufferDesc pInput,unsigned long Reserved2,PCtxtHandle phNewContext,PSecBufferDesc pOutput,unsigned long * pfContextAttr,PTimeStamp ptsExpiry)58 SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context(
59 	PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName,
60 	unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep,
61 	PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext,
62 	PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry)
63 {
64 	if (sspi_secur32_dll == NULL) {
65 		return -1;
66 	}
67 	initializeSecurityContext_fn pfn_initializeSecurityContext;
68 #ifdef _UNICODE
69 	pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextW");
70 #else
71 	pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextA");
72 #endif
73 	if (!pfn_initializeSecurityContext) {
74 		return -2;
75 	}
76 	return (*pfn_initializeSecurityContext)(
77 		phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep,
78 		pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
79 }
80 
call_sspi_query_context_attributes(PCtxtHandle phContext,unsigned long ulAttribute,void * pBuffer)81 SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer)
82 {
83 	if (sspi_secur32_dll == NULL) {
84 		return -1;
85 	}
86 	queryContextAttributes_fn pfn_queryContextAttributes;
87 #ifdef _UNICODE
88 	pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesW");
89 #else
90 	pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesA");
91 #endif
92 	if (!pfn_queryContextAttributes) {
93 		return -2;
94 	}
95 	return (*pfn_queryContextAttributes)(phContext, ulAttribute, pBuffer);
96 }
97