Humongous merge. It is incomplete, however; faces-config-navigation.xml and ClientConfigElement

were both beyond me, and are just the raw conflict merge data.  If Kev can't figure out how they should
go together by tomorrow AM (for me) I'll dig back in.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4306 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-11-08 05:17:40 +00:00
parent 2c20af6d2b
commit b2f9df29d1
140 changed files with 20060 additions and 16456 deletions

View File

@@ -26,12 +26,11 @@ import org.alfresco.filesys.netbios.server.NetBIOSNameServer;
import org.alfresco.filesys.server.NetworkServer;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.filesys.smb.server.SMBServer;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
@@ -41,7 +40,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author GKSpencer
*/
public class CIFSServer implements ApplicationListener
public class CIFSServer extends AbstractLifecycleBean
{
private static final Log logger = LogFactory.getLog("org.alfresco.smb.server");
@@ -81,29 +80,6 @@ public class CIFSServer implements ApplicationListener
return (filesysConfig != null && filesysConfig.isSMBServerEnabled());
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ApplicationEvent event)
{
if (event instanceof ContextRefreshedEvent)
{
try
{
startServer();
}
catch (SocketException e)
{
throw new AlfrescoRuntimeException("Failed to start CIFS server", e);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to start CIFS server", e);
}
}
}
/**
* Start the CIFS server components
*
@@ -264,5 +240,27 @@ public class CIFSServer implements ApplicationListener
System.exit(1);
}
@Override
protected void onBootstrap(ApplicationEvent event)
{
try
{
startServer();
}
catch (SocketException e)
{
throw new AlfrescoRuntimeException("Failed to start CIFS server", e);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to start CIFS server", e);
}
}
@Override
protected void onShutdown(ApplicationEvent event)
{
stopServer();
}
}

View File

@@ -24,11 +24,11 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.ftp.FTPNetworkServer;
import org.alfresco.filesys.server.NetworkServer;
import org.alfresco.filesys.server.config.ServerConfiguration;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -39,7 +39,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author GKSpencer
*/
public class FTPServer implements ApplicationListener
public class FTPServer extends AbstractLifecycleBean
{
private static final Log logger = LogFactory.getLog("org.alfresco.ftp.server");
@@ -79,29 +79,6 @@ public class FTPServer implements ApplicationListener
return (filesysConfig != null && filesysConfig.isFTPServerEnabled());
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ApplicationEvent event)
{
if (event instanceof ContextRefreshedEvent)
{
try
{
startServer();
}
catch (SocketException e)
{
throw new AlfrescoRuntimeException("Failed to start FTP server", e);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to start FTP server", e);
}
}
}
/**
* Start the FTP server components
*
@@ -251,4 +228,28 @@ public class FTPServer implements ApplicationListener
}
System.exit(1);
}
@Override
protected void onBootstrap(ApplicationEvent event)
{
try
{
startServer();
}
catch (SocketException e)
{
throw new AlfrescoRuntimeException("Failed to start FTP server", e);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Failed to start FTP server", e);
}
}
@Override
protected void onShutdown(ApplicationEvent event)
{
stopServer();
}
}

View File

@@ -852,7 +852,7 @@ public class FTPSrvSession extends SrvSession implements Runnable
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Logon failed", ex);
logger.debug("Logon failed for user " + cInfo.getUserName());
}
// Check if the logon was successful

View File

@@ -17,10 +17,17 @@
package org.alfresco.filesys.server.auth;
import java.security.NoSuchAlgorithmException;
import net.sf.acegisecurity.Authentication;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.AuthContext;
import org.alfresco.filesys.server.auth.CifsAuthenticator;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.util.HexDump;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
/**
* Alfresco Authenticator Class
@@ -88,10 +95,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
{
// Use the existing authentication token
if ( client.isGuest())
m_authComponent.setGuestUserAsCurrentUser();
else
m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName()));
m_authComponent.setCurrentUser(client.getUserName());
// Debug
@@ -107,7 +111,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
int authSts = AUTH_DISALLOW;
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(GUEST_USERNAME))
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Check if guest logons are allowed
@@ -140,7 +144,13 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
authSts = doMD4UserAuthentication(client, sess, alg);
}
else
{
// Perform passthru authentication password check
authSts = doPassthruUserAuthentication(client, sess, alg);
}
// Check if the logon status indicates a guest logon
if ( authSts == AUTH_GUEST)
@@ -172,6 +182,64 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
return authSts;
}
/**
* Return an authentication context for the new session
*
* @return AuthContext
*/
public AuthContext getAuthContext( SMBSrvSession sess)
{
// Check if the client is already authenticated, and it is not a null logon
AuthContext authCtx = null;
if ( sess.hasAuthenticationContext() && sess.hasAuthenticationToken() &&
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
{
// Return the previous challenge, user is already authenticated
authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Re-using existing challenge, already authenticated");
}
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Create a new authentication context for the session
authCtx = new NTLanManAuthContext();
sess.setAuthenticationContext( authCtx);
}
else
{
// Create an authentication token for the session
NTLMPassthruToken authToken = new NTLMPassthruToken();
// Run the first stage of the passthru authentication to get the challenge
m_authComponent.authenticate( authToken);
// Save the authentication token for the second stage of the authentication
sess.setAuthenticationToken(authToken);
// Get the challenge from the token
if ( authToken.getChallenge() != null)
{
authCtx = new NTLanManAuthContext( authToken.getChallenge().getBytes());
sess.setAuthenticationContext( authCtx);
}
}
// Return the authentication context
return authCtx;
}
/**
* Perform MD4 user authentication
*
@@ -217,6 +285,20 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Validate the password
byte[] clientHash = client.getPassword();
if ( clientHash == null || clientHash.length != 24)
{
// Use the secondary password hash from the client
clientHash = client.getANSIPassword();
// DEBUG
if ( logger.isDebugEnabled())
{
logger.debug( "Using secondary password hash - " + HexDump.hexString(clientHash));
logger.debug( " Local hash - " + HexDump.hexString( localHash));
}
}
if ( clientHash == null || clientHash.length != localHash.length)
return CifsAuthenticator.AUTH_BADPASSWORD;
@@ -229,7 +311,7 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
// Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( m_authComponent.setCurrentUser(mapUserNameToPerson(client.getUserName())));
client.setAuthenticationToken( m_authComponent.setCurrentUser(client.getUserName()));
// Get the users home folder node, if available
@@ -259,4 +341,101 @@ public class AlfrescoAuthenticator extends CifsAuthenticator
return allowGuest() ? CifsAuthenticator.AUTH_GUEST : CifsAuthenticator.AUTH_DISALLOW;
}
/**
* Perform passthru user authentication
*
* @param client Client information
* @param sess Server session
* @param alg Encryption algorithm
* @return int
*/
private final int doPassthruUserAuthentication(ClientInfo client, SrvSession sess, int alg)
{
// Get the authentication token for the session
NTLMPassthruToken authToken = (NTLMPassthruToken) sess.getAuthenticationToken();
if ( authToken == null)
return CifsAuthenticator.AUTH_DISALLOW;
// Get the appropriate hashed password for the algorithm
int authSts = CifsAuthenticator.AUTH_DISALLOW;
byte[] hashedPassword = null;
if ( alg == NTLM1)
hashedPassword = client.getPassword();
else if ( alg == LANMAN)
hashedPassword = client.getANSIPassword();
else
{
// Invalid/unsupported algorithm specified
return CifsAuthenticator.AUTH_DISALLOW;
}
// Set the username and hashed password in the authentication token
authToken.setUserAndPassword( client.getUserName(), hashedPassword, alg);
// Authenticate the user
Authentication genAuthToken = null;
try
{
// Run the second stage of the passthru authentication
genAuthToken = m_authComponent.authenticate( authToken);
// Check if the user has been logged on as a guest
if (authToken.isGuestLogon())
{
// Check if the local server allows guest access
if (allowGuest() == true)
{
// Allow the user access as a guest
authSts = CifsAuthenticator.AUTH_GUEST;
}
}
else
{
// Allow the user full access to the server
authSts = CifsAuthenticator.AUTH_ALLOW;
}
// Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( genAuthToken);
// Get the users home folder node, if available
getHomeFolderForUser( client);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Auth token " + genAuthToken);
}
catch ( Exception ex)
{
logger.error("Error during passthru authentication", ex);
}
// Clear the authentication token
sess.setAuthenticationToken(null);
// Return the authentication status
return authSts;
}
}

