001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.jlan; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsUser; 032import org.opencms.main.CmsException; 033import org.opencms.main.CmsLog; 034import org.opencms.main.OpenCms; 035 036import java.security.InvalidKeyException; 037import java.security.NoSuchAlgorithmException; 038 039import org.apache.commons.logging.Log; 040 041import org.alfresco.jlan.server.auth.PasswordEncryptor; 042import org.alfresco.jlan.server.auth.UserAccount; 043import org.alfresco.jlan.server.auth.UsersInterface; 044import org.alfresco.jlan.server.config.ServerConfiguration; 045import org.springframework.extensions.config.ConfigElement; 046 047/** 048 * This class is used for authenticating OpenCms users to JLAN.<p> 049 * 050 * Since JLAN requires MD4 password hashes for authentication, which are not by default stored in the database, 051 * users who want to use the JLAN functionality should log in at least once into OpenCms normally so that the MD4 052 * hash of their password can be computed and stored.<p> 053 * 054 */ 055public class CmsJlanUsers implements UsersInterface { 056 057 /** The default OU separator to use if none is configured. */ 058 public static final String DEFAULT_OU_SEPARATOR = "___"; 059 060 /** The additional info key for the MD4 password hash. */ 061 public static final String JLAN_HASH = "jlan_hash"; 062 063 /** Name of the runtime property used to configure the OU separator for CIFS login. */ 064 public static final String PARAM_JLAN_OU_SEPARATOR = "jlan.ou.separator"; 065 066 /** The logger instance for this class. */ 067 private static final Log LOG = CmsLog.getLog(CmsJlanUsers.class); 068 069 /** The CMS context. */ 070 private static CmsObject m_adminCms; 071 072 /** 073 * Computes an MD4 hash for the password. 074 * 075 * @param password the password for which to compute the hash 076 * @throws NoSuchAlgorithmException 077 * @throws InvalidKeyException 078 * 079 * @return the password hash 080 **/ 081 public static byte[] hashPassword(String password) throws InvalidKeyException, NoSuchAlgorithmException { 082 083 PasswordEncryptor encryptor = new PasswordEncryptor(); 084 return encryptor.generateEncryptedPassword(password, null, PasswordEncryptor.MD4, null, null); 085 } 086 087 /** 088 * Sets the CMS context.<p> 089 * 090 * @param cms the context to set 091 */ 092 public static void setAdminCms(CmsObject cms) { 093 094 if (m_adminCms == null) { 095 m_adminCms = cms; 096 } else { 097 LOG.warn("Can't set admin CmsObject twice!"); 098 } 099 } 100 101 /** 102 * Translates user names by replacing a custom OU separator with the standard OU separator '/'. 103 * 104 * This is needed because either JLAN or the client cuts off the part before the slash during authentication, 105 * so OpenCms never gets to see it. So if we want CIFS authentication for users from non-root OUs, we need to use 106 * a different separator.<p> 107 * 108 * @param name the user name to translate 109 * 110 * @return the translated user name 111 */ 112 public static final String translateUser(String name) { 113 114 String ouSeparator = (String)(OpenCms.getRuntimeProperty(PARAM_JLAN_OU_SEPARATOR)); 115 if (ouSeparator == null) { 116 ouSeparator = DEFAULT_OU_SEPARATOR; 117 } 118 String result = name; 119 result = result.replace(ouSeparator, "/"); 120 return result; 121 } 122 123 /** 124 * @see org.alfresco.jlan.server.auth.UsersInterface#getUserAccount(java.lang.String) 125 */ 126 public UserAccount getUserAccount(String userName) { 127 128 try { 129 userName = translateUser(userName); 130 CmsUser user = m_adminCms.readUser(userName); 131 UserAccount account = new UserAccount(userName, ""); 132 Object jlanHash = user.getAdditionalInfo(JLAN_HASH); 133 if (OpenCms.getTwoFactorAuthenticationHandler().needsTwoFactorAuthentication(user)) { 134 LOG.warn("JLAN: Users for who two-factor authentication is enabled cannot access the network share."); 135 } 136 if (jlanHash != null) { 137 account.setMD4Password((byte[])jlanHash); 138 } else { 139 LOG.warn("JLAN: Could not log in user " + userName + " because of missing hash"); 140 return null; 141 } 142 return account; 143 } catch (CmsException e) { 144 return null; 145 } 146 } 147 148 /** 149 * @see org.alfresco.jlan.server.auth.UsersInterface#initializeUsers(org.alfresco.jlan.server.config.ServerConfiguration, org.springframework.extensions.config.ConfigElement) 150 */ 151 public void initializeUsers(ServerConfiguration config, ConfigElement params) { 152 153 // do nothing 154 } 155}