1 13 package org.ejbca.core.model.services.workers; 14 15 import java.security.cert.X509Certificate ; 16 import java.sql.Connection ; 17 import java.sql.PreparedStatement ; 18 import java.sql.ResultSet ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Date ; 22 import java.util.Iterator ; 23 24 import org.apache.log4j.Logger; 25 import org.ejbca.core.ejb.JNDINames; 26 import org.ejbca.core.ejb.ca.store.CertificateDataBean; 27 import org.ejbca.core.model.InternalResources; 28 import org.ejbca.core.model.ra.UserDataVO; 29 import org.ejbca.core.model.services.BaseWorker; 30 import org.ejbca.core.model.services.ServiceExecutionFailedException; 31 import org.ejbca.core.model.services.actions.MailActionInfo; 32 import org.ejbca.util.Base64; 33 import org.ejbca.util.CertTools; 34 import org.ejbca.util.JDBCUtil; 35 import org.ejbca.util.NotificationParamGen; 36 37 47 public class CertificateExpirationNotifierWorker extends BaseWorker { 48 49 private static final Logger log = Logger.getLogger(CertificateExpirationNotifierWorker.class); 50 51 private static final InternalResources intres = InternalResources.getInstance(); 52 53 54 public static final String PROP_CAIDSTOCHECK = "worker.emailexpiration.caidstocheck"; 55 56 57 public static final String PROP_TIMEBEFOREEXPIRING = "worker.emailexpiration.timebeforeexpiring"; 58 59 60 public static final String PROP_TIMEUNIT = "worker.emailexpiration.timeunit"; 61 62 63 public static final String PROP_SENDTOENDUSERS = "worker.emailexpiration.sendtoendusers"; 64 65 66 public static final String PROP_SENDTOADMINS = "worker.emailexpiration.sendtoadmins"; 67 68 69 public static final String PROP_USERSUBJECT = "worker.emailexpiration.usersubject"; 70 71 73 public static final String PROP_USERMESSAGE = "worker.emailexpiration.usermessage"; 74 75 76 public static final String PROP_ADMINSUBJECT = "worker.emailexpiration.adminsubject"; 77 78 80 public static final String PROP_ADMINMESSAGE = "worker.emailexpiration.adminmessage"; 81 82 83 public static final String UNIT_SECONDS = "SECONDS"; 84 public static final String UNIT_MINUTES = "MINUTES"; 85 public static final String UNIT_HOURS = "HOURS"; 86 public static final String UNIT_DAYS = "DAYS"; 87 88 public static final int UNITVAL_SECONDS = 1; 89 public static final int UNITVAL_MINUTES = 60; 90 public static final int UNITVAL_HOURS = 3600; 91 public static final int UNITVAL_DAYS = 86400; 92 93 public static final String [] AVAILABLE_UNITS = {UNIT_SECONDS, UNIT_MINUTES, UNIT_HOURS, UNIT_DAYS}; 94 public static final int[] AVAILABLE_UNITSVALUES = {UNITVAL_SECONDS, UNITVAL_MINUTES, UNITVAL_HOURS, UNITVAL_DAYS}; 95 96 private transient Collection cAIdsToCheck = null; 97 private transient long timeBeforeExpire = -1; 98 private transient String endUserSubject = null; 99 private transient String adminSubject = null; 100 private transient String endUserMessage = null; 101 private transient String adminMessage = null; 102 103 private class EmailCertData{ 104 105 private String fingerPrint = null; 106 private MailActionInfo actionInfo = null; 107 108 public EmailCertData(String fingerPrint, MailActionInfo actionInfo) { 109 super(); 110 this.fingerPrint = fingerPrint; 111 this.actionInfo = actionInfo; 112 } 113 114 public String getFingerPrint() { 115 return fingerPrint; 116 } 117 118 public MailActionInfo getActionInfo() { 119 return actionInfo; 120 } 121 122 } 123 124 130 public void work() throws ServiceExecutionFailedException { 131 log.debug(">CertificateExpirationNotifierWorker.work started"); 132 133 ArrayList userEmailQueue = new ArrayList (); 134 ArrayList adminEmailQueue = new ArrayList (); 135 136 String cASelectString = ""; 138 if(getCAIdsToCheck().size() >0){ 139 Iterator iter = getCAIdsToCheck().iterator(); 140 while(iter.hasNext()){ 141 String caid = (String ) iter.next(); 142 String cadn = getCAAdminSession().getCAInfo(getAdmin(), Integer.parseInt(caid)).getSubjectDN(); 143 if(cASelectString.equals("")){ 144 cASelectString = "issuerDN='" + cadn +"' "; 145 }else{ 146 cASelectString += " OR issuerDN='" + cadn +"' "; 147 } 148 } 149 150 String checkDate = "expireDate <= " + ((new Date ()).getTime() + getTimeBeforeExpire()); 151 String statuses = "status=" +CertificateDataBean.CERT_ACTIVE; 152 153 Connection con = null; 155 PreparedStatement ps = null; 156 PreparedStatement updateStatus = null; 157 ResultSet result = null; 158 159 try{ 160 con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE); 161 ps = con.prepareStatement("SELECT DISTINCT fingerprint, base64Cert, username" 162 + " FROM CertificateData WHERE (" 163 + cASelectString + ") AND (" 164 + checkDate + ") AND (" 165 + statuses + ")"); 166 167 result = ps.executeQuery(); 168 169 while(result.next()){ 170 String fingerprint = result.getString(1); 172 String certBase64 = result.getString(2); 173 String username = result.getString(3); 174 X509Certificate cert = CertTools.getCertfromByteArray(Base64.decode(certBase64.getBytes())); 175 176 UserDataVO userData = getUserAdminSession().findUser(getAdmin(), username); 177 if(userData != null){ 178 String userDN = userData.getDN(); 179 180 if(isSendToEndUsers()){ 181 NotificationParamGen paramGen = new NotificationParamGen(userDN,cert); 182 if(userData.getEmail() == null || userData.getEmail().trim().equals("")){ 183 String msg = intres.getLocalizedMessage("services.certexpireworker.errornoemail", username); 184 log.info(msg); 185 }else{ 186 String message = NotificationParamGen.interpolate(paramGen.getParams(), getEndUserMessage()); 188 MailActionInfo mailActionInfo = new MailActionInfo(userData.getEmail(),getEndUserSubject(), message); 189 userEmailQueue.add(new EmailCertData(fingerprint,mailActionInfo)); 190 } 191 } 192 } 193 if(isSendToAdmins()){ 194 NotificationParamGen paramGen = new NotificationParamGen(cert.getSubjectDN().toString(),cert); 196 String message = NotificationParamGen.interpolate(paramGen.getParams(), getAdminMessage()); 197 MailActionInfo mailActionInfo = new MailActionInfo(null,getAdminSubject(), message); 198 adminEmailQueue.add(new EmailCertData(fingerprint,mailActionInfo)); 199 } 200 201 202 } 203 204 205 206 } catch (Exception fe) { 207 fe.printStackTrace(); 208 throw new ServiceExecutionFailedException(fe); 209 } finally { 210 if(updateStatus != null){ 211 JDBCUtil.close(updateStatus); 212 } 213 JDBCUtil.close(con, ps, result); 214 } 215 216 217 if(isSendToEndUsers()){ 218 sendEmails(userEmailQueue); 219 } 220 if(isSendToAdmins()){ 221 sendEmails(adminEmailQueue); 222 } 223 224 } 225 log.debug("<CertificateExpirationNotifierWorker.work ended"); 226 } 227 228 private void sendEmails(ArrayList queue) throws ServiceExecutionFailedException{ 229 Iterator iter = queue.iterator(); 230 while(iter.hasNext()){ 231 Connection con = null; 232 PreparedStatement updateStatus = null; 233 try{ 234 con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE); 235 EmailCertData next = (EmailCertData) iter.next(); 236 getAction().performAction(next.getActionInfo()); 237 updateStatus = con.prepareStatement("UPDATE CertificateData SET status=" + CertificateDataBean.CERT_NOTIFIEDABOUTEXPIRATION +" WHERE fingerprint='" + next.getFingerPrint() + "'"); 238 updateStatus.execute(); 239 } catch (Exception fe) { 240 fe.printStackTrace(); 241 throw new ServiceExecutionFailedException(fe); 242 } finally { 243 if(updateStatus != null){ 244 JDBCUtil.close(updateStatus); 245 } 246 if(con != null){ 247 JDBCUtil.close(con); 248 } 249 } 250 } 251 } 252 253 private Collection getCAIdsToCheck(){ 254 if(cAIdsToCheck == null){ 255 cAIdsToCheck = new ArrayList (); 256 String [] canames = properties.getProperty(PROP_CAIDSTOCHECK).split(";"); 257 for(int i=0;i<canames.length;i++ ){ 258 cAIdsToCheck.add(canames[i]); 259 } 260 } 261 return cAIdsToCheck; 262 } 263 264 private long getTimeBeforeExpire() throws ServiceExecutionFailedException{ 265 if(timeBeforeExpire == -1){ 266 String unit = properties.getProperty(PROP_TIMEUNIT); 267 if(unit == null){ 268 String msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "UNIT"); 269 throw new ServiceExecutionFailedException(msg); 270 } 271 int unitval = 0; 272 for(int i=0;i<AVAILABLE_UNITS.length;i++){ 273 if(AVAILABLE_UNITS[i].equalsIgnoreCase(unit)){ 274 unitval = AVAILABLE_UNITSVALUES[i]; 275 break; 276 } 277 } 278 if(unitval == 0){ 279 String msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "UNIT"); 280 throw new ServiceExecutionFailedException(msg); 281 } 282 283 String value = properties.getProperty(PROP_TIMEBEFOREEXPIRING); 284 int intvalue = 0; 285 try{ 286 intvalue = Integer.parseInt(value); 287 }catch(NumberFormatException e){ 288 String msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "VALUE"); 289 throw new ServiceExecutionFailedException(msg); 290 } 291 292 if(intvalue == 0){ 293 String msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "VALUE"); 294 throw new ServiceExecutionFailedException(msg); 295 } 296 timeBeforeExpire = intvalue * unitval; 297 } 298 299 return timeBeforeExpire * 1000; 300 } 301 302 private String getAdminMessage() { 303 if(adminMessage == null){ 304 adminMessage = properties.getProperty(PROP_ADMINMESSAGE,"No Message Configured"); 305 } 306 return adminMessage; 307 } 308 309 private String getAdminSubject() { 310 if(adminSubject == null){ 311 adminSubject = properties.getProperty(PROP_ADMINSUBJECT,"No Subject Configured"); 312 } 313 314 return adminSubject; 315 } 316 317 private String getEndUserMessage() { 318 if(endUserMessage == null){ 319 endUserMessage = properties.getProperty(PROP_USERMESSAGE,"No Message Configured"); 320 } 321 322 return endUserMessage; 323 } 324 325 private String getEndUserSubject() { 326 if(endUserSubject == null){ 327 endUserSubject = properties.getProperty(PROP_USERSUBJECT,"No Subject Configured"); 328 } 329 330 return endUserSubject; 331 } 332 333 private boolean isSendToAdmins() { 334 return properties.getProperty(PROP_SENDTOADMINS,"FALSE").equalsIgnoreCase("TRUE"); 335 } 336 337 private boolean isSendToEndUsers() { 338 return properties.getProperty(PROP_SENDTOENDUSERS,"FALSE").equalsIgnoreCase("TRUE"); 339 } 340 341 342 343 } 344 | Popular Tags |