// --- 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) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package com.netscape.cms.jobs;
import java.util.*;
import java.io.*;
import java.text.DateFormat;
import java.security.*;
import java.security.cert.*;
import netscape.security.x509.*;
import com.netscape.certsrv.notification.*;
import com.netscape.certsrv.jobs.*;
import com.netscape.certsrv.base.*;
import com.netscape.certsrv.apps.*;
import com.netscape.certsrv.logging.*;
import com.netscape.certsrv.ca.*;
import com.netscape.certsrv.request.*;
import com.netscape.certsrv.dbs.certdb.*;
import com.netscape.certsrv.ldap.*;
import com.netscape.certsrv.publish.*;
/**
* a job for the Jobs Scheduler. This job checks in the internal ldap
* db for certs that have expired and remove them from the ldap
* publishing directory.
*
* the $TOKENS that are available for the this jobs's summary outer form are:
*
* $Status
* $InstanceID
* $SummaryItemList
* $SummaryTotalNum
* $SummaryTotalSuccess
* $SummaryTotalfailure
* $ExecutionTime
*
* and for the inner list items:
*
* $SerialNumber
* $IssuerDN
* $SubjectDN
* $NotAfter
* $NotBefore
* $RequestorEmail
* $CertType
*
*
* @version $Revision$, $Date$
*/
public class UnpublishExpiredJob extends AJobBase
implements IJob, Runnable, IExtendedPluginInfo {
ICertificateAuthority mCa = null;
IRequestQueue mReqQ = null;
ICertificateRepository mRepository = null;
IPublisherProcessor mPublisherProcessor = null;
private boolean mSummary = false;
/* Holds configuration parameters accepted by this implementation.
* This list is passed to the configuration console so configuration
* for instances of this implementation can be configured through the
* console.
*/
protected static String[] mConfigParams =
new String[] {
"enabled",
"cron",
"summary.enabled",
"summary.emailSubject",
"summary.emailTemplate",
"summary.itemTemplate",
"summary.senderEmail",
"summary.recipientEmail"
};
/* Vector of extendedPluginInfo strings */
protected static Vector mExtendedPluginInfo = null;
static {
mExtendedPluginInfo = new Vector();
};
public String[] getExtendedPluginInfo(Locale locale) {
String s[] = {
IExtendedPluginInfo.HELP_TEXT +
"; A job that checks for expired certificates in the " +
"database, and removes them from the publishing " +
"directory",
"cron;string;Format: minute hour dayOfMonth month " +
"dayOfWeek. Use '*' for 'every'. For dayOfWeek, 0 is Sunday",
"summary.senderEmail;string;Specify the address to be used " +
"as the email's 'sender'. Bounces go to this address.",
"summary.recipientEmail;string;Who should receive summaries",
"enabled;boolean;Enable this plugin",
"summary.enabled;boolean;Enable the summary. You must enabled " +
"this for the job to work.",
"summary.emailSubject;string;Subject of summary email",
"summary.emailTemplate;string;Fully qualified pathname of " +
"template file of email to be sent",
"summary.itemTemplate;string;Fully qualified pathname of " +
"file containing template for each item",
IExtendedPluginInfo.HELP_TOKEN +
";configuration-jobrules-unpublishexpiredjobs",
};
return s;
}
/**
* initialize from the configuration file
*/
public void init(ISubsystem owner, String id, String implName, IConfigStore config) throws
EBaseException {
mConfig = config;
mId = id;
mImplName = implName;
mCa = (ICertificateAuthority)
CMS.getSubsystem("ca");
if (mCa == null) {
return;
}
mReqQ = mCa.getRequestQueue();
mRepository = (ICertificateRepository) mCa.getCertificateRepository();
mPublisherProcessor = mCa.getPublisherProcessor();
// read from the configuration file
mCron = mConfig.getString(IJobCron.PROP_CRON);
if (mCron == null) {
return;
}
// parse cron string into a JobCron class
IJobsScheduler scheduler = (IJobsScheduler) owner;
mJobCron = scheduler.createJobCron(mCron);
// initialize the summary related config info
IConfigStore sc = mConfig.getSubStore(PROP_SUMMARY);
if (sc.getBoolean(PROP_ENABLED, false)) {
mSummary = true;
mSummaryMailSubject = sc.getString(PROP_EMAIL_SUBJECT);
mMailForm = sc.getString(PROP_EMAIL_TEMPLATE);
mItemForm = sc.getString(PROP_ITEM_TEMPLATE);
mSummarySenderEmail = sc.getString(PROP_SENDER_EMAIL);
mSummaryReceiverEmail = sc.getString(PROP_RECEIVER_EMAIL);
} else {
mSummary = false;
}
}
/**
* look in the internal db for certificateRecords that are
* expired.
* remove them from ldap publishing directory
* if remove successfully, mark false on the
* InLdapPublishDir flag,
* else, if remove unsuccessfully, log it
*/
public void run() {
// System.out.println("in ExpiredUnpublishJob "+
// getId()+ " : run()");
// get time now..."now" is before the loop
Date date = CMS.getCurrentDate();
long now = date.getTime();
DateFormat dateFormat = DateFormat.getDateTimeInstance();
String nowString = dateFormat.format(date);
// form filter
String filter = "(&(x509Cert.notAfter<=" + now +
")(!(x509Cert.notAfter=" + now + "))" +
"(" + "certMetainfo=" + ICertRecord.META_LDAPPUBLISH +
":true))";
// a test for without CertRecord.META_LDAPPUBLISH
//String filter = "(x509Cert.notAfter<="+ now +")";
Enumeration expired = null;
try {
expired = mRepository.findCertRecs(filter);
// bug 399150
/*
CertRecordList list = null;
list = mRepository.findCertRecordsInList(filter, null, "serialno", 5);
int size = list.getSize();
expired = list.getCertRecords(0, size - 1);
*/
} catch (EBaseException e) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
}
int count = 0; // how many have been unpublished successfully
int negCount = 0; // how many have NOT been unpublished successfully
String contentForm = null;
String itemForm = null;
String itemListContent = null;
if (mSummary == true) {
contentForm = getTemplateContent(mMailForm);
itemForm = getTemplateContent(mItemForm);
}
// unpublish them and unpublish() will set inLdapPublishDir flag
while (expired != null && expired.hasMoreElements()) {
ICertRecord rec = (ICertRecord) expired.nextElement();
if (rec == null) break;
X509CertImpl cert = rec.getCertificate();
if (mSummary == true)
buildItemParams(cert);
// get request id from cert record MetaInfo
MetaInfo minfo = null;
try {
minfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
} catch (EBaseException e) {
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_META_INFO_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
}
String ridString = null;
try {
if (minfo != null)
ridString = (String) minfo.get(ICertRecord.META_REQUEST_ID);
} catch (EBaseException e) {
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
} catch (NullPointerException e) {
// no requestId in MetaInfo...skip to next record
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_META_REQUEST_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
}
if (ridString != null) {
RequestId rid = new RequestId(ridString);
// get request from request id
IRequest req = null;
try {
req = mReqQ.findRequest(rid);
if (req != null) {
if (mSummary == true)
buildItemParams(req);
}
} catch (EBaseException e) {
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_FIND_REQUEST_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
}
try {
if ((mPublisherProcessor != null) &&
mPublisherProcessor.enabled()) {
mPublisherProcessor.unpublishCert((X509Certificate) cert, req);
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_SUCCESS);
count += 1;
} else {
negCount += 1;
}
} catch (Exception e) {
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_UNPUBLISH_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
}
} // ridString != null
else {
try {
if ((mPublisherProcessor != null) &&
mPublisherProcessor.enabled()) {
mPublisherProcessor.unpublishCert((X509Certificate) cert, null);
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_SUCCESS);
count += 1;
} else {
negCount += 1;
}
} catch (Exception e) {
negCount += 1;
if (mSummary == true)
buildItemParams(IEmailFormProcessor.TOKEN_STATUS,
STATUS_FAILURE);
log(ILogger.LL_FAILURE,
CMS.getLogMessage("JOBS_UNPUBLISH_ERROR",
cert.getSerialNumber().toString(16) +
e.toString()));
}
} // ridString == null
// inLdapPublishDir flag should have been set by the
// unpublish() method
// if summary is enabled, form the item content
if (mSummary) {
IEmailFormProcessor emailItemFormProcessor =
CMS.getEmailFormProcessor();
String c = emailItemFormProcessor.getEmailContent(itemForm,
mItemParams);
// add item content to the item list
if (itemListContent == null) {
itemListContent = c;
} else {
itemListContent += c;
}
}
}
// time for summary
if (mSummary == true) {
buildContentParams(IEmailFormProcessor.TOKEN_ID,
mId);
buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_ITEM_LIST,
itemListContent);
buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_TOTAL_NUM,
String.valueOf(count + negCount));
buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_SUCCESS_NUM,
String.valueOf(count));
buildContentParams(IEmailFormProcessor.TOKEN_SUMMARY_FAILURE_NUM,
String.valueOf(negCount));
buildContentParams(IEmailFormProcessor.TOKEN_EXECUTION_TIME,
nowString);
IEmailFormProcessor emailFormProcessor = CMS.getEmailFormProcessor();
String mailContent =
emailFormProcessor.getEmailContent(contentForm,
mContentParams);
mailSummary(mailContent);
}
}
/**
* Returns a list of configuration parameter names.
* The list is passed to the configuration console so instances of
* this implementation can be configured through the console.
*
* @return String array of configuration parameter names.
*/
public String[] getConfigParams() {
return (mConfigParams);
}
}