From 74ec77c4d2b22fbafb86a3252c72b1999f1d3ecb Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Sat, 19 May 2012 10:52:07 -0500 Subject: Added Auditor service. A new Auditor service has been added to replace the audit service that was previously only available to subclasses of AdminServlet. The new service can be used by other components including REST services. The AdminServlet will be modified to use the Auditor service separately. Ticket #160 --- base/common/src/CMakeLists.txt | 2 + base/common/src/com/netscape/certsrv/apps/CMS.java | 12 ++ .../src/com/netscape/certsrv/apps/ICMSEngine.java | 10 + .../src/com/netscape/certsrv/logging/IAuditor.java | 78 ++++++++ .../src/com/netscape/cmscore/apps/CMSEngine.java | 6 + .../src/com/netscape/cmscore/logging/Auditor.java | 212 +++++++++++++++++++++ .../netscape/certsrv/app/CMSEngineDefaultStub.java | 5 + 7 files changed, 325 insertions(+) create mode 100644 base/common/src/com/netscape/certsrv/logging/IAuditor.java create mode 100644 base/common/src/com/netscape/cmscore/logging/Auditor.java (limited to 'base/common') diff --git a/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt index 0a9fcddfb..8ca357c7f 100644 --- a/base/common/src/CMakeLists.txt +++ b/base/common/src/CMakeLists.txt @@ -351,6 +351,7 @@ set(pki-certsrv_java_SRCS com/netscape/certsrv/logging/ELogException.java com/netscape/certsrv/logging/ConsoleLog.java com/netscape/certsrv/logging/LogPlugin.java + com/netscape/certsrv/logging/IAuditor.java com/netscape/certsrv/logging/ILogSubsystem.java com/netscape/certsrv/logging/IBundleLogEvent.java com/netscape/certsrv/logging/ELogPluginNotFound.java @@ -1037,6 +1038,7 @@ set(pki-cmscore_java_SRCS com/netscape/cmscore/logging/AuditEventFactory.java com/netscape/cmscore/logging/LogQueue.java com/netscape/cmscore/logging/LogSubsystem.java + com/netscape/cmscore/logging/Auditor.java com/netscape/cmscore/logging/AuditFormat.java com/netscape/cmscore/logging/Logger.java com/netscape/cmscore/logging/SignedAuditEventFactory.java diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java index 4d4577777..00d2e0653 100644 --- a/base/common/src/com/netscape/certsrv/apps/CMS.java +++ b/base/common/src/com/netscape/certsrv/apps/CMS.java @@ -73,6 +73,7 @@ import com.netscape.certsrv.ldap.ELdapException; import com.netscape.certsrv.ldap.ILdapAuthInfo; import com.netscape.certsrv.ldap.ILdapConnFactory; import com.netscape.certsrv.ldap.ILdapConnInfo; +import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogSubsystem; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.notification.IEmailFormProcessor; @@ -287,6 +288,17 @@ public final class CMS { return _engine.getLogger(); } + /** + * Returns the auditor of the current server. The auditor can + * be used to audit critical informational or critical error + * messages. + * + * @return auditor + */ + public static IAuditor getAuditor() { + return _engine.getAuditor(); + } + /** * Returns the signed audit logger of the current server. This logger can * be used to log critical informational or critical error diff --git a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java index 41f4c348e..f11005c07 100644 --- a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java +++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java @@ -64,6 +64,7 @@ import com.netscape.certsrv.ldap.ELdapException; import com.netscape.certsrv.ldap.ILdapAuthInfo; import com.netscape.certsrv.ldap.ILdapConnFactory; import com.netscape.certsrv.ldap.ILdapConnInfo; +import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.notification.IEmailFormProcessor; import com.netscape.certsrv.notification.IEmailResolver; @@ -186,6 +187,15 @@ public interface ICMSEngine extends ISubsystem { */ public ILogger getLogger(); + /** + * Returns the auditor of the current server. The auditor can + * be used to audit critical informational or critical error + * messages. + * + * @return auditor + */ + public IAuditor getAuditor(); + /** * Returns the signed audit logger of the current server. This logger can * be used to log critical informational or critical error diff --git a/base/common/src/com/netscape/certsrv/logging/IAuditor.java b/base/common/src/com/netscape/certsrv/logging/IAuditor.java new file mode 100644 index 000000000..a93622596 --- /dev/null +++ b/base/common/src/com/netscape/certsrv/logging/IAuditor.java @@ -0,0 +1,78 @@ +// --- 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) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.certsrv.logging; + +import java.util.Map; + +/** + * @author Endi S. Dewata + */ +public interface IAuditor { + + public final static String LOGGING_SIGNED_AUDIT_CONFIG_ROLE = + "LOGGING_SIGNED_AUDIT_CONFIG_ROLE_3"; + + public final static String SIGNED_AUDIT_SCOPE = "Scope"; + public final static String SIGNED_AUDIT_OPERATION = "Operation"; + public final static String SIGNED_AUDIT_RESOURCE = "Resource"; + public final static String SIGNED_AUDIT_RULENAME = "RULENAME"; + public final static String SIGNED_AUDIT_PASSWORD_VALUE = "********"; + public final static String SIGNED_AUDIT_EMPTY_NAME_VALUE_PAIR = "Unknown"; + public final static String SIGNED_AUDIT_NAME_VALUE_DELIMITER = ";;"; + public final static String SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER = "+"; + + /** + * Get signed audit log subject ID + * + * This method is called to obtain the "SubjectID" for + * a signed audit log message. + * + * @return id string containing the signed audit log message SubjectID + */ + public String getSubjectID(); + + /** + * Get signed audit groups + * + * This method is called to extract all "groups" associated + * with the "auditSubjectID()". + *

