1 /*
2 * Miscellaneous secur32 tests
3 *
4 * Copyright 2005, 2006 Kai Blin
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define SECURITY_WIN32
22
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include <windef.h>
27 #include <winbase.h>
28 #include <sspi.h>
29
30 #include "wine/test.h"
31
32 static HMODULE secdll;
33 static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
34 static SECURITY_STATUS (SEC_ENTRY * pEnumerateSecurityPackagesA)(PULONG, PSecPkgInfoA*);
35 static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
36 static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
37 static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
38 ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
39 static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
40 SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG,
41 PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
42 static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
43 static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
44 PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
45 PULONG, PTimeStamp);
46 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
47 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
48 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
49
InitFunctionPtrs(void)50 static void InitFunctionPtrs(void)
51 {
52 secdll = LoadLibraryA("secur32.dll");
53 if(!secdll)
54 secdll = LoadLibraryA("security.dll");
55 if(secdll)
56 {
57 pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
58 pEnumerateSecurityPackagesA = (PVOID)GetProcAddress(secdll, "EnumerateSecurityPackagesA");
59 pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
60 pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
61 pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
62 pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
63 pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
64 pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
65 pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
66 pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
67 pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
68 }
69 }
70
71 /*---------------------------------------------------------*/
72 /* General helper functions */
73
getSecError(SECURITY_STATUS status)74 static const char* getSecError(SECURITY_STATUS status)
75 {
76 static char buf[20];
77
78 #define _SEC_ERR(x) case (x): return #x;
79 switch(status)
80 {
81 _SEC_ERR(SEC_E_OK);
82 _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
83 _SEC_ERR(SEC_E_INVALID_HANDLE);
84 _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
85 _SEC_ERR(SEC_E_TARGET_UNKNOWN);
86 _SEC_ERR(SEC_E_INTERNAL_ERROR);
87 _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
88 _SEC_ERR(SEC_E_NOT_OWNER);
89 _SEC_ERR(SEC_E_CANNOT_INSTALL);
90 _SEC_ERR(SEC_E_INVALID_TOKEN);
91 _SEC_ERR(SEC_E_CANNOT_PACK);
92 _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
93 _SEC_ERR(SEC_E_NO_IMPERSONATION);
94 _SEC_ERR(SEC_I_CONTINUE_NEEDED);
95 _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
96 _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
97 _SEC_ERR(SEC_E_LOGON_DENIED);
98 _SEC_ERR(SEC_E_NO_CREDENTIALS);
99 _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
100 default:
101 sprintf(buf, "%08x\n", status);
102 return buf;
103 }
104 #undef _SEC_ERR
105 }
106
107 /*---------------------------------------------------------*/
108 /* Helper for testQuerySecurityPagageInfo */
109
setupPackageA(SEC_CHAR * p_package_name,PSecPkgInfoA * p_pkg_info)110 static SECURITY_STATUS setupPackageA(SEC_CHAR *p_package_name,
111 PSecPkgInfoA *p_pkg_info)
112 {
113 SECURITY_STATUS ret;
114
115 ret = pQuerySecurityPackageInfoA( p_package_name, p_pkg_info);
116 return ret;
117 }
118
119 /*--------------------------------------------------------- */
120 /* The test functions */
121
testInitSecurityInterface(void)122 static void testInitSecurityInterface(void)
123 {
124 PSecurityFunctionTableA sec_fun_table = NULL;
125
126 sec_fun_table = pInitSecurityInterfaceA();
127 ok(sec_fun_table != NULL, "InitSecurityInterface() returned NULL.\n");
128
129 }
130
testEnumerateSecurityPackages(void)131 static void testEnumerateSecurityPackages(void)
132 {
133
134 SECURITY_STATUS sec_status;
135 ULONG num_packages, i;
136 PSecPkgInfoA pkg_info = NULL;
137
138 trace("Running testEnumerateSecurityPackages\n");
139
140 sec_status = pEnumerateSecurityPackagesA(&num_packages, &pkg_info);
141
142 ok(sec_status == SEC_E_OK,
143 "EnumerateSecurityPackages() should return %d, not %08x\n",
144 SEC_E_OK, sec_status);
145
146 if (num_packages == 0)
147 {
148 todo_wine
149 ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %d\n",
150 num_packages);
151 skip("no sec packages to check\n");
152 return;
153 }
154 else
155 ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %d\n",
156 num_packages);
157
158 ok(pkg_info != NULL,
159 "pkg_info should not be NULL after EnumerateSecurityPackages\n");
160
161 trace("Number of packages: %d\n", num_packages);
162 for(i = 0; i < num_packages; ++i){
163 trace("%d: Package \"%s\"\n", i, pkg_info[i].Name);
164 trace("Supported flags:\n");
165 #define X(flag) \
166 if(pkg_info[i].fCapabilities & flag) \
167 trace("\t" #flag "\n")
168
169 X(SECPKG_FLAG_INTEGRITY);
170 X(SECPKG_FLAG_PRIVACY);
171 X(SECPKG_FLAG_TOKEN_ONLY);
172 X(SECPKG_FLAG_DATAGRAM);
173 X(SECPKG_FLAG_CONNECTION);
174 X(SECPKG_FLAG_MULTI_REQUIRED);
175 X(SECPKG_FLAG_CLIENT_ONLY);
176 X(SECPKG_FLAG_EXTENDED_ERROR);
177 X(SECPKG_FLAG_IMPERSONATION);
178 X(SECPKG_FLAG_ACCEPT_WIN32_NAME);
179 X(SECPKG_FLAG_STREAM);
180 X(SECPKG_FLAG_NEGOTIABLE);
181 X(SECPKG_FLAG_GSS_COMPATIBLE);
182 X(SECPKG_FLAG_LOGON);
183 X(SECPKG_FLAG_ASCII_BUFFERS);
184 X(SECPKG_FLAG_FRAGMENT);
185 X(SECPKG_FLAG_MUTUAL_AUTH);
186 X(SECPKG_FLAG_DELEGATION);
187 X(SECPKG_FLAG_READONLY_WITH_CHECKSUM);
188 X(SECPKG_FLAG_RESTRICTED_TOKENS);
189 X(SECPKG_FLAG_NEGO_EXTENDER);
190 X(SECPKG_FLAG_NEGOTIABLE2);
191 X(SECPKG_FLAG_APPCONTAINER_PASSTHROUGH);
192 X(SECPKG_FLAG_APPCONTAINER_CHECKS);
193 #undef X
194 trace("Comment: %s\n", pkg_info[i].Comment);
195 trace("\n");
196 }
197
198 pFreeContextBuffer(pkg_info);
199 }
200
201
testQuerySecurityPackageInfo(void)202 static void testQuerySecurityPackageInfo(void)
203 {
204 SECURITY_STATUS sec_status;
205 PSecPkgInfoA pkg_info;
206 static SEC_CHAR ntlm[] = "NTLM",
207 winetest[] = "Winetest";
208
209 trace("Running testQuerySecurityPackageInfo\n");
210
211 /* Test with an existing package. Test should pass */
212
213 pkg_info = (void *)0xdeadbeef;
214 sec_status = setupPackageA(ntlm, &pkg_info);
215
216 ok((sec_status == SEC_E_OK) || (sec_status == SEC_E_SECPKG_NOT_FOUND) ||
217 broken(sec_status == SEC_E_UNSUPPORTED_FUNCTION), /* win95 */
218 "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
219 getSecError(sec_status) );
220
221 if (sec_status == SEC_E_OK)
222 {
223 ok(pkg_info != (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
224 ok(pkg_info->wVersion == 1, "wVersion always should be 1, but is %d\n", pkg_info->wVersion);
225 /* there is no point in testing pkg_info->cbMaxToken since it varies
226 * between implementations.
227 */
228
229 sec_status = pFreeContextBuffer(pkg_info);
230 ok( sec_status == SEC_E_OK,
231 "Return value of FreeContextBuffer() shouldn't be %s\n",
232 getSecError(sec_status) );
233 }
234
235 /* Test with a nonexistent package, test should fail */
236
237 pkg_info = (void *)0xdeadbeef;
238 sec_status = pQuerySecurityPackageInfoA(winetest, &pkg_info);
239
240 ok( sec_status == SEC_E_SECPKG_NOT_FOUND,
241 "Return value of QuerySecurityPackageInfo() should be %s for a nonexistent package\n",
242 getSecError(SEC_E_SECPKG_NOT_FOUND));
243
244 ok(pkg_info == (void *)0xdeadbeef, "wrong pkg_info address %p\n", pkg_info);
245 }
246
START_TEST(main)247 START_TEST(main)
248 {
249 InitFunctionPtrs();
250 if(pInitSecurityInterfaceA)
251 testInitSecurityInterface();
252 if(pFreeContextBuffer)
253 {
254 if(pEnumerateSecurityPackagesA)
255 testEnumerateSecurityPackages();
256 if(pQuerySecurityPackageInfoA)
257 {
258 testQuerySecurityPackageInfo();
259 }
260 }
261 if(secdll)
262 FreeLibrary(secdll);
263 }
264