mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Moving to root below branch label
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
||||
import org.alfresco.filesys.util.DataPacker;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
|
||||
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
|
||||
import org.alfresco.repo.security.authentication.NTLMMode;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Alfresco Authenticator Class
|
||||
*
|
||||
* <p>The Alfresco authenticator implementation enables user level security mode using the Alfresco authentication
|
||||
* component.
|
||||
*
|
||||
* <p>Note: Switching off encrypted password support will cause later NT4 service pack releases and
|
||||
* Win2000 to refuse to connect to the server without a registry update on the client.
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public class AlfrescoAuthenticator extends SrvAuthenticator
|
||||
{
|
||||
// Logging
|
||||
|
||||
private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth");
|
||||
|
||||
// Random number generator used to generate challenge keys
|
||||
|
||||
private Random m_random = new Random(System.currentTimeMillis());
|
||||
|
||||
// Server configuration
|
||||
|
||||
private ServerConfiguration m_config;
|
||||
|
||||
// Authentication component, used to access internal authentication functions
|
||||
|
||||
private AuthenticationComponent m_authComponent;
|
||||
|
||||
// MD4 hash decoder
|
||||
|
||||
private MD4PasswordEncoder m_md4Encoder = new MD4PasswordEncoderImpl();
|
||||
|
||||
// Various services required to get user information
|
||||
|
||||
private NodeService m_nodeService;
|
||||
private PersonService m_personService;
|
||||
private TransactionService m_transactionService;
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*
|
||||
* <p>Default to user mode security with encrypted password support.
|
||||
*/
|
||||
public AlfrescoAuthenticator()
|
||||
{
|
||||
setAccessMode(SrvAuthenticator.USER_MODE);
|
||||
setEncryptedPasswords(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the connection to a share
|
||||
*
|
||||
* @param client ClienInfo
|
||||
* @param share SharedDevice
|
||||
* @param pwd Share level password.
|
||||
* @param sess Server session
|
||||
* @return Authentication status.
|
||||
*/
|
||||
public int authenticateShareConnect(ClientInfo client, SharedDevice share, String pwd, SrvSession sess)
|
||||
{
|
||||
// Allow write access
|
||||
//
|
||||
// Main authentication is handled by authenticateUser()
|
||||
|
||||
return SrvAuthenticator.Writeable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user
|
||||
*
|
||||
* @param client Client information
|
||||
* @param sess Server session
|
||||
* @param alg Encryption algorithm
|
||||
*/
|
||||
public int authenticateUser(ClientInfo client, SrvSession sess, int alg)
|
||||
{
|
||||
// Check if this is an SMB/CIFS null session logon.
|
||||
//
|
||||
// The null session will only be allowed to connect to the IPC$ named pipe share.
|
||||
|
||||
if (client.isNullSession() && sess instanceof SMBSrvSession)
|
||||
{
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Null CIFS logon allowed");
|
||||
|
||||
return SrvAuthenticator.AUTH_ALLOW;
|
||||
}
|
||||
|
||||
// Check if the client is already authenticated, and it is not a null logon
|
||||
|
||||
if ( client.getAuthenticationToken() != null && client.getLogonType() != ClientInfo.LogonNull)
|
||||
{
|
||||
// Use the existing authentication token
|
||||
|
||||
m_authComponent.setCurrentUser(client.getUserName());
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Re-using existing authentication token");
|
||||
|
||||
// Return the authentication status
|
||||
|
||||
return client.getLogonType() != ClientInfo.LogonGuest ? AUTH_ALLOW : AUTH_GUEST;
|
||||
}
|
||||
|
||||
// Check if MD4 or passthru mode is configured
|
||||
|
||||
int authSts = AUTH_DISALLOW;
|
||||
|
||||
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
{
|
||||
// Perform local MD4 password check
|
||||
|
||||
authSts = doMD4UserAuthentication(client, sess, alg);
|
||||
}
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Authenticated user " + client.getUserName() + " sts=" + getStatusAsString(authSts) +
|
||||
" via " + (m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER ? "MD4" : "Passthru"));
|
||||
|
||||
// Return the authentication status
|
||||
|
||||
return authSts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a challenge key
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getChallengeKey(SrvSession sess)
|
||||
{
|
||||
// In MD4 mode we generate the challenge locally
|
||||
|
||||
byte[] key = null;
|
||||
|
||||
// Check if the client is already authenticated, and it is not a null logon
|
||||
|
||||
if ( sess.hasClientInformation() && sess.getClientInformation().getAuthenticationToken() != null &&
|
||||
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
|
||||
{
|
||||
// Return the previous challenge, user is already authenticated
|
||||
|
||||
key = sess.getChallengeKey();
|
||||
|
||||
// DEBUG
|
||||
|
||||
if ( logger.isDebugEnabled())
|
||||
logger.debug("Re-using existing challenge, already authenticated");
|
||||
}
|
||||
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
{
|
||||
// Generate a new challenge key, pack the key and return
|
||||
|
||||
key = new byte[8];
|
||||
|
||||
DataPacker.putIntelLong(m_random.nextLong(), key, 0);
|
||||
}
|
||||
|
||||
// Return the challenge
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the required user account details in the defined user list
|
||||
*
|
||||
* @param user String
|
||||
* @return UserAccount
|
||||
*/
|
||||
public UserAccount getUserDetails(String user)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the authenticator
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
* @exception InvalidConfigurationException
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
|
||||
{
|
||||
// Save the server configuration so we can access the authentication component
|
||||
|
||||
m_config = config;
|
||||
|
||||
// Check that the required authentication classes are available
|
||||
|
||||
m_authComponent = m_config.getAuthenticationComponent();
|
||||
|
||||
if ( m_authComponent == null)
|
||||
throw new InvalidConfigurationException("Authentication component not available");
|
||||
|
||||
if ( m_authComponent.getNTLMMode() != NTLMMode.MD4_PROVIDER)
|
||||
throw new InvalidConfigurationException("Required authentication mode not available");
|
||||
|
||||
// Get hold of various services
|
||||
|
||||
m_nodeService = config.getNodeService();
|
||||
m_personService = config.getPersonService();
|
||||
m_transactionService = config.getTransactionService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform MD4 user authentication
|
||||
*
|
||||
* @param client Client information
|
||||
* @param sess Server session
|
||||
* @param alg Encryption algorithm
|
||||
* @return int
|
||||
*/
|
||||
private final int doMD4UserAuthentication(ClientInfo client, SrvSession sess, int alg)
|
||||
{
|
||||
// Get the stored MD4 hashed password for the user, or null if the user does not exist
|
||||
|
||||
String md4hash = m_authComponent.getMD4HashedPassword(client.getUserName());
|
||||
|
||||
if ( md4hash != null)
|
||||
{
|
||||
// Check if the client has supplied an NTLM hashed password, if not then do not allow access
|
||||
|
||||
if ( client.getPassword() == null)
|
||||
return SrvAuthenticator.AUTH_BADPASSWORD;
|
||||
|
||||
try
|
||||
{
|
||||
// Generate the local encrypted password using the challenge that was sent to the client
|
||||
|
||||
byte[] p21 = new byte[21];
|
||||
byte[] md4byts = m_md4Encoder.decodeHash(md4hash);
|
||||
System.arraycopy(md4byts, 0, p21, 0, 16);
|
||||
|
||||
// Generate the local hash of the password using the same challenge
|
||||
|
||||
byte[] localHash = getEncryptor().doNTLM1Encryption(p21, sess.getChallengeKey());
|
||||
|
||||
// Validate the password
|
||||
|
||||
byte[] clientHash = client.getPassword();
|
||||
|
||||
if ( clientHash == null || clientHash.length != localHash.length)
|
||||
return SrvAuthenticator.AUTH_BADPASSWORD;
|
||||
|
||||
for ( int i = 0; i < clientHash.length; i++)
|
||||
{
|
||||
if ( clientHash[i] != localHash[i])
|
||||
return SrvAuthenticator.AUTH_BADPASSWORD;
|
||||
}
|
||||
|
||||
// Set the current user to be authenticated, save the authentication token
|
||||
|
||||
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName()));
|
||||
|
||||
// Get the users home folder node, if available
|
||||
|
||||
getHomeFolderForUser( client);
|
||||
|
||||
// Passwords match, grant access
|
||||
|
||||
return SrvAuthenticator.AUTH_ALLOW;
|
||||
}
|
||||
catch (NoSuchAlgorithmException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Error during password check, do not allow access
|
||||
|
||||
return SrvAuthenticator.AUTH_DISALLOW;
|
||||
}
|
||||
|
||||
// Check if this is an SMB/CIFS null session logon.
|
||||
//
|
||||
// The null session will only be allowed to connect to the IPC$ named pipe share.
|
||||
|
||||
if (client.isNullSession() && sess instanceof SMBSrvSession)
|
||||
return SrvAuthenticator.AUTH_ALLOW;
|
||||
|
||||
// User does not exist, check if guest access is allowed
|
||||
|
||||
return allowGuest() ? SrvAuthenticator.AUTH_GUEST : SrvAuthenticator.AUTH_DISALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the home folder for the user
|
||||
*
|
||||
* @param client ClientInfo
|
||||
*/
|
||||
private final void getHomeFolderForUser(ClientInfo client)
|
||||
{
|
||||
// Get the home folder for the user
|
||||
|
||||
UserTransaction tx = m_transactionService.getUserTransaction();
|
||||
NodeRef homeSpaceRef = null;
|
||||
|
||||
try
|
||||
{
|
||||
tx.begin();
|
||||
homeSpaceRef = (NodeRef) m_nodeService.getProperty(m_personService.getPerson(client.getUserName()),
|
||||
ContentModel.PROP_HOMEFOLDER);
|
||||
client.setHomeFolder( homeSpaceRef);
|
||||
tx.commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
tx.rollback();
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
logger.error("Failed to rollback transaction", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
432
source/java/org/alfresco/filesys/server/auth/ClientInfo.java
Normal file
432
source/java/org/alfresco/filesys/server/auth/ClientInfo.java
Normal file
@@ -0,0 +1,432 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
/**
|
||||
* Client Information Class
|
||||
*
|
||||
* <p>The client information class holds the details of a remote user from a session setup or tree
|
||||
* connect request.
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public class ClientInfo
|
||||
{
|
||||
|
||||
// Logon types
|
||||
|
||||
public final static int LogonNormal = 0;
|
||||
public final static int LogonGuest = 1;
|
||||
public final static int LogonNull = 2;
|
||||
public final static int LogonAdmin = 3;
|
||||
|
||||
// Logon type strings
|
||||
|
||||
private static final String[] _logonTypStr = { "Normal", "Guest", "Null", "Administrator" };
|
||||
|
||||
// User name and password
|
||||
|
||||
private String m_user;
|
||||
private byte[] m_password;
|
||||
|
||||
// ANSI encrypted password
|
||||
|
||||
private byte[] m_ansiPwd;
|
||||
|
||||
// Logon type
|
||||
|
||||
private int m_logonType;
|
||||
|
||||
// User's domain
|
||||
|
||||
private String m_domain;
|
||||
|
||||
// Operating system type
|
||||
|
||||
private String m_opsys;
|
||||
|
||||
// Remote network address
|
||||
|
||||
private String m_ipAddr;
|
||||
|
||||
// Authentication token
|
||||
|
||||
private Authentication m_authToken;
|
||||
|
||||
// Home folder node
|
||||
|
||||
private NodeRef m_homeNode;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param user User name
|
||||
* @param pwd Password
|
||||
*/
|
||||
public ClientInfo(String user, byte[] pwd)
|
||||
{
|
||||
setUserName(user);
|
||||
setPassword(pwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote users domain.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getDomain()
|
||||
{
|
||||
return m_domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote operating system
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getOperatingSystem()
|
||||
{
|
||||
return m_opsys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the password.
|
||||
*
|
||||
* @return String.
|
||||
*/
|
||||
public final byte[] getPassword()
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the password as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getPasswordAsString()
|
||||
{
|
||||
if (m_password != null)
|
||||
return new String(m_password);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the client has specified an ANSI password
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasANSIPassword()
|
||||
{
|
||||
return m_ansiPwd != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ANSI encrypted password
|
||||
*
|
||||
* @return byte[]
|
||||
*/
|
||||
public final byte[] getANSIPassword()
|
||||
{
|
||||
return m_ansiPwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ANSI password as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getANSIPasswordAsString()
|
||||
{
|
||||
if (m_ansiPwd != null)
|
||||
return new String(m_ansiPwd);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getUserName()
|
||||
{
|
||||
return m_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the logon type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getLogonType()
|
||||
{
|
||||
return m_logonType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the logon type as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getLogonTypeString()
|
||||
{
|
||||
return _logonTypStr[m_logonType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is logged on as a guest
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean isGuest()
|
||||
{
|
||||
return m_logonType == LogonGuest ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the session is a null session
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean isNullSession()
|
||||
{
|
||||
return m_logonType == LogonNull ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user if logged on as an administrator
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean isAdministrator()
|
||||
{
|
||||
return m_logonType == LogonAdmin ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the client network address has been set
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasClientAddress()
|
||||
{
|
||||
return m_ipAddr != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the client network address
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getClientAddress()
|
||||
{
|
||||
return m_ipAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the client has an authentication token
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasAuthenticationToken()
|
||||
{
|
||||
return m_authToken != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authentication token
|
||||
*
|
||||
* @return Authentication
|
||||
*/
|
||||
public final Authentication getAuthenticationToken()
|
||||
{
|
||||
return m_authToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the client has a home folder node
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasHomeFolder()
|
||||
{
|
||||
return m_homeNode != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the home folder node
|
||||
*
|
||||
* @return NodeRef
|
||||
*/
|
||||
public final NodeRef getHomeFolder()
|
||||
{
|
||||
return m_homeNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the remote users domain
|
||||
*
|
||||
* @param domain Remote users domain
|
||||
*/
|
||||
public final void setDomain(String domain)
|
||||
{
|
||||
m_domain = domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the remote users operating system type.
|
||||
*
|
||||
* @param opsys Remote operating system
|
||||
*/
|
||||
public final void setOperatingSystem(String opsys)
|
||||
{
|
||||
m_opsys = opsys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password.
|
||||
*
|
||||
* @param pwd byte[]
|
||||
*/
|
||||
public final void setPassword(byte[] pwd)
|
||||
{
|
||||
m_password = pwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ANSI encrypted password
|
||||
*
|
||||
* @param pwd byte[]
|
||||
*/
|
||||
public final void setANSIPassword(byte[] pwd)
|
||||
{
|
||||
m_ansiPwd = pwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password
|
||||
*
|
||||
* @param pwd Password string.
|
||||
*/
|
||||
public final void setPassword(String pwd)
|
||||
{
|
||||
if (pwd != null)
|
||||
m_password = pwd.getBytes();
|
||||
else
|
||||
m_password = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user name
|
||||
*
|
||||
* @param user User name string.
|
||||
*/
|
||||
public final void setUserName(String user)
|
||||
{
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the logon type
|
||||
*
|
||||
* @param logonType int
|
||||
*/
|
||||
public final void setLogonType(int logonType)
|
||||
{
|
||||
m_logonType = logonType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the guest logon flag
|
||||
*
|
||||
* @param guest boolean
|
||||
*/
|
||||
public final void setGuest(boolean guest)
|
||||
{
|
||||
setLogonType(guest == true ? LogonGuest : LogonNormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the client network address
|
||||
*
|
||||
* @param addr String
|
||||
*/
|
||||
public final void setClientAddress(String addr)
|
||||
{
|
||||
m_ipAddr = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication toekn
|
||||
*
|
||||
* @param token Authentication
|
||||
*/
|
||||
public final void setAuthenticationToken(Authentication token)
|
||||
{
|
||||
m_authToken = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the home folder node
|
||||
*
|
||||
* @param homeNode NodeRef
|
||||
*/
|
||||
public final void setHomeFolder(NodeRef homeNode)
|
||||
{
|
||||
m_homeNode = homeNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the client information as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
str.append("[");
|
||||
str.append(getUserName());
|
||||
str.append(":");
|
||||
str.append(getPassword());
|
||||
str.append(",");
|
||||
str.append(getDomain());
|
||||
str.append(",");
|
||||
str.append(getOperatingSystem());
|
||||
|
||||
if (hasClientAddress())
|
||||
{
|
||||
str.append(",");
|
||||
str.append(getClientAddress());
|
||||
}
|
||||
|
||||
if ( hasAuthenticationToken())
|
||||
{
|
||||
str.append(",token=");
|
||||
str.append(getAuthenticationToken());
|
||||
}
|
||||
|
||||
if (isGuest())
|
||||
str.append(",Guest");
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Default authenticator class.
|
||||
* <p>
|
||||
* The default authenticator implementation enables user level security mode and allows any user to
|
||||
* connect to the server.
|
||||
*/
|
||||
public class DefaultAuthenticator extends SrvAuthenticator
|
||||
{
|
||||
|
||||
// Server configuration
|
||||
|
||||
private ServerConfiguration m_config;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public DefaultAuthenticator()
|
||||
{
|
||||
setAccessMode(USER_MODE);
|
||||
setEncryptedPasswords(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow any user to access the server
|
||||
*
|
||||
* @param client Client details.
|
||||
* @param share Shared device the user is connecting to.
|
||||
* @param pwd Share level password.
|
||||
* @param sess Server session
|
||||
* @return int
|
||||
*/
|
||||
public int authenticateShareConnect(ClientInfo client, SharedDevice share, String pwd, SrvSession sess)
|
||||
{
|
||||
return Writeable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow any user to access the server.
|
||||
*
|
||||
* @param client Client details.
|
||||
* @param sess Server session
|
||||
* @param alg Encryption algorithm
|
||||
* @return int
|
||||
*/
|
||||
public int authenticateUser(ClientInfo client, SrvSession sess, int alg)
|
||||
{
|
||||
return AUTH_ALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default authenticator does not use encrypted passwords.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getChallengeKey(SrvSession sess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the requried user account details in the defined user list
|
||||
*
|
||||
* @param user String
|
||||
* @return UserAccount
|
||||
*/
|
||||
public UserAccount getUserDetails(String user)
|
||||
{
|
||||
|
||||
// Get the user account list from the configuration
|
||||
|
||||
UserAccountList userList = m_config.getUserAccounts();
|
||||
if (userList == null || userList.numberOfUsers() == 0)
|
||||
return null;
|
||||
|
||||
// Search for the required user account record
|
||||
|
||||
return userList.findUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialzie the authenticator
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
* @exception InvalidConfigurationException
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
|
||||
{
|
||||
|
||||
// Save the server configuration so we can access the defined user list
|
||||
|
||||
m_config = config;
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
/**
|
||||
* Invalid User Exception Class
|
||||
*/
|
||||
public class InvalidUserException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 3833743295984645425L;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public InvalidUserException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param s java.lang.String
|
||||
*/
|
||||
public InvalidUserException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.ShareType;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.smb.server.SMBSrvSession;
|
||||
import org.alfresco.filesys.util.DataPacker;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Local Authenticator Class.
|
||||
* <p>
|
||||
* The local authenticator implementation enables user level security mode and uses the user account
|
||||
* list that is part of the server configuration to determine if a user is allowed to access the
|
||||
* server/share.
|
||||
* <p>
|
||||
* Note: Switching off encrypted password support will cause later NT4 service pack releases and
|
||||
* Win2000 to refuse to connect to the server without a registry update on the client.
|
||||
*/
|
||||
public class LocalAuthenticator extends SrvAuthenticator
|
||||
{
|
||||
|
||||
// Random number generator used to generate challenge keys
|
||||
|
||||
private Random m_random = new Random(System.currentTimeMillis());
|
||||
|
||||
// Server configuration
|
||||
|
||||
private ServerConfiguration m_config;
|
||||
|
||||
/**
|
||||
* Local Authenticator Constructor
|
||||
* <p>
|
||||
* Default to user mode security with encrypted password support.
|
||||
*/
|
||||
public LocalAuthenticator()
|
||||
{
|
||||
setAccessMode(SrvAuthenticator.USER_MODE);
|
||||
setEncryptedPasswords(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the connection to a share
|
||||
*
|
||||
* @param client ClienInfo
|
||||
* @param share SharedDevice
|
||||
* @param pwd Share level password.
|
||||
* @param sess Server session
|
||||
* @return Authentication status.
|
||||
*/
|
||||
public int authenticateShareConnect(ClientInfo client, SharedDevice share, String pwd, SrvSession sess)
|
||||
{
|
||||
|
||||
// If the server is in share mode security allow the user access
|
||||
|
||||
if (this.getAccessMode() == SHARE_MODE)
|
||||
return SrvAuthenticator.Writeable;
|
||||
|
||||
// Check if the IPC$ share is being accessed
|
||||
|
||||
if (share.getType() == ShareType.ADMINPIPE)
|
||||
return SrvAuthenticator.Writeable;
|
||||
|
||||
// Check if the user is allowed to access the specified shared device
|
||||
//
|
||||
// If a user does not have access to the requested share the connection will still be
|
||||
// allowed
|
||||
// but any attempts to access files or search directories will result in a 'no access
|
||||
// rights'
|
||||
// error being returned to the client.
|
||||
|
||||
UserAccount user = null;
|
||||
if (client != null)
|
||||
user = getUserDetails(client.getUserName());
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
||||
// Check if the guest account is enabled
|
||||
|
||||
return allowGuest() ? SrvAuthenticator.Writeable : SrvAuthenticator.NoAccess;
|
||||
}
|
||||
else if (user.hasShare(share.getName()) == false)
|
||||
return SrvAuthenticator.NoAccess;
|
||||
|
||||
// Allow user to access this share
|
||||
|
||||
return SrvAuthenticator.Writeable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user
|
||||
*
|
||||
* @param client Client information
|
||||
* @param sess Server session
|
||||
* @param alg Encryption algorithm
|
||||
*/
|
||||
public int authenticateUser(ClientInfo client, SrvSession sess, int alg)
|
||||
{
|
||||
|
||||
// Check if the user exists in the user list
|
||||
|
||||
UserAccount userAcc = getUserDetails(client.getUserName());
|
||||
if (userAcc != null)
|
||||
{
|
||||
|
||||
// Validate the password
|
||||
|
||||
boolean authSts = false;
|
||||
|
||||
if (client.getPassword() != null)
|
||||
{
|
||||
|
||||
// Validate using the Unicode password
|
||||
|
||||
authSts = validatePassword(userAcc.getPassword(), client.getPassword(), sess.getChallengeKey(), alg);
|
||||
}
|
||||
else if (client.hasANSIPassword())
|
||||
{
|
||||
|
||||
// Validate using the ANSI password with the LanMan encryption
|
||||
|
||||
authSts = validatePassword(userAcc.getPassword(), client.getANSIPassword(), sess.getChallengeKey(),
|
||||
SrvAuthenticator.LANMAN);
|
||||
}
|
||||
|
||||
// Return the authentication status
|
||||
|
||||
return authSts == true ? SrvAuthenticator.AUTH_ALLOW : SrvAuthenticator.AUTH_BADPASSWORD;
|
||||
}
|
||||
|
||||
// Check if this is an SMB/CIFS null session logon.
|
||||
//
|
||||
// The null session will only be allowed to connect to the IPC$ named pipe share.
|
||||
|
||||
if (client.isNullSession() && sess instanceof SMBSrvSession)
|
||||
return SrvAuthenticator.AUTH_ALLOW;
|
||||
|
||||
// Unknown user
|
||||
|
||||
return allowGuest() ? SrvAuthenticator.AUTH_GUEST : SrvAuthenticator.AUTH_DISALLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a challenge key
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getChallengeKey(SrvSession sess)
|
||||
{
|
||||
|
||||
// Generate a new challenge key, pack the key and return
|
||||
|
||||
byte[] key = new byte[8];
|
||||
|
||||
DataPacker.putIntelLong(m_random.nextLong(), key, 0);
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the requried user account details in the defined user list
|
||||
*
|
||||
* @param user String
|
||||
* @return UserAccount
|
||||
*/
|
||||
public UserAccount getUserDetails(String user)
|
||||
{
|
||||
|
||||
// Get the user account list from the configuration
|
||||
|
||||
UserAccountList userList = m_config.getUserAccounts();
|
||||
if (userList == null || userList.numberOfUsers() == 0)
|
||||
return null;
|
||||
|
||||
// Search for the required user account record
|
||||
|
||||
return userList.findUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the authenticator
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
* @exception InvalidConfigurationException
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
|
||||
{
|
||||
|
||||
// Save the server configuration so we can access the defined user list
|
||||
|
||||
m_config = config;
|
||||
}
|
||||
}
|
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Password Encryptor Class
|
||||
*
|
||||
* <p>Generates LanMan and NTLMv1 encrypted passwords from the plain text password and challenge key.
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public class PasswordEncryptor
|
||||
{
|
||||
|
||||
// Encryption algorithm types
|
||||
|
||||
public static final int LANMAN = 0;
|
||||
public static final int NTLM1 = 1;
|
||||
public static final int NTLM2 = 2;
|
||||
public static final int MD4 = 3;
|
||||
|
||||
// Encrpytion algorithm names
|
||||
|
||||
private final static String[] _algNames = { "LanMan", "NTLMv1", "NTLMv2", "MD4" };
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public PasswordEncryptor()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the required algorithms are available
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static final boolean checkEncryptionAlgorithms()
|
||||
{
|
||||
|
||||
boolean algOK = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Check if MD4 is available
|
||||
|
||||
MessageDigest.getInstance("MD4");
|
||||
|
||||
// Check if DES is available
|
||||
|
||||
Cipher.getInstance("DES");
|
||||
}
|
||||
catch (NoSuchAlgorithmException ex)
|
||||
{
|
||||
}
|
||||
catch (NoSuchPaddingException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Return the encryption algorithm status
|
||||
|
||||
return algOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the plain text password with the specified encryption key using the specified
|
||||
* encryption algorithm.
|
||||
*
|
||||
* @param plainPwd Plaintext password string
|
||||
* @param encryptKey byte[] Encryption key
|
||||
* @param alg int Encryption algorithm
|
||||
* @return byte[] Encrypted password
|
||||
* @exception NoSuchAlgorithmException If a required encryption algorithm is not available
|
||||
*/
|
||||
public byte[] generateEncryptedPassword(String plainPwd, byte[] encryptKey, int alg)
|
||||
throws NoSuchAlgorithmException
|
||||
{
|
||||
|
||||
// Get the password
|
||||
|
||||
String pwd = plainPwd;
|
||||
if (pwd == null)
|
||||
pwd = "";
|
||||
|
||||
// Determine the encryption algorithm
|
||||
|
||||
byte[] encPwd = null;
|
||||
MessageDigest md4 = null;
|
||||
int len = 0;
|
||||
byte[] pwdBytes = null;
|
||||
|
||||
switch (alg)
|
||||
{
|
||||
|
||||
// LanMan DES encryption
|
||||
|
||||
case LANMAN:
|
||||
encPwd = P24(pwd, encryptKey);
|
||||
break;
|
||||
|
||||
// NTLM v1 encryption
|
||||
|
||||
case NTLM1:
|
||||
|
||||
// Create the MD4 hash
|
||||
|
||||
md4 = MessageDigest.getInstance("MD4");
|
||||
|
||||
try {
|
||||
pwdBytes = pwd.getBytes("UnicodeLittleUnmarked");
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
}
|
||||
|
||||
md4.update(pwdBytes);
|
||||
byte[] p21 = new byte[21];
|
||||
System.arraycopy(md4.digest(), 0, p21, 0, 16);
|
||||
|
||||
// Now use the LM encryption
|
||||
|
||||
encPwd = P24(p21,encryptKey);
|
||||
break;
|
||||
|
||||
// NTLM v2 encryption
|
||||
|
||||
case NTLM2:
|
||||
break;
|
||||
|
||||
// MD4 encryption
|
||||
|
||||
case MD4:
|
||||
|
||||
// Create the MD4 hash
|
||||
|
||||
md4 = MessageDigest.getInstance("MD4");
|
||||
len = pwd.length();
|
||||
pwdBytes = new byte[len * 2];
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char ch = pwd.charAt(i);
|
||||
pwdBytes[i * 2] = (byte) ch;
|
||||
pwdBytes[i * 2 + 1] = (byte) ((ch >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
md4.update(pwdBytes);
|
||||
encPwd = new byte[16];
|
||||
System.arraycopy(md4.digest(), 0, encPwd, 0, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the encrypted password
|
||||
|
||||
return encPwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* P16 encryption
|
||||
*
|
||||
* @param pwd java.lang.String
|
||||
* @param s8 byte[]
|
||||
* @return byte[]
|
||||
* @exception NoSuchAlgorithmException If a required encryption algorithm is not available
|
||||
*/
|
||||
public final byte[] P16(String pwd, byte[] s8) throws NoSuchAlgorithmException
|
||||
{
|
||||
|
||||
// Make a 14 byte string using the password string. Truncate the
|
||||
// password or pad with nulls to 14 characters.
|
||||
|
||||
StringBuffer p14str = new StringBuffer();
|
||||
p14str.append(pwd.toUpperCase());
|
||||
if (p14str.length() > 14)
|
||||
p14str.setLength(14);
|
||||
|
||||
while (p14str.length() < 14)
|
||||
p14str.append((char) 0x00);
|
||||
|
||||
// Convert the P14 string to an array of bytes. Allocate a 21 byte buffer as the result is usually passed
|
||||
// through the P24() method
|
||||
|
||||
byte[] p14 = p14str.toString().getBytes();
|
||||
byte[] p16 = new byte[21];
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// DES encrypt the password bytes using the challenge key
|
||||
|
||||
Cipher des = Cipher.getInstance("DES");
|
||||
|
||||
// Set the encryption seed using the first 7 bytes of the password string.
|
||||
// Generate the first 8 bytes of the return value.
|
||||
|
||||
byte[] key = generateKey(p14, 0);
|
||||
|
||||
SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES");
|
||||
des.init(Cipher.ENCRYPT_MODE, chKey);
|
||||
byte[] res = des.doFinal(s8);
|
||||
System.arraycopy(res, 0, p16, 0, 8);
|
||||
|
||||
// Encrypt the second block
|
||||
|
||||
key = generateKey(p14, 7);
|
||||
|
||||
chKey = new SecretKeySpec(key, 0, key.length, "DES");
|
||||
des.init(Cipher.ENCRYPT_MODE, chKey);
|
||||
res = des.doFinal(s8);
|
||||
System.arraycopy(res, 0, p16, 8, 8);
|
||||
}
|
||||
catch (NoSuchPaddingException ex)
|
||||
{
|
||||
p16 = null;
|
||||
}
|
||||
catch (IllegalBlockSizeException ex)
|
||||
{
|
||||
p16 = null;
|
||||
}
|
||||
catch (BadPaddingException ex)
|
||||
{
|
||||
p16 = null;
|
||||
}
|
||||
catch (InvalidKeyException ex)
|
||||
{
|
||||
p16 = null;
|
||||
}
|
||||
|
||||
// Return the 16 byte encrypted value
|
||||
|
||||
return p16;
|
||||
}
|
||||
|
||||
/**
|
||||
* P24 DES encryption
|
||||
*
|
||||
* @param pwd java.lang.String
|
||||
* @param c8 byte[]
|
||||
* @return byte[]
|
||||
* @exception NoSuchAlgorithmException If a required encryption algorithm is not available
|
||||
*/
|
||||
private final byte[] P24(String pwd, byte[] c8) throws NoSuchAlgorithmException
|
||||
{
|
||||
|
||||
// Generate the 16 byte encrypted value using the password string and well
|
||||
// known value.
|
||||
|
||||
byte[] s8 = new String("KGS!@#$%").getBytes();
|
||||
byte[] p16 = P16(pwd, s8);
|
||||
|
||||
// Generate the 24 byte encrypted value
|
||||
|
||||
return P24(p16, c8);
|
||||
}
|
||||
|
||||
/**
|
||||
* P24 DES encryption
|
||||
*
|
||||
* @param p21 Plain password or hashed password bytes
|
||||
* @param ch Challenge bytes
|
||||
* @return Encrypted password
|
||||
* @exception NoSuchAlgorithmException If a required encryption algorithm is not available
|
||||
*/
|
||||
private final byte[] P24(byte[] p21, byte[] ch) throws NoSuchAlgorithmException
|
||||
{
|
||||
|
||||
byte[] enc = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// DES encrypt the password bytes using the challenge key
|
||||
|
||||
Cipher des = Cipher.getInstance("DES");
|
||||
|
||||
// Allocate the output bytes
|
||||
|
||||
enc = new byte[24];
|
||||
|
||||
// Encrypt the first block
|
||||
|
||||
byte[] key = generateKey(p21, 0);
|
||||
|
||||
SecretKeySpec chKey = new SecretKeySpec(key, 0, key.length, "DES");
|
||||
des.init(Cipher.ENCRYPT_MODE, chKey);
|
||||
byte[] res = des.doFinal(ch);
|
||||
System.arraycopy(res, 0, enc, 0, 8);
|
||||
|
||||
// Encrypt the second block
|
||||
|
||||
key = generateKey(p21, 7);
|
||||
|
||||
chKey = new SecretKeySpec(key, 0, key.length, "DES");
|
||||
des.init(Cipher.ENCRYPT_MODE, chKey);
|
||||
res = des.doFinal(ch);
|
||||
System.arraycopy(res, 0, enc, 8, 8);
|
||||
|
||||
// Encrypt the last block
|
||||
|
||||
key = generateKey(p21, 14);
|
||||
|
||||
chKey = new SecretKeySpec(key, 0, key.length, "DES");
|
||||
des.init(Cipher.ENCRYPT_MODE, chKey);
|
||||
res = des.doFinal(ch);
|
||||
System.arraycopy(res, 0, enc, 16, 8);
|
||||
}
|
||||
catch (NoSuchPaddingException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
enc = null;
|
||||
}
|
||||
catch (IllegalBlockSizeException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
enc = null;
|
||||
}
|
||||
catch (BadPaddingException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
enc = null;
|
||||
}
|
||||
catch (InvalidKeyException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
enc = null;
|
||||
}
|
||||
|
||||
// Return the encrypted password, or null if an error occurred
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the encryption algorithm as a string
|
||||
*
|
||||
* @param alg int
|
||||
* @return String
|
||||
*/
|
||||
public static String getAlgorithmName(int alg)
|
||||
{
|
||||
if (alg >= 0 && alg < _algNames.length)
|
||||
return _algNames[alg];
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a 7-byte string into a 64 bit/8 byte/longword key.
|
||||
*
|
||||
* @param byt byte[]
|
||||
* @param off int
|
||||
* @return byte[]
|
||||
*/
|
||||
private byte[] generateKey(byte[] byt, int off)
|
||||
{
|
||||
|
||||
// Allocate the key
|
||||
|
||||
byte[] key = new byte[8];
|
||||
|
||||
// Make a key from the input string
|
||||
|
||||
key[0] = (byte) (byt[off + 0] >> 1);
|
||||
key[1] = (byte) (((byt[off + 0] & 0x01) << 6) | ((byt[off + 1] & 0xFF) >> 2));
|
||||
key[2] = (byte) (((byt[off + 1] & 0x03) << 5) | ((byt[off + 2] & 0xFF) >> 3));
|
||||
key[3] = (byte) (((byt[off + 2] & 0x07) << 4) | ((byt[off + 3] & 0xFF) >> 4));
|
||||
key[4] = (byte) (((byt[off + 3] & 0x0F) << 3) | ((byt[off + 4] & 0xFF) >> 5));
|
||||
key[5] = (byte) (((byt[off + 4] & 0x1F) << 2) | ((byt[off + 5] & 0xFF) >> 6));
|
||||
key[6] = (byte) (((byt[off + 5] & 0x3F) << 1) | ((byt[off + 6] & 0xFF) >> 7));
|
||||
key[7] = (byte) (byt[off + 6] & 0x7F);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
key[i] = (byte) (key[i] << 1);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* NTLM1 encryption of the MD4 hashed password
|
||||
*
|
||||
* @param p21 byte[]
|
||||
* @param c8 byte[]
|
||||
* @return byte[]
|
||||
* @exception NoSuchAlgorithmException
|
||||
*/
|
||||
public final byte[] doNTLM1Encryption(byte[] p21, byte[] c8)
|
||||
throws NoSuchAlgorithmException
|
||||
{
|
||||
return P24(p21, c8);
|
||||
}
|
||||
}
|
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.InvalidConfigurationException;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* An authenticator is used by the SMB server to authenticate users when in user level access mode
|
||||
* and authenticate requests to connect to a share when in share level access.
|
||||
*/
|
||||
public abstract class SrvAuthenticator
|
||||
{
|
||||
|
||||
// Encryption algorithm types
|
||||
|
||||
public static final int LANMAN = PasswordEncryptor.LANMAN;
|
||||
public static final int NTLM1 = PasswordEncryptor.NTLM1;
|
||||
public static final int NTLM2 = PasswordEncryptor.NTLM2;
|
||||
|
||||
// Authentication status values
|
||||
|
||||
public static final int AUTH_ALLOW = 0;
|
||||
public static final int AUTH_GUEST = 0x10000000;
|
||||
public static final int AUTH_DISALLOW = -1;
|
||||
public static final int AUTH_BADPASSWORD = -2;
|
||||
public static final int AUTH_BADUSER = -3;
|
||||
|
||||
// Share access permissions, returned by authenticateShareConnect()
|
||||
|
||||
public static final int NoAccess = 0;
|
||||
public static final int ReadOnly = 1;
|
||||
public static final int Writeable = 2;
|
||||
|
||||
// Server access mode
|
||||
|
||||
public static final int SHARE_MODE = 0;
|
||||
public static final int USER_MODE = 1;
|
||||
|
||||
// Standard encrypted password length
|
||||
|
||||
public static final int STANDARD_PASSWORD_LEN = 24;
|
||||
|
||||
// Server access mode
|
||||
|
||||
private int m_accessMode = SHARE_MODE;
|
||||
|
||||
// Use encrypted password
|
||||
|
||||
private boolean m_encryptPwd = false;
|
||||
|
||||
// Password encryption algorithms
|
||||
|
||||
private PasswordEncryptor m_encryptor = new PasswordEncryptor();
|
||||
|
||||
// Flag to enable/disable the guest account
|
||||
|
||||
private boolean m_allowGuest;
|
||||
|
||||
/**
|
||||
* Authenticate a connection to a share.
|
||||
*
|
||||
* @param client User/client details from the tree connect request.
|
||||
* @param share Shared device the client wants to connect to.
|
||||
* @param pwd Share password.
|
||||
* @param sess Server session.
|
||||
* @return int Granted file permission level or disallow status if negative. See the
|
||||
* FilePermission class.
|
||||
*/
|
||||
public abstract int authenticateShareConnect(ClientInfo client, SharedDevice share, String sharePwd, SrvSession sess);
|
||||
|
||||
/**
|
||||
* Authenticate a user. A user may be granted full access, guest access or no access.
|
||||
*
|
||||
* @param client User/client details from the session setup request.
|
||||
* @param sess Server session
|
||||
* @param alg Encryption algorithm
|
||||
* @return int Access level or disallow status.
|
||||
*/
|
||||
public abstract int authenticateUser(ClientInfo client, SrvSession sess, int alg);
|
||||
|
||||
/**
|
||||
* Return the user account details for the specified user
|
||||
*
|
||||
* @param user String
|
||||
* @return UserAccount
|
||||
*/
|
||||
public abstract UserAccount getUserDetails(String user);
|
||||
|
||||
/**
|
||||
* Authenticate a user using a plain text password.
|
||||
*
|
||||
* @param client User/client details from the session setup request.
|
||||
* @param sess Server session
|
||||
* @return int Access level or disallow status.
|
||||
* @throws InvalidConfigurationException
|
||||
*/
|
||||
public final int authenticateUserPlainText(ClientInfo client, SrvSession sess)
|
||||
{
|
||||
|
||||
// Get a challenge key
|
||||
|
||||
sess.setChallengeKey(getChallengeKey(sess));
|
||||
|
||||
if (sess.hasChallengeKey() == false)
|
||||
return SrvAuthenticator.AUTH_DISALLOW;
|
||||
|
||||
// Get the plain text password
|
||||
|
||||
String textPwd = client.getPasswordAsString();
|
||||
if (textPwd == null)
|
||||
textPwd = client.getANSIPasswordAsString();
|
||||
|
||||
// Encrypt the password
|
||||
|
||||
byte[] encPwd = generateEncryptedPassword(textPwd, sess.getChallengeKey(), SrvAuthenticator.NTLM1);
|
||||
client.setPassword(encPwd);
|
||||
|
||||
// Authenticate the user
|
||||
|
||||
return authenticateUser(client, sess, SrvAuthenticator.NTLM1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the authenticator
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
* @exception InvalidConfigurationException
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params) throws InvalidConfigurationException
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt the plain text password with the specified encryption key using the specified
|
||||
* encryption algorithm.
|
||||
*
|
||||
* @return byte[]
|
||||
* @param plainPwd java.lang.String
|
||||
* @param encryptKey byte[]
|
||||
* @param alg int
|
||||
*/
|
||||
protected final byte[] generateEncryptedPassword(String plainPwd, byte[] encryptKey, int alg)
|
||||
{
|
||||
|
||||
// Use the password encryptor
|
||||
|
||||
byte[] encPwd = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Encrypt the password
|
||||
|
||||
encPwd = m_encryptor.generateEncryptedPassword(plainPwd, encryptKey, alg);
|
||||
}
|
||||
catch (NoSuchAlgorithmException ex)
|
||||
{
|
||||
}
|
||||
|
||||
// Return the encrypted password
|
||||
|
||||
return encPwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access mode of the server, either SHARE_MODE or USER_MODE.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getAccessMode()
|
||||
{
|
||||
return m_accessMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a challenge encryption key, when encrypted passwords are enabled.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @return byte[]
|
||||
*/
|
||||
public abstract byte[] getChallengeKey(SrvSession sess);
|
||||
|
||||
/**
|
||||
* Determine if encrypted passwords should be used.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasEncryptPasswords()
|
||||
{
|
||||
return m_encryptPwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if guest access is allowed
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean allowGuest()
|
||||
{
|
||||
return m_allowGuest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the access mode of the server.
|
||||
*
|
||||
* @param mode Either SHARE_MODE or USER_MODE.
|
||||
*/
|
||||
public final void setAccessMode(int mode)
|
||||
{
|
||||
m_accessMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/clear the encrypted passwords flag.
|
||||
*
|
||||
* @param encFlag Encrypt passwords if true, use plain text passwords if false.
|
||||
*/
|
||||
public final void setEncryptedPasswords(boolean encFlag)
|
||||
{
|
||||
m_encryptPwd = encFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable the guest account
|
||||
*
|
||||
* @param ena Enable the guest account if true, only allow defined user accounts access if false
|
||||
*/
|
||||
public final void setAllowGuest(boolean ena)
|
||||
{
|
||||
m_allowGuest = ena;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the authenticator, perform any cleanup
|
||||
*/
|
||||
public void closeAuthenticator()
|
||||
{
|
||||
// Override if cleanup required
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a password by encrypting the plain text password using the specified encryption key
|
||||
* and encryption algorithm.
|
||||
*
|
||||
* @return boolean
|
||||
* @param plainPwd java.lang.String
|
||||
* @param encryptedPwd java.lang.String
|
||||
* @param encryptKey byte[]
|
||||
* @param alg int
|
||||
*/
|
||||
protected final boolean validatePassword(String plainPwd, byte[] encryptedPwd, byte[] encryptKey, int alg)
|
||||
{
|
||||
|
||||
// Generate an encrypted version of the plain text password
|
||||
|
||||
byte[] encPwd = generateEncryptedPassword(plainPwd != null ? plainPwd : "", encryptKey, alg);
|
||||
|
||||
// Compare the generated password with the received password
|
||||
|
||||
if (encPwd != null && encryptedPwd != null && encPwd.length == STANDARD_PASSWORD_LEN
|
||||
&& encryptedPwd.length == STANDARD_PASSWORD_LEN)
|
||||
{
|
||||
|
||||
// Compare the password arrays
|
||||
|
||||
for (int i = 0; i < STANDARD_PASSWORD_LEN; i++)
|
||||
if (encPwd[i] != encryptedPwd[i])
|
||||
return false;
|
||||
|
||||
// Password is valid
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// User or password is invalid
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the password string to a byte array
|
||||
*
|
||||
* @param pwd String
|
||||
* @return byte[]
|
||||
*/
|
||||
|
||||
protected final byte[] convertPassword(String pwd)
|
||||
{
|
||||
|
||||
// Create a padded/truncated 14 character string
|
||||
|
||||
StringBuffer p14str = new StringBuffer();
|
||||
p14str.append(pwd);
|
||||
if (p14str.length() > 14)
|
||||
p14str.setLength(14);
|
||||
else
|
||||
{
|
||||
while (p14str.length() < 14)
|
||||
p14str.append((char) 0x00);
|
||||
}
|
||||
|
||||
// Convert the P14 string to an array of bytes. Allocate the return 16 byte array.
|
||||
|
||||
return p14str.toString().getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the password encryptor
|
||||
*
|
||||
* @return PasswordEncryptor
|
||||
*/
|
||||
protected final PasswordEncryptor getEncryptor()
|
||||
{
|
||||
return m_encryptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the authentication status as a string
|
||||
*
|
||||
* @param sts int
|
||||
* @return String
|
||||
*/
|
||||
protected final String getStatusAsString(int sts)
|
||||
{
|
||||
String str = null;
|
||||
|
||||
switch ( sts)
|
||||
{
|
||||
case AUTH_ALLOW:
|
||||
str = "Allow";
|
||||
break;
|
||||
case AUTH_DISALLOW:
|
||||
str = "Disallow";
|
||||
break;
|
||||
case AUTH_GUEST:
|
||||
str = "Guest";
|
||||
break;
|
||||
case AUTH_BADPASSWORD:
|
||||
str = "BadPassword";
|
||||
break;
|
||||
case AUTH_BADUSER:
|
||||
str = "BadUser";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
331
source/java/org/alfresco/filesys/server/auth/UserAccount.java
Normal file
331
source/java/org/alfresco/filesys/server/auth/UserAccount.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import org.alfresco.filesys.util.StringList;
|
||||
|
||||
/**
|
||||
* User Account Class
|
||||
* <p>
|
||||
* Holds the details of a user account on the server.
|
||||
*/
|
||||
public class UserAccount
|
||||
{
|
||||
|
||||
// User name and password
|
||||
|
||||
private String m_userName;
|
||||
private String m_password;
|
||||
|
||||
// Real user name and comment
|
||||
|
||||
private String m_realName;
|
||||
private String m_comment;
|
||||
|
||||
// List of shares this user is allowed to use
|
||||
|
||||
private StringList m_shares;
|
||||
|
||||
// Administrator flag
|
||||
|
||||
private boolean m_admin;
|
||||
|
||||
// Home directory
|
||||
|
||||
private String m_homeDir;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public UserAccount()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a user with the specified name and password.
|
||||
*
|
||||
* @param user String
|
||||
* @param pwd String
|
||||
*/
|
||||
public UserAccount(String user, String pwd)
|
||||
{
|
||||
setUserName(user);
|
||||
setPassword(pwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified share to the list of allowed shares for this user.
|
||||
*
|
||||
* @param shr java.lang.String
|
||||
*/
|
||||
public final void addShare(String shr)
|
||||
{
|
||||
if (m_shares == null)
|
||||
m_shares = new StringList();
|
||||
m_shares.addString(shr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this user is allowed to access the specified share.
|
||||
*
|
||||
* @return boolean
|
||||
* @param shr java.lang.String
|
||||
*/
|
||||
public final boolean allowsShare(String shr)
|
||||
{
|
||||
if (m_shares == null)
|
||||
return true;
|
||||
else if (m_shares.containsString(shr))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a home direectory configured
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasHomeDirectory()
|
||||
{
|
||||
return m_homeDir != null ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the home directory for this user
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getHomeDirectory()
|
||||
{
|
||||
return m_homeDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the password
|
||||
*
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public final String getPassword()
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user name.
|
||||
*
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public final String getUserName()
|
||||
{
|
||||
return m_userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the real user name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getRealName()
|
||||
{
|
||||
return m_realName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user comment
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getComment()
|
||||
{
|
||||
return m_comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified share is listed in the users allowed list.
|
||||
*
|
||||
* @return boolean
|
||||
* @param shr java.lang.String
|
||||
*/
|
||||
public final boolean hasShare(String shr)
|
||||
{
|
||||
if (m_shares != null && m_shares.containsString(shr) == false)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detemrine if this account is restricted to using certain shares only.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasShareRestrictions()
|
||||
{
|
||||
return m_shares == null ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of shares
|
||||
*
|
||||
* @return StringList
|
||||
*/
|
||||
public final StringList getShareList()
|
||||
{
|
||||
return m_shares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this user in an administrator.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean isAdministrator()
|
||||
{
|
||||
return m_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all shares from the list of restricted shares.
|
||||
*/
|
||||
public final void removeAllShares()
|
||||
{
|
||||
m_shares = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified share from the list of shares this user is allowed to access.
|
||||
*
|
||||
* @param shr java.lang.String
|
||||
*/
|
||||
public final void removeShare(String shr)
|
||||
{
|
||||
|
||||
// Check if the share list has been allocated
|
||||
|
||||
if (m_shares != null)
|
||||
{
|
||||
|
||||
// Remove the share from the list
|
||||
|
||||
m_shares.removeString(shr);
|
||||
|
||||
// Check if the list is empty
|
||||
|
||||
if (m_shares.numberOfStrings() == 0)
|
||||
m_shares = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the administrator flag.
|
||||
*
|
||||
* @param admin boolean
|
||||
*/
|
||||
public final void setAdministrator(boolean admin)
|
||||
{
|
||||
m_admin = admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user home directory
|
||||
*
|
||||
* @param home String
|
||||
*/
|
||||
public final void setHomeDirectory(String home)
|
||||
{
|
||||
m_homeDir = home;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password for this account.
|
||||
*
|
||||
* @param pwd java.lang.String
|
||||
*/
|
||||
public final void setPassword(String pwd)
|
||||
{
|
||||
m_password = pwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user name.
|
||||
*
|
||||
* @param user java.lang.String
|
||||
*/
|
||||
public final void setUserName(String user)
|
||||
{
|
||||
m_userName = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the real user name
|
||||
*
|
||||
* @param name String
|
||||
*/
|
||||
public final void setRealName(String name)
|
||||
{
|
||||
m_realName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comment
|
||||
*
|
||||
* @param comment String
|
||||
*/
|
||||
public final void setComment(String comment)
|
||||
{
|
||||
m_comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user account as a string.
|
||||
*
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("[");
|
||||
str.append(getUserName());
|
||||
str.append(":");
|
||||
str.append(getPassword());
|
||||
|
||||
if (isAdministrator())
|
||||
str.append("(ADMIN)");
|
||||
|
||||
str.append(",Real=");
|
||||
|
||||
str.append(getRealName());
|
||||
str.append(",Comment=");
|
||||
str.append(getComment());
|
||||
str.append(",Allow=");
|
||||
|
||||
if (m_shares == null)
|
||||
str.append("<ALL>");
|
||||
else
|
||||
str.append(m_shares);
|
||||
str.append("]");
|
||||
|
||||
str.append(",Home=");
|
||||
if (hasHomeDirectory())
|
||||
str.append(getHomeDirectory());
|
||||
else
|
||||
str.append("None");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* User Account List Class
|
||||
*/
|
||||
public class UserAccountList
|
||||
{
|
||||
|
||||
// User account list
|
||||
|
||||
private Vector<UserAccount> m_users;
|
||||
|
||||
/**
|
||||
* Create a user account list.
|
||||
*/
|
||||
public UserAccountList()
|
||||
{
|
||||
m_users = new Vector<UserAccount>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a user to the list of accounts.
|
||||
*
|
||||
* @param user UserAccount
|
||||
*/
|
||||
public final void addUser(UserAccount user)
|
||||
{
|
||||
|
||||
// Check if the user exists on the list
|
||||
|
||||
removeUser(user);
|
||||
m_users.add(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the required user account details.
|
||||
*
|
||||
* @param user java.lang.String
|
||||
* @return UserAccount
|
||||
*/
|
||||
public final UserAccount findUser(String user)
|
||||
{
|
||||
|
||||
// Search for the specified user account
|
||||
|
||||
for (int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
UserAccount acc = m_users.get(i);
|
||||
if (acc.getUserName().equalsIgnoreCase(user))
|
||||
return acc;
|
||||
}
|
||||
|
||||
// User not found
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified user account exists in the list.
|
||||
*
|
||||
* @return boolean
|
||||
* @param user java.lang.String
|
||||
*/
|
||||
public final boolean hasUser(String user)
|
||||
{
|
||||
|
||||
// Search for the specified user account
|
||||
|
||||
for (int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
UserAccount acc = m_users.get(i);
|
||||
if (acc.getUserName().compareTo(user) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
// User not found
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specified user account details
|
||||
*
|
||||
* @param idx int
|
||||
* @return UserAccount
|
||||
*/
|
||||
public final UserAccount getUserAt(int idx)
|
||||
{
|
||||
if (idx >= m_users.size())
|
||||
return null;
|
||||
return m_users.get(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of defined user accounts.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int numberOfUsers()
|
||||
{
|
||||
return m_users.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all user accounts from the list.
|
||||
*/
|
||||
public final void removeAllUsers()
|
||||
{
|
||||
m_users.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remvoe the specified user account from the list.
|
||||
*
|
||||
* @param userAcc UserAccount
|
||||
*/
|
||||
public final void removeUser(UserAccount userAcc)
|
||||
{
|
||||
|
||||
// Search for the specified user account
|
||||
|
||||
for (int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
UserAccount acc = m_users.get(i);
|
||||
if (acc.getUserName().compareTo(userAcc.getUserName()) == 0)
|
||||
{
|
||||
m_users.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remvoe the specified user account from the list.
|
||||
*
|
||||
* @param user java.lang.String
|
||||
*/
|
||||
public final void removeUser(String user)
|
||||
{
|
||||
|
||||
// Search for the specified user account
|
||||
|
||||
for (int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
UserAccount acc = m_users.get(i);
|
||||
if (acc.getUserName().compareTo(user) == 0)
|
||||
{
|
||||
m_users.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user account list as a string.
|
||||
*
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("[");
|
||||
str.append(m_users.size());
|
||||
str.append(":");
|
||||
|
||||
for (int i = 0; i < m_users.size(); i++)
|
||||
{
|
||||
UserAccount acc = m_users.get(i);
|
||||
str.append(acc.getUserName());
|
||||
str.append(",");
|
||||
}
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
/**
|
||||
* Access Control Parse Exception Class
|
||||
*/
|
||||
public class ACLParseException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 3978983284405776688L;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public ACLParseException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param s java.lang.String
|
||||
*/
|
||||
public ACLParseException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* Access Control Base Class
|
||||
* <p>
|
||||
* Controls access to a shared filesystem.
|
||||
*/
|
||||
public abstract class AccessControl
|
||||
{
|
||||
|
||||
// Access control type/status
|
||||
|
||||
public final static int NoAccess = 0;
|
||||
public final static int ReadOnly = 1;
|
||||
public final static int ReadWrite = 2;
|
||||
|
||||
public final static int MaxLevel = 2;
|
||||
|
||||
// Default access status, indicates that the access conrol did not apply
|
||||
|
||||
public final static int Default = -1;
|
||||
|
||||
// Access type strings
|
||||
|
||||
private final static String[] _accessType = { "None", "Read", "Write" };
|
||||
|
||||
// Access control name and type
|
||||
|
||||
private String m_name;
|
||||
private String m_type;
|
||||
|
||||
// Access type
|
||||
|
||||
private int m_access;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param name String
|
||||
* @param type String
|
||||
* @param access int
|
||||
*/
|
||||
protected AccessControl(String name, String type, int access)
|
||||
{
|
||||
setName(name);
|
||||
setType(type);
|
||||
|
||||
m_access = access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control type
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control check type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getAccess()
|
||||
{
|
||||
return m_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control check type as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getAccessString()
|
||||
{
|
||||
return _accessType[m_access];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the specified session has access to the shared device.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @param mgr AccessControlManager
|
||||
* @return int
|
||||
*/
|
||||
public abstract int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr);
|
||||
|
||||
/**
|
||||
* Return the index of a value from a list of valid values, or 01 if not valid
|
||||
*
|
||||
* @param val String
|
||||
* @param list String[]
|
||||
* @param caseSensitive boolean
|
||||
* @return int
|
||||
*/
|
||||
protected final static int indexFromList(String val, String[] valid, boolean caseSensitive)
|
||||
{
|
||||
|
||||
// Check if the value is valid
|
||||
|
||||
if (val == null || val.length() == 0)
|
||||
return -1;
|
||||
|
||||
// Search for the matching value in the valid list
|
||||
|
||||
for (int i = 0; i < valid.length; i++)
|
||||
{
|
||||
|
||||
// Check the current value in the valid list
|
||||
|
||||
if (caseSensitive)
|
||||
{
|
||||
if (valid[i].equals(val))
|
||||
return i;
|
||||
}
|
||||
else if (valid[i].equalsIgnoreCase(val))
|
||||
return i;
|
||||
}
|
||||
|
||||
// Value does not match any of the valid values
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of valid strings from a comma delimeted list
|
||||
*
|
||||
* @param str String
|
||||
* @return String[]
|
||||
*/
|
||||
protected final static String[] listFromString(String str)
|
||||
{
|
||||
|
||||
// Check if the string is valid
|
||||
|
||||
if (str == null || str.length() == 0)
|
||||
return null;
|
||||
|
||||
// Split the comma delimeted string into an array of strings
|
||||
|
||||
StringTokenizer token = new StringTokenizer(str, ",");
|
||||
int numStrs = token.countTokens();
|
||||
if (numStrs == 0)
|
||||
return null;
|
||||
|
||||
String[] list = new String[numStrs];
|
||||
|
||||
// Parse the string into a list of strings
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (token.hasMoreTokens())
|
||||
list[i++] = token.nextToken();
|
||||
|
||||
// Return the string list
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the access control type
|
||||
*
|
||||
* @param typ String
|
||||
*/
|
||||
protected final void setType(String typ)
|
||||
{
|
||||
m_type = typ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the access control name
|
||||
*
|
||||
* @param name String
|
||||
*/
|
||||
protected final void setName(String name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control type as a string
|
||||
*
|
||||
* @param access int
|
||||
* @return String
|
||||
*/
|
||||
public static final String asAccessString(int access)
|
||||
{
|
||||
if (access == Default)
|
||||
return "Default";
|
||||
return _accessType[access];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("[");
|
||||
str.append(getType());
|
||||
str.append(":");
|
||||
str.append(getName());
|
||||
str.append(",");
|
||||
str.append(getAccessString());
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
|
||||
/**
|
||||
* Access Control Factoy Class
|
||||
* <p>
|
||||
* The AccessControlFactory class holds a table of available AccessControlParsers that are used to
|
||||
* generate AccessControl instances.
|
||||
* <p>
|
||||
* An AccessControlParser has an associated unique type name that is used to call the appropriate
|
||||
* parser.
|
||||
*/
|
||||
public class AccessControlFactory
|
||||
{
|
||||
|
||||
// Access control parsers
|
||||
|
||||
private Hashtable<String, AccessControlParser> m_parsers;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public AccessControlFactory()
|
||||
{
|
||||
m_parsers = new Hashtable<String, AccessControlParser>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an access control using the specified parameters
|
||||
*
|
||||
* @param type String
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @exception ACLParseException
|
||||
* @exception InvalidACLTypeException
|
||||
*/
|
||||
public final AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException,
|
||||
InvalidACLTypeException
|
||||
{
|
||||
|
||||
// Find the access control parser
|
||||
|
||||
AccessControlParser parser = m_parsers.get(type);
|
||||
if (parser == null)
|
||||
throw new InvalidACLTypeException(type);
|
||||
|
||||
// Parse the parameters and create a new AccessControl instance
|
||||
|
||||
return parser.createAccessControl(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a parser to the list of available parsers
|
||||
*
|
||||
* @param parser AccessControlParser
|
||||
*/
|
||||
public final void addParser(AccessControlParser parser)
|
||||
{
|
||||
m_parsers.put(parser.getType(), parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a parser from the available parser list
|
||||
*
|
||||
* @param type String
|
||||
* @return AccessControlParser
|
||||
*/
|
||||
public final AccessControlParser removeParser(String type)
|
||||
{
|
||||
return (AccessControlParser) m_parsers.remove(type);
|
||||
}
|
||||
}
|
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Access Control List Class
|
||||
* <p>
|
||||
* Contains a list of access controls for a shared filesystem.
|
||||
*/
|
||||
public class AccessControlList
|
||||
{
|
||||
|
||||
// Access control list
|
||||
|
||||
private Vector<AccessControl> m_list;
|
||||
|
||||
// Default access level applied when rules return a default status
|
||||
|
||||
private int m_defaultAccess = AccessControl.ReadWrite;
|
||||
|
||||
/**
|
||||
* Create an access control list.
|
||||
*/
|
||||
public AccessControlList()
|
||||
{
|
||||
m_list = new Vector<AccessControl>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default access level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int getDefaultAccessLevel()
|
||||
{
|
||||
return m_defaultAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default access level
|
||||
*
|
||||
* @param level int
|
||||
* @exception InvalidACLTypeException If the access level is invalid
|
||||
*/
|
||||
public final void setDefaultAccessLevel(int level) throws InvalidACLTypeException
|
||||
{
|
||||
|
||||
// Check the default access level
|
||||
|
||||
if (level < AccessControl.NoAccess || level > AccessControl.MaxLevel)
|
||||
throw new InvalidACLTypeException();
|
||||
|
||||
// Set the default access level for the access control list
|
||||
|
||||
m_defaultAccess = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an access control to the list
|
||||
*
|
||||
* @param accCtrl AccessControl
|
||||
*/
|
||||
public final void addControl(AccessControl accCtrl)
|
||||
{
|
||||
|
||||
// Add the access control to the list
|
||||
|
||||
m_list.add(accCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specified access control
|
||||
*
|
||||
* @param idx int
|
||||
* @return AccessControl
|
||||
*/
|
||||
public final AccessControl getControlAt(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= m_list.size())
|
||||
return null;
|
||||
return m_list.get(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of access controls in the list
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public final int numberOfControls()
|
||||
{
|
||||
return m_list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all access controls from the list
|
||||
*/
|
||||
public final void removeAllControls()
|
||||
{
|
||||
m_list.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified access control from the list.
|
||||
*
|
||||
* @param idx int
|
||||
* @return AccessControl
|
||||
*/
|
||||
public final AccessControl removeControl(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= m_list.size())
|
||||
return null;
|
||||
return m_list.remove(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the access control list as a string.
|
||||
*
|
||||
* @return java.lang.String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("[");
|
||||
str.append(m_list.size());
|
||||
str.append(":");
|
||||
|
||||
str.append(":");
|
||||
str.append(AccessControl.asAccessString(getDefaultAccessLevel()));
|
||||
str.append(":");
|
||||
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
AccessControl ctrl = m_list.get(i);
|
||||
str.append(ctrl.toString());
|
||||
str.append(",");
|
||||
}
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.server.core.SharedDeviceList;
|
||||
|
||||
/**
|
||||
* Access Control Manager Interface
|
||||
* <p>
|
||||
* Used to control access to shared filesystems.
|
||||
*
|
||||
* @author Gary K. Spencer
|
||||
*/
|
||||
public interface AccessControlManager
|
||||
{
|
||||
|
||||
/**
|
||||
* Initialize the access control manager
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params);
|
||||
|
||||
/**
|
||||
* Check access to the shared filesystem for the specified session
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @return int
|
||||
*/
|
||||
public int checkAccessControl(SrvSession sess, SharedDevice share);
|
||||
|
||||
/**
|
||||
* Filter a shared device list to remove shares that are not visible or the session does not
|
||||
* have access to.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param shares SharedDeviceList
|
||||
* @return SharedDeviceList
|
||||
*/
|
||||
public SharedDeviceList filterShareList(SrvSession sess, SharedDeviceList shares);
|
||||
|
||||
/**
|
||||
* Create an access control
|
||||
*
|
||||
* @param type String
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @exception ACLParseException
|
||||
* @exception InvalidACLTypeException
|
||||
*/
|
||||
public AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException,
|
||||
InvalidACLTypeException;
|
||||
|
||||
/**
|
||||
* Add an access control parser to the list of available access control types.
|
||||
*
|
||||
* @param parser AccessControlParser
|
||||
*/
|
||||
public void addAccessControlType(AccessControlParser parser);
|
||||
}
|
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
|
||||
/**
|
||||
* Access Control Parser Class
|
||||
* <p>
|
||||
* Creates an AccessControl instance by parsing a set of name/value parameters.
|
||||
*/
|
||||
public abstract class AccessControlParser
|
||||
{
|
||||
|
||||
// Constants
|
||||
//
|
||||
// Standard parameter names
|
||||
|
||||
public final static String ParameterAccess = "access";
|
||||
|
||||
// Access control type names
|
||||
|
||||
private final static String[] _accessTypes = { "None", "Read", "Write" };
|
||||
|
||||
/**
|
||||
* Return the access control type name that uniquely identifies this type of access control.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public abstract String getType();
|
||||
|
||||
/**
|
||||
* Create an AccessControl instance by parsing the set of name/value parameters
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @exception ACLParseException
|
||||
*/
|
||||
public abstract AccessControl createAccessControl(ConfigElement params) throws ACLParseException;
|
||||
|
||||
/**
|
||||
* Find the access parameter and parse the value
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return int
|
||||
* @exception ACLParseException
|
||||
*/
|
||||
protected final int parseAccessType(ConfigElement params) throws ACLParseException
|
||||
{
|
||||
|
||||
// Check if the parameter list is valid
|
||||
|
||||
if (params == null)
|
||||
throw new ACLParseException("Empty parameter list");
|
||||
|
||||
// Find the access type parameter
|
||||
|
||||
String accessType = params.getAttribute(ParameterAccess);
|
||||
|
||||
if (accessType == null || accessType.length() == 0)
|
||||
throw new ACLParseException("Required parameter 'access' missing");
|
||||
|
||||
// Parse the access type value
|
||||
|
||||
return parseAccessTypeString(accessType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the access level type and validate
|
||||
*
|
||||
* @param accessType String
|
||||
* @return int
|
||||
* @exception ACLParseException
|
||||
*/
|
||||
public static final int parseAccessTypeString(String accessType) throws ACLParseException
|
||||
{
|
||||
|
||||
// Check if the access type is valid
|
||||
|
||||
if (accessType == null || accessType.length() == 0)
|
||||
throw new ACLParseException("Empty access type string");
|
||||
|
||||
// Parse the access type value
|
||||
|
||||
int access = -1;
|
||||
|
||||
for (int i = 0; i < _accessTypes.length; i++)
|
||||
{
|
||||
|
||||
// Check if the access type matches the current type
|
||||
|
||||
if (accessType.equalsIgnoreCase(_accessTypes[i]))
|
||||
access = i;
|
||||
}
|
||||
|
||||
// Check if we found a valid access type
|
||||
|
||||
if (access == -1)
|
||||
throw new ACLParseException("Invalid access type, " + accessType);
|
||||
|
||||
// Return the access type
|
||||
|
||||
return access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser details as a string
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("[");
|
||||
str.append(getType());
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.config.ServerConfiguration;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.server.core.SharedDeviceList;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Default Access Control Manager Class
|
||||
* <p>
|
||||
* Default access control manager implementation.
|
||||
*
|
||||
* @author Gary K. Spencer
|
||||
*/
|
||||
public class DefaultAccessControlManager implements AccessControlManager
|
||||
{
|
||||
|
||||
// Debug logging
|
||||
|
||||
private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol");
|
||||
|
||||
// Access control factory
|
||||
|
||||
private AccessControlFactory m_factory;
|
||||
|
||||
// Debug enable flag
|
||||
|
||||
private boolean m_debug;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public DefaultAccessControlManager()
|
||||
{
|
||||
|
||||
// Create the access control factory
|
||||
|
||||
m_factory = new AccessControlFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session has access to the shared device.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @return int
|
||||
*/
|
||||
public int checkAccessControl(SrvSession sess, SharedDevice share)
|
||||
{
|
||||
|
||||
// Check if the shared device has any access control configured
|
||||
|
||||
if (share.hasAccessControls() == false)
|
||||
{
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Check access control for " + share.getName() + ", no ACLs");
|
||||
|
||||
// Allow full access to the share
|
||||
|
||||
return AccessControl.ReadWrite;
|
||||
}
|
||||
|
||||
// Process the access control list
|
||||
|
||||
AccessControlList acls = share.getAccessControls();
|
||||
int access = AccessControl.Default;
|
||||
|
||||
// DEBUG
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Check access control for " + share.getName() + ", ACLs=" + acls.numberOfControls());
|
||||
|
||||
for (int i = 0; i < acls.numberOfControls(); i++)
|
||||
{
|
||||
|
||||
// Get the current access control and run
|
||||
|
||||
AccessControl acl = acls.getControlAt(i);
|
||||
int curAccess = acl.allowsAccess(sess, share, this);
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug(" Check access ACL=" + acl + ", access=" + AccessControl.asAccessString(curAccess));
|
||||
|
||||
// Update the allowed access
|
||||
|
||||
if (curAccess != AccessControl.Default)
|
||||
access = curAccess;
|
||||
}
|
||||
|
||||
// Check if the default access level is still selected, if so then get the default level
|
||||
// from the
|
||||
// access control list
|
||||
|
||||
if (access == AccessControl.Default)
|
||||
{
|
||||
|
||||
// Use the default access level
|
||||
|
||||
access = acls.getDefaultAccessLevel();
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Access defaulted=" + AccessControl.asAccessString(access) + ", share=" + share);
|
||||
}
|
||||
else if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Access allowed=" + AccessControl.asAccessString(access) + ", share=" + share);
|
||||
|
||||
// Return the access type
|
||||
|
||||
return access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of shared devices to return a list that contains only the shares that are
|
||||
* visible or accessible by the session.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param shares SharedDeviceList
|
||||
* @return SharedDeviceList
|
||||
*/
|
||||
public SharedDeviceList filterShareList(SrvSession sess, SharedDeviceList shares)
|
||||
{
|
||||
|
||||
// Check if the share list is valid or empty
|
||||
|
||||
if (shares == null || shares.numberOfShares() == 0)
|
||||
return shares;
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Filter share list for " + sess + ", shares=" + shares);
|
||||
|
||||
// For each share in the list check the access, remove any shares that the session does not
|
||||
// have access to.
|
||||
|
||||
SharedDeviceList filterList = new SharedDeviceList();
|
||||
Enumeration<SharedDevice> enm = shares.enumerateShares();
|
||||
|
||||
while (enm.hasMoreElements())
|
||||
{
|
||||
|
||||
// Get the current share
|
||||
|
||||
SharedDevice share = enm.nextElement();
|
||||
|
||||
// Check if the share has any access controls
|
||||
|
||||
if (share.hasAccessControls())
|
||||
{
|
||||
|
||||
// Check if the session has access to this share
|
||||
|
||||
int access = checkAccessControl(sess, share);
|
||||
if (access != AccessControl.NoAccess)
|
||||
filterList.addShare(share);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Add the share to the filtered list
|
||||
|
||||
filterList.addShare(share);
|
||||
}
|
||||
}
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("Filtered share list " + filterList);
|
||||
|
||||
// Return the filtered share list
|
||||
|
||||
return filterList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the access control manager
|
||||
*
|
||||
* @param config ServerConfiguration
|
||||
* @param params ConfigElement
|
||||
*/
|
||||
public void initialize(ServerConfiguration config, ConfigElement params)
|
||||
{
|
||||
|
||||
// Check if debug output is enabled
|
||||
|
||||
if (params != null && params.getChild("debug") != null)
|
||||
setDebug(true);
|
||||
|
||||
// Add the default access control types
|
||||
|
||||
addAccessControlType(new UserAccessControlParser());
|
||||
addAccessControlType(new ProtocolAccessControlParser());
|
||||
addAccessControlType(new DomainAccessControlParser());
|
||||
addAccessControlType(new IpAddressAccessControlParser());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an access control.
|
||||
*
|
||||
* @param type String
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @throws ACLParseException
|
||||
* @throws InvalidACLTypeException
|
||||
*/
|
||||
public AccessControl createAccessControl(String type, ConfigElement params) throws ACLParseException,
|
||||
InvalidACLTypeException
|
||||
{
|
||||
|
||||
// Use the access control factory to create the access control instance
|
||||
|
||||
return m_factory.createAccessControl(type, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an access control parser to the list of available access control types.
|
||||
*
|
||||
* @param parser AccessControlParser
|
||||
*/
|
||||
public void addAccessControlType(AccessControlParser parser)
|
||||
{
|
||||
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled() && hasDebug())
|
||||
logger.debug("AccessControlManager Add rule type " + parser.getType());
|
||||
|
||||
// Add the new access control type to the factory
|
||||
|
||||
m_factory.addParser(parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if debug output is enabled
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean hasDebug()
|
||||
{
|
||||
return m_debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/disable debug output
|
||||
*
|
||||
* @param dbg boolean
|
||||
*/
|
||||
public final void setDebug(boolean dbg)
|
||||
{
|
||||
m_debug = dbg;
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.auth.ClientInfo;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* Domain Name Access Control Class
|
||||
* <p>
|
||||
* Allow/disallow access based on the SMB/CIFS session callers domain name.
|
||||
*/
|
||||
public class DomainAccessControl extends AccessControl
|
||||
{
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param domainName String
|
||||
* @param type String
|
||||
* @param access int
|
||||
*/
|
||||
protected DomainAccessControl(String domainName, String type, int access)
|
||||
{
|
||||
super(domainName, type, access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the domain name matches the access control domain name and return the allowed
|
||||
* access.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @param mgr AccessControlManager
|
||||
* @return int
|
||||
*/
|
||||
public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr)
|
||||
{
|
||||
|
||||
// Check if the session has client information
|
||||
|
||||
if (sess.hasClientInformation() == false
|
||||
|| sess instanceof org.alfresco.filesys.smb.server.SMBSrvSession == false)
|
||||
return Default;
|
||||
|
||||
// Check if the domain name matches the access control name
|
||||
|
||||
ClientInfo cInfo = sess.getClientInformation();
|
||||
|
||||
if (cInfo.getDomain() != null && cInfo.getDomain().equalsIgnoreCase(getName()))
|
||||
return getAccess();
|
||||
return Default;
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
|
||||
/**
|
||||
* Domain Name Access Control Parser Class
|
||||
*/
|
||||
public class DomainAccessControlParser extends AccessControlParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public DomainAccessControlParser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser type
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return "domain";
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the parameters and create a user access control
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @throws ACLParseException
|
||||
*/
|
||||
public AccessControl createAccessControl(ConfigElement params) throws ACLParseException
|
||||
{
|
||||
|
||||
// Get the access type
|
||||
|
||||
int access = parseAccessType(params);
|
||||
|
||||
// Get the domain name to check for
|
||||
|
||||
String domainName = params.getAttribute("name");
|
||||
if (domainName == null || domainName.length() == 0)
|
||||
throw new ACLParseException("Domain name not specified");
|
||||
|
||||
// Create the domain access control
|
||||
|
||||
return new DomainAccessControl(domainName, getType(), access);
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
/**
|
||||
* Invalid ACL Type Exception Class
|
||||
*/
|
||||
public class InvalidACLTypeException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 3257844398418310708L;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public InvalidACLTypeException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param s java.lang.String
|
||||
*/
|
||||
public InvalidACLTypeException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
import org.alfresco.filesys.util.IPAddress;
|
||||
|
||||
/**
|
||||
* Ip Address Access Control Class
|
||||
* <p>
|
||||
* Allow/disallow access by checking for a particular TCP/IP address or checking that the address is
|
||||
* within a specified subnet.
|
||||
*/
|
||||
public class IpAddressAccessControl extends AccessControl
|
||||
{
|
||||
|
||||
// Subnet and network mask if the address specifies the subnet
|
||||
|
||||
private String m_subnet;
|
||||
private String m_netMask;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param address String
|
||||
* @param mask String
|
||||
* @param type String
|
||||
* @param access int
|
||||
*/
|
||||
protected IpAddressAccessControl(String address, String mask, String type, int access)
|
||||
{
|
||||
super(address, type, access);
|
||||
|
||||
// Save the subnet and network mask, if specified
|
||||
|
||||
m_subnet = address;
|
||||
m_netMask = mask;
|
||||
|
||||
// Change the rule name if a network mask has been specified
|
||||
|
||||
if (m_netMask != null)
|
||||
setName(m_subnet + "/" + m_netMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the TCP/IP address matches the specifed address or is within the subnet.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @param mgr AccessControlManager
|
||||
* @return int
|
||||
*/
|
||||
public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr)
|
||||
{
|
||||
|
||||
// Check if the remote address is set for the session
|
||||
|
||||
InetAddress remoteAddr = sess.getRemoteAddress();
|
||||
|
||||
if (remoteAddr == null)
|
||||
return Default;
|
||||
|
||||
// Get the remote address as a numeric IP address string
|
||||
|
||||
String ipAddr = remoteAddr.getHostAddress();
|
||||
|
||||
// Check if the access control is a single TCP/IP address check
|
||||
|
||||
int sts = Default;
|
||||
|
||||
if (m_netMask == null)
|
||||
{
|
||||
|
||||
// Check if the TCP/IP address matches the check address
|
||||
|
||||
if (IPAddress.parseNumericAddress(ipAddr) == IPAddress.parseNumericAddress(getName()))
|
||||
sts = getAccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Check if the address is within the subnet range
|
||||
|
||||
if (IPAddress.isInSubnet(ipAddr, m_subnet, m_netMask) == true)
|
||||
sts = getAccess();
|
||||
}
|
||||
|
||||
// Return the access status
|
||||
|
||||
return sts;
|
||||
}
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.util.IPAddress;
|
||||
|
||||
/**
|
||||
* Ip Address Access Control Parser Class
|
||||
*/
|
||||
public class IpAddressAccessControlParser extends AccessControlParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public IpAddressAccessControlParser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser type
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return "address";
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the parameters and create an address access control
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @throws ACLParseException
|
||||
*/
|
||||
public AccessControl createAccessControl(ConfigElement params) throws ACLParseException
|
||||
{
|
||||
|
||||
// Get the access type
|
||||
|
||||
int access = parseAccessType(params);
|
||||
|
||||
// Check if the single IP address format has been specified
|
||||
|
||||
String ipAddr = params.getAttribute("ip");
|
||||
if (ipAddr != null)
|
||||
{
|
||||
|
||||
// Validate the parameters
|
||||
|
||||
if (ipAddr.length() == 0 || IPAddress.isNumericAddress(ipAddr) == false)
|
||||
throw new ACLParseException("Invalid IP address, " + ipAddr);
|
||||
|
||||
if (params.getAttributeCount() != 2)
|
||||
throw new ACLParseException("Invalid parameter(s) specified for address");
|
||||
|
||||
// Create a single TCP/IP address access control rule
|
||||
|
||||
return new IpAddressAccessControl(ipAddr, null, getType(), access);
|
||||
}
|
||||
|
||||
// Check if a subnet address and mask have been specified
|
||||
|
||||
String subnet = params.getAttribute("subnet");
|
||||
if (subnet != null)
|
||||
{
|
||||
|
||||
// Get the network mask parameter
|
||||
|
||||
String netmask = params.getAttribute("mask");
|
||||
|
||||
// Validate the parameters
|
||||
|
||||
if (subnet.length() == 0 || netmask == null || netmask.length() == 0)
|
||||
throw new ACLParseException("Invalid subnet/mask parameter");
|
||||
|
||||
if (IPAddress.isNumericAddress(subnet) == false)
|
||||
throw new ACLParseException("Invalid subnet parameter, " + subnet);
|
||||
|
||||
if (IPAddress.isNumericAddress(netmask) == false)
|
||||
throw new ACLParseException("Invalid mask parameter, " + netmask);
|
||||
|
||||
// Create a subnet address access control rule
|
||||
|
||||
return new IpAddressAccessControl(subnet, netmask, getType(), access);
|
||||
}
|
||||
|
||||
// Invalid parameters
|
||||
|
||||
throw new ACLParseException("Unknown address parameter(s)");
|
||||
}
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* Protocol Access Control Class
|
||||
* <p>
|
||||
* Allow/disallow access to a share based on the protocol type.
|
||||
*/
|
||||
public class ProtocolAccessControl extends AccessControl
|
||||
{
|
||||
|
||||
// Available protocol type names
|
||||
|
||||
private static final String[] _protoTypes = { "SMB", "CIFS", "NFS", "FTP" };
|
||||
|
||||
// Parsed list of protocol types
|
||||
|
||||
private String[] m_checkList;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param protList String
|
||||
* @param type String
|
||||
* @param access int
|
||||
*/
|
||||
protected ProtocolAccessControl(String protList, String type, int access)
|
||||
{
|
||||
super(protList, type, access);
|
||||
|
||||
// Parse the protocol list
|
||||
|
||||
m_checkList = listFromString(protList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the protocol matches the access control protocol list and return the allowed access.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @param mgr AccessControlManager
|
||||
* @return int
|
||||
*/
|
||||
public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr)
|
||||
{
|
||||
|
||||
// Determine the session protocol type
|
||||
|
||||
String sessProto = null;
|
||||
String sessName = sess.getClass().getName();
|
||||
|
||||
if (sessName.endsWith(".SMBSrvSession"))
|
||||
sessProto = "CIFS";
|
||||
else if (sessName.endsWith(".FTPSrvSession"))
|
||||
sessProto = "FTP";
|
||||
else if (sessName.endsWith(".NFSSrvSession"))
|
||||
sessProto = "NFS";
|
||||
|
||||
// Check if the session protocol type is in the protocols to be checked
|
||||
|
||||
if (sessProto != null && indexFromList(sessProto, m_checkList, false) != -1)
|
||||
return getAccess();
|
||||
return Default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the protocol list
|
||||
*
|
||||
* @param protList String
|
||||
* @return boolean
|
||||
*/
|
||||
public static final boolean validateProtocolList(String protList)
|
||||
{
|
||||
|
||||
// Check if the protocol list string is valid
|
||||
|
||||
if (protList == null || protList.length() == 0)
|
||||
return false;
|
||||
|
||||
// Split the protocol list and validate each protocol name
|
||||
|
||||
StringTokenizer tokens = new StringTokenizer(protList, ",");
|
||||
|
||||
while (tokens.hasMoreTokens())
|
||||
{
|
||||
|
||||
// Get the current protocol name and validate
|
||||
|
||||
String name = tokens.nextToken().toUpperCase();
|
||||
if (indexFromList(name, _protoTypes, false) == -1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Protocol list is valid
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
|
||||
/**
|
||||
* Protocol Access Control Parser Class
|
||||
*/
|
||||
public class ProtocolAccessControlParser extends AccessControlParser
|
||||
{
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public ProtocolAccessControlParser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser type
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return "protocol";
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the parameters and create a user access control
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @throws ACLParseException
|
||||
*/
|
||||
public AccessControl createAccessControl(ConfigElement params) throws ACLParseException
|
||||
{
|
||||
|
||||
// Get the access type
|
||||
|
||||
int access = parseAccessType(params);
|
||||
|
||||
// Get the list of protocols to check for
|
||||
|
||||
String protos = params.getAttribute("type");
|
||||
if (protos == null || protos.length() == 0)
|
||||
throw new ACLParseException("Protocol type not specified");
|
||||
|
||||
// Validate the protocol list
|
||||
|
||||
if (ProtocolAccessControl.validateProtocolList(protos) == false)
|
||||
throw new ACLParseException("Invalid protocol type");
|
||||
|
||||
// Create the protocol access control
|
||||
|
||||
return new ProtocolAccessControl(protos, getType(), access);
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.filesys.server.SrvSession;
|
||||
import org.alfresco.filesys.server.auth.ClientInfo;
|
||||
import org.alfresco.filesys.server.core.SharedDevice;
|
||||
|
||||
/**
|
||||
* User Access Control Class
|
||||
* <p>
|
||||
* Allow/disallow access to a shared device by checking the user name.
|
||||
*/
|
||||
public class UserAccessControl extends AccessControl
|
||||
{
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param userName String
|
||||
* @param type String
|
||||
* @param access int
|
||||
*/
|
||||
protected UserAccessControl(String userName, String type, int access)
|
||||
{
|
||||
super(userName, type, access);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user name matches the access control user name and return the allowed access.
|
||||
*
|
||||
* @param sess SrvSession
|
||||
* @param share SharedDevice
|
||||
* @param mgr AccessControlManager
|
||||
* @return int
|
||||
*/
|
||||
public int allowsAccess(SrvSession sess, SharedDevice share, AccessControlManager mgr)
|
||||
{
|
||||
|
||||
// Check if the session has client information
|
||||
|
||||
if (sess.hasClientInformation() == false)
|
||||
return Default;
|
||||
|
||||
// Check if the user name matches the access control name
|
||||
|
||||
ClientInfo cInfo = sess.getClientInformation();
|
||||
|
||||
if (cInfo.getUserName() != null && cInfo.getUserName().equalsIgnoreCase(getName()))
|
||||
return getAccess();
|
||||
return Default;
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.server.auth.acl;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
|
||||
/**
|
||||
* User Access Control Parser Class
|
||||
*/
|
||||
public class UserAccessControlParser extends AccessControlParser
|
||||
{
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public UserAccessControlParser()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser type
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return "user";
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the parameters and create a user access control
|
||||
*
|
||||
* @param params ConfigElement
|
||||
* @return AccessControl
|
||||
* @throws ACLParseException
|
||||
*/
|
||||
public AccessControl createAccessControl(ConfigElement params) throws ACLParseException
|
||||
{
|
||||
|
||||
// Get the access type
|
||||
|
||||
int access = parseAccessType(params);
|
||||
|
||||
// Get the user name to check for
|
||||
|
||||
String userName = params.getAttribute("name");
|
||||
if (userName == null || userName.length() == 0)
|
||||
throw new ACLParseException("User name not specified");
|
||||
|
||||
// Create the user access control
|
||||
|
||||
return new UserAccessControl(userName, getType(), access);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user