*: update kube vendor to v1.7.4

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-08-04 13:13:19 +02:00
parent c67859731f
commit d56bf090ce
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
1032 changed files with 273965 additions and 40081 deletions

77
vendor/gopkg.in/mgo.v2/internal/sasl/sasl.c generated vendored Normal file
View file

@ -0,0 +1,77 @@
// +build !windows
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sasl/sasl.h>
static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len)
{
if (!result) {
return SASL_BADPARAM;
}
switch (id) {
case SASL_CB_USER:
*result = (char *)context;
break;
case SASL_CB_AUTHNAME:
*result = (char *)context;
break;
case SASL_CB_LANGUAGE:
*result = NULL;
break;
default:
return SASL_BADPARAM;
}
if (len) {
*len = *result ? strlen(*result) : 0;
}
return SASL_OK;
}
typedef int (*callback)(void);
static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result)
{
if (!conn || !result || id != SASL_CB_PASS) {
return SASL_BADPARAM;
}
*result = (sasl_secret_t *)context;
return SASL_OK;
}
sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password)
{
sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t));
int n = 0;
size_t len = strlen(password);
sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len);
if (!secret) {
free(cb);
return NULL;
}
strcpy((char *)secret->data, password);
secret->len = len;
cb[n].id = SASL_CB_PASS;
cb[n].proc = (callback)&mgo_sasl_secret;
cb[n].context = secret;
n++;
cb[n].id = SASL_CB_USER;
cb[n].proc = (callback)&mgo_sasl_simple;
cb[n].context = (char*)username;
n++;
cb[n].id = SASL_CB_AUTHNAME;
cb[n].proc = (callback)&mgo_sasl_simple;
cb[n].context = (char*)username;
n++;
cb[n].id = SASL_CB_LIST_END;
cb[n].proc = NULL;
cb[n].context = NULL;
return cb;
}

138
vendor/gopkg.in/mgo.v2/internal/sasl/sasl.go generated vendored Normal file
View file

