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 
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 
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 
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 
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 
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 
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 
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