View File

@@ -470,7 +470,7 @@ public abstract class CifsAuthenticator
// Store the client maximum buffer size, maximum multiplexed requests count and client
// capability flags
sess.setClientMaximumBufferSize(maxBufSize);
sess.setClientMaximumBufferSize(maxBufSize != 0 ? maxBufSize : SMBSrvSession.DefaultBufferSize);
sess.setClientMaximumMultiplex(maxMpx);
sess.setClientCapabilities(capabs);

View File

@@ -71,6 +71,10 @@ public class ClientInfo
private Authentication m_authToken;
// Authentication ticket, used for web access without having to re-authenticate
private String m_authTicket;
// Home folder node
private NodeRef m_homeNode;
@@ -286,6 +290,26 @@ public class ClientInfo
{
return m_authToken;
}
/**
* Check if the client has an authentication ticket
*
* @return boolean
*/
public final boolean hasAuthenticationTicket()
{
return m_authTicket != null ? true : false;
}
/**
* Return the authentication ticket
*
* @return String
*/
public final String getAuthenticationTicket()
{
return m_authTicket;
}
/**
* Check if the client has a home folder node
@@ -409,6 +433,16 @@ public class ClientInfo
{
m_authToken = token;
}
/**
* Set the authentication ticket
*
* @param ticket String
*/
public final void setAuthenticationTicket(String ticket)
{
m_authTicket = ticket;
}
/**
* Set the home folder node
@@ -448,6 +482,12 @@ public class ClientInfo
str.append(",token=");
str.append(getAuthenticationToken());
}
if ( hasAuthenticationTicket())
{
str.append(",ticket=");
str.append(getAuthenticationTicket());
}
if (isGuest())
str.append(",Guest");

View File

@@ -584,7 +584,7 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticator implements Ca
// Store the client maximum buffer size, maximum multiplexed requests count and client capability flags
sess.setClientMaximumBufferSize(maxBufSize);
sess.setClientMaximumBufferSize(maxBufSize != 0 ? maxBufSize : SMBSrvSession.DefaultBufferSize);
sess.setClientMaximumMultiplex(maxMpx);
sess.setClientCapabilities(capabs);

View File

@@ -1,427 +0,0 @@
/*
* Copyright (C) 2005-2006 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.ntlm;
import java.security.NoSuchAlgorithmException;
import net.sf.acegisecurity.Authentication;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.AuthContext;
import org.alfresco.filesys.server.auth.CifsAuthenticator;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.auth.NTLanManAuthContext;
import org.alfresco.filesys.smb.server.SMBSrvSession;
import org.alfresco.filesys.util.DataPacker;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
/**
* 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 CifsAuthenticator
{
/**
* Default Constructor
*
* <p>Default to user mode security with encrypted password support.
*/
public AlfrescoAuthenticator()
{
}
/**
* Validate that the authentication component supports the required mode
*
* @return boolean
*/
protected boolean validateAuthenticationMode()
{
// Make sure the authentication component supports MD4 hashed passwords or passthru mode
if ( m_authComponent.getNTLMMode() != NTLMMode.MD4_PROVIDER &&
m_authComponent.getNTLMMode() != NTLMMode.PASS_THROUGH)
return false;
return true;
}
/**
* 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 CifsAuthenticator.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 this is a guest logon
int authSts = AUTH_DISALLOW;
if ( client.isGuest() || client.getUserName().equalsIgnoreCase(getGuestUserName()))
{
// Check if guest logons are allowed
if ( allowGuest() == false)
return AUTH_DISALLOW;
// Get a guest authentication token
doGuestLogon( client, sess);
// Indicate logged on as guest
authSts = AUTH_GUEST;
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Authenticated user " + client.getUserName() + " sts=" + getStatusAsString(authSts));
// Return the guest status
return authSts;
}
// Check if MD4 or passthru mode is configured
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Perform local MD4 password check
authSts = doMD4UserAuthentication(client, sess, alg);
}
else
{
// Perform passthru authentication password check
authSts = doPassthruUserAuthentication(client, sess, alg);
}
// Check if the logon status indicates a guest logon
if ( authSts == AUTH_GUEST)
{
// Only allow the guest logon if user mapping is enabled
if ( mapUnknownUserToGuest())
{
// Logon as guest, setup the security context
doGuestLogon( client, sess);
}
else
{
// Do not allow the guest logon
authSts = AUTH_DISALLOW;
}
}
// 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;
}
/**
* Return an authentication context for the new session
*
* @return AuthContext
*/
public AuthContext getAuthContext( SMBSrvSession sess)
{
// Check if the client is already authenticated, and it is not a null logon
AuthContext authCtx = null;
if ( sess.hasAuthenticationContext() && sess.hasAuthenticationToken() &&
sess.getClientInformation().getLogonType() != ClientInfo.LogonNull)
{
// Return the previous challenge, user is already authenticated
authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Re-using existing challenge, already authenticated");
}
else if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{
// Create a new authentication context for the session
authCtx = new NTLanManAuthContext();
sess.setAuthenticationContext( authCtx);
}
else
{
// Create an authentication token for the session
NTLMPassthruToken authToken = new NTLMPassthruToken();
// Run the first stage of the passthru authentication to get the challenge
m_authComponent.authenticate( authToken);
// Save the authentication token for the second stage of the authentication
sess.setAuthenticationToken(authToken);
// Get the challenge from the token
if ( authToken.getChallenge() != null)
{
authCtx = new NTLanManAuthContext( authToken.getChallenge().getBytes());
sess.setAuthenticationContext( authCtx);
}
}
// Return the authentication context
return authCtx;
}
/**
* 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 CifsAuthenticator.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);
// Get the challenge that was sent to the client
NTLanManAuthContext authCtx = null;
if ( sess.hasAuthenticationContext() && sess.getAuthenticationContext() instanceof NTLanManAuthContext)
authCtx = (NTLanManAuthContext) sess.getAuthenticationContext();
else
return CifsAuthenticator.AUTH_DISALLOW;
// Generate the local hash of the password using the same challenge
byte[] localHash = getEncryptor().doNTLM1Encryption(p21, authCtx.getChallenge());
// Validate the password
byte[] clientHash = client.getPassword();
if ( clientHash == null || clientHash.length != localHash.length)
return CifsAuthenticator.AUTH_BADPASSWORD;
for ( int i = 0; i < clientHash.length; i++)
{
if ( clientHash[i] != localHash[i])
return CifsAuthenticator.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 CifsAuthenticator.AUTH_ALLOW;
}
catch (NoSuchAlgorithmException ex)
{
}
// Error during password check, do not allow access
return CifsAuthenticator.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 CifsAuthenticator.AUTH_ALLOW;
// User does not exist, check if guest access is allowed
return allowGuest() ? CifsAuthenticator.AUTH_GUEST : CifsAuthenticator.AUTH_DISALLOW;
}
/**
* Perform passthru user authentication
*
* @param client Client information
* @param sess Server session
* @param alg Encryption algorithm
* @return int
*/
private final int doPassthruUserAuthentication(ClientInfo client, SrvSession sess, int alg)
{
// Get the authentication token for the session
NTLMPassthruToken authToken = (NTLMPassthruToken) sess.getAuthenticationToken();
if ( authToken == null)
return CifsAuthenticator.AUTH_DISALLOW;
// Get the appropriate hashed password for the algorithm
int authSts = CifsAuthenticator.AUTH_DISALLOW;
byte[] hashedPassword = null;
if ( alg == NTLM1)
hashedPassword = client.getPassword();
else if ( alg == LANMAN)
hashedPassword = client.getANSIPassword();
else
{
// Invalid/unsupported algorithm specified
return CifsAuthenticator.AUTH_DISALLOW;
}
// Set the username and hashed password in the authentication token
authToken.setUserAndPassword( client.getUserName(), hashedPassword, alg);
// Authenticate the user
Authentication genAuthToken = null;
try
{
// Run the second stage of the passthru authentication
genAuthToken = m_authComponent.authenticate( authToken);
// Check if the user has been logged on as a guest
if (authToken.isGuestLogon())
{
// Check if the local server allows guest access
if (allowGuest() == true)
{
// Allow the user access as a guest
authSts = CifsAuthenticator.AUTH_GUEST;
}
}
else
{
// Allow the user full access to the server
authSts = CifsAuthenticator.AUTH_ALLOW;
}
// Set the current user to be authenticated, save the authentication token
client.setAuthenticationToken( genAuthToken);
// Get the users home folder node, if available
getHomeFolderForUser( client);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Auth token " + genAuthToken);
}
catch ( Exception ex)
{
logger.error("Error during passthru authentication", ex);
}
// Clear the authentication token
sess.setAuthenticationToken(null);
// Return the authentication status
return authSts;
}
}

