1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package waffle.windows.auth;
25
26 import static org.assertj.core.api.Assertions.assertThat;
27
28 import com.sun.jna.WString;
29 import com.sun.jna.platform.win32.Advapi32Util;
30 import com.sun.jna.platform.win32.LMAccess;
31 import com.sun.jna.platform.win32.LMErr;
32 import com.sun.jna.platform.win32.LMJoin;
33 import com.sun.jna.platform.win32.Netapi32;
34 import com.sun.jna.platform.win32.Netapi32Util;
35 import com.sun.jna.platform.win32.Sspi;
36 import com.sun.jna.platform.win32.SspiUtil.ManagedSecBufferDesc;
37
38 import java.util.Base64;
39
40 import org.junit.jupiter.api.Assertions;
41 import org.junit.jupiter.api.Assumptions;
42 import org.junit.jupiter.api.Disabled;
43 import org.junit.jupiter.api.Test;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 import waffle.mock.MockWindowsAccount;
48 import waffle.windows.auth.impl.WindowsAccountImpl;
49 import waffle.windows.auth.impl.WindowsAuthProviderImpl;
50 import waffle.windows.auth.impl.WindowsCredentialsHandleImpl;
51 import waffle.windows.auth.impl.WindowsSecurityContextImpl;
52
53
54
55
56 class WindowsAuthProviderTest {
57
58
59 private static final Logger LOGGER = LoggerFactory.getLogger(WindowsAuthProviderTest.class);
60
61
62
63
64
65 @Disabled
66 @Test
67 void testLogonGuestUser() {
68 final IWindowsAuthProvider prov = new WindowsAuthProviderImpl();
69 final IWindowsIdentity identity = prov.logonUser("garbage", "garbage");
70 WindowsAuthProviderTest.LOGGER.info("Fqn: {}", identity.getFqn());
71 WindowsAuthProviderTest.LOGGER.info("Guest: {}", Boolean.valueOf(identity.isGuest()));
72 Assertions.assertTrue(identity.getFqn().endsWith("\\Guest"));
73 Assertions.assertTrue(identity.isGuest());
74 identity.dispose();
75 }
76
77
78
79
80 @Test
81 void testLogonUser() {
82 final LMAccess.USER_INFO_1 userInfo = new LMAccess.USER_INFO_1();
83 userInfo.usri1_name = new WString("WaffleTestUser").toString();
84 userInfo.usri1_password = new WString("!WAFFLEP$$Wrd0").toString();
85 userInfo.usri1_priv = LMAccess.USER_PRIV_USER;
86
87 Assumptions.assumeTrue(LMErr.NERR_Success == Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null));
88 try {
89 final IWindowsAuthProvider prov = new WindowsAuthProviderImpl();
90 final IWindowsIdentity identity = prov.logonUser(userInfo.usri1_name, userInfo.usri1_password.toString());
91 Assertions.assertTrue(identity.getFqn().endsWith("\\" + userInfo.usri1_name));
92 Assertions.assertFalse(identity.isGuest());
93 identity.dispose();
94 } finally {
95 Assertions.assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel(null, userInfo.usri1_name));
96 }
97 }
98
99
100
101
102 @Test
103 void testImpersonateLoggedOnUser() {
104 final LMAccess.USER_INFO_1 userInfo = new LMAccess.USER_INFO_1();
105 userInfo.usri1_name = new WString(MockWindowsAccount.TEST_USER_NAME).toString();
106 userInfo.usri1_password = new WString(MockWindowsAccount.TEST_PASSWORD).toString();
107 userInfo.usri1_priv = LMAccess.USER_PRIV_USER;
108
109 Assumptions.assumeTrue(LMErr.NERR_Success == Netapi32.INSTANCE.NetUserAdd(null, 1, userInfo, null));
110 try {
111 final IWindowsAuthProvider prov = new WindowsAuthProviderImpl();
112 final IWindowsIdentity identity = prov.logonUser(userInfo.usri1_name, userInfo.usri1_password);
113 final IWindowsImpersonationContext ctx = identity.impersonate();
114 Assertions.assertEquals(userInfo.usri1_name, Advapi32Util.getUserName());
115 ctx.revertToSelf();
116 Assertions.assertNotEquals(userInfo.usri1_name, Advapi32Util.getUserName());
117 identity.dispose();
118 } finally {
119 Assertions.assertEquals(LMErr.NERR_Success, Netapi32.INSTANCE.NetUserDel(null, userInfo.usri1_name));
120 }
121 }
122
123
124
125
126 @Test
127 void testGetCurrentComputer() {
128 final IWindowsAuthProvider prov = new WindowsAuthProviderImpl();
129 final IWindowsComputer computer = prov.getCurrentComputer();
130 WindowsAuthProviderTest.LOGGER.info(computer.getComputerName());
131 assertThat(computer.getComputerName()).isNotEmpty();
132 WindowsAuthProviderTest.LOGGER.info(computer.getJoinStatus());
133 WindowsAuthProviderTest.LOGGER.info(computer.getMemberOf());
134 final String[] localGroups = computer.getGroups();
135 Assertions.assertNotNull(localGroups);
136 assertThat(localGroups).isNotEmpty();
137 for (final String localGroup : localGroups) {
138 WindowsAuthProviderTest.LOGGER.info(" {}", localGroup);
139 }
140 }
141
142
143
144
145 @Test
146 void testGetDomains() {
147 if (Netapi32Util.getJoinStatus() != LMJoin.NETSETUP_JOIN_STATUS.NetSetupDomainName) {
148 return;
149 }
150
151 final IWindowsAuthProvider prov = new WindowsAuthProviderImpl();
152 final IWindowsDomain[] domains = prov.getDomains();
153 Assertions.assertNotNull(domains);
154 for (final IWindowsDomain domain : domains) {
155 WindowsAuthProviderTest.LOGGER.info("{}: {}", domain.getFqn(), domain.getTrustDirectionString());
156 }
157 }
158
159
160
161
162 @Test
163 void testAcceptSecurityToken() {
164 final String securityPackage = "Negotiate";
165 final String targetName = "localhost";
166 IWindowsCredentialsHandle clientCredentials = null;
167 WindowsSecurityContextImpl clientContext = null;
168 IWindowsSecurityContext serverContext = null;
169 try {
170
171 clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
172 clientCredentials.initialize();
173
174 clientContext = new WindowsSecurityContextImpl();
175 clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
176 clientContext.setCredentialsHandle(clientCredentials);
177 clientContext.setSecurityPackage(securityPackage);
178 clientContext.initialize(null, null, targetName);
179
180 final WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
181 final String connectionId = "testConnection-" + Thread.currentThread().getId();
182 do {
183
184 serverContext = provider.acceptSecurityToken(connectionId, clientContext.getToken(), securityPackage);
185
186 if (serverContext != null && serverContext.isContinue()) {
187
188 final ManagedSecBufferDesc continueToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN,
189 serverContext.getToken());
190 clientContext.initialize(clientContext.getHandle(), continueToken, targetName);
191 WindowsAuthProviderTest.LOGGER.info("Token: {}",
192 Base64.getEncoder().encodeToString(serverContext.getToken()));
193 }
194
195 } while (serverContext != null && serverContext.isContinue());
196
197 if (serverContext != null) {
198 assertThat(serverContext.getIdentity().getFqn()).isNotEmpty();
199
200 WindowsAuthProviderTest.LOGGER.info(serverContext.getIdentity().getFqn());
201 for (final IWindowsAccount group : serverContext.getIdentity().getGroups()) {
202 WindowsAuthProviderTest.LOGGER.info(" {}", group.getFqn());
203 }
204 }
205 } finally {
206 if (serverContext != null) {
207 serverContext.dispose();
208 }
209 if (clientContext != null) {
210 clientContext.dispose();
211 }
212 if (clientCredentials != null) {
213 clientCredentials.dispose();
214 }
215 }
216 }
217
218
219
220
221
222
223
224 @Test
225 void testSecurityContextsExpire() throws InterruptedException {
226 final String securityPackage = "Negotiate";
227 IWindowsCredentialsHandle clientCredentials = null;
228 WindowsSecurityContextImpl clientContext = null;
229 IWindowsSecurityContext serverContext = null;
230 try {
231
232 clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
233 clientCredentials.initialize();
234
235 clientContext = new WindowsSecurityContextImpl();
236 clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
237 clientContext.setCredentialsHandle(clientCredentials);
238 clientContext.setSecurityPackage(securityPackage);
239 clientContext.initialize(null, null, WindowsAccountImpl.getCurrentUsername());
240
241 final WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl(1);
242 final int max = 100;
243 for (int i = 0; i < max; i++) {
244 Thread.sleep(25);
245 final String connectionId = "testConnection_" + i;
246 serverContext = provider.acceptSecurityToken(connectionId, clientContext.getToken(), securityPackage);
247 assertThat(provider.getContinueContextsSize()).isPositive();
248 }
249 WindowsAuthProviderTest.LOGGER.info("Cached security contexts: {}",
250 Integer.valueOf(provider.getContinueContextsSize()));
251 Assertions.assertNotEquals(max, provider.getContinueContextsSize());
252 } finally {
253 if (serverContext != null) {
254 serverContext.dispose();
255 }
256 if (clientContext != null) {
257 clientContext.dispose();
258 }
259 if (clientCredentials != null) {
260 clientCredentials.dispose();
261 }
262 }
263 }
264
265
266
267
268 @Test
269 void testAcceptAndImpersonateSecurityToken() {
270 final String securityPackage = "Negotiate";
271 final String targetName = "localhost";
272 IWindowsCredentialsHandle clientCredentials = null;
273 WindowsSecurityContextImpl clientContext = null;
274 IWindowsSecurityContext serverContext = null;
275 try {
276
277 clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
278 clientCredentials.initialize();
279
280 clientContext = new WindowsSecurityContextImpl();
281 clientContext.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
282 clientContext.setCredentialsHandle(clientCredentials);
283 clientContext.setSecurityPackage(securityPackage);
284 clientContext.initialize(null, null, targetName);
285
286 final WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
287 final String connectionId = "testConnection";
288 do {
289
290 serverContext = provider.acceptSecurityToken(connectionId, clientContext.getToken(), securityPackage);
291
292 if (serverContext != null && serverContext.isContinue()) {
293
294 final ManagedSecBufferDesc continueToken = new ManagedSecBufferDesc(Sspi.SECBUFFER_TOKEN,
295 serverContext.getToken());
296 clientContext.initialize(clientContext.getHandle(), continueToken, targetName);
297 }
298
299 } while (serverContext != null && serverContext.isContinue());
300
301 if (serverContext != null) {
302 assertThat(serverContext.getIdentity().getFqn()).isNotEmpty();
303
304 final IWindowsImpersonationContext impersonationCtx = serverContext.impersonate();
305 impersonationCtx.revertToSelf();
306
307 WindowsAuthProviderTest.LOGGER.info(serverContext.getIdentity().getFqn());
308 for (final IWindowsAccount group : serverContext.getIdentity().getGroups()) {
309 WindowsAuthProviderTest.LOGGER.info(" {}", group.getFqn());
310 }
311 }
312 } finally {
313 if (serverContext != null) {
314 serverContext.dispose();
315 }
316 if (clientContext != null) {
317 clientContext.dispose();
318 }
319 if (clientCredentials != null) {
320 clientCredentials.dispose();
321 }
322 }
323 }
324 }