@ -0,0 +1,138 @@
// Package sasl is an implementation detail of the mgo package.
//
// This package is not meant to be used by itself.
//
// +build !windows
package sasl
// #cgo LDFLAGS: -lsasl2
//
// struct sasl_conn {};
//
// #include <stdlib.h>
// #include <sasl/sasl.h>
//
// sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password);
//
import "C"
import (
"fmt"
"strings"
"sync"
"unsafe"
)
type saslStepper interface {
Step(serverData []byte) (clientData []byte, done bool, err error)
Close()
}
type saslSession struct {
conn *C.sasl_conn_t
step int
mech string
cstrings []*C.char
callbacks *C.sasl_callback_t
}
var initError error
var initOnce sync.Once
func initSASL() {
rc := C.sasl_client_init(nil)
if rc != C.SASL_OK {
initError = saslError(rc, nil, "cannot initialize SASL library")
}
}
func New(username, password, mechanism, service, host string) (saslStepper, error) {
initOnce.Do(initSASL)
if initError != nil {
return nil, initError
}
ss := &saslSession{mech: mechanism}
if service == "" {
service = "mongodb"
}
if i := strings.Index(host, ":"); i >= 0 {
host = host[:i]
}
ss.callbacks = C.mgo_sasl_callbacks(ss.cstr(username), ss.cstr(password))
rc := C.sasl_client_new(ss.cstr(service), ss.cstr(host), nil, nil, ss.callbacks, 0, &ss.conn)
if rc != C.SASL_OK {
ss.Close()
return nil, saslError(rc, nil, "cannot create new SASL client")
}
return ss, nil
}
func (ss *saslSession) cstr(s string) *C.char {
cstr := C.CString(s)
ss.cstrings = append(ss.cstrings, cstr)
return cstr
}
func (ss *saslSession) Close() {
for _, cstr := range ss.cstrings {
C.free(unsafe.Pointer(cstr))
}
ss.cstrings = nil
if ss.callbacks != nil {
C.free(unsafe.Pointer(ss.callbacks))
}
// The documentation of SASL dispose makes it clear that this should only
// be done when the connection is done, not when the authentication phase
// is done, because an encryption layer may have been negotiated.
// Even then, we'll do this for now, because it's simpler and prevents
// keeping track of this state for every socket. If it breaks, we'll fix it.
C.sasl_dispose(&ss.conn)
}
func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) {
ss.step++
if ss.step > 10 {
return nil, false, fmt.Errorf("too many SASL steps without authentication")
}
var cclientData *C.char
var cclientDataLen C.uint
var rc C.int
if ss.step == 1 {
var mechanism *C.char // ignored - must match cred
rc = C.sasl_client_start(ss.conn, ss.cstr(ss.mech), nil, &cclientData, &cclientDataLen, &mechanism)
} else {
var cserverData *C.char
var cserverDataLen C.uint
if len(serverData) > 0 {
cserverData = (*C.char)(unsafe.Pointer(&serverData[0]))
cserverDataLen = C.uint(len(serverData))
}
rc = C.sasl_client_step(ss.conn, cserverData, cserverDataLen, nil, &cclientData, &cclientDataLen)
}
if cclientData != nil && cclientDataLen > 0 {
clientData = C.GoBytes(unsafe.Pointer(cclientData), C.int(cclientDataLen))
}
if rc == C.SASL_OK {
return clientData, true, nil
}
if rc == C.SASL_CONTINUE {
return clientData, false, nil
}
return nil, false, saslError(rc, ss.conn, "cannot establish SASL session")
}
func saslError(rc C.int, conn *C.sasl_conn_t, msg string) error {
var detail string
if conn == nil {
detail = C.GoString(C.sasl_errstring(rc, nil, nil))
} else {
detail = C.GoString(C.sasl_errdetail(conn))
}
return fmt.Errorf(msg + ": " + detail)
}

122
vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.c generated vendored Normal file
View file

