/* Copyright (C) 2005 Juan Lang * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * This file implements the schannel provider, or, the SSL/TLS implementations. * FIXME: It should be rather obvious that this file is empty of any * implementation. */ #include #include "windef.h" #include "winbase.h" #include "sspi.h" #include "schannel.h" #include "secur32_priv.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); static SECURITY_STATUS schan_QueryCredentialsAttributes( PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; switch (ulAttribute) { case SECPKG_ATTR_SUPPORTED_ALGS: if (pBuffer) { /* FIXME: get from CryptoAPI */ FIXME("%ld: stub\n", ulAttribute); ret = SEC_E_UNSUPPORTED_FUNCTION; } else ret = SEC_E_INTERNAL_ERROR; break; case SECPKG_ATTR_CIPHER_STRENGTHS: if (pBuffer) { /* FIXME: get from CryptoAPI */ FIXME("%ld: stub\n", ulAttribute); ret = SEC_E_UNSUPPORTED_FUNCTION; } else ret = SEC_E_INTERNAL_ERROR; break; case SECPKG_ATTR_SUPPORTED_PROTOCOLS: if (pBuffer) { /* FIXME: get from OpenSSL? */ FIXME("%ld: stub\n", ulAttribute); ret = SEC_E_UNSUPPORTED_FUNCTION; } else ret = SEC_E_INTERNAL_ERROR; break; default: ret = SEC_E_UNSUPPORTED_FUNCTION; } return ret; } static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesA( PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; TRACE("(%p, %ld, %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 = schan_QueryCredentialsAttributes(phCredential, ulAttribute, pBuffer); } return ret; } static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW( PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { SECURITY_STATUS ret; TRACE("(%p, %ld, %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 = schan_QueryCredentialsAttributes(phCredential, ulAttribute, pBuffer); } return ret; } static SECURITY_STATUS schan_AcquireCredentialsHandle(ULONG fCredentialUse, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS ret; if (fCredentialUse == SECPKG_CRED_BOTH) ret = SEC_E_NO_CREDENTIALS; else { /* For now, the only thing I'm interested in is the direction of the * connection, so just store it. */ phCredential->dwUpper = fCredentialUse; /* According to MSDN, all versions prior to XP do this */ if (ptsExpiry) ptsExpiry->QuadPart = 0; ret = SEC_E_OK; } return ret; } static SECURITY_STATUS SEC_ENTRY schan_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%08lx, %p, %p, %p, %p, %p, %p)\n", debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); return schan_AcquireCredentialsHandle(fCredentialUse, phCredential, ptsExpiry); } static SECURITY_STATUS SEC_ENTRY schan_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%08lx, %p, %p, %p, %p, %p, %p)\n", debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); return schan_AcquireCredentialsHandle(fCredentialUse, phCredential, ptsExpiry); } static SecurityFunctionTableA schanTableA = { 1, NULL, /* EnumerateSecurityPackagesA */ schan_QueryCredentialsAttributesA, schan_AcquireCredentialsHandleA, NULL, /* FreeCredentialsHandle */ NULL, /* Reserved2 */ NULL, /* InitializeSecurityContextA */ NULL, /* AcceptSecurityContext */ NULL, /* CompleteAuthToken */ NULL, /* DeleteSecurityContext */ NULL, /* ApplyControlToken */ NULL, /* QueryContextAttributesA */ NULL, /* ImpersonateSecurityContext */ NULL, /* RevertSecurityContext */ NULL, /* MakeSignature */ NULL, /* VerifySignature */ FreeContextBuffer, NULL, /* QuerySecurityPackageInfoA */ NULL, /* Reserved3 */ NULL, /* Reserved4 */ NULL, /* ExportSecurityContext */ NULL, /* ImportSecurityContextA */ NULL, /* AddCredentialsA */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ NULL, /* EncryptMessage */ NULL, /* DecryptMessage */ NULL, /* SetContextAttributesA */ }; static SecurityFunctionTableW schanTableW = { 1, NULL, /* EnumerateSecurityPackagesW */ schan_QueryCredentialsAttributesW, schan_AcquireCredentialsHandleW, NULL, /* FreeCredentialsHandle */ NULL, /* Reserved2 */ NULL, /* InitializeSecurityContextW */ NULL, /* AcceptSecurityContext */ NULL, /* CompleteAuthToken */ NULL, /* DeleteSecurityContext */ NULL, /* ApplyControlToken */ NULL, /* QueryContextAttributesW */ NULL, /* ImpersonateSecurityContext */ NULL, /* RevertSecurityContext */ NULL, /* MakeSignature */ NULL, /* VerifySignature */ FreeContextBuffer, NULL, /* QuerySecurityPackageInfoW */ NULL, /* Reserved3 */ NULL, /* Reserved4 */ NULL, /* ExportSecurityContext */ NULL, /* ImportSecurityContextW */ NULL, /* AddCredentialsW */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ NULL, /* EncryptMessage */ NULL, /* DecryptMessage */ NULL, /* SetContextAttributesW */ }; static const WCHAR schannelComment[] = { 'S','c','h','a','n','n','e','l',' ', 'S','e','c','u','r','i','t','y',' ','P','a','c','k','a','g','e',0 }; void SECUR32_initSchannelSP(void) { SecureProvider *provider = SECUR32_addProvider(&schanTableA, &schanTableW, NULL); if (provider) { /* This is what Windows reports. This shouldn't break any applications * even though the functions are missing, because the wrapper will * return SEC_E_UNSUPPORTED_FUNCTION if our function is NULL. */ 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_STREAM; static const short version = 1; static const long maxToken = 16384; SEC_WCHAR *uniSPName = (SEC_WCHAR *)UNISP_NAME_W, *schannel = (SEC_WCHAR *)SCHANNEL_NAME_W; const SecPkgInfoW info[] = { { caps, version, UNISP_RPC_ID, maxToken, uniSPName, uniSPName }, { caps, version, UNISP_RPC_ID, maxToken, schannel, (SEC_WCHAR *)schannelComment }, }; SECUR32_addPackages(provider, sizeof(info) / sizeof(info[0]), NULL, info); } }