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