summaryrefslogtreecommitdiffstats
path: root/base/common
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2013-10-02 12:39:13 -0400
committerEndi S. Dewata <edewata@redhat.com>2013-10-08 19:01:18 -0400
commit53ef3a1a1c80539a470537a03ec77cdcb71b2fd3 (patch)
treeb51352a2e48c6d68c558bcd048e9b3be5aae4b8f /base/common
parentae753b2f5775b5f523d5183235d8820a65cf0eea (diff)
downloadpki-53ef3a1a1c80539a470537a03ec77cdcb71b2fd3.tar.gz
pki-53ef3a1a1c80539a470537a03ec77cdcb71b2fd3.tar.xz
pki-53ef3a1a1c80539a470537a03ec77cdcb71b2fd3.zip
Added audit resource.
A new REST service and clients have been added to manage the audit configuration in all subsystems. Ticket #652
Diffstat (limited to 'base/common')
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CAClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/kra/KRAClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/logging/AuditClient.java52
-rw-r--r--base/common/src/com/netscape/certsrv/logging/AuditConfig.java318
-rw-r--r--base/common/src/com/netscape/certsrv/logging/AuditResource.java46
-rw-r--r--base/common/src/com/netscape/certsrv/ocsp/OCSPClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/tks/TKSClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/tps/TPSClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/tps/config/ConfigCollection.java65
-rw-r--r--base/common/src/com/netscape/cms/logging/LogFile.java133
-rw-r--r--base/common/src/com/netscape/cmscore/logging/AuditService.java177
11 files changed, 678 insertions, 123 deletions
diff --git a/base/common/src/com/netscape/certsrv/ca/CAClient.java b/base/common/src/com/netscape/certsrv/ca/CAClient.java
index 82411186b..24a84a2ea 100644
--- a/base/common/src/com/netscape/certsrv/ca/CAClient.java
+++ b/base/common/src/com/netscape/certsrv/ca/CAClient.java
@@ -23,6 +23,7 @@ import com.netscape.certsrv.cert.CertClient;
import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.SubsystemClient;
import com.netscape.certsrv.group.GroupClient;
+import com.netscape.certsrv.logging.AuditClient;
import com.netscape.certsrv.profile.ProfileData;
import com.netscape.certsrv.profile.ProfileDataInfos;
import com.netscape.certsrv.profile.ProfileResource;
@@ -40,6 +41,7 @@ public class CAClient extends SubsystemClient {
public void init() throws URISyntaxException {
+ addClient(new AuditClient(client, name));
addClient(new CertClient(client, name));
addClient(new GroupClient(client, name));
addClient(new SelfTestClient(client, name));
diff --git a/base/common/src/com/netscape/certsrv/kra/KRAClient.java b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
index 28991caf6..658aba50b 100644
--- a/base/common/src/com/netscape/certsrv/kra/KRAClient.java
+++ b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
@@ -20,6 +20,7 @@ import com.netscape.certsrv.key.KeyRequestInfo;
import com.netscape.certsrv.key.KeyRequestInfos;
import com.netscape.certsrv.key.KeyRequestResource;
import com.netscape.certsrv.key.KeyResource;
+import com.netscape.certsrv.logging.AuditClient;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.selftests.SelfTestClient;
import com.netscape.certsrv.system.SystemCertResource;
@@ -39,6 +40,7 @@ public class KRAClient extends SubsystemClient {
public void init() throws URISyntaxException {
+ addClient(new AuditClient(client, name));
addClient(new GroupClient(client, name));
addClient(new SelfTestClient(client, name));
addClient(new UserClient(client, name));
diff --git a/base/common/src/com/netscape/certsrv/logging/AuditClient.java b/base/common/src/com/netscape/certsrv/logging/AuditClient.java
new file mode 100644
index 000000000..5892a20cb
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/AuditClient.java
@@ -0,0 +1,52 @@
+//--- BEGIN COPYRIGHT BLOCK ---
+//This program is free software; you can redistribute it and/or modify
+//it under the terms of the GNU General Public License as published by
+//the Free Software Foundation; version 2 of the License.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//GNU General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License along
+//with this program; if not, write to the Free Software Foundation, Inc.,
+//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//(C) 2013 Red Hat, Inc.
+//All rights reserved.
+//--- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.logging;
+
+import java.net.URISyntaxException;
+
+import org.jboss.resteasy.client.ClientResponse;
+
+import com.netscape.certsrv.client.Client;
+import com.netscape.certsrv.client.PKIClient;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class AuditClient extends Client {
+
+ public AuditResource resource;
+
+ public AuditClient(PKIClient client, String subsystem) throws URISyntaxException {
+ super(client, subsystem, "audit");
+ init();
+ }
+
+ public void init() throws URISyntaxException {
+ resource = createProxy(AuditResource.class);
+ }
+
+ public AuditConfig getAuditConfig() {
+ return resource.getAuditConfig();
+ }
+
+ public AuditConfig updateAuditConfig(AuditConfig auditConfig) {
+ @SuppressWarnings("unchecked")
+ ClientResponse<AuditConfig> response = (ClientResponse<AuditConfig>)resource.updateAuditConfig(auditConfig);
+ return client.getEntity(response);
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/AuditConfig.java b/base/common/src/com/netscape/certsrv/logging/AuditConfig.java
new file mode 100644
index 000000000..6abe7af2a
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/AuditConfig.java
@@ -0,0 +1,318 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.certsrv.logging;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+/**
+ * @author Endi S. Dewata
+ */
+@XmlRootElement(name="Audit")
+public class AuditConfig {
+
+ public static Marshaller marshaller;
+ public static Unmarshaller unmarshaller;
+
+ static {
+ try {
+ marshaller = JAXBContext.newInstance(AuditConfig.class).createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ unmarshaller = JAXBContext.newInstance(AuditConfig.class).createUnmarshaller();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ Boolean enabled;
+ Boolean signed;
+ Integer interval;
+ Integer bufferSize;
+ Collection<String> mandatoryEvents = new TreeSet<String>();
+ Map<String, Boolean> optionalEvents = new TreeMap<String, Boolean>();
+
+ Link link;
+
+ @XmlElement(name="Enabled")
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @XmlElement(name="Signed")
+ public Boolean getSigned() {
+ return signed;
+ }
+
+ public void setSigned(Boolean signed) {
+ this.signed = signed;
+ }
+
+ @XmlElement(name="Interval")
+ public Integer getInterval() {
+ return interval;
+ }
+
+ public void setInterval(Integer interval) {
+ this.interval = interval;
+ }
+
+ @XmlElement(name="BufferSize")
+ public Integer getBufferSize() {
+ return bufferSize;
+ }
+
+ public void setBufferSize(Integer bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ @XmlElement(name="MandatoryEvents")
+ @XmlJavaTypeAdapter(MandatoryEventsAdapter.class)
+ public Collection<String> getMandatoryEvents() {
+ return mandatoryEvents;
+ }
+
+ public void setMandatoryEvents(Collection<String> mandatoryEvents) {
+ this.mandatoryEvents.clear();
+ this.mandatoryEvents.addAll(mandatoryEvents);
+ }
+
+ public void addMandatoryEvent(String event) {
+ mandatoryEvents.add(event);
+ }
+
+ public void removeMandatoryEvent(String event) {
+ mandatoryEvents.remove(event);
+ }
+
+ @XmlElement(name="OptionalEvents")
+ @XmlJavaTypeAdapter(OptionalEventsAdapter.class)
+ public Map<String, Boolean> getOptionalEvents() {
+ return optionalEvents;
+ }
+
+ public void setOptionalEvents(Map<String, Boolean> optionalEvents) {
+ this.optionalEvents.clear();
+ this.optionalEvents.putAll(optionalEvents);
+ }
+
+ public Collection<String> getOptionalEventNames() {
+ return optionalEvents.keySet();
+ }
+
+ public Boolean getOptionalEvent(String name) {
+ return optionalEvents.get(name);
+ }
+
+ public void setOptionalEvent(String name, Boolean value) {
+ optionalEvents.put(name, value);
+ }
+
+ public Boolean removeOptionalEvent(String name) {
+ return optionalEvents.remove(name);
+ }
+
+ public static class MandatoryEventsAdapter extends XmlAdapter<EventList, Collection<String>> {
+
+ public EventList marshal(Collection<String> input) {
+ EventList output = new EventList();
+ for (String name : input) {
+ Event event = new Event();
+ event.name = name;
+ output.entries.add(event);
+ }
+ return output;
+ }
+
+ public Collection<String> unmarshal(EventList input) {
+ Collection<String> output = new TreeSet<String>();
+ for (Event event : input.entries) {
+ output.add(event.name);
+ }
+ return output;
+ }
+ }
+
+ public static class OptionalEventsAdapter extends XmlAdapter<EventList, Map<String, Boolean>> {
+
+ public EventList marshal(Map<String, Boolean> map) {
+ EventList list = new EventList();
+ for (Map.Entry<String, Boolean> entry : map.entrySet()) {
+ Event event = new Event();
+ event.name = entry.getKey();
+ event.value = entry.getValue();
+ list.entries.add(event);
+ }
+ return list;
+ }
+
+ public Map<String, Boolean> unmarshal(EventList list) {
+ Map<String, Boolean> map = new LinkedHashMap<String, Boolean>();
+ for (Event event : list.entries) {
+ map.put(event.name, event.value);
+ }
+ return map;
+ }
+ }
+
+ public static class EventList {
+ @XmlElement(name="Event")
+ public List<Event> entries = new ArrayList<Event>();
+ }
+
+ public static class Event {
+
+ @XmlAttribute
+ public String name;
+
+ @XmlValue
+ public Boolean value;
+ }
+
+ @XmlElement(name="Link")
+ public Link getLink() {
+ return link;
+ }
+
+ public void setLink(Link link) {
+ this.link = link;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((bufferSize == null) ? 0 : bufferSize.hashCode());
+ result = prime * result + ((enabled == null) ? 0 : enabled.hashCode());
+ result = prime * result + ((optionalEvents == null) ? 0 : optionalEvents.hashCode());
+ result = prime * result + ((interval == null) ? 0 : interval.hashCode());
+ result = prime * result + ((link == null) ? 0 : link.hashCode());
+ result = prime * result + ((mandatoryEvents == null) ? 0 : mandatoryEvents.hashCode());
+ result = prime * result + ((signed == null) ? 0 : signed.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AuditConfig other = (AuditConfig) obj;
+ if (bufferSize == null) {
+ if (other.bufferSize != null)
+ return false;
+ } else if (!bufferSize.equals(other.bufferSize))
+ return false;
+ if (enabled == null) {
+ if (other.enabled != null)
+ return false;
+ } else if (!enabled.equals(other.enabled))
+ return false;
+ if (optionalEvents == null) {
+ if (other.optionalEvents != null)
+ return false;
+ } else if (!optionalEvents.equals(other.optionalEvents))
+ return false;
+ if (interval == null) {
+ if (other.interval != null)
+ return false;
+ } else if (!interval.equals(other.interval))
+ return false;
+ if (link == null) {
+ if (other.link != null)
+ return false;
+ } else if (!link.equals(other.link))
+ return false;
+ if (mandatoryEvents == null) {
+ if (other.mandatoryEvents != null)
+ return false;
+ } else if (!mandatoryEvents.equals(other.mandatoryEvents))
+ return false;
+ if (signed == null) {
+ if (other.signed != null)
+ return false;
+ } else if (!signed.equals(other.signed))
+ return false;
+ return true;
+ }
+
+ public String toString() {
+ try {
+ StringWriter sw = new StringWriter();
+ marshaller.marshal(this, sw);
+ return sw.toString();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return super.toString();
+ }
+ }
+
+ public static AuditConfig valueOf(String string) throws Exception {
+ try {
+ return (AuditConfig)unmarshaller.unmarshal(new StringReader(string));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+
+ AuditConfig before = new AuditConfig();
+ before.setEnabled(true);
+ before.setSigned(false);
+ before.setInterval(10);
+ before.setBufferSize(512);
+ before.addMandatoryEvent("event1");
+ before.addMandatoryEvent("event2");
+ before.setOptionalEvent("event3", true);
+ before.setOptionalEvent("event4", false);
+
+ String string = before.toString();
+ System.out.println(string);
+
+ AuditConfig after = AuditConfig.valueOf(string);
+ System.out.println(before.equals(after));
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/logging/AuditResource.java b/base/common/src/com/netscape/certsrv/logging/AuditResource.java
new file mode 100644
index 000000000..4b705a5f9
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/AuditResource.java
@@ -0,0 +1,46 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.logging;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.jboss.resteasy.annotations.ClientResponseType;
+
+
+/**
+ * @author Endi S. Dewata
+ */
+@Path("audit")
+public interface AuditResource {
+
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public AuditConfig getAuditConfig();
+
+ @PUT
+ @ClientResponseType(entityType=AuditConfig.class)
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public Response updateAuditConfig(AuditConfig configData);
+}
diff --git a/base/common/src/com/netscape/certsrv/ocsp/OCSPClient.java b/base/common/src/com/netscape/certsrv/ocsp/OCSPClient.java
index ab85bd200..6163d4818 100644
--- a/base/common/src/com/netscape/certsrv/ocsp/OCSPClient.java
+++ b/base/common/src/com/netscape/certsrv/ocsp/OCSPClient.java
@@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.SubsystemClient;
import com.netscape.certsrv.group.GroupClient;
+import com.netscape.certsrv.logging.AuditClient;
import com.netscape.certsrv.selftests.SelfTestClient;
import com.netscape.certsrv.user.UserClient;
@@ -33,6 +34,7 @@ public class OCSPClient extends SubsystemClient {
}
public void init() throws URISyntaxException {
+ addClient(new AuditClient(client, name));
addClient(new GroupClient(client, name));
addClient(new SelfTestClient(client, name));
addClient(new UserClient(client, name));
diff --git a/base/common/src/com/netscape/certsrv/tks/TKSClient.java b/base/common/src/com/netscape/certsrv/tks/TKSClient.java
index a972241ce..5adde7461 100644
--- a/base/common/src/com/netscape/certsrv/tks/TKSClient.java
+++ b/base/common/src/com/netscape/certsrv/tks/TKSClient.java
@@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.SubsystemClient;
import com.netscape.certsrv.group.GroupClient;
+import com.netscape.certsrv.logging.AuditClient;
import com.netscape.certsrv.selftests.SelfTestClient;
import com.netscape.certsrv.system.TPSConnectorClient;
import com.netscape.certsrv.user.UserClient;
@@ -34,6 +35,7 @@ public class TKSClient extends SubsystemClient {
}
public void init() throws URISyntaxException {
+ addClient(new AuditClient(client, name));
addClient(new GroupClient(client, name));
addClient(new SelfTestClient(client, name));
addClient(new TPSConnectorClient(client, name));
diff --git a/base/common/src/com/netscape/certsrv/tps/TPSClient.java b/base/common/src/com/netscape/certsrv/tps/TPSClient.java
index eeccdb018..40820d84d 100644
--- a/base/common/src/com/netscape/certsrv/tps/TPSClient.java
+++ b/base/common/src/com/netscape/certsrv/tps/TPSClient.java
@@ -23,6 +23,7 @@ import com.netscape.certsrv.client.PKIClient;
import com.netscape.certsrv.client.SubsystemClient;
import com.netscape.certsrv.group.GroupClient;
import com.netscape.certsrv.logging.ActivityClient;
+import com.netscape.certsrv.logging.AuditClient;
import com.netscape.certsrv.selftests.SelfTestClient;
import com.netscape.certsrv.tps.authenticator.AuthenticatorClient;
import com.netscape.certsrv.tps.cert.TPSCertClient;
@@ -44,6 +45,7 @@ public class TPSClient extends SubsystemClient {
public void init() throws URISyntaxException {
addClient(new ActivityClient(client, name));
+ addClient(new AuditClient(client, name));
addClient(new AuthenticatorClient(client, name));
addClient(new TPSCertClient(client, name));
addClient(new ConfigClient(client, name));
diff --git a/base/common/src/com/netscape/certsrv/tps/config/ConfigCollection.java b/base/common/src/com/netscape/certsrv/tps/config/ConfigCollection.java
deleted file mode 100644
index a36f61fd1..000000000
--- a/base/common/src/com/netscape/certsrv/tps/config/ConfigCollection.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2013 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
-package com.netscape.certsrv.tps.config;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.jboss.resteasy.plugins.providers.atom.Link;
-
-
-/**
- * @author Endi S. Dewata
- */
-@XmlRootElement(name="Configurations")
-public class ConfigCollection {
-
- Collection<ConfigData> configs = new ArrayList<ConfigData>();
- Collection<Link> links = new ArrayList<Link>();
-
- @XmlElementRef
- public Collection<ConfigData> getConfigs() {
- return configs;
- }
-
- public void setConfigs(Collection<ConfigData> configs) {
- this.configs = configs;
- }
-
- public void addConfig(ConfigData configData) {
- configs.add(configData);
- }
-
- @XmlElement(name="Link")
- public Collection<Link> getLinks() {
- return links;
- }
-
- public void setLink(Collection<Link> links) {
- this.links = links;
- }
-
- public void addLink(Link link) {
- links.add(link);
- }
-}
diff --git a/base/common/src/com/netscape/cms/logging/LogFile.java b/base/common/src/com/netscape/cms/logging/LogFile.java
index 2c3510c74..c465a4e53 100644
--- a/base/common/src/com/netscape/cms/logging/LogFile.java
+++ b/base/common/src/com/netscape/cms/logging/LogFile.java
@@ -47,13 +47,15 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
+import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Properties;
-import java.util.StringTokenizer;
+import java.util.Set;
import java.util.Vector;
import javax.servlet.ServletException;
+import org.apache.commons.lang.StringUtils;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.ObjectNotFoundException;
@@ -91,7 +93,9 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
public static final String PROP_SIGNED_AUDIT_LOG_SIGNING = "logSigning";
public static final String PROP_SIGNED_AUDIT_CERT_NICKNAME =
"signedAuditCertNickname";
- public static final String PROP_SIGNED_AUDIT_EVENTS = "events";
+ public static final String PROP_SIGNED_AUDIT_SELECTED_EVENTS = "events";
+ public static final String PROP_SIGNED_AUDIT_UNSELECTED_EVENTS = "unselected.events";
+ public static final String PROP_SIGNED_AUDIT_MANDATORY_EVENTS = "mandatory.events";
public static final String PROP_LEVEL = "level";
static final String PROP_FILE_NAME = "fileName";
static final String PROP_LAST_HASH_FILE_NAME = "lastHashFileName";
@@ -184,10 +188,19 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
private Thread mFlushThread = null;
/**
+ * The mandatory log event types
+ */
+ protected Set<String> mandatoryEvents = new LinkedHashSet<String>();
+
+ /**
* The selected log event types
*/
- protected String mSelectedEventsList = null;
- protected Vector<String> mSelectedEvents = null;
+ protected Set<String> selectedEvents = new LinkedHashSet<String>();
+
+ /**
+ * The unselected log event types
+ */
+ protected Set<String> unselectedEvents = new LinkedHashSet<String>();
/**
* The eventType that this log is triggered
@@ -272,40 +285,29 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
}
}
- // selective logging
- mSelectedEventsList = null;
- try {
- mSelectedEventsList = config.getString(PROP_SIGNED_AUDIT_EVENTS);
- } catch (EBaseException e) {
- // when not specified, ALL are selected by default
+ // mandatory events
+ String mandatoryEventsList = config.getString(PROP_SIGNED_AUDIT_MANDATORY_EVENTS, "");
+ for (String event : StringUtils.split(mandatoryEventsList, ", ")) {
+ mandatoryEvents.add(event);
}
- mSelectedEvents = string2Vector(mSelectedEventsList);
- try {
- init(config);
- } catch (IOException e) {
- throw new ELogException(CMS.getUserMessage("CMS_LOG_UNEXPECTED_EXCEPTION", e.toString()));
+ // selected events
+ String selectedEventsList = config.getString(PROP_SIGNED_AUDIT_SELECTED_EVENTS, "");
+ for (String event : StringUtils.split(selectedEventsList, ", ")) {
+ selectedEvents.add(event);
}
- }
- /**
- * turns a comma-separated String into a Vector
- */
- protected Vector<String> string2Vector(String theString) {
- Vector<String> theVector = new Vector<String>();
- if (theString == null) {
- return theVector;
+ // unselected events
+ String unselectedEventsList = config.getString(PROP_SIGNED_AUDIT_UNSELECTED_EVENTS, "");
+ for (String event : StringUtils.split(unselectedEventsList, ", ")) {
+ unselectedEvents.add(event);
}
- StringTokenizer tokens = new StringTokenizer(theString,
- ",");
- while (tokens.hasMoreTokens()) {
- String eventId = tokens.nextToken().trim();
-
- theVector.addElement(eventId);
- CMS.debug("LogFile: log event type selected: " + eventId);
+ try {
+ init(config);
+ } catch (IOException e) {
+ throw new ELogException(CMS.getUserMessage("CMS_LOG_UNEXPECTED_EXCEPTION", e.toString()));
}
- return theVector;
}
/**
@@ -314,8 +316,8 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
* @param event to be selected
*/
public void selectEvent(String event) {
- if (!mSelectedEvents.contains(event))
- mSelectedEvents.addElement(event);
+ selectedEvents.add(event);
+ unselectedEvents.remove(event);
}
/**
@@ -324,8 +326,8 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
* @param event to be de-selected
*/
public void deselectEvent(String event) {
- if (mSelectedEvents.contains(event))
- mSelectedEvents.removeElement(event);
+ selectedEvents.remove(event);
+ unselectedEvents.add(event);
}
/**
@@ -334,9 +336,14 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
* @param events comma-separated event list
*/
public void replaceEvents(String events) {
- Vector<String> v = string2Vector(events);
- mSelectedEvents.removeAllElements();
- mSelectedEvents = v;
+ // unselect all events
+ unselectedEvents.addAll(selectedEvents);
+ selectedEvents.clear();
+
+ // select specified events
+ for (String event : StringUtils.split(events, ", ")) {
+ selectEvent(event);
+ }
}
public static String base64Encode(byte[] bytes) throws IOException {
@@ -1066,22 +1073,29 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
}
}
- // Is the event type selected?
// If no selection specified in configuration, then all are selected
+ if (selectedEvents.isEmpty()) {
+ String entry = logEvt2String(ev);
+ log(entry);
+ return;
+ }
+
// If no type specified in propertity file, then treated as selected
- if (mSelectedEvents.size() > 0) {
- String type = ev.getEventType();
- if (type != null) {
- if (!mSelectedEvents.contains(type)) {
- CMS.debug("LogFile: event type not selected: " + type);
- return;
- }
- }
+ String type = ev.getEventType();
+ if (type == null) {
+ String entry = logEvt2String(ev);
+ log(entry);
+ return;
}
- String entry = logEvt2String(ev);
+ // Is the event type mandatory or selected?
+ if (mandatoryEvents.contains(type) || selectedEvents.contains(type)) {
+ String entry = logEvt2String(ev);
+ log(entry);
+ return;
+ }
- log(entry);
+ CMS.debug("LogFile: event type not selected: " + type);
}
public String logEvt2String(ILogEvent ev) {
@@ -1378,7 +1392,9 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
//if( mType.equals( ILogger.PROP_SIGNED_AUDIT ) ) {
v.addElement(PROP_SIGNED_AUDIT_LOG_SIGNING + "=");
v.addElement(PROP_SIGNED_AUDIT_CERT_NICKNAME + "=");
- v.addElement(PROP_SIGNED_AUDIT_EVENTS + "=");
+ v.addElement(PROP_SIGNED_AUDIT_MANDATORY_EVENTS + "=");
+ v.addElement(PROP_SIGNED_AUDIT_SELECTED_EVENTS + "=");
+ v.addElement(PROP_SIGNED_AUDIT_UNSELECTED_EVENTS + "=");
//}
return v;
@@ -1431,12 +1447,9 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
+ mSAuditCertNickName);
}
- if (mSelectedEventsList == null) {
- v.addElement(PROP_SIGNED_AUDIT_EVENTS + "=");
- } else {
- v.addElement(PROP_SIGNED_AUDIT_EVENTS + "="
- + mSelectedEventsList);
- }
+ v.addElement(PROP_SIGNED_AUDIT_MANDATORY_EVENTS + "=" + StringUtils.join(mandatoryEvents, ","));
+ v.addElement(PROP_SIGNED_AUDIT_SELECTED_EVENTS + "=" + StringUtils.join(selectedEvents, ","));
+ v.addElement(PROP_SIGNED_AUDIT_UNSELECTED_EVENTS + "=" + StringUtils.join(unselectedEvents, ","));
}
} catch (Exception e) {
}
@@ -1469,8 +1482,12 @@ public class LogFile implements ILogEventListener, IExtendedPluginInfo {
";boolean;Enable audit logs to be signed",
PROP_SIGNED_AUDIT_CERT_NICKNAME +
";string;The nickname of the certificate to be used to sign audit logs",
- PROP_SIGNED_AUDIT_EVENTS +
- ";string;A comma-separated list of strings used to specify particular signed audit log events",
+ PROP_SIGNED_AUDIT_MANDATORY_EVENTS +
+ ";string;A comma-separated list of strings used to specify mandatory signed audit log events",
+ PROP_SIGNED_AUDIT_SELECTED_EVENTS +
+ ";string;A comma-separated list of strings used to specify selected signed audit log events",
+ PROP_SIGNED_AUDIT_UNSELECTED_EVENTS +
+ ";string;A comma-separated list of strings used to specify unselected signed audit log events",
};
return params;
diff --git a/base/common/src/com/netscape/cmscore/logging/AuditService.java b/base/common/src/com/netscape/cmscore/logging/AuditService.java
new file mode 100644
index 000000000..89ac6263e
--- /dev/null
+++ b/base/common/src/com/netscape/cmscore/logging/AuditService.java
@@ -0,0 +1,177 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmscore.logging;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.lang.StringUtils;
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.logging.AuditConfig;
+import com.netscape.certsrv.logging.AuditResource;
+import com.netscape.cms.servlet.base.PKIService;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class AuditService extends PKIService implements AuditResource {
+
+ @Context
+ private UriInfo uriInfo;
+
+ @Context
+ private HttpHeaders headers;
+
+ @Context
+ private Request request;
+
+ @Context
+ private HttpServletRequest servletRequest;
+
+ public final static int DEFAULT_SIZE = 20;
+
+ public AuditService() {
+ CMS.debug("AuditService.<init>()");
+ }
+
+ public AuditConfig createAuditConfig() throws UnsupportedEncodingException, EBaseException {
+
+ IConfigStore cs = CMS.getConfigStore();
+
+ AuditConfig auditConfig = new AuditConfig();
+ auditConfig.setEnabled(cs.getBoolean("log.instance.SignedAudit.enable", false));
+ auditConfig.setSigned(cs.getBoolean("log.instance.SignedAudit.logSigning", false));
+ auditConfig.setInterval(cs.getInteger("log.instance.SignedAudit.flushInterval", 5));
+ auditConfig.setBufferSize(cs.getInteger("log.instance.SignedAudit.bufferSize", 512));
+
+ // unselected events
+ for (String event : StringUtils.split(cs.getString("log.instance.SignedAudit.unselected.events", ""), ", ")) {
+ auditConfig.setOptionalEvent(event.trim(), false);
+ }
+
+ // in case of duplicates, selected events override unselected events
+ for (String event : StringUtils.split(cs.getString("log.instance.SignedAudit.events", ""), ", ")) {
+ auditConfig.setOptionalEvent(event.trim(), true);
+ }
+
+ // mandatory events
+ for (String event : StringUtils.split(cs.getString("log.instance.SignedAudit.mandatory.events", ""), ", ")) {
+ auditConfig.addMandatoryEvent(event.trim());
+ }
+
+ URI uri = uriInfo.getBaseUriBuilder().path(AuditResource.class).build();
+ auditConfig.setLink(new Link("self", uri));
+
+ return auditConfig;
+ }
+
+ @Override
+ public AuditConfig getAuditConfig() {
+
+ CMS.debug("AuditService.getAuditConfig()");
+
+ try {
+ return createAuditConfig();
+
+ } catch (PKIException e) {
+ throw e;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Response updateAuditConfig(AuditConfig auditConfig) {
+
+ CMS.debug("AuditService.updateAuditConfig()");
+
+ try {
+ IConfigStore cs = CMS.getConfigStore();
+
+ if (auditConfig.getEnabled() != null) {
+ cs.putBoolean("log.instance.SignedAudit.enable", auditConfig.getEnabled());
+ }
+
+ if (auditConfig.getSigned() != null) {
+ cs.putBoolean("log.instance.SignedAudit.logSigning", auditConfig.getSigned());
+ }
+
+ if (auditConfig.getInterval() != null) {
+ cs.putInteger("log.instance.SignedAudit.flushInterval", auditConfig.getInterval());
+ }
+
+ if (auditConfig.getBufferSize() != null) {
+ cs.putInteger("log.instance.SignedAudit.bufferSize", auditConfig.getBufferSize());
+ }
+
+ // update events selection
+ Collection<String> selected = new LinkedHashSet<String>();
+ Collection<String> unselected = new LinkedHashSet<String>();
+
+ for (String name : auditConfig.getOptionalEvents().keySet()) {
+ Boolean value = auditConfig.getOptionalEvent(name);
+
+ if (value) {
+ selected.add(name);
+
+ } else {
+ unselected.add(name);
+ }
+ }
+
+ cs.putString("log.instance.SignedAudit.events", StringUtils.join(selected, ","));
+ cs.putString("log.instance.SignedAudit.unselected.events", StringUtils.join(unselected, ","));
+
+ // mandatory events cannot be updated
+
+ cs.commit(true);
+
+ auditConfig = createAuditConfig();
+
+ return Response
+ .ok(auditConfig)
+ .type(MediaType.APPLICATION_XML)
+ .build();
+
+ } catch (PKIException e) {
+ throw e;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+}