diff options
author | Endi S. Dewata <edewata@redhat.com> | 2013-10-02 12:39:13 -0400 |
---|---|---|
committer | Endi S. Dewata <edewata@redhat.com> | 2013-10-08 19:01:18 -0400 |
commit | 53ef3a1a1c80539a470537a03ec77cdcb71b2fd3 (patch) | |
tree | b51352a2e48c6d68c558bcd048e9b3be5aae4b8f /base/common | |
parent | ae753b2f5775b5f523d5183235d8820a65cf0eea (diff) | |
download | pki-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')
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()); + } + } +} |