PageRenderTime 69ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/dxp/apps/vldap/vldap-server/src/main/java/com/liferay/vldap/server/internal/handler/BindLdapHandler.java

http://github.com/liferay/liferay-portal
Java | 347 lines | 249 code | 81 blank | 17 comment | 41 complexity | 91d8eeff7bdcf72f7e1c291e012e897e MD5 | raw file
Possible License(s): LGPL-2.0
  1. /**
  2. * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
  3. *
  4. * The contents of this file are subject to the terms of the Liferay Enterprise
  5. * Subscription License ("License"). You may not use this file except in
  6. * compliance with the License. You can obtain a copy of the License by
  7. * contacting Liferay, Inc. See the License for the specific language governing
  8. * permissions and limitations under the License, including but not limited to
  9. * distribution rights of the Software.
  10. *
  11. *
  12. *
  13. */
  14. package com.liferay.vldap.server.internal.handler;
  15. import com.liferay.petra.string.StringBundler;
  16. import com.liferay.petra.string.StringPool;
  17. import com.liferay.portal.kernel.exception.NoSuchCompanyException;
  18. import com.liferay.portal.kernel.exception.PortalException;
  19. import com.liferay.portal.kernel.log.Log;
  20. import com.liferay.portal.kernel.log.LogFactoryUtil;
  21. import com.liferay.portal.kernel.model.Company;
  22. import com.liferay.portal.kernel.model.User;
  23. import com.liferay.portal.kernel.security.auth.Authenticator;
  24. import com.liferay.portal.kernel.service.CompanyLocalServiceUtil;
  25. import com.liferay.portal.kernel.service.UserLocalServiceUtil;
  26. import com.liferay.portal.kernel.util.GetterUtil;
  27. import com.liferay.portal.kernel.util.PortalUtil;
  28. import com.liferay.portal.kernel.util.StringUtil;
  29. import com.liferay.portal.kernel.util.Validator;
  30. import com.liferay.vldap.server.internal.handler.util.LdapHandlerContext;
  31. import com.liferay.vldap.server.internal.handler.util.LdapHandlerThreadLocal;
  32. import com.liferay.vldap.server.internal.handler.util.SaslCallbackHandler;
  33. import com.liferay.vldap.server.internal.util.PortletPropsValues;
  34. import java.net.InetSocketAddress;
  35. import java.util.HashMap;
  36. import java.util.List;
  37. import java.util.Map;
  38. import javax.security.sasl.Sasl;
  39. import javax.security.sasl.SaslException;
  40. import javax.security.sasl.SaslServer;
  41. import org.apache.directory.api.ldap.model.message.BindRequest;
  42. import org.apache.directory.api.ldap.model.message.BindResponse;
  43. import org.apache.directory.api.ldap.model.message.Request;
  44. import org.apache.directory.api.ldap.model.message.Response;
  45. import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
  46. import org.apache.directory.api.ldap.model.name.Dn;
  47. import org.apache.directory.api.ldap.model.name.Rdn;
  48. import org.apache.directory.api.util.StringConstants;
  49. import org.apache.mina.core.session.IoSession;
  50. /**
  51. * @author Jonathan Potter
  52. * @author Brian Wing Shun Chan
  53. */
  54. public class BindLdapHandler extends BaseLdapHandler {
  55. public static final String DIGEST_MD5 = "DIGEST-MD5";
  56. @Override
  57. public List<Response> messageReceived(
  58. Request request, IoSession ioSession,
  59. LdapHandlerContext ldapHandlerContext)
  60. throws PortalException {
  61. BindRequest bindRequest = (BindRequest)request;
  62. if (_log.isDebugEnabled()) {
  63. _log.debug(
  64. StringBundler.concat(
  65. "Bind request from ", ioSession.getRemoteAddress(), " for ",
  66. bindRequest.getName()));
  67. }
  68. String saslMechanism = GetterUtil.getString(
  69. bindRequest.getSaslMechanism());
  70. Response response = null;
  71. if (saslMechanism.equals(DIGEST_MD5)) {
  72. response = getSaslResponse(
  73. bindRequest, ioSession, ldapHandlerContext);
  74. }
  75. else if (bindRequest.isSimple()) {
  76. response = getSimpleResponse(bindRequest, ldapHandlerContext);
  77. }
  78. else {
  79. response = getUnsupportedResponse(bindRequest);
  80. }
  81. return toList(response);
  82. }
  83. protected String getSaslHostName(IoSession ioSession) {
  84. String saslHostName = PortletPropsValues.BIND_SASL_HOSTNAME;
  85. if (Validator.isNull(saslHostName)) {
  86. InetSocketAddress inetSocketAddress =
  87. (InetSocketAddress)ioSession.getLocalAddress();
  88. saslHostName = inetSocketAddress.getHostName();
  89. }
  90. if (_log.isDebugEnabled()) {
  91. _log.debug("SASL host name " + saslHostName);
  92. }
  93. return saslHostName;
  94. }
  95. protected Response getSaslResponse(
  96. BindRequest bindRequest, IoSession ioSession,
  97. LdapHandlerContext ldapHandlerContext)
  98. throws PortalException {
  99. if (bindRequest.getCredentials() == null) {
  100. bindRequest.setCredentials(StringConstants.EMPTY);
  101. }
  102. SaslServer saslServer = ldapHandlerContext.getSaslServer();
  103. try {
  104. if (saslServer == null) {
  105. synchronized (ldapHandlerContext) {
  106. saslServer = ldapHandlerContext.getSaslServer();
  107. if (saslServer == null) {
  108. SaslCallbackHandler saslCallbackHandler =
  109. new SaslCallbackHandler();
  110. ldapHandlerContext.setSaslCallbackHandler(
  111. saslCallbackHandler);
  112. saslServer = Sasl.createSaslServer(
  113. DIGEST_MD5, _LDAP, getSaslHostName(ioSession), null,
  114. saslCallbackHandler);
  115. ldapHandlerContext.setSaslServer(saslServer);
  116. }
  117. }
  118. }
  119. BindResponse bindResponse =
  120. (BindResponse)bindRequest.getResultResponse();
  121. byte[] challenge = saslServer.evaluateResponse(
  122. bindRequest.getCredentials());
  123. bindResponse.setServerSaslCreds(challenge);
  124. }
  125. catch (SaslException saslException) {
  126. _log.error(saslException, saslException);
  127. ldapHandlerContext.setSaslCallbackHandler(null);
  128. ldapHandlerContext.setSaslServer(null);
  129. return getResultResponse(
  130. bindRequest, ResultCodeEnum.INVALID_CREDENTIALS);
  131. }
  132. if (saslServer.isComplete()) {
  133. SaslCallbackHandler saslCallbackHandler =
  134. ldapHandlerContext.getSaslCallbackHandler();
  135. ldapHandlerContext.setSaslCallbackHandler(null);
  136. ldapHandlerContext.setSaslServer(null);
  137. Dn name = saslCallbackHandler.getName();
  138. setCompany(ldapHandlerContext, name);
  139. setUser(ldapHandlerContext, name);
  140. return getResultResponse(bindRequest, ResultCodeEnum.SUCCESS);
  141. }
  142. return getResultResponse(
  143. bindRequest, ResultCodeEnum.SASL_BIND_IN_PROGRESS);
  144. }
  145. protected Response getSimpleResponse(
  146. BindRequest bindRequest, LdapHandlerContext ldapHandlerContext)
  147. throws PortalException {
  148. Dn name = bindRequest.getDn();
  149. if (Validator.isNull(name.getName())) {
  150. return getResultResponse(bindRequest, ResultCodeEnum.SUCCESS);
  151. }
  152. Company company = setCompany(ldapHandlerContext, name);
  153. String screenName = getValue(name, "cn");
  154. if (Validator.isNull(screenName)) {
  155. screenName = getValue(name, "uid");
  156. }
  157. String emailAddress = getValue(name, "mail");
  158. String password = new String(bindRequest.getCredentials());
  159. Map<String, String[]> headerMap = new HashMap<>();
  160. Map<String, String[]> parameterMap = new HashMap<>();
  161. Map<String, Object> resultsMap = new HashMap<>();
  162. int authResult = Authenticator.FAILURE;
  163. if (Validator.isNotNull(screenName)) {
  164. authResult = UserLocalServiceUtil.authenticateByScreenName(
  165. company.getCompanyId(), screenName, password, headerMap,
  166. parameterMap, resultsMap);
  167. }
  168. else if (Validator.isNotNull(emailAddress)) {
  169. if (isEmailAddressWhitelisted(emailAddress)) {
  170. authResult = Authenticator.SUCCESS;
  171. }
  172. else {
  173. authResult = UserLocalServiceUtil.authenticateByEmailAddress(
  174. company.getCompanyId(), emailAddress, password, headerMap,
  175. parameterMap, resultsMap);
  176. }
  177. }
  178. if (authResult != Authenticator.SUCCESS) {
  179. return getResultResponse(
  180. bindRequest, ResultCodeEnum.INVALID_CREDENTIALS);
  181. }
  182. setUser(ldapHandlerContext, name);
  183. return getResultResponse(bindRequest, ResultCodeEnum.SUCCESS);
  184. }
  185. protected Response getUnsupportedResponse(BindRequest bindRequest) {
  186. return getResultResponse(
  187. bindRequest, ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED);
  188. }
  189. protected String getValue(Dn dn, String normType) {
  190. for (Rdn rdn : dn) {
  191. if (StringUtil.equalsIgnoreCase(rdn.getNormType(), normType)) {
  192. return GetterUtil.getString(rdn.getValue());
  193. }
  194. }
  195. return StringPool.BLANK;
  196. }
  197. protected boolean isEmailAddressWhitelisted(String emailAddress) {
  198. for (String allowedEmailAddress :
  199. PortletPropsValues.EMAIL_ADDRESSES_WHITELIST) {
  200. String[] parts = StringUtil.split(
  201. allowedEmailAddress, StringPool.COLON);
  202. if (!emailAddress.equals(parts[0])) {
  203. continue;
  204. }
  205. if (parts.length == 1) {
  206. return true;
  207. }
  208. String[] hostsAllowed = StringUtil.split(
  209. parts[1], StringPool.SEMICOLON);
  210. if (LdapHandlerThreadLocal.isHostAllowed(hostsAllowed)) {
  211. return true;
  212. }
  213. }
  214. return false;
  215. }
  216. protected Company setCompany(LdapHandlerContext ldapHandlerContext, Dn name)
  217. throws PortalException {
  218. String webId = getValue(name, "webId");
  219. Company company = null;
  220. try {
  221. company = CompanyLocalServiceUtil.getCompanyByWebId(webId);
  222. }
  223. catch (NoSuchCompanyException noSuchCompanyException) {
  224. if (_log.isWarnEnabled()) {
  225. _log.warn(
  226. "Unable to get company with web ID " + webId,
  227. noSuchCompanyException);
  228. }
  229. long companyId = PortalUtil.getDefaultCompanyId();
  230. company = CompanyLocalServiceUtil.getCompany(companyId);
  231. }
  232. ldapHandlerContext.setCompany(company);
  233. return company;
  234. }
  235. protected void setUser(LdapHandlerContext ldapHandlerContext, Dn name)
  236. throws PortalException {
  237. User user = null;
  238. boolean allowDefaultUser = false;
  239. String screenName = getValue(name, "cn");
  240. if (Validator.isNull(screenName)) {
  241. screenName = getValue(name, "uid");
  242. }
  243. String emailAddress = getValue(name, "mail");
  244. if (Validator.isNotNull(screenName)) {
  245. user = UserLocalServiceUtil.fetchUserByScreenName(
  246. ldapHandlerContext.getCompanyId(), screenName);
  247. }
  248. else if (Validator.isNotNull(emailAddress)) {
  249. if (isEmailAddressWhitelisted(emailAddress)) {
  250. user = UserLocalServiceUtil.getDefaultUser(
  251. ldapHandlerContext.getCompanyId());
  252. allowDefaultUser = true;
  253. }
  254. else {
  255. user = UserLocalServiceUtil.fetchUserByEmailAddress(
  256. ldapHandlerContext.getCompanyId(), emailAddress);
  257. }
  258. }
  259. if ((user != null) && (!user.isDefaultUser() || allowDefaultUser)) {
  260. ldapHandlerContext.setUser(user);
  261. }
  262. }
  263. private static final String _LDAP = "ldap";
  264. private static final Log _log = LogFactoryUtil.getLog(
  265. BindLdapHandler.class);
  266. }