diff options
author | Maria Odea B. Ching <oching@apache.org> | 2008-10-05 14:39:22 +0000 |
---|---|---|
committer | Maria Odea B. Ching <oching@apache.org> | 2008-10-05 14:39:22 +0000 |
commit | a8bedf6adf2b60d4f17ec10693d064ee3aa16f2f (patch) | |
tree | 521c46ff3ff15fa23a397eabe4f508bf448c9437 | |
parent | ee6c59862a135322858348df618f74d4391eac7b (diff) | |
download | archiva-a8bedf6adf2b60d4f17ec10693d064ee3aa16f2f.tar.gz archiva-a8bedf6adf2b60d4f17ec10693d064ee3aa16f2f.zip |
-fix security issue
-updated tests
git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/archiva-security-fix@701801 13f79535-47bb-0310-9956-ffa450edef68
6 files changed, 82 insertions, 47 deletions
diff --git a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java index 31d1245c9..7059598df 100644 --- a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java +++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java @@ -93,11 +93,18 @@ public class ArchivaServletAuthenticator return true; } - public boolean isAuthorized( String principal, String repoId ) + public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest ) throws UnauthorizedException { try { + String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; + + if ( isWriteRequest ) + { + permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD; + } + User user = securitySystem.getUserManager().findUser( principal ); if ( user.isLocked() ) { @@ -107,8 +114,7 @@ public class ArchivaServletAuthenticator AuthenticationResult authn = new AuthenticationResult( true, principal, null ); SecuritySession securitySession = new DefaultSecuritySession( authn, user ); - return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, - repoId ); + return securitySystem.isAuthorized( securitySession, permission, repoId ); } catch ( UserNotFoundException e ) { diff --git a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java index 2edda8120..407d7d0ee 100644 --- a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java +++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java @@ -41,6 +41,6 @@ public interface ServletAuthenticator public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId, boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException; - public boolean isAuthorized( String principal, String repoId ) + public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest ) throws UnauthorizedException; } diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 625768186..2731f257e 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java @@ -263,8 +263,7 @@ public class ArchivaDavResourceFactory } } catch ( DavException de ) - { - de.printStackTrace(); + { e = de; continue; } @@ -288,6 +287,7 @@ public class ArchivaDavResourceFactory } } + System.out.println( "Available resources --> " + availableResources ); if ( availableResources.isEmpty() ) { throw e; @@ -735,12 +735,14 @@ public class ArchivaDavResourceFactory } catch ( AuthenticationException e ) { + boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); + // safety check for MRM-911 String guest = archivaXworkUser.getGuest(); try { if( servletAuth.isAuthorized( guest, - ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId() ) ) + ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) ) { return true; } @@ -797,6 +799,8 @@ public class ArchivaDavResourceFactory if( allow ) { + boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); + for( String repository : repositories ) { // for prompted authentication @@ -819,7 +823,7 @@ public class ArchivaDavResourceFactory // for the current user logged in try { - if( servletAuth.isAuthorized( activePrincipal, repository ) ) + if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) ) { getResource( locator, mergedRepositoryContents, logicalResource, repository ); } @@ -911,11 +915,12 @@ public class ArchivaDavResourceFactory } else { + boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); for( String repository : repositories ) { try - { - if( servletAuth.isAuthorized( activePrincipal, repository ) ) + { + if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) ) { allow = true; break; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java index 2c5a39d35..1ebf02a93 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java @@ -24,6 +24,7 @@ import org.apache.jackrabbit.webdav.WebdavRequest; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavServletRequest; import org.apache.maven.archiva.webdav.util.RepositoryPathUtil; +import org.apache.maven.archiva.webdav.util.WebdavMethodUtil; import org.apache.maven.archiva.security.ArchivaXworkUser; import org.apache.maven.archiva.security.ServletAuthenticator; import org.codehaus.plexus.redback.authentication.AuthenticationException; @@ -72,12 +73,14 @@ public class ArchivaDavSessionProvider } catch ( AuthenticationException e ) { + boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); + // safety check for MRM-911 String guest = archivaXworkUser.getGuest(); try { if( servletAuth.isAuthorized( guest, - ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId() ) ) + ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) ) { request.setDavSession(new ArchivaDavSession()); return true; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java index e882c5ad6..1b7d82bda 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java @@ -362,7 +362,7 @@ public class ArchivaDavSessionProviderTest extends TestCase return true; } - public boolean isAuthorized(String arg0, String arg1) + public boolean isAuthorized(String arg0, String arg1, boolean isWriteRequest) throws UnauthorizedException { return true; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java index acabdb51c..f1301aabc 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java @@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletResponse; import net.sf.ehcache.CacheManager; import org.apache.commons.io.FileUtils; -import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavResourceFactory; import org.apache.jackrabbit.webdav.DavSessionProvider; import org.apache.maven.archiva.configuration.ArchivaConfiguration; @@ -50,7 +49,6 @@ import org.easymock.internal.AlwaysMatcher; import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.HttpUnitOptions; -import com.meterware.httpunit.PostMethodWebRequest; import com.meterware.httpunit.PutMethodWebRequest; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; @@ -61,6 +59,9 @@ import com.meterware.servletunit.ServletUnitClient; /** * RepositoryServletSecurityTest * + * Test the flow of the authentication and authorization checks. This does not necessarily + * perform redback security checking. + * * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a> * @version $Id$ */ @@ -123,12 +124,12 @@ public class RepositoryServletSecurityTest sc = sr.newClient(); servletAuthControl = MockControl.createControl( ServletAuthenticator.class ); - servletAuthControl.setDefaultMatcher( new AlwaysMatcher() ); + servletAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER ); servletAuth = (ServletAuthenticator) servletAuthControl.getMock(); httpAuthControl = MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() ); - httpAuthControl.setDefaultMatcher( new AlwaysMatcher() ); + httpAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER ); httpAuth = (HttpAuthenticator) httpAuthControl.getMock(); archivaXworkUser = new ArchivaXworkUser(); @@ -209,7 +210,11 @@ public class RepositoryServletSecurityTest { setupCleanRepo( repoRootInternal ); - WebRequest request = new PostMethodWebRequest( "http://machine.com/repository/internal/path/to/artifact.jar" ); + String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar"; + InputStream is = getClass().getResourceAsStream( "/artifact.jar" ); + assertNotNull( "artifact.jar inputstream", is ); + + WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" ); InvocationContext ic = sc.newInvocation( request ); servlet = (RepositoryServlet) ic.getServlet(); servlet.setDavSessionProvider( davSessionProvider ); @@ -217,18 +222,22 @@ public class RepositoryServletSecurityTest AuthenticationResult result = new AuthenticationResult(); httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), - new AuthenticationException( "Authentication error" ) ); - // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), false ); + new AuthenticationException( "Authentication error" ) ); + + servletAuth.isAuthorized( "guest", "internal", true ); + servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER ); + servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) ); httpAuthControl.replay(); servletAuthControl.replay(); - WebResponse response = sc.getResponse( request ); - + //WebResponse response = sc.getResponse( request ); + servlet.service( ic.getRequest(), ic.getResponse() ); + httpAuthControl.verify(); servletAuthControl.verify(); - // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode()); + //assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode()); } // test deploy with invalid user, but guest has write access to repo @@ -257,7 +266,11 @@ public class RepositoryServletSecurityTest httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), new AuthenticationException( "Authentication error" ) ); - servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + servletAuth.isAuthorized( "guest", "internal", true ); + servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER ); + servletAuthControl.setReturnValue( true ); + //servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", true ), true ); // ArchivaDavResourceFactory#isAuthorized() SecuritySession session = new DefaultSecuritySession(); @@ -267,7 +280,10 @@ public class RepositoryServletSecurityTest new AuthenticationException( "Authentication error" ) ); // check if guest has write access - servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + servletAuth.isAuthorized( "guest", "internal", true ); + servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER ); + servletAuthControl.setReturnValue( true ); + //servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", true ), true ); httpAuthControl.replay(); servletAuthControl.replay(); @@ -287,33 +303,42 @@ public class RepositoryServletSecurityTest { setupCleanRepo( repoRootInternal ); - WebRequest request = new PostMethodWebRequest( "http://machine.com/repository/internal/path/to/artifact.jar" ); - InvocationContext ic = sc.newInvocation( request ); + String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar"; + InputStream is = getClass().getResourceAsStream( "/artifact.jar" ); + assertNotNull( "artifact.jar inputstream", is ); + + WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" ); + + InvocationContext ic = sc.newInvocation( request ); servlet = (RepositoryServlet) ic.getServlet(); servlet.setDavSessionProvider( davSessionProvider ); - servlet.setResourceFactory( davResourceFactory ); + + ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory(); + archivaDavResourceFactory.setHttpAuth( httpAuth ); + archivaDavResourceFactory.setServletAuth( servletAuth ); + servlet.setResourceFactory( archivaDavResourceFactory ); AuthenticationResult result = new AuthenticationResult(); httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true ); - // servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), - // new AuthenticationException( "Authentication error" ) ); - // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); - - DavException e = new DavException( 401, "User not authorized." ); - davResourceFactoryControl.expectAndThrow( davResourceFactory.createResource( null, null, null ), - new UnauthorizedDavException( "internal", "User not authorized" ) ); - + + // ArchivaDavResourceFactory#isAuthorized() + SecuritySession session = new DefaultSecuritySession(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true ); + servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ), + new UnauthorizedException( "User not authorized" ) ); + httpAuthControl.replay(); servletAuthControl.replay(); - davResourceFactoryControl.replay(); - - WebResponse response = sc.getResponse( request ); + + //WebResponse response = sc.getResponse( request ); + servlet.service( ic.getRequest(), ic.getResponse() ); httpAuthControl.verify(); servletAuthControl.verify(); - davResourceFactoryControl.verify(); - + // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode()); } @@ -351,10 +376,6 @@ public class RepositoryServletSecurityTest servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true ); servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true ); - // servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), - // new AuthenticationException( "Authentication error" ) ); - // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); - httpAuthControl.replay(); servletAuthControl.replay(); @@ -396,7 +417,7 @@ public class RepositoryServletSecurityTest httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), new AuthenticationException( "Authentication error" ) ); - servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), true ); // ArchivaDavResourceFactory#isAuthorized() SecuritySession session = new DefaultSecuritySession(); @@ -438,7 +459,7 @@ public class RepositoryServletSecurityTest httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), new AuthenticationException( "Authentication error" ) ); - servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), false ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), false ); httpAuthControl.replay(); servletAuthControl.replay(); @@ -519,7 +540,7 @@ public class RepositoryServletSecurityTest httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true ); - DavException e = new DavException( 401, "User not authorized." ); + //TODO remove davResourceFactoryControl! davResourceFactoryControl.expectAndThrow( davResourceFactory.createResource( null, null, null ), new UnauthorizedDavException( "internal", "User not authorized" ) ); |