View File

@@ -39,6 +39,10 @@ public class NTLMLogonDetails
private String m_authSrvAddr;
// Date/time authentication was started
private long m_createTime;
// Date/time the user was authenticated
private long m_authTime;
@@ -61,6 +65,7 @@ public class NTLMLogonDetails
*/
public NTLMLogonDetails()
{
m_createTime = System.currentTimeMillis();
}
/**
@@ -74,6 +79,8 @@ public class NTLMLogonDetails
*/
public NTLMLogonDetails(String user, String wks, String domain, boolean guest, String authSrv)
{
m_createTime = System.currentTimeMillis();
setDetails(user, wks, domain, guest, authSrv);
}
@@ -117,6 +124,16 @@ public class NTLMLogonDetails
return m_authSrvAddr;
}
/**
* Return the date/time the authentication was started
*
* @return long
*/
public final long createdAt()
{
return m_createTime;
}
/**
* Return the date/time the user was authenticated
*

View File

@@ -81,11 +81,10 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.AbstractLifecycleBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
/**
* <p>
@@ -93,7 +92,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
*
* @author Gary K. Spencer
*/
public class ServerConfiguration implements ApplicationListener
public class ServerConfiguration extends AbstractLifecycleBean
{
// Debug logging
@@ -425,18 +424,6 @@ public class ServerConfiguration implements ApplicationListener
return initialised;
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ApplicationEvent event)
{
if (event instanceof ContextRefreshedEvent)
{
init();
}
}
/**
* Initialize the configuration using the configuration service
*/
@@ -1791,9 +1778,7 @@ public class ServerConfiguration implements ApplicationListener
// Load the Alfresco authenticator dynamically
auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.ntlm.AlfrescoAuthenticator");
if ( auth == null)
auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.AlfrescoAuthenticator");
auth = loadAuthenticatorClass("org.alfresco.filesys.server.auth.AlfrescoAuthenticator");
if ( auth == null)
throw new AlfrescoRuntimeException("Failed to load Alfresco authenticator");
@@ -3359,4 +3344,17 @@ public class ServerConfiguration implements ApplicationListener
return srvAuth;
}
@Override
protected void onBootstrap(ApplicationEvent event)
{
init();
}
@Override
protected void onShutdown(ApplicationEvent event)
{
// NO-OP
}
}