@ -0,0 +1,122 @@
#include "sasl_windows.h"
static const LPSTR SSPI_PACKAGE_NAME = "kerberos";
SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle *cred_handle, char *username, char *password, char *domain)
{
SEC_WINNT_AUTH_IDENTITY auth_identity;
SECURITY_INTEGER ignored;
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
auth_identity.User = (LPSTR) username;
auth_identity.UserLength = strlen(username);
auth_identity.Password = NULL;
auth_identity.PasswordLength = 0;
if(password){
auth_identity.Password = (LPSTR) password;
auth_identity.PasswordLength = strlen(password);
}
auth_identity.Domain = (LPSTR) domain;
auth_identity.DomainLength = strlen(domain);
return call_sspi_acquire_credentials_handle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, cred_handle, &ignored);
}
int sspi_step(CredHandle *cred_handle, int has_context, CtxtHandle *context, PVOID buffer, ULONG buffer_length, PVOID *out_buffer, ULONG *out_buffer_length, char *target)
{
SecBufferDesc inbuf;
SecBuffer in_bufs[1];
SecBufferDesc outbuf;
SecBuffer out_bufs[1];
if (has_context > 0) {
// If we already have a context, we now have data to send.
// Put this data in an inbuf.
inbuf.ulVersion = SECBUFFER_VERSION;
inbuf.cBuffers = 1;
inbuf.pBuffers = in_bufs;
in_bufs[0].pvBuffer = buffer;
in_bufs[0].cbBuffer = buffer_length;
in_bufs[0].BufferType = SECBUFFER_TOKEN;
}
outbuf.ulVersion = SECBUFFER_VERSION;
outbuf.cBuffers = 1;
outbuf.pBuffers = out_bufs;
out_bufs[0].pvBuffer = NULL;
out_bufs[0].cbBuffer = 0;
out_bufs[0].BufferType = SECBUFFER_TOKEN;
ULONG context_attr = 0;
int ret = call_sspi_initialize_security_context(cred_handle,
has_context > 0 ? context : NULL,
(LPSTR) target,
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH,
0,
SECURITY_NETWORK_DREP,
has_context > 0 ? &inbuf : NULL,
0,
context,
&outbuf,
&context_attr,
NULL);
*out_buffer = malloc(out_bufs[0].cbBuffer);
*out_buffer_length = out_bufs[0].cbBuffer;
memcpy(*out_buffer, out_bufs[0].pvBuffer, *out_buffer_length);
return ret;
}
int sspi_send_client_authz_id(CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *user_plus_realm)
{
SecPkgContext_Sizes sizes;
SECURITY_STATUS status = call_sspi_query_context_attributes(context, SECPKG_ATTR_SIZES, &sizes);
if (status != SEC_E_OK) {
return status;
}
size_t user_plus_realm_length = strlen(user_plus_realm);
int msgSize = 4 + user_plus_realm_length;
char *msg = malloc((sizes.cbSecurityTrailer + msgSize + sizes.cbBlockSize) * sizeof(char));
msg[sizes.cbSecurityTrailer + 0] = 1;
msg[sizes.cbSecurityTrailer + 1] = 0;
msg[sizes.cbSecurityTrailer + 2] = 0;
msg[sizes.cbSecurityTrailer + 3] = 0;
memcpy(&msg[sizes.cbSecurityTrailer + 4], user_plus_realm, user_plus_realm_length);
SecBuffer wrapBufs[3];
SecBufferDesc wrapBufDesc;
wrapBufDesc.cBuffers = 3;
wrapBufDesc.pBuffers = wrapBufs;
wrapBufDesc.ulVersion = SECBUFFER_VERSION;
wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer;
wrapBufs[0].BufferType = SECBUFFER_TOKEN;
wrapBufs[0].pvBuffer = msg;
wrapBufs[1].cbBuffer = msgSize;
wrapBufs[1].BufferType = SECBUFFER_DATA;
wrapBufs[1].pvBuffer = msg + sizes.cbSecurityTrailer;
wrapBufs[2].cbBuffer = sizes.cbBlockSize;
wrapBufs[2].BufferType = SECBUFFER_PADDING;
wrapBufs[2].pvBuffer = msg + sizes.cbSecurityTrailer + msgSize;
status = call_sspi_encrypt_message(context, SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0);
if (status != SEC_E_OK) {
free(msg);
return status;
}
*buffer_length = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer;
*buffer = malloc(*buffer_length);
memcpy(*buffer, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer);
memcpy(*buffer + wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer);
memcpy(*buffer + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer);
free(msg);
return SEC_E_OK;
}

142
vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.go generated vendored Normal file
View file

