From 4a51a8f96715ffb2a42189b93b9fa91b453b8530 Mon Sep 17 00:00:00 2001 From: sg481n Date: Thu, 3 Aug 2017 17:39:12 -0400 Subject:  [AAF-21] Initial code import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia1dd196befd061f6ba0c2be6bf4456a30ea50f97 Signed-off-by: sg481n --- aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java | 787 +++++++++++++++++++++ 1 file changed, 787 insertions(+) create mode 100644 aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java (limited to 'aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java') diff --git a/aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java b/aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java new file mode 100644 index 0000000..9e5e77a --- /dev/null +++ b/aaf/src/src/main/java/com/att/cadi/cm/CmAgent.java @@ -0,0 +1,787 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aai + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * Copyright © 2017 Amdocs + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package com.att.cadi.cm; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import com.att.cadi.Access; +import com.att.cadi.Symm; +import com.att.cadi.aaf.client.ErrMessage; +import com.att.cadi.aaf.v2_0.AAFCon; +import com.att.cadi.aaf.v2_0.AAFConHttp; +import com.att.cadi.client.EnvAccess; +import com.att.cadi.client.Future; +import com.att.cadi.config.Config; +import com.att.cadi.http.HBasicAuthSS; +import com.att.inno.env.Data.TYPE; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.att.inno.env.util.Chrono; +import com.att.inno.env.util.Split; +import com.att.rosetta.env.RosettaDF; +import com.att.rosetta.env.RosettaEnv; + +import certman.v1_0.Artifacts; +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; +import certman.v1_0.CertificateRequest; + +public class CmAgent { + private static final String PRINT = "print"; + private static final String FILE = "file"; + private static final String PKCS12 = "pkcs12"; + private static final String JKS = "jks"; + private static final String SCRIPT="script"; + + private static final String CM_VER = "1.0"; + public static final int PASS_SIZE = 24; + private static int TIMEOUT; + + private static MyConsole cons; + + private static RosettaDF reqDF; + private static RosettaDF certDF; + private static RosettaDF artifactsDF; + private static ErrMessage errMsg; + private static Map placeArtifact; + private static RosettaEnv env; + + public static void main(String[] args) { + int exitCode = 0; + env = new RosettaEnv(Config.CADI_PROP_FILES,args); + Deque cmds = new ArrayDeque(); + for(String p : args) { + if(p.indexOf('=')<0) { + cmds.add(p); + } + } + + if(cmds.size()==0) { + System.out.println("Usage: java -jar cmd []*"); + System.out.println(" create []"); + System.out.println(" read []"); + System.out.println(" update []"); + System.out.println(" delete []"); + System.out.println(" copy [,]*"); + System.out.println(" place []"); + System.out.println(" showpass []"); + System.out.println(" check []"); + System.exit(1); + } + + TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000")); + cons = TheConsole.implemented()?new TheConsole():new SubStandardConsole(); + + try { + reqDF = env.newDataFactory(CertificateRequest.class); + artifactsDF = env.newDataFactory(Artifacts.class); + certDF = env.newDataFactory(CertInfo.class); + errMsg = new ErrMessage(env); + + placeArtifact = new HashMap(); + placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS)); + placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12)); + placeArtifact.put(FILE, new PlaceArtifactInFiles()); + placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out)); + placeArtifact.put(SCRIPT, new PlaceArtifactScripts()); + + Access access = new EnvAccess(env); + Trans trans = env.newTrans(); + try { + getProperty(env,false, Config.CM_URL,Config.CM_URL+": "); + String str=env.getProperty(Config.CADI_ALIAS); + if(str==null) { // ask for MechID pass + getProperty(env,false,Config.AAF_MECHID,"Your Identity: "); + getProperty(env,true,Config.AAF_MECHPASS,"Password: "); + } + AAFCon aafcon = new AAFConHttp(access,Config.CM_URL); + + String cmd = cmds.removeFirst(); + if("place".equals(cmd)) { + placeCerts(trans,aafcon,cmds); + } else if("create".equals(cmd)) { + createArtifact(trans, aafcon,cmds); + } else if("read".equals(cmd)) { + readArtifact(trans, aafcon, cmds); + } else if("copy".equals(cmd)) { + copyArtifact(trans, aafcon, cmds); + } else if("update".equals(cmd)) { + updateArtifact(trans, aafcon, cmds); + } else if("delete".equals(cmd)) { + deleteArtifact(trans, aafcon, cmds); + } else if("showpass".equals(cmd)) { + showPass(trans,aafcon,cmds); + } else if("check".equals(cmd)) { + try { + exitCode = check(trans,aafcon,cmds); + } catch (Exception e) { + exitCode = 1; + throw e; + } + } else { + cons.printf("Unknown command \"%s\"\n", cmd); + } + } finally { + StringBuilder sb = new StringBuilder(); + trans.auditTrail(4, sb, Trans.REMOTE); + if(sb.length()>0) { + trans.info().log("Trans Info\n",sb); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + if(exitCode!=0) { + System.exit(exitCode); + } + } + + private static String getProperty(Env env, boolean secure, String tag, String prompt, Object ... def) { + String value; + if((value=env.getProperty(tag))==null) { + if(secure) { + value = new String(cons.readPassword(prompt, def)); + } else { + value = cons.readLine(prompt,def).trim(); + } + if(value!=null) { + if(value.length()>0) { + env.setProperty(tag,value); + } else if(def.length==1) { + value=def[0].toString(); + env.setProperty(tag,value); + } + } + } + return value; + } + + private interface MyConsole { + public String readLine(String fmt, Object ... args); + public char[] readPassword(String fmt, Object ... args); + public void printf(String fmt, Object ...args); + } + + private static class TheConsole implements MyConsole { + @Override + public String readLine(String fmt, Object... args) { + String rv = System.console().readLine(fmt, args); + if(args.length>0 && args[0]!=null && rv.length()==0) { + rv = args[0].toString(); + } + return rv; + } + + @Override + public char[] readPassword(String fmt, Object... args) { + return System.console().readPassword(fmt, args); + } + + public static boolean implemented() { + return System.console()!=null; + } + + @Override + public void printf(String fmt, Object... args) { + System.console().printf(fmt, args); + } + } + + // Substandard, because System.in doesn't do Passwords.. + private static class SubStandardConsole implements MyConsole { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + @Override + public String readLine(String fmt, Object... args) { + String rv; + try { + System.out.printf(fmt,args); + rv = br.readLine(); + if(args.length==1 && rv.length()==0) { + rv = args[0].toString(); + } + } catch (IOException e) { + System.err.println("uh oh..."); + rv = ""; + } + return rv; + } + + @Override + public char[] readPassword(String fmt, Object... args) { + try { + System.out.printf(fmt,args); + return br.readLine().toCharArray(); + } catch (IOException e) { + System.err.println("uh oh..."); + return new char[0]; + } + } + + @Override + public void printf(String fmt, Object... args) { + System.out.printf(fmt, args); + } + } + +// private static class AutoData implements MyConsole { +//// private Env env; +// private Map data; +// +// @Override +// public String readLine(String fmt, Object... args) { +// String rv=data.get(fmt); +// return rv==null?"":rv; +// } +// +// @Override +// public char[] readPassword(String fmt, Object... args) { +// String rv=data.get(fmt); +// return rv==null?new char[0]:rv.toCharArray(); +// } +// +// @Override +// public void printf(String fmt, Object... args) { +// System.out.printf(fmt, args); +// } +// +// } +// + private static String mechID(Deque cmds) { + if(cmds.size()<1) { + String alias = env.getProperty(Config.CADI_ALIAS); + return alias!=null?alias:cons.readLine("MechID: "); + } + return cmds.removeFirst(); + } + + private static String machine(Deque cmds) throws UnknownHostException { + if(cmds.size()>0) { + return cmds.removeFirst(); + } else { + String mach = env.getProperty(Config.HOSTNAME); + return mach!=null?mach:InetAddress.getLocalHost().getHostName(); + } + } + + private static String[] machines(Deque cmds) { + String machines; + if(cmds.size()>0) { + machines = cmds.removeFirst(); + } else { + machines = cons.readLine("Machines (sep by ','): "); + } + return Split.split(',', machines); + } + + private static void createArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + Artifacts artifacts = new Artifacts(); + Artifact arti = new Artifact(); + artifacts.getArtifact().add(arti); + arti.setMechid(mechID!=null?mechID:cons.readLine("MechID: ")); + arti.setMachine(machine!=null?machine:cons.readLine("Machine (%s): ",InetAddress.getLocalHost().getHostName())); + arti.setCa(cons.readLine("CA: (%s): ","aaf")); + + String resp = cons.readLine("Types [file,jks,pkcs12] (%s): ", "jks"); + for(String s : Split.splitTrim(',', resp)) { + arti.getType().add(s); + } + // Always do Script + if(!resp.contains(SCRIPT)) { + arti.getType().add(SCRIPT); + } + + // Note: Sponsor is set on Creation by CM + String configRootName = AAFCon.reverseDomain(arti.getMechid()); + arti.setAppName(cons.readLine("AppName (%s): ",configRootName)); + arti.setDir(cons.readLine("Directory (%s): ", System.getProperty("user.dir"))); + arti.setOsUser(cons.readLine("OS User (%s): ", System.getProperty("user.name"))); + arti.setRenewDays(Integer.parseInt(cons.readLine("Renewal Days (%s):", "30"))); + arti.setNotification(toNotification(cons.readLine("Notification (mailto owner):", ""))); + + TimeTaken tt = trans.start("Create Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER).create("/cert/artifacts", artifactsDF, artifacts); + if(future.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",arti.getMechid(), arti.getMachine()); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + + private static String toNotification(String notification) { + if(notification==null) { + notification=""; + } else if(notification.length()>0) { + if(notification.indexOf(':')<0) { + notification = "mailto:" + notification; + } + } + return notification; + } + + + private static void readArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Read Artifact", Env.SUB); + try { + Future future = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(future.get(TIMEOUT)) { + boolean printed = false; + for(Artifact a : future.value.getArtifact()) { + cons.printf("MechID: %s\n",a.getMechid()); + cons.printf(" Sponsor: %s\n",a.getSponsor()); + cons.printf("Machine: %s\n",a.getMachine()); + cons.printf("CA: %s\n",a.getCa()); + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(String t : a.getType()) { + if(first) {first=false;} + else{sb.append(',');} + sb.append(t); + } + cons.printf("Types: %s\n",sb); + cons.printf("AppName: %s\n",a.getAppName()); + cons.printf("Directory: %s\n",a.getDir()); + cons.printf("O/S User: %s\n",a.getOsUser()); + cons.printf("Renew Days: %d\n",a.getRenewDays()); + cons.printf("Notification %s\n",a.getNotification()); + printed = true; + } + if(!printed) { + cons.printf("Artifact for %s %s does not exist", mechID, machine); + } + } else { + trans.error().log(errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + + private static void copyArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + String[] newmachs = machines(cmds); + if(newmachs==null || newmachs == null) { + trans.error().log("No machines listed to copy to"); + } else { + TimeTaken tt = trans.start("Copy Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(future.get(TIMEOUT)) { + boolean printed = false; + for(Artifact a : future.value.getArtifact()) { + for(String m : newmachs) { + a.setMachine(m); + Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, future.value); + if(fup.get(TIMEOUT)) { + trans.info().printf("Copy of %s %s successful to %s",mechID,machine,m); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(fup)); + } + + printed = true; + } + } + if(!printed) { + cons.printf("Artifact for %s %s does not exist", mechID, machine); + } + } else { + trans.error().log(errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + } + + private static void updateArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Update Artifact", Env.REMOTE); + try { + Future fread = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(fread.get(TIMEOUT)) { + Artifacts artifacts = new Artifacts(); + for(Artifact a : fread.value.getArtifact()) { + Artifact arti = new Artifact(); + artifacts.getArtifact().add(arti); + + cons.printf("For %s on %s\n", a.getMechid(),a.getMachine()); + arti.setMechid(a.getMechid()); + arti.setMachine(a.getMachine()); + arti.setCa(cons.readLine("CA: (%s): ",a.getCa())); + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(String t : a.getType()) { + if(first) {first=false;} + else{sb.append(',');} + sb.append(t); + } + + String resp = cons.readLine("Types [file,jks,pkcs12] (%s): ", sb); + for(String s : Split.splitTrim(',', resp)) { + arti.getType().add(s); + } + // Always do Script + if(!resp.contains(SCRIPT)) { + arti.getType().add(SCRIPT); + } + + // Note: Sponsor is set on Creation by CM + arti.setAppName(cons.readLine("AppName (%s): ",a.getAppName())); + arti.setDir(cons.readLine("Directory (%s): ", a.getDir())); + arti.setOsUser(cons.readLine("OS User (%s): ", a.getOsUser())); + arti.setRenewDays(Integer.parseInt(cons.readLine("Renew Days (%s):", a.getRenewDays()))); + arti.setNotification(toNotification(cons.readLine("Notification (%s):", a.getNotification()))); + + } + if(artifacts.getArtifact().size()==0) { + cons.printf("Artifact for %s %s does not exist", mechID, machine); + } else { + Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, artifacts); + if(fup.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",mechID,machine); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(fup)); + } + } + } else { + trans.error().printf("Call to AAF Certman failed, %s %s, %s", + errMsg.toMsg(fread),mechID,machine); + } + } finally { + tt.done(); + } + } + + private static void deleteArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechid = mechID(cmds); + String machine = mechID(cmds); + + TimeTaken tt = trans.start("Delete Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER) + .delete("/cert/artifacts/"+mechid+"/"+machine,"application/json" ); + + if(future.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",mechid,machine); + } else { + trans.error().printf("Call to AAF Certman failed, %s %s, %s", + errMsg.toMsg(future),mechid,machine); + } + } finally { + tt.done(); + } + } + + + + private static boolean placeCerts(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + boolean rv = false; + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Place Artifact", Env.REMOTE); + try { + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + cons.printf("There are no artifacts for %s %s", mechID, machine); + } else { + for(Artifact a : acf.value.getArtifact()) { + CertificateRequest cr = new CertificateRequest(); + cr.setMechid(a.getMechid()); + cr.setSponsor(a.getSponsor()); + cr.getFqdns().add(a.getMachine()); + Future f = aafcon.client(CM_VER) + .setQueryParams("withTrust") + .updateRespondString("/cert/" + a.getCa(),reqDF, cr); + if(f.get(TIMEOUT)) { + CertInfo capi = certDF.newData().in(TYPE.JSON).load(f.body()).asObject(); + for(String type : a.getType()) { + PlaceArtifact pa = placeArtifact.get(type); + if(pa!=null) { + if(rv = pa.place(trans, capi, a)) { + notifyPlaced(a,rv); + } + } + } + // Cover for the above multiple pass possibilities with some static Data, then clear per Artifact + ArtifactDir.clear(); + } else { + trans.error().log(errMsg.toMsg(f)); + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + } + } finally { + tt.done(); + } + return rv; + } + + private static void notifyPlaced(Artifact a, boolean rv) { + + + } + + private static void showPass(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Show Password", Env.REMOTE); + try { + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + cons.printf("No Artifacts found for %s on %s", mechID, machine); + } else { + String id = aafcon.defID(); + boolean allowed; + for(Artifact a : acf.value.getArtifact()) { + allowed = id!=null && (id.equals(a.getSponsor()) || + (id.equals(a.getMechid()) + && aafcon.securityInfo().defSS.getClass().isAssignableFrom(HBasicAuthSS.class))); + if(!allowed) { + Future pf = aafcon.client(CM_VER).read("/cert/may/" + + a.getAppName() + ".certman|"+a.getCa()+"|showpass","*/*"); + if(pf.get(TIMEOUT)) { + allowed = true; + } else { + trans.error().log(errMsg.toMsg(pf)); + } + } + if(allowed) { + File dir = new File(a.getDir()); + Properties props = new Properties(); + FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); + try { + props.load(fis); + fis.close(); + fis = new FileInputStream(new File(dir,a.getAppName()+".chal")); + props.load(fis); + } finally { + fis.close(); + } + + File f = new File(dir,a.getAppName()+".keyfile"); + if(f.exists()) { + Symm symm = Symm.obtain(f); + + for(Iterator> iter = props.entrySet().iterator(); iter.hasNext();) { + Entry en = iter.next(); + if(en.getValue().toString().startsWith("enc:???")) { + System.out.printf("%s=%s\n", en.getKey(), symm.depass(en.getValue().toString())); + } + } + } else { + trans.error().printf("%s.keyfile must exist to read passwords for %s on %s", + f.getCanonicalPath(),a.getMechid(), a.getMachine()); + } + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + } + } finally { + tt.done(); + } + + } + + + /** + * Check returns Error Codes, so that Scripts can know what to do + * + * 0 - Check Complete, nothing to do + * 1 - General Error + * 2 - Error for specific Artifact - read check.msg + * 10 - Certificate Updated - check.msg is email content + * + * @param trans + * @param aafcon + * @param cmds + * @return + * @throws Exception + */ + private static int check(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + int exitCode=1; + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Check Certificate", Env.REMOTE); + try { + + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + cons.printf("No Artifacts found for %s on %s", mechID, machine); + } else { + String id = aafcon.defID(); + GregorianCalendar now = new GregorianCalendar(); + for(Artifact a : acf.value.getArtifact()) { + if(id.equals(a.getMechid())) { + File dir = new File(a.getDir()); + Properties props = new Properties(); + FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); + try { + props.load(fis); + } finally { + fis.close(); + } + + String prop; + File f; + + if((prop=props.getProperty(Config.CADI_KEYFILE))==null || + !(f=new File(prop)).exists()) { + trans.error().printf("Keyfile must exist to check Certificates for %s on %s", + a.getMechid(), a.getMachine()); + } else { + String ksf = props.getProperty(Config.CADI_KEYSTORE); + String ksps = props.getProperty(Config.CADI_KEYSTORE_PASSWORD); + if(ksf==null || ksps == null) { + trans.error().printf("Properties %s and %s must exist to check Certificates for %s on %s", + Config.CADI_KEYSTORE, Config.CADI_KEYSTORE_PASSWORD,a.getMechid(), a.getMachine()); + } else { + KeyStore ks = KeyStore.getInstance("JKS"); + Symm symm = Symm.obtain(f); + + fis = new FileInputStream(ksf); + try { + ks.load(fis,symm.depass(ksps).toCharArray()); + } finally { + fis.close(); + } + X509Certificate cert = (X509Certificate)ks.getCertificate(mechID); + String msg = null; + + if(cert==null) { + msg = String.format("X509Certificate does not exist for %s on %s in %s", + a.getMechid(), a.getMachine(), ksf); + trans.error().log(msg); + exitCode = 2; + } else { + GregorianCalendar renew = new GregorianCalendar(); + renew.setTime(cert.getNotAfter()); + renew.add(GregorianCalendar.DAY_OF_MONTH,-1*a.getRenewDays()); + if(renew.after(now)) { + msg = String.format("As of %s, X509Certificate for %s on %s, expiration %s is still within %d renewal days.\n", + Chrono.dateOnlyStamp(), a.getMechid(), a.getMachine(), cert.getNotAfter(),a.getRenewDays()); + trans.info().log(msg); + exitCode = 0; // OK + } else { + trans.info().printf("X509Certificate for %s on %s expiration, %s, needs Renewal.\n", + a.getMechid(), a.getMachine(),cert.getNotAfter()); + cmds.offerLast(mechID); + cmds.offerLast(machine); + if(placeCerts(trans,aafcon,cmds)) { + msg = String.format("X509Certificate for %s on %s has been renewed. Ensure services using are refreshed.\n", + a.getMechid(), a.getMachine()); + exitCode = 10; // Refreshed + } else { + msg = String.format("X509Certificate for %s on %s attempted renewal, but failed. Immediate Investigation is required!\n", + a.getMechid(), a.getMachine()); + exitCode = 1; // Error Renewing + } + } + } + if(msg!=null) { + FileOutputStream fos = new FileOutputStream(a.getDir()+'/'+a.getAppName()+".msg"); + try { + fos.write(msg.getBytes()); + } finally { + fos.close(); + } + } + } + + } + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + exitCode=1; + } + } finally { + tt.done(); + } + return exitCode; + } + +} + + + + -- cgit 1.2.3-korg