From 8ed54feb5885857c714ecc80d466b56eaeb25818 Mon Sep 17 00:00:00 2001 From: Martin Stockhammer Date: Fri, 17 Dec 2021 00:10:02 +0100 Subject: [PATCH] [MRM-2026] Improving audit log --- .../default-repository/.indexer/_0.fdt | Bin 0 -> 33 bytes .../default-repository/.indexer/_0.fdx | Bin 0 -> 12 bytes .../default-repository/.indexer/_0.fnm | 2 + .../default-repository/.indexer/_0.frq | 1 + .../default-repository/.indexer/_0.nrm | 1 + .../default-repository/.indexer/_0.prx | Bin 0 -> 1 bytes .../default-repository/.indexer/_0.tii | Bin 0 -> 35 bytes .../default-repository/.indexer/_0.tis | Bin 0 -> 40 bytes .../default-repository/.indexer/segments.gen | Bin 0 -> 20 bytes .../default-repository/.indexer/segments_2 | Bin 0 -> 246 bytes .../default-repository/.indexer/write.lock | 0 .../interceptors/AuditInfoFilter.java | 161 ++++++++++++++++++ .../resources/META-INF/spring-context.xml | 1 + .../ArchivaUserManagerAuthenticator.java | 49 +++++- .../src/main/resources/log4j2.xml | 17 +- .../org/apache/archiva/audit/AuditLog.java | 1 - 16 files changed, 210 insertions(+), 23 deletions(-) create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdt create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdx create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fnm create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.frq create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.nrm create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.prx create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tii create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tis create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments.gen create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments_2 create mode 100644 archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/write.lock create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/interceptors/AuditInfoFilter.java diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdt b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdt new file mode 100644 index 0000000000000000000000000000000000000000..bdbf9e89e8965ab4375742465535aa4e61ce7deb GIT binary patch literal 33 ocmZQzU|?oqVBqpgttc(_%u7kFU}WGi)HA3lNi8l3N-f9-0B(B-i2wiq literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdx b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fdx new file mode 100644 index 0000000000000000000000000000000000000000..b8ee80957685785cf4fa43c7adecee1e634fd737 GIT binary patch literal 12 OcmZQzU|?o|02TlMD*y-p literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fnm b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fnm new file mode 100644 index 000000000..54c9c6652 --- /dev/null +++ b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.fnm @@ -0,0 +1,2 @@ +ýÿÿÿ +DESCRIPTORIDXINFO \ No newline at end of file diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.frq b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.frq new file mode 100644 index 000000000..6b2aaa764 --- /dev/null +++ b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.frq @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.nrm b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.nrm new file mode 100644 index 000000000..98f7c5aa6 --- /dev/null +++ b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.nrm @@ -0,0 +1 @@ +NRMÿ| \ No newline at end of file diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.prx b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.prx new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tii b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tii new file mode 100644 index 0000000000000000000000000000000000000000..509d02d09d46ef246162afa9da614a793c690db7 GIT binary patch literal 35 fcmezW|NkEb2w((K4L~da#9Ryv|ABxX$dmv8uM!Bj literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tis b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/_0.tis new file mode 100644 index 0000000000000000000000000000000000000000..67da5290e88375342f7f1d056b8e2f0e9869209d GIT binary patch literal 40 lcmezW|NkEb2w((K4L~da#9RzqeyJ6u#h!U7sTB-B834{q2&(`9 literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments.gen b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments.gen new file mode 100644 index 0000000000000000000000000000000000000000..225a55b3c336e69bb83a6d5e7d3339a5c525e7e1 GIT binary patch literal 20 QcmezW|NlP*2w;NI07=aR00000 literal 0 HcmV?d00001 diff --git a/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments_2 b/archiva-modules/archiva-scheduler/archiva-scheduler-repository/src/test/repositories/default-repository/.indexer/segments_2 new file mode 100644 index 0000000000000000000000000000000000000000..e1bc4ee760eef1adad7f1092f1d88b0ba5bcb197 GIT binary patch literal 246 zcmezW|NmD82FBW>g*RjwfD903HP$oJGh&K20CD~!0SE^u3RcI?lwZv1lbKgq!JU;@ zmZ(>jnwOGa#2ZkQS(aFms^C#&bPR&aNY5_}V zgDq4rG%+$ZH!@YwRVd0W%`5`aMh1pPx*%ksU}$M&Vrpe#z@A^MmspgX!J3$xVrIft uoL^d$oXVP(Q(BzC1(brCC}^r@Xsl { + + public AuditInfoThreadLocal() { + + } + + @Override + protected AuditInfo initialValue( ) + { + return new AuditInfo(); + } + } + + public static class AuditInfo { + + private String remoteAddress = "0.0.0.0"; + private String localAddress = "0.0.0.0"; + private String remoteHost = "0.0.0.0"; + private String protocol = ""; + private int remotePort = 0; + private String method = ""; + + public AuditInfo() { + + } + + public String getRemoteAddress( ) + { + return remoteAddress; + } + + public void setRemoteAddress( String remoteAddress ) + { + this.remoteAddress = remoteAddress; + } + + public String getLocalAddress( ) + { + return localAddress; + } + + public void setLocalAddress( String localAddress ) + { + this.localAddress = localAddress; + } + + public String getRemoteHost( ) + { + return remoteHost; + } + + public void setRemoteHost( String remoteHost ) + { + this.remoteHost = remoteHost; + } + + public int getRemotePort( ) + { + return remotePort; + } + + public void setRemotePort( int remotePort ) + { + this.remotePort = remotePort; + } + + public String getMethod( ) + { + return method; + } + + public void setMethod( String method ) + { + this.method = method; + } + + public String getProtocol( ) + { + return protocol; + } + + public void setProtocol( String protocol ) + { + this.protocol = protocol; + } + } + + + + @Override + public void filter( ContainerRequestContext containerRequestContext ) throws IOException + { + if (log.isDebugEnabled()) + { + log.debug( "Filter {}, {}", servletRequest.getRemoteAddr( ), servletRequest.getRemoteHost( ) ); + } + AuditInfo auditInfo = auditInfoThreadLocal.get( ); + auditInfo.setRemoteAddress( servletRequest.getRemoteAddr( ) ); + auditInfo.setLocalAddress( servletRequest.getLocalAddr( ) ); + auditInfo.setProtocol( servletRequest.getProtocol( ) ); + auditInfo.setRemoteHost( servletRequest.getRemoteHost( ) ); + auditInfo.setRemotePort( servletRequest.getRemotePort( ) ); + auditInfo.setMethod( containerRequestContext.getMethod( ) ); + } + + public static AuditInfo getAuditInfo() { + return auditInfoThreadLocal.get( ); + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml index c9e677db6..f51795d86 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/resources/META-INF/spring-context.xml @@ -50,6 +50,7 @@ + diff --git a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaUserManagerAuthenticator.java b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaUserManagerAuthenticator.java index 0a74e395b..95b6d4db6 100644 --- a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaUserManagerAuthenticator.java +++ b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaUserManagerAuthenticator.java @@ -20,6 +20,7 @@ package org.apache.archiva.web.security; import org.apache.archiva.admin.model.RepositoryAdminException; import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin; +import org.apache.archiva.metadata.model.facets.AuditEvent; import org.apache.archiva.redback.authentication.AbstractAuthenticator; import org.apache.archiva.redback.authentication.AuthenticationConstants; import org.apache.archiva.redback.authentication.AuthenticationDataSource; @@ -35,6 +36,8 @@ import org.apache.archiva.redback.policy.UserSecurityPolicy; import org.apache.archiva.redback.users.User; import org.apache.archiva.redback.users.UserManager; import org.apache.archiva.redback.users.UserNotFoundException; +import org.apache.archiva.repository.events.AuditListener; +import org.apache.archiva.rest.services.interceptors.AuditInfoFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -65,6 +68,9 @@ public class ArchivaUserManagerAuthenticator @Inject private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin; + @Inject + private List auditListeners = new ArrayList<>(); + private List userManagers; private boolean valid = false; @@ -94,6 +100,27 @@ public class ArchivaUserManagerAuthenticator } } + protected AuditInfoFilter.AuditInfo getAuditInformation() + { + return AuditInfoFilter.getAuditInfo( ); + } + + public List getAuditListeners() + { + return auditListeners; + } + + protected void triggerAuditEvent( String repositoryId, String filePath, String action, String user ) + { + AuditEvent auditEvent = new AuditEvent( repositoryId, user, filePath, action ); + AuditInfoFilter.AuditInfo auditInformation = getAuditInformation(); + auditEvent.setUserId( user ); + auditEvent.setRemoteIP( auditInformation.getRemoteHost() + ":" + auditInformation.getRemotePort() ); + for ( AuditListener auditListener : getAuditListeners() ) + { + auditListener.auditEvent( auditEvent ); + } + } @Override public AuthenticationResult authenticate( AuthenticationDataSource ds ) @@ -104,21 +131,23 @@ public class ArchivaUserManagerAuthenticator Exception resultException = null; PasswordBasedAuthenticationDataSource source = (PasswordBasedAuthenticationDataSource) ds; List authnResultErrors = new ArrayList<>(); + final String loginUserId = source.getUsername( ); for ( UserManager userManager : userManagers ) { try { log.debug( "Authenticate: {} with userManager: {}", source, userManager.getId() ); - User user = userManager.findUser( source.getUsername() ); + User user = userManager.findUser( loginUserId ); username = user.getUsername(); if ( user.isLocked() ) { //throw new AccountLockedException( "Account " + source.getUsername() + " is locked.", user ); AccountLockedException e = - new AccountLockedException( "Account " + source.getUsername() + " is locked.", user ); + new AccountLockedException( "Account " + loginUserId + " is locked.", user ); log.warn( "{}", e.getMessage() ); + triggerAuditEvent( "", "", "login-account-locked", loginUserId ); resultException = e; authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_LOCKED_USER_EXCEPTION, @@ -131,6 +160,7 @@ public class ArchivaUserManagerAuthenticator MustChangePasswordException e = new MustChangePasswordException( "Password expired.", user ); log.warn( "{}", e.getMessage() ); resultException = e; + triggerAuditEvent( "", "", "login-password-change-required", loginUserId ); authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_MUST_CHANGE_PASSWORD_EXCEPTION, e.getMessage() ) ); @@ -142,13 +172,15 @@ public class ArchivaUserManagerAuthenticator boolean isPasswordValid = encoder.isPasswordValid( user.getEncodedPassword(), source.getPassword() ); if ( isPasswordValid ) { - log.debug( "User {} provided a valid password", source.getUsername() ); + log.debug( "User {} provided a valid password", loginUserId ); try { securityPolicy.extensionPasswordExpiration( user ); authenticationSuccess = true; + triggerAuditEvent( "", "", "login-success", loginUserId ); + //REDBACK-151 do not make unnessesary updates to the user object if ( user.getCountFailedLoginAttempts() > 0 ) @@ -160,11 +192,12 @@ public class ArchivaUserManagerAuthenticator } } - return new AuthenticationResult( true, source.getUsername(), null ); + return new AuthenticationResult( true, loginUserId, null ); } catch ( MustChangePasswordException e ) { user.setPasswordChangeRequired( true ); + triggerAuditEvent( "", "", "login-password-change-required", loginUserId ); //throw e; resultException = e; authnResultErrors.add( new AuthenticationFailureCause( @@ -175,6 +208,8 @@ public class ArchivaUserManagerAuthenticator { log.warn( "Password is Invalid for user {} and userManager '{}'.", source.getUsername(), userManager.getId() ); + triggerAuditEvent( "", "", "login-authentication-failed", loginUserId ); + authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER, "Password is Invalid for user " + source.getUsername() + "." ).user( user ) ); @@ -198,18 +233,20 @@ public class ArchivaUserManagerAuthenticator } catch ( UserNotFoundException e ) { - log.warn( "Login for user {} and userManager {} failed. user not found.", source.getUsername(), + log.warn( "Login for user {} and userManager {} failed. user not found.", loginUserId, userManager.getId() ); resultException = e; + triggerAuditEvent( "", "", "login-user-unknown", loginUserId ); authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER, "Login for user " + source.getUsername() + " failed. user not found." ) ); } catch ( Exception e ) { - log.warn( "Login for user {} and userManager {} failed, message: {}", source.getUsername(), + log.warn( "Login for user {} and userManager {} failed, message: {}", loginUserId, userManager.getId(), e.getMessage() ); resultException = e; + triggerAuditEvent( "", "", "login-error", loginUserId ); authnResultErrors.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION, "Login for user " + source.getUsername() + " failed, message: " + e.getMessage() ) ); diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml index f22ee0691..462ebddfb 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/log4j2.xml @@ -40,7 +40,7 @@ + immediateFlush="true" append="true"> %d{yyyy-MM-dd HH:mm:ss} %m%n @@ -49,24 +49,9 @@ - - - %d{yyyy-MM-dd HH:mm:ss} - %X{redback.currentUser} - %m%n - - - - - - - - - - diff --git a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditLog.java b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditLog.java index 37b5a5211..bd6887d02 100644 --- a/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditLog.java +++ b/archiva-modules/plugins/audit/src/main/java/org/apache/archiva/audit/AuditLog.java @@ -54,7 +54,6 @@ public class AuditLog msg.append( checkNull( event.getRemoteIP() ) ).append( DELIM ); msg.append( '\"' ).append( checkNull( event.getResource() ) ).append( '\"' ).append( DELIM ); msg.append( '\"' ).append( event.getAction() ).append( '\"' ); - logger.info( msg.toString() ); } -- 2.39.5