release version 1.10.0

This commit is contained in:
2024-12-14 04:07:49 +03:00
parent a5088587f7
commit c6b3d793c4
1916 changed files with 254306 additions and 0 deletions

View File

@ -0,0 +1,5 @@
<!-- -->
<configfile finalname="etc/ru.entaxy.audit.interpreter.jmx.cfg" override="true">
mvn:ru.entaxy.platform.logging/entaxy-audit/1.10.0/cfg/ru.entaxy.audit.interpreter.jmx
</configfile>
<!-- -->

View File

@ -0,0 +1,27 @@
###
# ~~~~~~licensing~~~~~~
# entaxy-audit
# ==========
# Copyright (C) 2020 - 2024 EmDev LLC
# ==========
# You may not use this file except in accordance with the License Terms of the Copyright
# Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
# rights to the Software and any copies are the property of the Copyright Holder. Unless
# it is explicitly allowed the Copyright Holder, the User is prohibited from using the
# Software for commercial purposes to provide services to third parties.
#
# The Copyright Holder hereby declares that the Software is provided on an "AS IS".
# Under no circumstances does the Copyright Holder guarantee or promise that the
# Software provided by him will be suitable or not suitable for the specific purposes
# of the User, that the Software will meet all commercial and personal subjective
# expectations of the User, that the Software will work properly, without technical
# errors, quickly and uninterruptedly.
#
# Under no circumstances shall the Copyright Holder or its Affiliates is not liable
# to the User for any direct or indirect losses of the User, his expenses or actual
# damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
# or damage to data, property, etc.
# ~~~~~~/licensing~~~~~~
###
topics.ignore=GETATTRIBUTE,GETMBEANINFO
topics.process=INVOKE

View File

@ -0,0 +1,31 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.data;
public enum Actions {
LOGIN,
LOGOUT
}

View File

@ -0,0 +1,147 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.data;
import ru.entaxy.audit.utils.AuditHelper;
public class AuditEvent {
private final String target;
private final String category;
private final String suser;
private final String duser;
private final String message;
private final Outcome outcome;
private final Severity severity;
private final String src;
public AuditEvent(String target, String category, String suser,
String duser, String message, Outcome outcome,
Severity severity, String src) {
this.target = target;
this.category = category;
this.suser = suser;
this.duser = duser;
this.message = message;
this.outcome = outcome;
this.severity = severity;
this.src = src;
}
public String getTarget() {
return target;
}
public String getCategory() {
return category;
}
public String getSuser() {
return suser;
}
public String getDuser() {
return duser;
}
public String getMessage() {
return message;
}
public Outcome getOutcome() {
return outcome;
}
public Severity getSeverity() {
return severity;
}
public String getSrc() {
return src;
}
public static class AuditLoggingEventBuilder {
private String target = AuditHelper.DEFAULT_TARGET;
private String category;
private String suser;
private String duser;
private String message;
private String src;
private Outcome outcome = Outcome.SUCCESS;
private Severity severity = AuditHelper.DEFAULT_SEVERITY;
public static AuditLoggingEventBuilder getInstance() {
return new AuditLoggingEventBuilder();
}
public AuditLoggingEventBuilder target(String target) {
this.target = target;
return this;
}
public AuditLoggingEventBuilder category(String category) {
this.category = category;
return this;
}
public AuditLoggingEventBuilder suser(String suser) {
this.suser = suser;
return this;
}
public AuditLoggingEventBuilder duser(String duser) {
this.duser = duser;
return this;
}
public AuditLoggingEventBuilder message(String message) {
this.message = message;
return this;
}
public AuditLoggingEventBuilder outcome(Outcome outcome) {
this.outcome = outcome;
return this;
}
public AuditLoggingEventBuilder severity(Severity severity) {
this.severity = severity;
return this;
}
public AuditLoggingEventBuilder src(String src) {
this.src = src;
return this;
}
public AuditEvent build() {
return new AuditEvent(target, category, suser, duser,
message, outcome, severity, src);
}
}
}

View File