View File

@@ -18,6 +18,7 @@ package org.alfresco.filesys.smb.server.repo;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.util.List;
import javax.transaction.UserTransaction;
@@ -58,7 +59,6 @@ import org.alfresco.filesys.util.WildCard;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.lock.NodeLockedException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -66,6 +66,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService;
@@ -91,6 +92,10 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
private static final String KEY_ROOT_PATH = "rootPath";
private static final String KEY_RELATIVE_PATH = "relativePath";
// Token name to substitute current servers DNS name or TCP/IP address into the webapp URL
private static final String TokenLocalName = "${localname}";
// Services and helpers
private CifsHelper cifsHelper;
@@ -102,6 +107,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
private PermissionService permissionService;
private AuthenticationComponent authComponent;
private AuthenticationService authService;
// Service registry for desktop actions
@@ -127,6 +133,16 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
return this.cifsHelper;
}
/**
* Return the authentication service
*
* @return AuthenticationService
*/
public final AuthenticationService getAuthenticationService()
{
return authService;
}
/**
* Return the transaction service
*
@@ -185,7 +201,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
{
return this.serviceRegistry;
}
/**
* @param contentService the content service
*/
@@ -255,6 +271,16 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
{
this.authComponent = authComponent;
}
/**
* Set the authentication service
*
* @param authService AuthenticationService
*/
public void setAuthenticationService(AuthenticationService authService)
{
this.authService = authService;
}
/**
* Parse and validate the parameter string and create a device context object for this instance
@@ -418,7 +444,39 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
if ( pseudoName.getValue().endsWith(".url") == false)
throw new DeviceContextException("URL link file must end with .url, " + pseudoName.getValue());
// Set the URL link file name and web path
// Check if the URL path name contains the local name token
int pos = path.indexOf(TokenLocalName);
if (pos != -1)
{
// Get the local server name
String srvName = "localhost";
try
{
srvName = InetAddress.getLocalHost().getHostName();
}
catch ( Exception ex)
{
}
// Rebuild the host name substituting the token with the local server name
StringBuilder hostStr = new StringBuilder();
hostStr.append( path.substring(0, pos));
hostStr.append(srvName);
pos += TokenLocalName.length();
if (pos < path.length())
hostStr.append( path.substring(pos));
path = hostStr.toString();
}
// Set the URL link file name and web path
context.setURLFileName( pseudoName.getValue());
context.setURLPrefix( path);

View File

@@ -19,6 +19,7 @@ package org.alfresco.filesys.smb.server.repo;
import java.io.FileNotFoundException;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.filesys.IOControlNotImplementedException;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.server.filesys.TreeConnection;
@@ -30,10 +31,12 @@ import org.alfresco.filesys.smb.server.repo.ContentDiskDriver;
import org.alfresco.filesys.smb.server.repo.IOControlHandler;
import org.alfresco.filesys.util.DataBuffer;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -85,6 +88,16 @@ public class ContentIOControlHandler implements IOControlHandler
return contentDriver.getCifsHelper();
}
/**
* Return the authentication service
*
* @return AuthenticationService
*/
public final AuthenticationService getAuthenticationService()
{
return contentDriver.getAuthenticationService();
}
/**
* Return the transaction service
*
@@ -511,6 +524,11 @@ public class ContentIOControlHandler implements IOControlHandler
// Start a transaction
sess.beginTransaction( getTransactionService(), true);
// Get an authentication ticket for the client, or validate the existing ticket. The ticket can be used when
// generating URLs for the client-side application so that the user does not have to re-authenticate
getTicketForClient( sess);
// Get the list of targets for the action
@@ -624,4 +642,65 @@ public class ContentIOControlHandler implements IOControlHandler
return respBuf;
}
/**
* Get, or validate, an authentication ticket for the client
*
* @param sess SrvSession
*/
private final void getTicketForClient(SrvSession sess)
{
// Get the client information and check if there is a ticket allocated
ClientInfo cInfo = sess.getClientInformation();
if ( cInfo == null)
return;
boolean needTicket = true;
if ( cInfo.hasAuthenticationTicket())
{
// Validate the existing ticket, it may have expired
try
{
// Validate the existing ticket
getAuthenticationService().validate( cInfo.getAuthenticationTicket());
needTicket = false;
}
catch ( AuthenticationException ex)
{
// Invalidate the current ticket
try
{
getAuthenticationService().invalidateTicket( cInfo.getAuthenticationTicket());
cInfo.setAuthenticationTicket( null);
}
catch (Exception ex2)
{
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Error during invalidate ticket", ex2);
}
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Auth ticket expired or invalid");
}
}
// Check if a ticket needs to be allocated
if ( needTicket == true)
{
// Allocate a new ticket and store in the client information for this session
String ticket = getAuthenticationService().getCurrentTicket();
cInfo.setAuthenticationTicket( ticket);
}
}
}