@ -0,0 +1,142 @@
package sasl
// #include "sasl_windows.h"
import "C"
import (
"fmt"
"strings"
"sync"
"unsafe"
)
type saslStepper interface {
Step(serverData []byte) (clientData []byte, done bool, err error)
Close()
}
type saslSession struct {
// Credentials
mech string
service string
host string
userPlusRealm string
target string
domain string
// Internal state
authComplete bool
errored bool
step int
// C internal state
credHandle C.CredHandle
context C.CtxtHandle
hasContext C.int
// Keep track of pointers we need to explicitly free
stringsToFree []*C.char
}
var initError error
var initOnce sync.Once
func initSSPI() {
rc := C.load_secur32_dll()
if rc != 0 {
initError = fmt.Errorf("Error loading libraries: %v", rc)
}
}
func New(username, password, mechanism, service, host string) (saslStepper, error) {
initOnce.Do(initSSPI)
ss := &saslSession{mech: mechanism, hasContext: 0, userPlusRealm: username}
if service == "" {
service = "mongodb"
}
if i := strings.Index(host, ":"); i >= 0 {
host = host[:i]
}
ss.service = service
ss.host = host
usernameComponents := strings.Split(username, "@")
if len(usernameComponents) < 2 {
return nil, fmt.Errorf("Username '%v' doesn't contain a realm!", username)
}
user := usernameComponents[0]
ss.domain = usernameComponents[1]
ss.target = fmt.Sprintf("%s/%s", ss.service, ss.host)
var status C.SECURITY_STATUS
// Step 0: call AcquireCredentialsHandle to get a nice SSPI CredHandle
if len(password) > 0 {
status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), ss.cstr(password), ss.cstr(ss.domain))
} else {
status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), nil, ss.cstr(ss.domain))
}
if status != C.SEC_E_OK {
ss.errored = true
return nil, fmt.Errorf("Couldn't create new SSPI client, error code %v", status)
}
return ss, nil
}
func (ss *saslSession) cstr(s string) *C.char {
cstr := C.CString(s)
ss.stringsToFree = append(ss.stringsToFree, cstr)
return cstr
}
func (ss *saslSession) Close() {
for _, cstr := range ss.stringsToFree {
C.free(unsafe.Pointer(cstr))
}
}
func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) {
ss.step++
if ss.step > 10 {
return nil, false, fmt.Errorf("too many SSPI steps without authentication")
}
var buffer C.PVOID
var bufferLength C.ULONG
var outBuffer C.PVOID
var outBufferLength C.ULONG
if len(serverData) > 0 {
buffer = (C.PVOID)(unsafe.Pointer(&serverData[0]))
bufferLength = C.ULONG(len(serverData))
}
var status C.int
if ss.authComplete {
// Step 3: last bit of magic to use the correct server credentials
status = C.sspi_send_client_authz_id(&ss.context, &outBuffer, &outBufferLength, ss.cstr(ss.userPlusRealm))
} else {
// Step 1 + Step 2: set up security context with the server and TGT
status = C.sspi_step(&ss.credHandle, ss.hasContext, &ss.context, buffer, bufferLength, &outBuffer, &outBufferLength, ss.cstr(ss.target))
}
if outBuffer != C.PVOID(nil) {
defer C.free(unsafe.Pointer(outBuffer))
}
if status != C.SEC_E_OK && status != C.SEC_I_CONTINUE_NEEDED {
ss.errored = true
return nil, false, ss.handleSSPIErrorCode(status)
}
clientData = C.GoBytes(unsafe.Pointer(outBuffer), C.int(outBufferLength))
if status == C.SEC_E_OK {
ss.authComplete = true
return clientData, true, nil
} else {
ss.hasContext = 1
return clientData, false, nil
}
}
func (ss *saslSession) handleSSPIErrorCode(code C.int) error {
switch {
case code == C.SEC_E_TARGET_UNKNOWN:
return fmt.Errorf("Target %v@%v not found", ss.target, ss.domain)
}
return fmt.Errorf("Unknown error doing step %v, error code %v", ss.step, code)
}

7
vendor/gopkg.in/mgo.v2/internal/sasl/sasl_windows.h generated vendored Normal file
View file

@ -0,0 +1,7 @@
#include <windows.h>
#include "sspi_windows.h"
SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle* cred_handle, char* username, char* password, char* domain);
int sspi_step(CredHandle* cred_handle, int has_context, CtxtHandle* context, PVOID buffer, ULONG buffer_length, PVOID* out_buffer, ULONG* out_buffer_length, char* target);
int sspi_send_client_authz_id(CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* user_plus_realm);

96
vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.c generated vendored Normal file
View file