+ * + * @param subjectID string containing the signed audit log message SubjectID + * @return a delimited string of groups associated + * with the "auditSubjectID()" + */ + public String getGroups(String subjectID); + + /** + * Get signed audit parameters as a string. + * + * This method is called to convert parameters into a + * string of name;;value pairs separated by a '+' + * if more than one name;;value pair exists. + * + * @return a delimited string of one or more delimited name/value pairs + */ + public String getParamString(String scope, String type, String id, Map params); + + /** + * Log audit message. + */ + public void log(String message); +} \ No newline at end of file diff --git a/base/common/src/com/netscape/cmscore/apps/CMSEngine.java b/base/common/src/com/netscape/cmscore/apps/CMSEngine.java index 19fc5162b..72e8c49e8 100644 --- a/base/common/src/com/netscape/cmscore/apps/CMSEngine.java +++ b/base/common/src/com/netscape/cmscore/apps/CMSEngine.java @@ -100,6 +100,7 @@ import com.netscape.certsrv.ldap.ILdapAuthInfo; import com.netscape.certsrv.ldap.ILdapConnFactory; import com.netscape.certsrv.ldap.ILdapConnInfo; import com.netscape.certsrv.logging.ELogException; +import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogEvent; import com.netscape.certsrv.logging.ILogEventListener; import com.netscape.certsrv.logging.ILogQueue; @@ -152,6 +153,7 @@ import com.netscape.cmscore.ldapconn.LdapBoundConnFactory; import com.netscape.cmscore.ldapconn.LdapBoundConnection; import com.netscape.cmscore.ldapconn.LdapConnInfo; import com.netscape.cmscore.ldapconn.LdapJssSSLSocketFactory; +import com.netscape.cmscore.logging.Auditor; import com.netscape.cmscore.logging.LogSubsystem; import com.netscape.cmscore.logging.Logger; import com.netscape.cmscore.logging.SignedAuditLogger; @@ -1513,6 +1515,10 @@ public class CMSEngine implements ICMSEngine { return Logger.getLogger(); } + public IAuditor getAuditor() { + return Auditor.getAuditor(); + } + public ILogger getSignedAuditLogger() { return SignedAuditLogger.getLogger(); } diff --git a/base/common/src/com/netscape/cmscore/logging/Auditor.java b/base/common/src/com/netscape/cmscore/logging/Auditor.java new file mode 100644 index 000000000..eef4ad14b --- /dev/null +++ b/base/common/src/com/netscape/cmscore/logging/Auditor.java @@ -0,0 +1,212 @@ +// --- 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) 2012 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cmscore.logging; + +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.SessionContext; +import com.netscape.certsrv.common.Constants; +import com.netscape.certsrv.logging.IAuditor; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.usrgrp.IGroup; +import com.netscape.certsrv.usrgrp.IUGSubsystem; + +/** + * @author Endi S. Dewata + */ +public class Auditor implements IAuditor { + + public final static Auditor auditor = new Auditor(); + + public ILogger signedAuditLogger = CMS.getSignedAuditLogger(); + + public static IAuditor getAuditor() { + return auditor; + } + + @Override + public String getSubjectID() { + // if no signed audit object exists, bail + if (signedAuditLogger == null) return null; + + SessionContext context = SessionContext.getExistingContext(); + if (context == null) return ILogger.UNIDENTIFIED; + + // Initialize subject ID + String subjectID = (String)context.get(SessionContext.USER_ID); + if (subjectID == null) return ILogger.NONROLEUSER; + + return subjectID.trim(); + } + + @Override + public String getGroups(String subjectID) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) return null; + + if (subjectID == null || subjectID.equals(ILogger.UNIDENTIFIED)) + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + + Enumeration groups; + + try { + IUGSubsystem userGroupSubsystem = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); + groups = userGroupSubsystem.findGroups("*"); + + } catch (Exception e) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + StringBuilder sb = new StringBuilder(); + + while (groups.hasMoreElements()) { + IGroup group = groups.nextElement(); + + if (group.isMember(subjectID) == true) { + if (sb.length() != 0) sb.append(", "); + sb.append(group.getGroupID()); + } + } + + if (sb.length() == 0) return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + + return sb.toString(); + } + + @Override + public String getParamString(String scope, String type, String id, Map params) { + + // if no signed audit object exists, bail + if (signedAuditLogger == null) return null; + + String parameters = SIGNED_AUDIT_EMPTY_NAME_VALUE_PAIR; + + // always identify the scope of the request + if (scope != null) { + parameters = SIGNED_AUDIT_SCOPE + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + scope; + } + + // identify the operation type of the request + if (type != null) { + parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER; + + parameters += SIGNED_AUDIT_OPERATION + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + type; + } + + // identify the resource type of the request + if (id != null) { + parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER; + + parameters += SIGNED_AUDIT_RESOURCE + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + id; + } + + if (params == null) return parameters; + + // identify any remaining request parameters + Collection names = params.keySet(); + + for (Iterator i = names.iterator(); i.hasNext(); ) { + String name = i.next(); + + // skip "RULENAME" parameter + if (name.equals(SIGNED_AUDIT_RULENAME)) continue; + + parameters += SIGNED_AUDIT_NAME_VALUE_PAIRS_DELIMITER; + + String value = params.get(name); + + if (value == null) { + parameters += name + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + ILogger.SIGNED_AUDIT_EMPTY_VALUE; + continue; + } + + value = value.trim(); + + if (value.equals("")) { + parameters += name + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + ILogger.SIGNED_AUDIT_EMPTY_VALUE; + continue; + } + + // + // To fix Blackflag Bug # 613800: + // + // Check "com.netscape.certsrv.common.Constants" for + // case-insensitive "password", "pwd", and "passwd" + // name fields, and hide any password values: + // + if (name.equals(Constants.PASSWORDTYPE) || /* "password" */ + name.equals(Constants.TYPE_PASSWORD) || + name.equals(Constants.PR_USER_PASSWORD) || + name.equals(Constants.PT_OLD_PASSWORD) || + name.equals(Constants.PT_NEW_PASSWORD) || + name.equals(Constants.PT_DIST_STORE) || + name.equals(Constants.PT_DIST_EMAIL) || + /* "pwd" */name.equals(Constants.PR_AUTH_ADMIN_PWD) || + // ignore this one name.equals( Constants.PR_BINDPWD_PROMPT ) || + name.equals(Constants.PR_DIRECTORY_MANAGER_PWD) || + name.equals(Constants.PR_OLD_AGENT_PWD) || + name.equals(Constants.PR_AGENT_PWD) || + name.equals(Constants.PT_PUBLISH_PWD) || + /* "passwd" */name.equals(Constants.PR_BIND_PASSWD) || + name.equals(Constants.PR_BIND_PASSWD_AGAIN) || + name.equals(Constants.PR_TOKEN_PASSWD)) { + + // hide password value + parameters += name + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + SIGNED_AUDIT_PASSWORD_VALUE; + + } else { + // process normally + parameters += name + + SIGNED_AUDIT_NAME_VALUE_DELIMITER + + value; + } + } + + return parameters; + } + + @Override + public void log(String message) { + + if (signedAuditLogger == null) return; + + signedAuditLogger.log( + ILogger.EV_SIGNED_AUDIT, + null, + ILogger.S_SIGNED_AUDIT, + ILogger.LL_SECURITY, + message); + } +} diff --git a/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java b/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java index cddd1205a..ce5570667 100644 --- a/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java +++ b/base/common/test/com/netscape/certsrv/app/CMSEngineDefaultStub.java @@ -49,6 +49,7 @@ import com.netscape.certsrv.ldap.ELdapException; import com.netscape.certsrv.ldap.ILdapAuthInfo; import com.netscape.certsrv.ldap.ILdapConnFactory; import com.netscape.certsrv.ldap.ILdapConnInfo; +import com.netscape.certsrv.logging.IAuditor; import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.notification.IEmailFormProcessor; import com.netscape.certsrv.notification.IEmailResolver; @@ -142,6 +143,10 @@ public class CMSEngineDefaultStub implements ICMSEngine { return null; } + public IAuditor getAuditor() { + return null; + } + public ILogger getSignedAuditLogger() { return null; } -- cgit