@ -0,0 +1,39 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.data;
public enum Outcome {
SUCCESS("Success"), FAILURE("Failed");
private final String label;
Outcome(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.data;
public enum Severity {
INFO(3), WARNING(8), IMPORTANT(6);
private final int value;
Severity(int i) {
this.value = i;
}
public int getValue() {
return value;
}
}

View File

@ -0,0 +1,53 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.event.Event;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.data.Outcome;
public interface AuditService {
void onAudit(AuditEvent record);
void onLogin(String username, HttpServletRequest request, Outcome outcome);
void onLogout(String username, HttpServletRequest request);
void onOSGIEvent(Event event);
void onFileChange(Event event);
boolean interpret(Event event);
void setRequestAndSubject(Subject subject, HttpServletRequest request);
void setRequestAndUser(String user, HttpServletRequest request);
}

View File

@ -0,0 +1,38 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import ru.entaxy.audit.service.impl.AuditServiceImpl;
public class AuditServiceFactory {
private static final AuditServiceImpl INSTANCE = new AuditServiceImpl();
public static AuditService getAuditService() {
return INSTANCE;
}
}

View File

@ -0,0 +1,41 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import ru.entaxy.audit.data.AuditEvent;
public interface EventConverter {
default Class<? extends InterpretedEvent>[] getAllowedClasses() {
if (getClass().isAnnotationPresent(EventConverterInfo.class)) {
return getClass().getAnnotation(EventConverterInfo.class).classes();
}
return new Class[] {};
};
<T extends InterpretedEvent> AuditEvent convert(T event);
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface EventConverterInfo {
Class<? extends InterpretedEvent>[] classes();
}

View File

@ -0,0 +1,34 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import org.osgi.service.event.Event;
public interface EventInterpreter {
InterpretedEvent interpret(Event origin);
}

View File

@ -0,0 +1,43 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import ru.entaxy.audit.service.filter.EventRouter;
public class EventSubscriber implements EventHandler {
private final EventRouter eventRouter;
public EventSubscriber(EventRouter eventRouter) {
this.eventRouter = eventRouter;
}
@Override
public void handleEvent(Event event) {
eventRouter.consumeEvent(event);
}
}

View File

@ -0,0 +1,56 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service;
import java.util.HashMap;
import java.util.Map;
import org.osgi.service.event.Event;
public class InterpretedEvent {
public enum EventResolution {
IGNORE,
PROCESS,
NONE
}
public Event originalEvent;
public EventResolution resolution = EventResolution.NONE;
protected Map<String, Object> eventEssense = new HashMap<>();
public InterpretedEvent(Event origin) {
this.originalEvent = origin;
eventEssense.put("event.topic", origin.getTopic());
}
public Map<String, Object> getEventEssense() {
return eventEssense;
}
}

View File

@ -0,0 +1,108 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.filter;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import org.osgi.service.event.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.audit.service.AuditService;
public class EventRouter {
private final Queue<Event> events = new LinkedBlockingQueue<>(10_000);
private final AtomicLong counter = new AtomicLong(0);
private final AtomicLong consumed = new AtomicLong(0);
private final AtomicLong rejected = new AtomicLong(0);
private final ExecutorService executor = Executors.newFixedThreadPool(3,
(r) -> new Thread(r, "audit-logger-helper-thread #" + counter.getAndIncrement()));
private final AuditService auditService;
private static final Logger LOGGER = LoggerFactory.getLogger(EventRouter.class);
public EventRouter(AuditService service) {
this.auditService = service;
}
private boolean processEvent(Event event) {
if (event == null) {
return false;
}
if (event.getTopic().contains("EXECUTED") && event.getProperty("command") != null) {
auditService.onOSGIEvent(event);
return true;
} else {
// if it's a log event
if (event.getTopic().startsWith("org/osgi/service/log")) {
String bundleSymbolicName = (String) event.getProperty("bundle.symbolicname");
// if it's configuration update event
if (bundleSymbolicName != null && "org.apache.felix.fileinstall".equals(bundleSymbolicName)) {
Object message = event.getProperty("message");
if (message instanceof String) {
String messageText = (String) message;
if (messageText.contains("Updating")) {
auditService.onFileChange(event);
return true;
}
}
}
} else {
return auditService.interpret(event);
}
}
return false;
}
public String stats() {
return String.format("Consumed: %d, rejected: %d", consumed.get(), rejected.get());
}
public void consumeEvent(Event event) {
boolean added = events.offer(event);
if (added) {
executor.submit(() -> {
Event evt = events.poll();
if (processEvent(evt)) {
consumed.incrementAndGet();
} else {
rejected.incrementAndGet();
}
});
} else {
LOGGER.warn("Cannot consume event {}, queue is probably full", event);
}
}
public void stop() {
executor.shutdown();
events.clear();
}
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.hawtio;
import org.osgi.service.component.annotations.Component;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.data.Outcome;
import ru.entaxy.audit.data.Severity;
import ru.entaxy.audit.service.EventConverter;
import ru.entaxy.audit.service.EventConverterInfo;
import ru.entaxy.audit.service.InterpretedEvent;
@Component(service = EventConverter.class, immediate = true)
@EventConverterInfo(classes = {HawtioInterpretedEvent.class})
public class HawtioEventConverter implements EventConverter {
@Override
public <T extends InterpretedEvent> AuditEvent convert(T event) {
if (!(event instanceof HawtioInterpretedEvent))
return null;
HawtioInterpretedEvent hawtioEvent = (HawtioInterpretedEvent) event;
AuditEvent result = AuditEvent.AuditLoggingEventBuilder.getInstance()
.target("auth")
.outcome(hawtioEvent.isSuccessful ? Outcome.SUCCESS : Outcome.FAILURE)
.message(String.format("%s", hawtioEvent.getMessage()))
.severity(Severity.IMPORTANT)
.category(hawtioEvent.getAction())
.suser(hawtioEvent.getUser())
.src(hawtioEvent.getSrc())
.build();
return result;
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.hawtio;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.event.Event;
import ru.entaxy.audit.service.EventInterpreter;
import ru.entaxy.audit.service.InterpretedEvent;
@Component(service = EventInterpreter.class, immediate = true, configurationPolicy = ConfigurationPolicy.OPTIONAL)
public class HawtioEventInterpreter implements EventInterpreter {
private static final String HAWTIO_AUDIT_TOPIC = "entaxy/hawtio/audit";
@Override
public InterpretedEvent interpret(Event origin) {
if (!HAWTIO_AUDIT_TOPIC.equals(origin.getTopic()))
return null;
return new HawtioInterpretedEvent(origin);
}
}

View File

@ -0,0 +1,74 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.hawtio;
import org.osgi.service.event.Event;
import ru.entaxy.audit.service.InterpretedEvent;
public class HawtioInterpretedEvent extends InterpretedEvent {
String action;
String message;
String user;
String src;
boolean isSuccessful;
public HawtioInterpretedEvent(Event origin) {
super(origin);
action = origin.getProperty("category").toString();
message = origin.getProperty("message").toString();
user = origin.getProperty("user").toString();
src = origin.getProperty("src").toString();
isSuccessful = (Boolean) origin.getProperty("result");
}
public String getAction() {
return action;
}
public String getMessage() {
return message;
}
public String getUser() {
return user;
}
public String getSrc() {
return src;
}
public boolean isSuccessful() {
return isSuccessful;
}
}

View File

@ -0,0 +1,143 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.impl;
import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.event.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.data.Outcome;
import ru.entaxy.audit.service.AuditService;
import ru.entaxy.audit.service.InterpretedEvent;
import ru.entaxy.audit.utils.AuditHelper;
public class AuditServiceImpl implements AuditService {
private static final Logger LOG = LoggerFactory.getLogger(AuditServiceImpl.class);
private final WebLoginModule webLoginModule = new WebLoginModule();
private final OSGIEventModule osgiEventModule = new OSGIEventModule();
@Override
public void onAudit(AuditEvent record) {
throw new RuntimeException("Not implemented");
}
@Override
public void onLogin(String username, HttpServletRequest request, Outcome outcome) {
webLoginModule.onLogin(username, request, outcome);
}
@Override
public void onLogout(String username, HttpServletRequest request) {
webLoginModule.onLogout(username, request);
}
@Override
public void onOSGIEvent(Event event) {
osgiEventModule.onEvent(event);
}
@Override
public void onFileChange(Event event) {
osgiEventModule.onFileChange(event);
}
@Override
public boolean interpret(Event event) {
if (InterpreterService.INSTANCE == null)
return false;
InterpretedEvent result = InterpreterService.INSTANCE.interpret(event);
if (result == null) {
if (LOG.isTraceEnabled())
LOG.trace("Event from topic [{}] not interpreted", event.getTopic());
return false;
}
if (result.resolution.equals(InterpretedEvent.EventResolution.IGNORE)) {
if (LOG.isTraceEnabled())
LOG.trace("Event from topic [{}] IGNORED; interpreted as [{}] -> [{}]", event.getTopic(),
result.getClass().getName());
return false;
}
if (ConverterService.INSTANCE == null)
return false;
AuditEvent convertedEvent = ConverterService.INSTANCE.convert(result);
if (convertedEvent == null) {
if (LOG.isDebugEnabled())
LOG.debug("NOT CONVERTED: Event from topic [{}] interpreted as [{}]", event.getTopic(),
result.getClass().getName());
return false;
}
Subject subject = (Subject) event.getProperty("subject");
boolean processed = false;
String suser = "local";
String address = "localhost";
if (subject != null) {
suser = AuditHelper.findRemoteUser(subject);
address = AuditHelper.findAddress(subject);
}
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
.category(convertedEvent.getCategory())
.duser(convertedEvent.getDuser())
.message(convertedEvent.getMessage())
.outcome(convertedEvent.getOutcome())
.severity(convertedEvent.getSeverity())
.src(convertedEvent.getSrc() != null ? convertedEvent.getSrc() : address)
.suser(convertedEvent.getSuser() != null ? convertedEvent.getSuser() : suser)
.target(convertedEvent.getTarget())
.build();
AuditHelper.log(auditEvent);
processed = true;
return processed;
}
@Override
public void setRequestAndSubject(Subject subject, HttpServletRequest request) {
webLoginModule.setMDC(subject, request);
}
@Override
public void setRequestAndUser(String user, HttpServletRequest request) {
webLoginModule.setMDC(user, request);
}
}

View File

@ -0,0 +1,101 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.impl;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.service.EventConverter;
import ru.entaxy.audit.service.InterpretedEvent;
@Component(service = ConverterService.class, immediate = true)
public class ConverterService {
static public ConverterService INSTANCE = null;
protected Map<Class<? extends InterpretedEvent>, Set<EventConverter>> converters = new HashMap<>();
protected Object convertersLock = new Object();
@Activate
public void activate() {
INSTANCE = this;
}
@Deactivate
public void deactivate() {
INSTANCE = null;
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY,
policy = ReferencePolicy.DYNAMIC, unbind = "removeConverter")
public void addInterpreter(EventConverter converter) {
synchronized (convertersLock) {
for (Class<? extends InterpretedEvent> clazz : converter.getAllowedClasses()) {
this.converters.putIfAbsent(clazz, new HashSet<>());
this.converters.get(clazz).add(converter);
}
}
}
public void removeConverter(EventConverter converter) {
synchronized (convertersLock) {
for (Class<? extends InterpretedEvent> clazz : converter.getAllowedClasses()) {
if (converters.containsKey(clazz))
converters.get(clazz).remove(converter);
}
}
}
public <T extends InterpretedEvent> AuditEvent convert(T event) {
AuditEvent result = null;
if (converters.containsKey(event.getClass())) {
for (EventConverter converter : converters.get(event.getClass())) {
try {
result = converter.convert(event);
} catch (Exception ignore) {
// NOOP
}
if (result != null)
break;
}
}
return result;
}
}

View File

@ -0,0 +1,91 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.event.Event;
import ru.entaxy.audit.service.EventInterpreter;
import ru.entaxy.audit.service.InterpretedEvent;
@Component(service = InterpreterService.class, immediate = true)
public class InterpreterService {
static public InterpreterService INSTANCE = null;
protected List<EventInterpreter> interpreters = new ArrayList<>();
protected Object interpretersLock = new Object();
@Activate
public void activate() {
INSTANCE = this;
}
@Deactivate
public void deactivate() {
INSTANCE = null;
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY,
policy = ReferencePolicy.DYNAMIC, unbind = "removeInterpreter")
public void addInterpreter(EventInterpreter interpreter) {
synchronized (interpretersLock) {
if (!interpreters.contains(interpreter))
interpreters.add(interpreter);
}
}
public void removeInterpreter(EventInterpreter interpreter) {
synchronized (interpretersLock) {
interpreters.remove(interpreter);
}
}
public InterpretedEvent interpret(Event event) {
InterpretedEvent result = null;
for (EventInterpreter interpreter : interpreters) {
try {
result = interpreter.interpret(event);
} catch (Exception ignore) {
// NOOP
}
if (result != null)
break;
}
return result;
}
}

View File

@ -0,0 +1,117 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.impl;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.security.auth.Subject;
import org.osgi.service.event.Event;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.data.Severity;
import ru.entaxy.audit.utils.AuditHelper;
import ru.entaxy.audit.utils.CommandWeight;
public class OSGIEventModule {
private Map<String, LongAdder> processedCommands = new ConcurrentHashMap<>();
private Map<String, LongAdder> skippedCommands = new ConcurrentHashMap<>();
private final Set<String> targets = new HashSet<String>() {{
add("jaas");
}};
private final static Pattern COMMAND_PATTERN = Pattern.compile("^(.+):([A-Za-z-]+)\\s?+(.+)?$");
private final static Pattern FILE_PATTERN = Pattern.compile("^Updating ([a-zA-Z]+)\\s+(from)?\\s?(.+)$");
public void onEvent(Event event) {
String command = (String) event.getProperty("command");
if (command == null) {
return;
}
Subject subject = (Subject) event.getProperty("subject");
boolean processed = false;
Matcher m = checkCommand(command);
if (m != null && subject != null) {
String suser = AuditHelper.findRemoteUser(subject);
String address = AuditHelper.findAddress(subject);
String target = m.group(1);
String commandName = m.group(2);
String arguments = m.group(3);
if (targets.contains(target)) {
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
.target(target)
.suser(suser)
.src(address)
.category(commandName)
.severity(CommandWeight.getByTarget(target))
.message(arguments == null ? "" : arguments).build();
AuditHelper.log(auditEvent);
processed = true;
}
}
Map<String, LongAdder> target = processed ? processedCommands : skippedCommands;
target.computeIfAbsent(command, (s) -> new LongAdder()).increment();
}
private Matcher checkCommand(String command) {
Matcher m = COMMAND_PATTERN.matcher(command);
if (m.find()) {
return m;
}
return null;
}
public void onFileChange(Event event) {
String message = (String) event.getProperty("message");
Matcher m = FILE_PATTERN.matcher(message);
if (m.find()) {
String filename = m.group(3);
String changeSubject = m.group(1);
String target = "Update " + changeSubject;
if (changeSubject.equals("bundle") || changeSubject.equals("configuration")) {
AuditEvent auditEvent = AuditEvent.AuditLoggingEventBuilder.getInstance()
.target(target)
.suser("local")
.src("localhost")
.category(filename)
.severity(Severity.WARNING)
.message(message).build();
AuditHelper.log(auditEvent);
processedCommands.computeIfAbsent(target, (s) -> new LongAdder()).increment();
}
skippedCommands.computeIfAbsent(target, (s) -> new LongAdder()).increment();
}
}
}

View File

@ -0,0 +1,93 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.impl;
import org.slf4j.MDC;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.utils.AuditHelper;
import ru.entaxy.audit.utils.Constants;
import ru.entaxy.audit.data.Outcome;
import ru.entaxy.audit.data.Severity;
import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class WebLoginModule {
public void onLogin(String username, HttpServletRequest request, Outcome outcome) {
String remoteAddress = requestRemoteAddress(request);
AuditEvent event = AuditEvent.AuditLoggingEventBuilder.getInstance()
.suser(username)
.outcome(outcome)
.severity(outcome == Outcome.SUCCESS ? Severity.INFO : Severity.WARNING)
.src(remoteAddress)
.category(outcome == Outcome.SUCCESS ? "Login success" : "Login failed")
.target("auth")
.build();
AuditHelper.log(event);
}
public void onLogout(String username, HttpServletRequest request) {
String remoteAddress = requestRemoteAddress(request);
AuditEvent event = AuditEvent.AuditLoggingEventBuilder.getInstance()
.suser(username)
.outcome(Outcome.SUCCESS)
.severity(Severity.INFO)
.src(remoteAddress)
.category("Logout")
.target("auth")
.build();
AuditHelper.log(event);
}
private static String requestRemoteAddress(HttpServletRequest request) {
return Optional.ofNullable(request.getHeader(Constants.X_FORWARDER_FOR))
.orElse(request.getRemoteHost());
}
public void setMDC(Subject subject, HttpServletRequest request) {
String remoteUser = AuditHelper.findRemoteUser(subject);
saveMDC(remoteUser, request);
}
public void setMDC(String username, HttpServletRequest request) {
saveMDC(username, request);
}
private void saveMDC(String username, HttpServletRequest request) {
Map<String, String> contextMap = MDC.getCopyOfContextMap();
if (contextMap == null) {
contextMap = new HashMap<>();
}
contextMap.put(Constants.HTTP_REQUEST_USER, username);
contextMap.put(Constants.HTTP_REQUEST_REMOTE_IP, requestRemoteAddress(request));
contextMap.put(Constants.HTTP_REQUEST_SERVER_IP, request.getServerName());
MDC.setContextMap(contextMap);
}
}

View File

@ -0,0 +1,140 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.jmx;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.event.Event;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.audit.service.EventInterpreter;
import ru.entaxy.audit.service.InterpretedEvent;
import ru.entaxy.audit.service.InterpretedEvent.EventResolution;
@Component(service = EventInterpreter.class, immediate = true, configurationPid = "ru.entaxy.audit.interpreter.jmx",
configurationPolicy = ConfigurationPolicy.OPTIONAL)
public class JMXEventInterpreter implements EventInterpreter {
private static final Logger LOG = LoggerFactory.getLogger(JMXEventInterpreter.class);
public static final String JMX_AUDIT_TOPIC_PREFIX = "javax/management/MBeanServer";
public static final String JMX_AUDIT_INVOKE_SUBTOPIC = "INVOKE";
protected static final String PROP_IGNORE_TOPICS = "topics.ignore";
protected static final String PROP_PROCESS_TOPICS = "topics.process";
protected List<String> topicsToIgnore = new ArrayList<>();
protected List<String> topicsToProcess = new ArrayList<>();
@Activate
public void activate(Map<String, Object> properties) {
parseProperties(properties);
}
@Modified
public void modified(Map<String, Object> properties) {
parseProperties(properties);
}
protected void parseProperties(Map<String, Object> properties) {
if (properties == null)
return;
if (LOG.isDebugEnabled())
LOG.debug("\n CONFIGURATION :: \n " + properties.toString());
if (properties.containsKey(PROP_IGNORE_TOPICS)) {
String ignoreTopics = (String) properties.get(PROP_IGNORE_TOPICS);
if (ignoreTopics == null)
topicsToIgnore = new ArrayList<>();
else {
topicsToIgnore = Arrays.asList(ignoreTopics.split(","));
}
} else {
topicsToIgnore = new ArrayList<>();
}
if (properties.containsKey(PROP_PROCESS_TOPICS)) {
String processTopics = (String) properties.get(PROP_PROCESS_TOPICS);
if (processTopics == null)
topicsToProcess = new ArrayList<>();
else {
topicsToProcess = Arrays.asList(processTopics.split(","));
}
} else {
topicsToProcess = new ArrayList<>();
}
}
@Override
public InterpretedEvent interpret(Event origin) {
if (!origin.getTopic().startsWith(JMX_AUDIT_TOPIC_PREFIX))
return null;
JMXInterpretedEvent result;
String subtopic = origin.getTopic().substring(JMX_AUDIT_TOPIC_PREFIX.length() + 1);
if (subtopic.startsWith(JMX_AUDIT_INVOKE_SUBTOPIC))
result = new JMXInvokeEvent(origin);
else
result = new JMXInterpretedEvent(origin);
result.subtopic = subtopic;
result.resolution = EventResolution.IGNORE;
if (!topicsToProcess.isEmpty()) {
for (String process : topicsToProcess)
if (result.subtopic.startsWith(process)) {
result.resolution = EventResolution.PROCESS;
break;
}
} else {
result.resolution = EventResolution.PROCESS;
}
for (String ignore : topicsToIgnore)
if (result.subtopic.startsWith(ignore)) {
result.resolution = EventResolution.IGNORE;
break;
}
return result;
}
}

View File

@ -0,0 +1,56 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.jmx;
import org.osgi.service.event.Event;
import ru.entaxy.audit.service.InterpretedEvent;
public class JMXInterpretedEvent extends InterpretedEvent {
protected String subtopic = null;
public JMXInterpretedEvent(Event origin) {
super(origin);
this.eventEssense.put("event.source", "jmx");
}
public JMXInterpretedEvent subtopic(String value) {
setSubtopic(value);
return this;
}
public String getSubtopic() {
return subtopic;
}
public void setSubtopic(String subtopic) {
this.subtopic = subtopic;
this.eventEssense.put("event.subtopic", this.subtopic);
}
}

View File

@ -0,0 +1,104 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.jmx;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import javax.management.ObjectName;
import org.osgi.service.event.Event;
public class JMXInvokeEvent extends JMXInterpretedEvent {
public static final String PROP_PARAMS = "params";
protected ObjectName objectName;
protected String methodName;
protected Object[] methodParams;
protected Map<String, Object> objectNameData = new HashMap<>();
public JMXInvokeEvent(Event origin) {
super(origin);
if (this.originalEvent.containsProperty(PROP_PARAMS)) {
Object[] data = (Object[]) this.originalEvent.getProperty(PROP_PARAMS);
setObjectName((ObjectName) data[0]);
setMethodName((String) data[1]);
setMethodParams((Object[]) data[2]);
}
}
protected void parseObjectName() {
this.objectNameData.clear();
this.objectNameData.put("jmx.domain", this.objectName.getDomain());
Hashtable<String, String> properties = this.objectName.getKeyPropertyList();
for (Map.Entry<String, String> entry : properties.entrySet()) {
this.objectNameData.put("jmx.property." + entry.getKey(), entry.getValue());
}
}
public ObjectName getObjectName() {
return objectName;
}
public void setObjectName(ObjectName objectName) {
this.objectName = objectName;
parseObjectName();
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
this.eventEssense.put("jmx.methodName", methodName);
}
public Object[] getMethodParams() {
return methodParams;
}
public void setMethodParams(Object[] methodParams) {
this.methodParams = methodParams;
}
@Override
public Map<String, Object> getEventEssense() {
Map<String, Object> result = new HashMap<>(super.getEventEssense());
result.putAll(this.objectNameData);
return result;
}
}

View File

@ -0,0 +1,115 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.service.osgi;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import ru.entaxy.audit.service.AuditService;
import ru.entaxy.audit.service.AuditServiceFactory;
import ru.entaxy.audit.service.EventSubscriber;
import ru.entaxy.audit.service.filter.EventRouter;
import ru.entaxy.audit.service.impl.AuditServiceImpl;
public class Activator implements BundleActivator {
private static final String LOGS_TOPIC = "org/osgi/service/*";
private static final String COMMANDS_TOPIC = "org/apache/karaf/shell/console/*";
private static final String JMX_AUDIT_TOPIC = "javax/management/MBeanServer/*";
private static final String HAWTIO_AUDIT_TOPIC = "entaxy/hawtio/audit";
private ServiceRegistration<?> listenerRegistration = null;
private ServiceRegistration<?> serviceRegistration = null;
private ServiceRegistration<?> commandRegistration = null;
private ServiceRegistration<?> jmxRegistration = null;
private ServiceRegistration<?> hawtioRegistration = null;
private ServiceRegistration<?> eventRouterRegistration = null;
private EventRouter eventRouter;
@Override
public void start(BundleContext bundleContext) throws Exception {
// System.err.println("I'm activating!");
AuditService auditService = AuditServiceFactory.getAuditService();
serviceRegistration =
bundleContext.registerService(AuditService.class.getName(), new AuditServiceImpl(), new Hashtable<>());
eventRouter = new EventRouter(auditService);
eventRouterRegistration = bundleContext.registerService(EventRouter.class, eventRouter, new Hashtable<>());
EventHandler logSubscriber = new EventSubscriber(eventRouter);
EventHandler commandsSubscriber = new EventSubscriber(eventRouter);
EventHandler jmxSubscriber = new EventSubscriber(eventRouter);
EventHandler hawtioSubscriber = new EventSubscriber(eventRouter);
Dictionary<String, Object> events = new Hashtable<>();
events.put(EventConstants.EVENT_TOPIC, LOGS_TOPIC);
listenerRegistration = bundleContext.registerService(EventHandler.class.getName(), logSubscriber, events);
Dictionary<String, Object> commandEvents = new Hashtable<>();
commandEvents.put(EventConstants.EVENT_TOPIC, COMMANDS_TOPIC);
commandRegistration =
bundleContext.registerService(EventHandler.class.getName(), commandsSubscriber, commandEvents);
Dictionary<String, Object> jmxEvents = new Hashtable<>();
jmxEvents.put(EventConstants.EVENT_TOPIC, JMX_AUDIT_TOPIC);
jmxRegistration =
bundleContext.registerService(EventHandler.class.getName(), jmxSubscriber, jmxEvents);
Dictionary<String, Object> hawtioEvents = new Hashtable<>();
hawtioEvents.put(EventConstants.EVENT_TOPIC, HAWTIO_AUDIT_TOPIC);
hawtioRegistration =
bundleContext.registerService(EventHandler.class.getName(), hawtioSubscriber, hawtioEvents);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
if (listenerRegistration != null) {
listenerRegistration.unregister();
}
if (commandRegistration != null) {
commandRegistration.unregister();
}
if (jmxRegistration != null) {
jmxRegistration.unregister();
}
if (serviceRegistration != null) {
serviceRegistration.unregister();
}
if (eventRouterRegistration != null) {
eventRouterRegistration.unregister();
}
if (eventRouter != null) {
eventRouter.stop();
}
}
}

View File

@ -0,0 +1,103 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.utils;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.audit.data.AuditEvent;
import ru.entaxy.audit.data.Severity;
import javax.security.auth.Subject;
import java.lang.reflect.Method;
import java.security.Principal;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
public class AuditHelper {
public static final String TARGET_ACTION = "action";
public static final Severity DEFAULT_SEVERITY = Severity.IMPORTANT;
public static final String DEFAULT_TARGET = TARGET_ACTION;
private static final Logger AUDIT = LoggerFactory.getLogger(Constants.LOG_FACILITY_NAME);
private static final Logger logger = LoggerFactory.getLogger(AuditHelper.class);
public static void log(AuditEvent event) {
JsonObject logRecord = new JsonObject();
logRecord.addProperty("isEmdevEvents", true);
logRecord.addProperty("typ", event.getTarget());
logRecord.addProperty("action", event.getCategory());
logRecord.addProperty("performedBy", event.getSuser());
JsonObject info = new JsonObject();
if (event.getSrc() != null) {
info.addProperty("src", event.getSrc());
}
if (event.getDuser() != null) {
info.addProperty("duser", event.getDuser());
}
info.addProperty("suser", event.getSuser());
info.addProperty("severity", event.getSeverity().getValue());
info.addProperty("msg", event.getMessage());
info.addProperty("outcome", event.getOutcome().getLabel());
logRecord.add("info", info);
AUDIT.info(logRecord.toString());
}
public static String findRemoteUser(Subject subject) {
return findAndProcessPrincipal(subject, "UserPrincipal", Principal::getName);
}
private static String findAndProcessPrincipal(Subject subject, String principalName, Function<Principal, String> mapping) {
Set<Principal> principals = subject.getPrincipals();
if (principals != null) {
Optional<String> userName = principals.stream()
.filter(p -> p.getClass().getSimpleName().startsWith(principalName)).findFirst()
.map(mapping);
return userName.orElse(null);
}
return null;
}
public static String findAddress(Subject subject) {
return findAndProcessPrincipal(subject, "ClientPrincipal", AuditHelper::getAddress);
}
private static String getAddress(Principal p) {
//We're assumiming to process Karaf's ClientPrincipal. We need method getAddress();
try {
Method m = p.getClass().getMethod("getAddress");
Object result = m.invoke(p);
return (String) result;
} catch (Throwable t) {
logger.error("Cannot get address from principal {}:", p, t);
return null;
}
}
}

View File

@ -0,0 +1,57 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.utils;
import ru.entaxy.audit.data.Severity;
public enum CommandWeight {
JAAS("jaas", Severity.IMPORTANT);
private final String target;
private final Severity severity;
CommandWeight(String target, Severity severity) {
this.target = target;
this.severity = severity;
}
public String getTarget() {
return target;
}
public Severity getSeverity() {
return severity;
}
public static Severity getByTarget(String target) {
for (CommandWeight value : values()) {
if (value.getTarget().equals(target)) {
return value.severity;
}
}
return Severity.INFO;
}
}

View File

@ -0,0 +1,38 @@
/*-
* ~~~~~~licensing~~~~~~
* entaxy-audit
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.audit.utils;
public class Constants {
public static final String X_FORWARDER_FOR = "X-Forwarder-For";
public static final String LOG_FACILITY_NAME = "AUDIT_LOGFILE";
public static final String HTTP_REQUEST_USER = "Audit-HTTP-Request-User";
public static final String HTTP_REQUEST_REMOTE_IP = "Audit-HTTP-Request-Remote-IP";
public static final String HTTP_REQUEST_SERVER_IP = "Audit-HTTP-Request-Server-IP";
private Constants() {}
}