/Source/JNA/waffle-tests/src/test/java/waffle/jaas/WindowsLoginModuleTests.java

http://github.com/dblock/waffle · Java · 349 lines · 236 code · 25 blank · 88 comment · 16 complexity · 1ae238aafa95954f4ff1928cbf983dd1 MD5 · raw file

  1. /**
  2. * Waffle (https://github.com/Waffle/waffle)
  3. *
  4. * Copyright (c) 2010-2018 Application Security, Inc.
  5. *
  6. * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
  7. * Public License v1.0 which accompanies this distribution, and is available at
  8. * https://www.eclipse.org/legal/epl-v10.html.
  9. *
  10. * Contributors: Application Security, Inc.
  11. */
  12. package waffle.jaas;
  13. import static org.assertj.core.api.Assertions.assertThat;
  14. import java.security.Principal;
  15. import java.util.Enumeration;
  16. import java.util.HashMap;
  17. import java.util.Map;
  18. import javax.security.auth.Subject;
  19. import javax.security.auth.login.LoginException;
  20. import org.junit.jupiter.api.Assertions;
  21. import org.junit.jupiter.api.BeforeEach;
  22. import org.junit.jupiter.api.Test;
  23. import waffle.mock.MockWindowsAuthProvider;
  24. import waffle.windows.auth.impl.WindowsAccountImpl;
  25. /**
  26. * The Class WindowsLoginModuleTests.
  27. *
  28. * @author dblock[at]dblock[dot]org
  29. */
  30. public class WindowsLoginModuleTests {
  31. /** The login module. */
  32. WindowsLoginModule loginModule;
  33. /** The provider. */
  34. MockWindowsAuthProvider provider;
  35. /**
  36. * Sets the up.
  37. */
  38. @BeforeEach
  39. public void setUp() {
  40. this.provider = new MockWindowsAuthProvider();
  41. this.loginModule = new WindowsLoginModule();
  42. this.loginModule.setAuth(this.provider);
  43. }
  44. /**
  45. * Test initialize.
  46. */
  47. @Test
  48. public void testInitialize() {
  49. final Subject subject = new Subject();
  50. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("", "");
  51. final Map<String, String> options = new HashMap<>();
  52. options.put("debug", "true");
  53. this.loginModule.initialize(subject, callbackHandler, null, options);
  54. Assertions.assertTrue(this.loginModule.isDebug());
  55. }
  56. /**
  57. * Test get set auth.
  58. */
  59. @Test
  60. public void testGetSetAuth() {
  61. Assertions.assertNotNull(this.loginModule.getAuth());
  62. this.loginModule.setAuth(null);
  63. Assertions.assertNull(this.loginModule.getAuth());
  64. }
  65. /**
  66. * Test login.
  67. *
  68. * @throws LoginException
  69. * the login exception
  70. */
  71. @Test
  72. public void testLogin() throws LoginException {
  73. final Subject subject = new Subject();
  74. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  75. WindowsAccountImpl.getCurrentUsername(), "password");
  76. final Map<String, String> options = new HashMap<>();
  77. options.put("debug", "true");
  78. this.loginModule.initialize(subject, callbackHandler, null, options);
  79. Assertions.assertTrue(this.loginModule.login());
  80. Assertions.assertEquals(0, subject.getPrincipals().size());
  81. Assertions.assertTrue(this.loginModule.commit());
  82. Assertions.assertEquals(2, subject.getPrincipals().size());
  83. Assertions.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
  84. for (final Principal principal : subject.getPrincipals()) {
  85. if (principal instanceof GroupPrincipal) {
  86. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
  87. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
  88. }
  89. }
  90. Assertions.assertTrue(
  91. subject.getPrincipals().contains(new UserPrincipal(WindowsAccountImpl.getCurrentUsername())));
  92. Assertions.assertTrue(this.loginModule.logout());
  93. Assertions.assertSame(Integer.valueOf(subject.getPrincipals().size()), Integer.valueOf(0));
  94. }
  95. /**
  96. * Test no callback handler.
  97. *
  98. * @throws LoginException
  99. * the login exception
  100. */
  101. @Test
  102. public void testNoCallbackHandler() throws LoginException {
  103. final Subject subject = new Subject();
  104. final Map<String, String> options = new HashMap<>();
  105. this.loginModule.initialize(subject, null, null, options);
  106. Assertions.assertThrows(LoginException.class, () -> {
  107. this.loginModule.login();
  108. });
  109. }
  110. /**
  111. * Test login no username.
  112. *
  113. * @throws LoginException
  114. * the login exception
  115. */
  116. @Test
  117. public void testLoginNoUsername() throws LoginException {
  118. final Subject subject = new Subject();
  119. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("", "");
  120. final Map<String, String> options = new HashMap<>();
  121. options.put("debug", "true");
  122. this.loginModule.initialize(subject, callbackHandler, null, options);
  123. final Throwable exception = Assertions.assertThrows(LoginException.class, () -> {
  124. Assertions.assertFalse(this.loginModule.login());
  125. });
  126. Assertions.assertEquals("Mock error: ", exception.getMessage());
  127. }
  128. /**
  129. * Test role format none.
  130. *
  131. * @throws LoginException
  132. * the login exception
  133. */
  134. @Test
  135. public void testRoleFormatNone() throws LoginException {
  136. final Subject subject = new Subject();
  137. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  138. WindowsAccountImpl.getCurrentUsername(), "password");
  139. final Map<String, String> options = new HashMap<>();
  140. options.put("debug", "true");
  141. options.put("roleFormat", "none");
  142. this.loginModule.initialize(subject, callbackHandler, null, options);
  143. Assertions.assertTrue(this.loginModule.login());
  144. Assertions.assertTrue(this.loginModule.commit());
  145. Assertions.assertEquals(1, subject.getPrincipals().size());
  146. }
  147. /**
  148. * Test role format both.
  149. *
  150. * @throws LoginException
  151. * the login exception
  152. */
  153. @Test
  154. public void testRoleFormatBoth() throws LoginException {
  155. final Subject subject = new Subject();
  156. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  157. WindowsAccountImpl.getCurrentUsername(), "password");
  158. final Map<String, String> options = new HashMap<>();
  159. options.put("debug", "true");
  160. options.put("roleFormat", "both");
  161. this.loginModule.initialize(subject, callbackHandler, null, options);
  162. Assertions.assertTrue(this.loginModule.login());
  163. Assertions.assertTrue(this.loginModule.commit());
  164. Assertions.assertEquals(2, subject.getPrincipals().size());
  165. Assertions.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
  166. for (final Principal principal : subject.getPrincipals()) {
  167. if (principal instanceof GroupPrincipal) {
  168. int size = 0;
  169. int sidSize = 0;
  170. final Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
  171. while (groupPrincipal.hasMoreElements()) {
  172. if (groupPrincipal.nextElement().getName().startsWith("S-")) {
  173. sidSize++;
  174. }
  175. size++;
  176. }
  177. Assertions.assertEquals(4, size);
  178. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
  179. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
  180. Assertions.assertEquals(2, sidSize);
  181. }
  182. }
  183. }
  184. /**
  185. * Test principal format both.
  186. *
  187. * @throws LoginException
  188. * the login exception
  189. */
  190. @Test
  191. public void testPrincipalFormatBoth() throws LoginException {
  192. final Subject subject = new Subject();
  193. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  194. WindowsAccountImpl.getCurrentUsername(), "password");
  195. final Map<String, String> options = new HashMap<>();
  196. options.put("debug", "true");
  197. options.put("principalFormat", "both");
  198. options.put("roleFormat", "none");
  199. this.loginModule.initialize(subject, callbackHandler, null, options);
  200. Assertions.assertTrue(this.loginModule.login());
  201. Assertions.assertTrue(this.loginModule.commit());
  202. Assertions.assertEquals(2, subject.getPrincipals().size());
  203. }
  204. /**
  205. * Test role format sid.
  206. *
  207. * @throws LoginException
  208. * the login exception
  209. */
  210. @Test
  211. public void testRoleFormatSid() throws LoginException {
  212. final Subject subject = new Subject();
  213. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  214. WindowsAccountImpl.getCurrentUsername(), "password");
  215. final Map<String, String> options = new HashMap<>();
  216. options.put("debug", "true");
  217. options.put("roleFormat", "sid");
  218. this.loginModule.initialize(subject, callbackHandler, null, options);
  219. Assertions.assertTrue(this.loginModule.login());
  220. Assertions.assertTrue(this.loginModule.commit());
  221. Assertions.assertEquals(2, subject.getPrincipals().size());
  222. Assertions.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
  223. for (final Principal principal : subject.getPrincipals()) {
  224. if (principal instanceof GroupPrincipal) {
  225. int size = 0;
  226. final Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
  227. while (groupPrincipal.hasMoreElements()) {
  228. if (groupPrincipal.nextElement().getName().startsWith("S-")) {
  229. size++;
  230. }
  231. }
  232. Assertions.assertEquals(2, size);
  233. } else {
  234. Assertions.assertTrue(principal.getName().equals(WindowsAccountImpl.getCurrentUsername()));
  235. }
  236. }
  237. }
  238. /**
  239. * Test role unique.
  240. *
  241. * @throws LoginException
  242. * the login exception
  243. */
  244. @Test
  245. public void testRoleUnique() throws LoginException {
  246. final Subject subject = new Subject();
  247. // the mock has an "Everyone" group
  248. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler(
  249. WindowsAccountImpl.getCurrentUsername(), "password");
  250. this.provider.addGroup("Group 1");
  251. this.provider.addGroup("Group 1");
  252. final Map<String, String> options = new HashMap<>();
  253. options.put("debug", "true");
  254. this.loginModule.initialize(subject, callbackHandler, null, options);
  255. Assertions.assertTrue(this.loginModule.login());
  256. Assertions.assertTrue(this.loginModule.commit());
  257. Assertions.assertEquals(2, subject.getPrincipals().size());
  258. Assertions.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
  259. for (final Principal principal : subject.getPrincipals()) {
  260. if (principal instanceof GroupPrincipal) {
  261. int size = 0;
  262. final Enumeration<? extends Principal> groupPrincipal = ((GroupPrincipal) principal).members();
  263. while (groupPrincipal.hasMoreElements()) {
  264. groupPrincipal.nextElement();
  265. size++;
  266. }
  267. Assertions.assertEquals(3, size);
  268. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
  269. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
  270. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Group 1")));
  271. }
  272. }
  273. }
  274. /**
  275. * Test guest login.
  276. *
  277. * @throws LoginException
  278. * the login exception
  279. */
  280. @Test
  281. public void testGuestLogin() throws LoginException {
  282. final Subject subject = new Subject();
  283. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("Guest",
  284. "password");
  285. final Map<String, String> options = new HashMap<>();
  286. options.put("debug", "true");
  287. this.loginModule.initialize(subject, callbackHandler, null, options);
  288. Assertions.assertTrue(this.loginModule.isAllowGuestLogin());
  289. Assertions.assertTrue(this.loginModule.login());
  290. Assertions.assertEquals(0, subject.getPrincipals().size());
  291. Assertions.assertTrue(this.loginModule.commit());
  292. Assertions.assertEquals(2, subject.getPrincipals().size());
  293. Assertions.assertTrue(subject.getPrincipals().contains(new GroupPrincipal("Roles")));
  294. for (final Principal principal : subject.getPrincipals()) {
  295. if (principal instanceof GroupPrincipal) {
  296. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Everyone")));
  297. Assertions.assertTrue(((GroupPrincipal) principal).isMember(new RolePrincipal("Users")));
  298. }
  299. }
  300. this.loginModule.setAllowGuestLogin(false);
  301. final Throwable exception = Assertions.assertThrows(LoginException.class, () -> {
  302. Assertions.assertTrue(this.loginModule.login());
  303. });
  304. Assertions.assertEquals("Guest login disabled", exception.getMessage());
  305. }
  306. /**
  307. * Test abort.
  308. *
  309. * @throws LoginException
  310. * the login exception
  311. */
  312. @Test
  313. public void testAbort() throws LoginException {
  314. final Subject subject = new Subject();
  315. final UsernamePasswordCallbackHandler callbackHandler = new UsernamePasswordCallbackHandler("Guest",
  316. "password");
  317. final Map<String, String> options = new HashMap<>();
  318. options.put("debug", "true");
  319. this.loginModule.initialize(subject, callbackHandler, null, options);
  320. Assertions.assertTrue(this.loginModule.login());
  321. this.loginModule.abort();
  322. assertThat(subject.getPrincipals().size()).isEqualTo(0);
  323. }
  324. }