@ -0,0 +1,96 @@
// Code adapted from the NodeJS kerberos library:
//
// https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.c
//
// Under the terms of the Apache License, Version 2.0:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
#include <stdlib.h>
#include "sspi_windows.h"
static HINSTANCE sspi_secur32_dll = NULL;
int load_secur32_dll()
{
sspi_secur32_dll = LoadLibrary("secur32.dll");
if (sspi_secur32_dll == NULL) {
return GetLastError();
}
return 0;
}
SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo)
{
if (sspi_secur32_dll == NULL) {
return -1;
}
encryptMessage_fn pfn_encryptMessage = (encryptMessage_fn) GetProcAddress(sspi_secur32_dll, "EncryptMessage");
if (!pfn_encryptMessage) {
return -2;
}
return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo);
}
SECURITY_STATUS SEC_ENTRY 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)
{
if (sspi_secur32_dll == NULL) {
return -1;
}
acquireCredentialsHandle_fn pfn_acquireCredentialsHandle;
#ifdef _UNICODE
pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleW");
#else
pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleA");
#endif
if (!pfn_acquireCredentialsHandle) {
return -2;
}
return (*pfn_acquireCredentialsHandle)(
pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData,
pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
}
SECURITY_STATUS SEC_ENTRY 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)
{
if (sspi_secur32_dll == NULL) {
return -1;
}
initializeSecurityContext_fn pfn_initializeSecurityContext;
#ifdef _UNICODE
pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextW");
#else
pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextA");
#endif
if (!pfn_initializeSecurityContext) {
return -2;
}
return (*pfn_initializeSecurityContext)(
phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep,
pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
}
SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer)
{
if (sspi_secur32_dll == NULL) {
return -1;
}
queryContextAttributes_fn pfn_queryContextAttributes;
#ifdef _UNICODE
pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesW");
#else
pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesA");
#endif
if (!pfn_queryContextAttributes) {
return -2;
}
return (*pfn_queryContextAttributes)(phContext, ulAttribute, pBuffer);
}

70
vendor/gopkg.in/mgo.v2/internal/sasl/sspi_windows.h generated vendored Normal file
View file

@ -0,0 +1,70 @@
// Code adapted from the NodeJS kerberos library:
//
// https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.h
//
// Under the terms of the Apache License, Version 2.0:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
#ifndef SSPI_WINDOWS_H
#define SSPI_WINDOWS_H
#define SECURITY_WIN32 1
#include <windows.h>
#include <sspi.h>
int load_secur32_dll();
SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo);
typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle(
LPSTR pszPrincipal, // Name of principal
LPSTR pszPackage, // Name of package
unsigned long fCredentialUse, // Flags indicating use
void *pvLogonId, // Pointer to logon ID
void *pAuthData, // Package specific data
SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
void *pvGetKeyArgument, // Value to pass to GetKey()
PCredHandle phCredential, // (out) Cred Handle
PTimeStamp ptsExpiry // (out) Lifetime (optional)
);
typedef DWORD (WINAPI *acquireCredentialsHandle_fn)(
LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse,
void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
PCredHandle phCredential, PTimeStamp ptsExpiry
);
SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context(
PCredHandle phCredential, // Cred to base context
PCtxtHandle phContext, // Existing context (OPT)
LPSTR pszTargetName, // Name of target
unsigned long fContextReq, // Context Requirements
unsigned long Reserved1, // Reserved, MBZ
unsigned long TargetDataRep, // Data rep of target
PSecBufferDesc pInput, // Input Buffers
unsigned long Reserved2, // Reserved, MBZ
PCtxtHandle phNewContext, // (out) New Context handle
PSecBufferDesc pOutput, // (inout) Output Buffers
unsigned long *pfContextAttr, // (out) Context attrs
PTimeStamp ptsExpiry // (out) Life span (OPT)
);
typedef DWORD (WINAPI *initializeSecurityContext_fn)(
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);
SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(
PCtxtHandle phContext, // Context to query
unsigned long ulAttribute, // Attribute to query
void *pBuffer // Buffer for attributes
);
typedef DWORD (WINAPI *queryContextAttributes_fn)(
PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer);
#endif // SSPI_WINDOWS_H