/* * Copyright 2005 Kai Blin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * This file implements the negotiate provider. * FIXME: So far, this beast doesn't do anything. */ #include <assert.h> #include <stdarg.h> #include "windef.h" #include "winbase.h" #include "sspi.h" #include "secur32_priv.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); static char nego_name_A[] = "Negotiate"; static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0}; static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; /* FIXME: More attributes to be added here. Need to fix the sspi.h header * for that, too. */ switch(ulAttribute) { default: ret = SEC_E_UNSUPPORTED_FUNCTION; } return ret; } /*********************************************************************** * QueryCredentialsAttributesA */ static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA( PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer); switch(ulAttribute) { case SECPKG_CRED_ATTR_NAMES: FIXME("SECPKG_CRED_ATTR_NAMES: stub\n"); ret = SEC_E_UNSUPPORTED_FUNCTION; break; default: ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, pBuffer); } return ret; } /*********************************************************************** * QueryCredentialsAttributesW */ static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW( PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer); switch(ulAttribute) { case SECPKG_CRED_ATTR_NAMES: FIXME("SECPKG_CRED_ATTR_NAMES: stub\n"); ret = SEC_E_UNSUPPORTED_FUNCTION; break; default: ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, pBuffer); } return ret; } /*********************************************************************** * AcquireCredentialsHandleA */ static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA( SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n", debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); return SEC_E_UNSUPPORTED_FUNCTION; } /*********************************************************************** * AcquireCredentialsHandleW */ static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW( SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n", debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); return SEC_E_UNSUPPORTED_FUNCTION; } /*********************************************************************** * InitializeSecurityContextA */ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA( PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS ret; TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext, debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); if(phCredential){ ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * InitializeSecurityContextW */ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW( PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS ret; TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext, debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); if (phCredential) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * AcceptSecurityContext */ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext( PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS ret; TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsExpiry); if (phCredential) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * CompleteAuthToken */ static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken) { SECURITY_STATUS ret; TRACE("%p %p\n", phContext, pToken); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * DeleteSecurityContext */ static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS ret; TRACE("%p\n", phContext); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * ApplyControlToken */ static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput) { SECURITY_STATUS ret; TRACE("%p %p\n", phContext, pInput); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * QueryContextAttributesW */ static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { SECURITY_STATUS ret; /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is * the SecurePackage part and the dwLower part is the actual context * handle. It should be easy to extract the context attributes from that. */ TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * QueryContextAttributesA */ static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer); } /*********************************************************************** * ImpersonateSecurityContext */ static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS ret; TRACE("%p\n", phContext); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * RevertSecurityContext */ static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext) { SECURITY_STATUS ret; TRACE("%p\n", phContext); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * MakeSignature */ static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { SECURITY_STATUS ret; TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } /*********************************************************************** * VerifySignature */ static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) { SECURITY_STATUS ret; TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); if (phContext) { ret = SEC_E_UNSUPPORTED_FUNCTION; } else { ret = SEC_E_INVALID_HANDLE; } return ret; } static const SecurityFunctionTableA negoTableA = { 1, NULL, /* EnumerateSecurityPackagesA */ nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */ nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */ FreeCredentialsHandle, /* FreeCredentialsHandle */ NULL, /* Reserved2 */ nego_InitializeSecurityContextA, /* InitializeSecurityContextA */ nego_AcceptSecurityContext, /* AcceptSecurityContext */ nego_CompleteAuthToken, /* CompleteAuthToken */ nego_DeleteSecurityContext, /* DeleteSecurityContext */ nego_ApplyControlToken, /* ApplyControlToken */ nego_QueryContextAttributesA, /* QueryContextAttributesA */ nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ nego_RevertSecurityContext, /* RevertSecurityContext */ nego_MakeSignature, /* MakeSignature */ nego_VerifySignature, /* VerifySignature */ FreeContextBuffer, /* FreeContextBuffer */ NULL, /* QuerySecurityPackageInfoA */ NULL, /* Reserved3 */ NULL, /* Reserved4 */ NULL, /* ExportSecurityContext */ NULL, /* ImportSecurityContextA */ NULL, /* AddCredentialsA */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ NULL, /* EncryptMessage */ NULL, /* DecryptMessage */ NULL, /* SetContextAttributesA */ }; static const SecurityFunctionTableW negoTableW = { 1, NULL, /* EnumerateSecurityPackagesW */ nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */ nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */ FreeCredentialsHandle, /* FreeCredentialsHandle */ NULL, /* Reserved2 */ nego_InitializeSecurityContextW, /* InitializeSecurityContextW */ nego_AcceptSecurityContext, /* AcceptSecurityContext */ nego_CompleteAuthToken, /* CompleteAuthToken */ nego_DeleteSecurityContext, /* DeleteSecurityContext */ nego_ApplyControlToken, /* ApplyControlToken */ nego_QueryContextAttributesW, /* QueryContextAttributesW */ nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ nego_RevertSecurityContext, /* RevertSecurityContext */ nego_MakeSignature, /* MakeSignature */ nego_VerifySignature, /* VerifySignature */ FreeContextBuffer, /* FreeContextBuffer */ NULL, /* QuerySecurityPackageInfoW */ NULL, /* Reserved3 */ NULL, /* Reserved4 */ NULL, /* ExportSecurityContext */ NULL, /* ImportSecurityContextW */ NULL, /* AddCredentialsW */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ NULL, /* EncryptMessage */ NULL, /* DecryptMessage */ NULL, /* SetContextAttributesW */ }; static WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', 0}; static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator"; void SECUR32_initNegotiateSP(void) { SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL); /* According to Windows, Negotiate has the following capabilities. */ static const LONG caps = SECPKG_FLAG_INTEGRITY | SECPKG_FLAG_PRIVACY | SECPKG_FLAG_CONNECTION | SECPKG_FLAG_MULTI_REQUIRED | SECPKG_FLAG_EXTENDED_ERROR | SECPKG_FLAG_IMPERSONATION | SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_READONLY_WITH_CHECKSUM; static const USHORT version = 1; static const USHORT rpcid = 15; static const ULONG max_token = 12000; const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W, negotiate_comment_W}; const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A, negotiate_comment_A}; SECUR32_addPackages(provider, 1L, &infoA, &infoW); }