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:
Derek Hulley
2005-12-08 07:13:07 +00:00
commit e1e6508fec
1095 changed files with 230566 additions and 0 deletions

View File

@@ -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);
}
}
}
}

View 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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View 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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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)");
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}