View File

@@ -19,10 +19,12 @@ package org.alfresco.filesys.smb.server.repo;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLDecoder;
import org.alfresco.config.ConfigElement;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
import org.alfresco.filesys.smb.server.repo.pseudo.LocalPseudoFile;
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile;
@@ -88,7 +90,11 @@ public abstract class DesktopAction {
public static final int StsLaunchURL = 7;
public static final int StsCommandLine = 8;
// Action name
// Token name to substitute current servers DNS name or TCP/IP address into the webapp URL
private static final String TokenLocalName = "${localname}";
// Action name
private String m_name;
@@ -109,6 +115,10 @@ public abstract class DesktopAction {
private ContentDiskDriver m_contentDriver;
private ContentContext m_contentContext;
// Webapp URL
private String m_webappURL;
// Debug enable flag
private boolean m_debug;
@@ -254,6 +264,26 @@ public abstract class DesktopAction {
return m_debug;
}
/**
* Check if the webapp URL is set
*
* @return boolean
*/
public final boolean hasWebappURL()
{
return m_webappURL != null ? true : false;
}
/**
* Return the webapp URL
*
* @return String
*/
public final String getWebappURL()
{
return m_webappURL;
}
/**
* Initialize the desktop action
*
@@ -348,7 +378,50 @@ public abstract class DesktopAction {
if ( findConfigElement("noConfirm", global, config) != null && hasPreProcessAction(PreConfirmAction))
setPreProcessActions(getPreProcessActions() - PreConfirmAction);
// Check if the webapp URL has been specified
ConfigElement webURL = findConfigElement("webpath", global, config);
if ( webURL != null)
{
// Check if the path name contains the local name token
String webPath = webURL.getValue();
if ( webPath.endsWith("/") == false)
webPath = webPath + "/";
int pos = webPath.indexOf(TokenLocalName);
if (pos != -1)
{
// Get the local server name
String srvName = "localhost";
try
{
srvName = InetAddress.getLocalHost().getHostName();
}
catch ( Exception ex)
{
}
// Rebuild the host name substituting the token with the local server name
StringBuilder hostStr = new StringBuilder();
hostStr.append(webPath.substring(0, pos));
hostStr.append(srvName);
pos += TokenLocalName.length();
if (pos < webPath.length())
hostStr.append(webPath.substring(pos));
webPath = hostStr.toString();
setWebappURL( webPath);
}
}
// Check if debug output is enabled for the action
ConfigElement debug = findConfigElement("debug", global, config);
@@ -511,6 +584,16 @@ public abstract class DesktopAction {
m_debug = ena;
}
/**
* Set the webapp URL
*
* @param urlStr String
*/
public final void setWebappURL(String urlStr)
{
m_webappURL = urlStr;
}
/**
* Equality check
*

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List;
import org.alfresco.filesys.server.SrvSession;
import org.alfresco.filesys.server.auth.ClientInfo;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -88,6 +89,19 @@ public class DesktopParams {
{
return m_session;
}
/**
* Return the authentication ticket for the user/session
*
* @return String
*/
public final String getTicket()
{
ClientInfo cInfo = m_session.getClientInformation();
if ( cInfo != null)
return cInfo.getAuthenticationTicket();
return null;
}
/**
* Return the working directory node

View File

@@ -284,6 +284,11 @@ public class JavaScriptDesktopAction extends DesktopAction {
model.put("deskParams", params);
model.put("out", System.out);
// Add the webapp URL, if valid
if ( hasWebappURL())
model.put("webURL", getWebappURL());
// Start a transaction
params.getSession().beginTransaction(getTransactionService(), false);

View File

@@ -16,6 +16,9 @@
*/
package org.alfresco.filesys.smb.server.repo.desk;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.alfresco.filesys.smb.server.repo.DesktopAction;
import org.alfresco.filesys.smb.server.repo.DesktopParams;
import org.alfresco.filesys.smb.server.repo.DesktopResponse;
@@ -45,8 +48,29 @@ public class URLDesktopAction extends DesktopAction {
@Override
public DesktopResponse runAction(DesktopParams params) {
// Return a URL in the status message
// Get the local IP address
return new DesktopResponse(StsLaunchURL, "http://www.alfresco.com");
String ipAddr = null;
try
{
ipAddr = InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException ex)
{
}
// Return a URL in the status message to browse to the folder node
StringBuilder urlStr = new StringBuilder();
urlStr.append( "http://");
urlStr.append(ipAddr);
urlStr.append(":8080/alfresco/navigate/browse/workspace/SpacesStore/");
urlStr.append( params.getFolderNode().getId());
urlStr.append("?ticket=");
urlStr.append(params.getTicket());
return new DesktopResponse(StsLaunchURL, urlStr.toString());
}
}

View File

@@ -19,7 +19,6 @@ package org.alfresco.filesys.smb.server.repo.pseudo;
import java.io.IOException;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.FileInfo;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.smb.SeekType;
@@ -222,9 +221,7 @@ public class MemoryNetworkFile extends NetworkFile
*/
public void truncateFile(long siz) throws IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot truncate pseudo file");
// Allow the truncate, do not alter the pseduo file data
}
/**
@@ -236,9 +233,7 @@ public class MemoryNetworkFile extends NetworkFile
*/
public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot write to pseudo file");
// Allow the write, just do not do anything
}
/**
@@ -252,8 +247,6 @@ public class MemoryNetworkFile extends NetworkFile
*/
public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot write to pseudo file");
// Allow the write, just do not do anything
}
}

View File

@@ -21,7 +21,6 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.alfresco.filesys.server.filesys.AccessDeniedException;
import org.alfresco.filesys.server.filesys.NetworkFile;
import org.alfresco.filesys.smb.SeekType;
@@ -272,9 +271,7 @@ public class PseudoNetworkFile extends NetworkFile
*/
public void truncateFile(long siz) throws IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot truncate pseudo file");
// Allow the truncate, just do not do anything
}
/**
@@ -286,9 +283,7 @@ public class PseudoNetworkFile extends NetworkFile
*/
public void writeFile(byte[] buf, int len, int pos) throws java.io.IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot write to pseudo file");
// Allow the write, just do not do anything
}
/**
@@ -302,8 +297,6 @@ public class PseudoNetworkFile extends NetworkFile
*/
public void writeFile(byte[] buf, int len, int pos, long offset) throws java.io.IOException
{
// Do not allow the file to be written to
throw new AccessDeniedException("Cannot write to pseudo file");
// Allow the write, just do not do anything
}
}