diff --git a/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java b/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java index cbcd8d4faa..3e6d803d9a 100644 --- a/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java +++ b/cli/src/main/java/org/onosproject/cli/AbstractShellCommand.java @@ -169,7 +169,7 @@ public abstract class AbstractShellCommand implements Action, CodecContext { if (auditService != null && auditService.isAuditing()) { // FIXME: Compose and log audit message here; this is a hack String user = "foo"; // FIXME - String action = Thread.currentThread().getName().substring(5); // FIXME + String action = "{\"command\" : \"" + Thread.currentThread().getName().substring(5) + "\"}"; auditService.logUserAction(user, action); } } diff --git a/core/net/src/main/java/org/onosproject/audit/impl/AuditManager.java b/core/net/src/main/java/org/onosproject/audit/impl/AuditManager.java index a871f3c018..0cef9f2df7 100644 --- a/core/net/src/main/java/org/onosproject/audit/impl/AuditManager.java +++ b/core/net/src/main/java/org/onosproject/audit/impl/AuditManager.java @@ -41,7 +41,7 @@ import static org.onosproject.net.OsgiPropertyConstants.AUDIT_ENABLED_DEFAULT; */ @Component( immediate = true, - service = { AuditService.class }, + service = {AuditService.class}, property = { AUDIT_ENABLED + ":Boolean=" + AUDIT_ENABLED_DEFAULT, AUDIT_LOGGER + "=" + AUDIT_LOGGER_DEFAULT, @@ -52,11 +52,15 @@ public class AuditManager implements AuditService { private Logger auditLog = log; - /** Specifies whether or not audit logging is enabled. */ + /** + * Specifies whether or not audit logging is enabled. + */ private boolean auditEnabled = AUDIT_ENABLED_DEFAULT; - /** Name of the audit logger. */ - private String auditFile = AUDIT_LOGGER_DEFAULT; + /** + * Name of the audit logger. + */ + private String auditLogger = AUDIT_LOGGER_DEFAULT; @Reference(cardinality = ReferenceCardinality.MANDATORY) protected ComponentConfigService cfgService; @@ -78,9 +82,9 @@ public class AuditManager implements AuditService { Dictionary properties = ctx.getProperties(); if (properties != null) { auditEnabled = Boolean.parseBoolean(get(properties, AUDIT_ENABLED)); - auditFile = get(properties, AUDIT_LOGGER); - auditLog = LoggerFactory.getLogger(auditFile); - log.info("Reconfigured; auditEnabled={}; auditFile={}", auditEnabled, auditFile); + auditLogger = get(properties, AUDIT_LOGGER); + auditLog = LoggerFactory.getLogger(auditLogger); + log.info("Reconfigured; auditEnabled={}; auditLogger={}", auditEnabled, auditLogger); } } diff --git a/tools/package/etc/org.ops4j.pax.logging.cfg b/tools/package/etc/org.ops4j.pax.logging.cfg index 88688aa0f2..d88fd3c49c 100644 --- a/tools/package/etc/org.ops4j.pax.logging.cfg +++ b/tools/package/etc/org.ops4j.pax.logging.cfg @@ -62,6 +62,16 @@ log4j2.logger.audit.level = TRACE log4j2.logger.audit.additivity = false log4j2.logger.audit.appenderRef.AuditRollingFile.ref = AuditRollingFile +log4j2.logger.securityAudit.name = securityAudit +log4j2.logger.securityAudit.level = TRACE +log4j2.logger.securityAudit.additivity = false +log4j2.logger.securityAudit.appenderRef.AuditRollingFile.ref = AuditRollingFile + +log4j2.logger.karafAudit.name = karafAudit +log4j2.logger.karafAudit.level = TRACE +log4j2.logger.karafAudit.additivity = false +log4j2.logger.karafAudit.appenderRef.AuditRollingFile.ref = KarafRollingFile + # Appenders configuration # Console appender not used by default (see log4j2.rootLogger.appenderRefs) @@ -70,23 +80,6 @@ log4j2.appender.console.name = Console log4j2.appender.console.layout.type = PatternLayout log4j2.appender.console.layout.pattern = ${log4j2.out.pattern} -# Rest Audit file appender -log4j2.appender.auditOnos.type = RollingRandomAccessFile -log4j2.appender.auditOnos.name = AuditFile -log4j2.appender.auditOnos.filter.regex.type = RegexFilter -log4j2.appender.auditOnos.filter.regex.regex = .*AuditLog.* -log4j2.appender.auditOnos.filter.regex.onMatch = ACCEPT -log4j2.appender.auditOnos.filter.regex.onMisMatch = DENY -log4j2.appender.auditOnos.fileName = ${karaf.data}/log/audit.log -log4j2.appender.auditOnos.filePattern = ${karaf.data}/log/audit-%i.log -log4j2.appender.auditOnos.append = true -log4j2.appender.auditOnos.layout.type = PatternLayout -log4j2.appender.auditOnos.layout.pattern = ${log4j2.pattern} -log4j2.appender.auditOnos.policies.type = Policies -log4j2.appender.auditOnos.policies.size.type = SizeBasedTriggeringPolicy -log4j2.appender.auditOnos.policies.size.size = 8MB - - # Rolling file appender log4j2.appender.rolling.type = RollingRandomAccessFile log4j2.appender.rolling.name = RollingFile @@ -117,6 +110,28 @@ log4j2.appender.audit.policies.type = Policies log4j2.appender.audit.policies.size.type = SizeBasedTriggeringPolicy log4j2.appender.audit.policies.size.size = 8MB +log4j2.appender.securityAudit.type = RollingRandomAccessFile +log4j2.appender.securityAudit.name = AuditRollingFile +log4j2.appender.securityAudit.fileName = ${karaf.data}/log/audit.log +log4j2.appender.securityAudit.filePattern = ${karaf.data}/log/audit-%i.log +log4j2.appender.securityAudit.append = true +log4j2.appender.securityAudit.layout.type = PatternLayout +log4j2.appender.securityAudit.layout.pattern = ${log4j2.pattern} +log4j2.appender.securityAudit.policies.type = Policies +log4j2.appender.securityAudit.policies.size.type = SizeBasedTriggeringPolicy +log4j2.appender.securityAudit.policies.size.size = 8MB + +log4j2.appender.karafAudit.type = RollingRandomAccessFile +log4j2.appender.karafAudit.name = KarafRollingFile +log4j2.appender.karafAudit.fileName = ${karaf.data}/log/karaf.log +log4j2.appender.karafAudit.filePattern = ${karaf.data}/log/karaf-%i.log +log4j2.appender.karafAudit.append = true +log4j2.appender.karafAudit.layout.type = PatternLayout +log4j2.appender.karafAudit.layout.pattern = ${log4j2.pattern} +log4j2.appender.karafAudit.policies.type = Policies +log4j2.appender.karafAudit.policies.size.type = SizeBasedTriggeringPolicy +log4j2.appender.karafAudit.policies.size.size = 8MB + # OSGi appender log4j2.appender.osgi.type = PaxOsgi log4j2.appender.osgi.name = PaxOsgi diff --git a/web/api/src/main/java/org/onosproject/rest/resources/AuditFilter.java b/web/api/src/main/java/org/onosproject/rest/resources/AuditFilter.java index 38471abcd6..81c4f426d0 100644 --- a/web/api/src/main/java/org/onosproject/rest/resources/AuditFilter.java +++ b/web/api/src/main/java/org/onosproject/rest/resources/AuditFilter.java @@ -36,7 +36,8 @@ import static org.onlab.util.Tools.readTreeFromStream; public class AuditFilter implements ContainerRequestFilter, ContainerResponseFilter { private ObjectMapper mapper = new ObjectMapper(); - private final String separator = " | "; + private final String separator = "\", \""; + private final String logCompSeperator = "\" : \""; private static boolean disableForTests = false; private static ServiceDirectory services = new DefaultServiceDirectory(); @@ -55,13 +56,15 @@ public class AuditFilter implements ContainerRequestFilter, ContainerResponseFil (readTreeFromStream(mapper, requestContext.getEntityStream()).toString()) : ""); requestContext.setProperty("requestBody", requestBody); // FIXME: audit message should be better structured - requestContext.setProperty("auditMessage", "Path: " + requestContext.getUriInfo().getPath() + separator - + "Method: " + requestContext.getMethod() + separator + requestContext.setProperty("auditMessage", "{\"Path" + logCompSeperator + + requestContext.getUriInfo().getPath() + separator + "Method" + + logCompSeperator + requestContext.getMethod() + separator + (requestContext.getMethod().equals("PUT") ? // FIXME: is there really a need to differentiate based on method? - ("Path_Parameters: " + requestContext.getUriInfo().getPathParameters().toString() + separator - + "Query_Parameters: " + requestContext.getUriInfo().getQueryParameters().toString() - + separator + "Request_Body: " + requestBody) : "")); + ("Path_Parameters" + logCompSeperator + requestContext.getUriInfo().getPathParameters().toString() + + separator + "Query_Parameters" + logCompSeperator + + requestContext.getUriInfo().getQueryParameters().toString() + + separator + "Request_Body" + logCompSeperator + requestBody) : "")); requestContext.setEntityStream(IOUtils.toInputStream(requestBody)); } } @@ -72,7 +75,8 @@ public class AuditFilter implements ContainerRequestFilter, ContainerResponseFil AuditService auditService = auditService(); if (auditService != null) { containerRequestContext.setProperty("auditMessage", containerRequestContext.getProperty("auditMessage") - + separator + "Status: " + containerResponseContext.getStatusInfo().toString()); + + separator + "Status" + logCompSeperator + containerResponseContext.getStatusInfo().toString() + + "\"}"); // FIXME: Audit record should indicate who did it, not just what was done and when String user = containerRequestContext.getSecurityContext().getUserPrincipal().getName(); String action = containerRequestContext.getProperty("auditMessage").toString();