add check and showpass
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / configure / Agent.java
index 3c8719b..ef73ada 100644 (file)
@@ -24,29 +24,35 @@ package org.onap.aaf.cadi.configure;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.net.ConnectException;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.file.Files;
+import java.security.KeyPair;
 import java.security.KeyStore;
 import java.security.cert.X509Certificate;
 import java.util.ArrayDeque;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Deque;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
+import java.util.TreeMap;
 
 import org.onap.aaf.cadi.CadiException;
 import org.onap.aaf.cadi.CmdLine;
 import org.onap.aaf.cadi.LocatorException;
 import org.onap.aaf.cadi.PropAccess;
 import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.aaf.Defaults;
 import org.onap.aaf.cadi.aaf.client.ErrMessage;
 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
 import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;
@@ -58,6 +64,7 @@ import org.onap.aaf.cadi.config.SecurityInfoC;
 import org.onap.aaf.cadi.http.HBasicAuthSS;
 import org.onap.aaf.cadi.locator.SingleEndpointLocator;
 import org.onap.aaf.cadi.sso.AAFSSO;
+import org.onap.aaf.cadi.util.Chmod;
 import org.onap.aaf.cadi.util.FQI;
 import org.onap.aaf.misc.env.APIException;
 import org.onap.aaf.misc.env.Data.TYPE;
@@ -82,8 +89,8 @@ public class Agent {
        private static final String HASHES = "################################################################";
        private static final String PRINT = "print";
        private static final String FILE = "file";
-       private static final String PKCS12 = "pkcs12";
-       private static final String JKS = "jks";
+       public static final String PKCS12 = "pkcs12";
+       public static final String JKS = "jks";
        private static final String SCRIPT="script";
        
        private static final String CM_VER = "1.0";
@@ -100,167 +107,203 @@ public class Agent {
        private static RosettaEnv env;
        
        private static boolean doExit;
+       private static AAFCon<?> aafcon;
 
        public static void main(String[] args) {
                int exitCode = 0;
                doExit = true;
-               try {
-                       AAFSSO aafsso;
-                       PropAccess access;
-                       
-                       if(args.length>0 && args[0].equals("validate")) {
-                               int idx = args[1].indexOf('=');
-                               aafsso = null;
-                               access = new PropAccess(
-                                                       (idx<0?Config.CADI_PROP_FILES:args[1].substring(0, idx))+
-                                                       '='+
-                                                   (idx<0?args[1]:args[1].substring(idx+1)));
-                       } else {
-                               aafsso= new AAFSSO(args, new AAFSSO.ProcessArgs() {
-                                       @Override
-                                       public Properties process(String[] args, Properties props) {
-                                               if(args.length>1) {
-                                                       if (!args[0].equals("genkeypair")) {
-                                                               props.put("aaf_id", args[1]);
-                                                       }       
-                                               }
-                                               return props;
-                                       }
-                               });
-                               access = aafsso.access();
+               if(args.length>0 && "cadi".equals(args[0])) {
+                       String[] newArgs = new String[args.length-1];
+                       System.arraycopy(args, 1, newArgs, 0, newArgs.length);
+                       if(newArgs.length==0) {
+                               System.out.println(HASHES);
+                               System.out.println("Note: Cadi CmdLine is a separate component.  When running with\n\t"
+                                               + "Agent, always preface with \"cadi\",\n\tex: cadi keygen [<keyfile>]");
+                               System.out.println(HASHES);
                        }
+                       CmdLine.main(newArgs);
+               } else {
+                       try {
+                               AAFSSO aafsso=null;
+                               PropAccess access;
                                
-                       if(aafsso!=null && aafsso.loginOnly()) {
-                               aafsso.setLogDefault();
-                               aafsso.writeFiles();
-                               System.out.println("AAF SSO information created in ~/.aaf");
-                       } else {
-                               env = new RosettaEnv(access.getProperties());
-                               Deque<String> cmds = new ArrayDeque<String>();
-                               for(String p : args) {
-                                       if("-noexit".equalsIgnoreCase(p)) {
-                                               doExit = false;
-                                       } else if(p.indexOf('=') < 0) {
-                                               cmds.add(p);
-                                       }
+                               if(args.length>1 && args[0].equals("validate") ) {
+                                       int idx = args[1].indexOf('=');
+                                       aafsso = null;
+                                       access = new PropAccess(
+                                                               (idx<0?Config.CADI_PROP_FILES:args[1].substring(0, idx))+
+                                                               '='+
+                                                           (idx<0?args[1]:args[1].substring(idx+1)));
+                               } else {
+                                       aafsso= new AAFSSO(args, new AAFSSO.ProcessArgs() {
+                                               @Override
+                                               public Properties process(String[] args, Properties props) {
+                                                       if(args.length>1) {
+                                                               if (!args[0].equals("keypairgen")) {
+                                                                       props.put("aaf_id", args[1]);
+                                                               }       
+                                                       }
+                                                       return props;
+                                               }
+                                       });
+                                       access = aafsso.access();
                                }
-                               
-                               if(cmds.size()==0) {
+                                       
+                               if(aafsso!=null && aafsso.loginOnly()) {
                                        aafsso.setLogDefault();
-                                       // NOTE: CHANGE IN CMDS should be reflected in AAFSSO constructor, to get FQI->aaf-id or not
-                                       System.out.println("Usage: java -jar <cadi-aaf-*-full.jar> cmd [<tag=value>]*");
-                                       System.out.println("   create   <FQI> [<machine>]");
-                                       System.out.println("   read     <FQI> [<machine>]");
-                                       System.out.println("   update   <FQI> [<machine>]");
-                                       System.out.println("   delete   <FQI> [<machine>]");
-                                       System.out.println("   copy     <FQI> <machine> <newmachine>[,<newmachine>]*");
-                                       System.out.println("   place    <FQI> [<machine>]");
-                                       System.out.println("   showpass <FQI> [<machine>]");
-                                       System.out.println("   check    <FQI> [<machine>]");
-                                       System.out.println("   config   <FQI>");
-                                       System.out.println("   validate <FQI>.props>");
-                                       System.out.println("   genkeypair");
-                                       if (doExit) {
-                                               System.exit(1);
+                                       aafsso.writeFiles();
+                                       System.out.println("AAF SSO information created in ~/.aaf");
+                               } else {
+                                       env = new RosettaEnv(access.getProperties());
+                                       Deque<String> cmds = new ArrayDeque<String>();
+                                       for(String p : args) {
+                                               if("-noexit".equalsIgnoreCase(p)) {
+                                                       doExit = false;
+                                               } else if(p.indexOf('=') < 0) {
+                                                       cmds.add(p);
+                                               }
                                        }
-                               }
+                                       
+                                       if(cmds.size()==0) {
+                                               if(aafsso!=null) {
+                                                       aafsso.setLogDefault();
+                                               }
+                                               // NOTE: CHANGE IN CMDS should be reflected in AAFSSO constructor, to get FQI->aaf-id or not
+                                               System.out.println("Usage: java -jar <cadi-aaf-*-full.jar> cmd [<tag=value>]*");
+                                               System.out.println("   create     <FQI> [<machine>]");
+                                               System.out.println("   read       <FQI> [<machine>]");
+                                               System.out.println("   update     <FQI> [<machine>]");
+                                               System.out.println("   delete     <FQI> [<machine>]");
+                                               System.out.println("   copy       <FQI> <machine> <newmachine>[,<newmachine>]*");
+                                               System.out.println("   place      <FQI> [<machine>]");
+                                               System.out.println("   showpass   <FQI> [<machine>]");
+                                               System.out.println("   check      <FQI> [<machine>]");
+                                               System.out.println("   keypairgen <FQI>");
+                                               System.out.println("   config     <FQI>");
+                                               System.out.println("   validate   <NS>.props>");
+                                               System.out.println("   --- Additional Tool Access ---");
+                                               System.out.println("     ** Type with no params for Tool Help");
+                                               System.out.println("     ** If using with Agent, preface with \"cadi\"");
+                                               System.out.println("   cadi <cadi tool params, see -?>");
+                                               
+                                               if (doExit) {
+                                                       System.exit(1);
+                                               }
+                                       }
+                                       
+                                       TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000"));
                                
-                               TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000"));
-                       
-                               reqDF = env.newDataFactory(CertificateRequest.class);
-                               artifactsDF = env.newDataFactory(Artifacts.class);
-                               certDF = env.newDataFactory(CertInfo.class);
-                               configDF = env.newDataFactory(Configuration.class);
-                               permDF = env.newDataFactory(Perms.class);
-                               errMsg = new ErrMessage(env);
+                                       reqDF = env.newDataFactory(CertificateRequest.class);
+                                       artifactsDF = env.newDataFactory(Artifacts.class);
+                                       certDF = env.newDataFactory(CertInfo.class);
+                                       configDF = env.newDataFactory(Configuration.class);
+                                       permDF = env.newDataFactory(Perms.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());
+                                       
+                                       Trans trans = env.newTrans();
+                                       String token;
+                                       if((token=access.getProperty("oauth_token"))!=null) {
+                                               trans.setProperty("oauth_token", token);
+                                       }
+                                       try {
+                                               if(aafsso!=null) {
+                                               // show Std out again
+                                                       aafsso.setLogDefault();
+                                                       aafsso.setStdErrDefault();
+                                                       
+                                                       // if CM_URL can be obtained, add to sso.props, if written
+                                                       String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": ");
+                                                       if(cm_url!=null) {
+                                                               aafsso.addProp(Config.CM_URL, cm_url);
+                                                       }
+                                                       aafsso.writeFiles();
+                                               }
        
-                               placeArtifact = new HashMap<String,PlaceArtifact>();
-                               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());
-                               
-                               Trans trans = env.newTrans();
-                               String token;
-                               if((token=access.getProperty("oauth_token"))!=null) {
-                                       trans.setProperty("oauth_token", token);
-                               }
-                               try {
-                                       if(aafsso!=null) {
-                                       // show Std out again
-                                               aafsso.setLogDefault();
-                                               aafsso.setStdErrDefault();
                                                
-                                               // if CM_URL can be obtained, add to sso.props, if written
-                                               String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": ");
-                                               if(cm_url!=null) {
-                                                       aafsso.addProp(Config.CM_URL, cm_url);
+       
+                                               String cmd = cmds.removeFirst();
+                                               switch(cmd) {
+                                                       case "place":
+                                                               placeCerts(trans,aafcon(access),cmds);
+                                                               break;
+                                                       case "create":
+                                                               createArtifact(trans, aafcon(access),cmds);
+                                                               break;
+                                                       case "read":
+                                                               readArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "copy":
+                                                               copyArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "update":
+                                                               updateArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "delete":
+                                                               deleteArtifact(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "showpass":
+                                                               showPass(trans, aafcon(access), cmds);
+                                                               break;
+                                                       case "keypairgen":
+                                                               keypairGen(trans, access, cmds);
+                                                               break;
+                                                       case "config":
+                                                               if(access.getProperty(Config.CADI_PROP_FILES)!=null) {
+                                                                       // Get Properties from initialization Prop Files
+                                                                       config(trans,access,null,cmds);
+                                                               } else {
+                                                                       // Get Properties from existing AAF Instance
+                                                                       config(trans,access,aafcon(access),cmds);
+                                                               }
+                                                               break;
+                                                       case "validate":
+                                                               validate(access);
+                                                               break;
+                                                       case "check":
+                                                               try {
+                                                                       exitCode = check(trans,aafcon(access),cmds);
+                                                               } catch (Exception e) {
+                                                                       exitCode = 1;
+                                                                       throw e;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd);
                                                }
-                                               aafsso.writeFiles();
+                                       } finally {
+                                               StringBuilder sb = new StringBuilder();
+                               trans.auditTrail(4, sb, Trans.REMOTE);
+                               if(sb.length()>0) {
+                                       trans.info().log("Trans Info\n",sb);
+                               }
                                        }
-
-                                       AAFCon<?> aafcon = new AAFConHttp(access,Config.CM_URL);
-
-                                       String cmd = cmds.removeFirst();
-                                       switch(cmd) {
-                                               case "place":
-                                                       placeCerts(trans,aafcon,cmds);
-                                                       break;
-                                               case "create":
-                                                       createArtifact(trans, aafcon,cmds);
-                                                       break;
-                                               case "read":
-                                                       readArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "copy":
-                                                       copyArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "update":
-                                                       updateArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "delete":
-                                                       deleteArtifact(trans, aafcon, cmds);
-                                                       break;
-                                               case "showpass":
-                                                       showPass(trans, aafcon, cmds);
-                                                       break;
-                                               case "config":
-                                                       initConfig(trans,access,aafcon,cmds);
-                                                       break;
-                                               case "validate":
-                                                       validate(access);
-                                                       break;
-                                               case "check":
-                                                       try {
-                                                               exitCode = check(trans,aafcon,cmds);
-                                                       } catch (Exception e) {
-                                                               exitCode = 1;
-                                                               throw e;
-                                                       }
-                                                       break;
-                                               default:
-                                                       AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd);
+                                       if(aafsso!=null) {
+                                               aafsso.close();
                                        }
-                               } finally {
-                                       StringBuilder sb = new StringBuilder();
-                       trans.auditTrail(4, sb, Trans.REMOTE);
-                       if(sb.length()>0) {
-                               trans.info().log("Trans Info\n",sb);
-                       }
-                               }
-                               if(aafsso!=null) {
-                                       aafsso.close();
                                }
+                       } catch (Exception e) {
+                               e.printStackTrace();
                        }
-               } catch (Exception e) {
-                       e.printStackTrace();
                }
                if(exitCode != 0 && doExit) {
                        System.exit(exitCode);
                }
        }
 
+       private static synchronized AAFCon<?> aafcon(PropAccess access) throws APIException, CadiException, LocatorException {
+               if(aafcon==null) {
+                       aafcon = new AAFConHttp(access,Config.CM_URL);
+               }
+               return aafcon;
+       }
+
        private static String getProperty(PropAccess pa, Env env, boolean secure, String tag, String prompt, Object ... def) {
                String value;
                if((value=pa.getProperty(tag))==null) {
@@ -286,7 +329,7 @@ public class Agent {
        private static String fqi(Deque<String> cmds) {
                if(cmds.size()<1) {
                        String alias = env.getProperty(Config.CADI_ALIAS);
-                       return alias!=null?alias:AAFSSO.cons.readLine("MechID: ");
+                       return alias!=null?alias:AAFSSO.cons.readLine("AppID: ");
                }
                return cmds.removeFirst();      
        }
@@ -311,17 +354,17 @@ public class Agent {
        }
 
        private static void createArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {
-               String mechID = fqi(cmds);
-               String machine = machine(cmds);
+               final String mechID = fqi(cmds);
+               final String machine = machine(cmds);
 
                Artifacts artifacts = new Artifacts();
                Artifact arti = new Artifact();
                artifacts.getArtifact().add(arti);
-               arti.setMechid(mechID!=null?mechID:AAFSSO.cons.readLine("MechID: "));
+               arti.setMechid(mechID!=null?mechID:AAFSSO.cons.readLine("AppID: "));
                arti.setMachine(machine!=null?machine:AAFSSO.cons.readLine("Machine (%s): ",InetAddress.getLocalHost().getHostName()));
                arti.setCa(AAFSSO.cons.readLine("CA: (%s): ","aaf"));
                
-               String resp = AAFSSO.cons.readLine("Types [file,jks,script] (%s): ", "jks");
+               String resp = AAFSSO.cons.readLine("Types [file,pkcs12,jks,script] (%s): ", PKCS12);
                for(String s : Split.splitTrim(',', resp)) {
                        arti.getType().add(s);
                }
@@ -376,7 +419,7 @@ public class Agent {
                        if(future.get(TIMEOUT)) {
                                boolean printed = false;
                                for(Artifact a : future.value.getArtifact()) {
-                                       AAFSSO.cons.printf("MechID:          %s\n",a.getMechid()); 
+                                       AAFSSO.cons.printf("AppID:          %s\n",a.getMechid()); 
                                        AAFSSO.cons.printf("  Sponsor:       %s\n",a.getSponsor()); 
                                        AAFSSO.cons.printf("Machine:         %s\n",a.getMachine()); 
                                        AAFSSO.cons.printf("CA:              %s\n",a.getCa()); 
@@ -607,7 +650,7 @@ public class Agent {
                                // Have to wait for JDK 1.7 source...
                                //switch(artifact.getType()) {
                                if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) {
-                                       AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine);
+                                       AAFSSO.cons.printf("No Artifacts found for %s on %s ", mechID, machine);
                                } else {
                                        String id = aafcon.defID();
                                        boolean allowed;
@@ -617,7 +660,7 @@ public class Agent {
                                                                                && aafcon.securityInfo().defSS.getClass().isAssignableFrom(HBasicAuthSS.class)));
                                                if(!allowed) {
                                                        Future<String> pf = aafcon.client(CM_VER).read("/cert/may/" + 
-                                                                       a.getNs() + ".certman|"+a.getCa()+"|showpass","*/*");
+                                                                       a.getNs()+"|certman|"+a.getCa()+"|showpass","*/*");
                                                        if(pf.get(TIMEOUT)) {
                                                                allowed = true;
                                                        } else {
@@ -663,10 +706,31 @@ public class Agent {
 
        }
        
+       private static void keypairGen(final Trans trans, final PropAccess access, final Deque<String> cmds) throws IOException {
+               final String fqi = fqi(cmds);
+               final String ns = FQI.reverseDomain(fqi);
+               File dir = new File(access.getProperty(Config.CADI_ETCDIR,".")); // default to current Directory
+               File f = new File(dir,ns+".key");
+               
+               if(f.exists()) {
+                       String line = AAFSSO.cons.readLine("%s exists. Overwrite? (y/n): ", f.getCanonicalPath());
+                       if(!"Y".equalsIgnoreCase(line)) {
+                               System.out.println("Canceling...");
+                               return;
+                       }
+               }
+               
+               KeyPair kp = Factory.generateKeyPair(trans);
+               ArtifactDir.write(f, Chmod.to400, Factory.toString(trans, kp.getPrivate()));
+               System.out.printf("Wrote %s\n", f.getCanonicalFile());
 
-       private static void initConfig(Trans trans, PropAccess pa, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {
+               f=new File(dir,ns+".pubkey");
+               ArtifactDir.write(f, Chmod.to644, Factory.toString(trans, kp.getPublic()));
+               System.out.printf("Wrote %s\n", f.getCanonicalFile());
+       }
+       
+       private static void config(Trans trans, PropAccess pa, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {
                final String fqi = fqi(cmds);
-               final String locator = getProperty(pa,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: ");
                final String rootFile = FQI.reverseDomain(fqi);
                final File dir = new File(pa.getProperty(Config.CADI_ETCDIR, "."));
                if(dir.exists()) {
@@ -694,7 +758,7 @@ public class Agent {
                                        psProps.print("# Configuration File generated on ");
                                        psProps.println(new Date().toString());
                                        psProps.println(HASHES);
-                                       for(String tag : new String[] {Config.CADI_LATITUDE,Config.CADI_LONGITUDE}) {
+                                       for(String tag : LOC_TAGS) {
                                                psProps.print(tag);
                                                psProps.print('=');
                                                psProps.println(getProperty(pa, trans, false, tag, "%s: ",tag));
@@ -728,42 +792,56 @@ public class Agent {
                                        if(!fkf.exists()) {
                                                CmdLine.main(new String[] {"keygen",fkf.toString()});
                                        }
-                                       psCredProps.print("cadi_keyfile=");
-                                       psCredProps.println(fkf.getCanonicalPath());
-                                       
-                                       psCredProps.print(Config.AAF_APPID);
-                                       psCredProps.print('=');
-                                       psCredProps.println(fqi);
-                                       
                                        Symm filesymm = Symm.obtain(fkf);
-                                       psCredProps.print(Config.AAF_APPPASS);
-                                       psCredProps.print("=enc:");
-                                       String ps = pa.decrypt(pa.getProperty(Config.AAF_APPPASS), false);
-                                       ps = filesymm.enpass(ps);
-                                       psCredProps.println(ps);
+                                       Map<String,String> normal = new TreeMap<>();
+                                       Map<String,String> creds = new TreeMap<>();
+
+                                       directedPut(pa, filesymm, normal,creds, Config.CADI_KEYFILE, fkf.getCanonicalPath());
+                                       directedPut(pa, filesymm, normal,creds, Config.AAF_APPID,fqi);
+                                       directedPut(pa, filesymm, normal,creds, Config.AAF_APPPASS,null);
+                                       directedPut(pa, filesymm, normal,creds, Config.AAF_URL, Defaults.AAF_URL);
                                        
-                                       psCredProps.print(Config.CADI_TRUSTSTORE);
-                                       psCredProps.print("=");
-                                       File origTruststore = new File(pa.getProperty(Config.CADI_TRUSTSTORE));
-                                       File newTruststore = new File(dir,origTruststore.getName());
-                                       if(!newTruststore.exists()) {
-                                               Files.copy(origTruststore.toPath(), newTruststore.toPath());
+
+                                       String cts = pa.getProperty(Config.CADI_TRUSTSTORE);
+                                       if(cts!=null) {
+                                               File origTruststore = new File(cts);
+                                               if(!origTruststore.exists()) {
+                                                       // Try same directory as cadi_prop_files
+                                                       String cpf = pa.getProperty(Config.CADI_PROP_FILES);
+                                                       if(cpf!=null) {
+                                                               for(String f : Split.split(File.pathSeparatorChar, cpf)) {
+                                                                       File fcpf = new File(f);
+                                                                       if(fcpf.exists()) {
+                                                                               int lastSep = cts.lastIndexOf(File.pathSeparator);
+                                                                               origTruststore = new File(fcpf.getParentFile(),lastSep>=0?cts.substring(lastSep):cts);
+                                                                               if(origTruststore.exists()) { 
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               if(!origTruststore.exists()) {
+                                                                       throw new CadiException(cts + " does not exist");
+                                                               }
+                                                       }
+                                                       
+                                               }
+                                               File newTruststore = new File(dir,origTruststore.getName());
+                                               if(!newTruststore.exists()) {
+                                                       Files.copy(origTruststore.toPath(), newTruststore.toPath());
+                                               }
+                                               
+                                               directedPut(pa, filesymm, normal,creds, Config.CADI_TRUSTSTORE,newTruststore.getCanonicalPath());
+                                               directedPut(pa, filesymm, normal,creds, Config.CADI_TRUSTSTORE_PASSWORD,null);
                                        }
-                                       psCredProps.println(newTruststore.getCanonicalPath());
-               
-                                       psCredProps.print(Config.CADI_TRUSTSTORE_PASSWORD);
-                                       psCredProps.print("=enc:");
-                                       ps = pa.decrypt(pa.getProperty(Config.CADI_TRUSTSTORE_PASSWORD), false);
-                                       ps = filesymm.enpass(ps);
-                                       psCredProps.println(ps);
                                        
-                                       try {
+                                       if(aafcon!=null) { // get Properties from Remote AAF
+                                               final String locator = getProperty(pa,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: ");
+
                                                Future<Configuration> acf = aafcon.client(new SingleEndpointLocator(locator))
                                                                .read("/configure/"+fqi+"/aaf", configDF);
                                                if(acf.get(TIMEOUT)) {
-               //                                      out.println(acf.value.getName());
                                                        for(Props props : acf.value.getProps()) {
-                                                               psProps.println(props.getTag() + '=' + props.getValue());                                       
+                                                               directedPut(pa, filesymm, normal,creds, props.getTag(),props.getValue());                                       
                                                        }
                                                        ok = true;
                                                } else if(acf.code()==401){
@@ -771,15 +849,53 @@ public class Agent {
                                                } else {
                                                        trans.error().log(errMsg.toMsg(acf));
                                                }
-                                       } finally {
-                                               psProps.close();
+                                       } else {
+                                               String cpf = pa.getProperty(Config.CADI_PROP_FILES);
+                                               if(cpf!=null){
+                                                       for(String f : Split.split(File.pathSeparatorChar, cpf)) {
+                                                               System.out.format("Reading %s\n",f);
+                                                               FileInputStream fis = new FileInputStream(f); 
+                                                               try {
+                                                                       Properties props = new Properties();
+                                                                       props.load(fis);
+                                                                       for(Entry<Object, Object> prop : props.entrySet()) {
+                                                                               directedPut(pa, filesymm, normal,creds, prop.getKey().toString(),prop.getValue().toString());
+                                                                       }
+                                                               } finally {
+                                                                       fis.close();
+                                                               }
+                                                       }
+                                               }
+                                               ok = true;
                                        }
                                        if(ok) {
+                                               for(Entry<String, String> es : normal.entrySet()) {
+                                                       psProps.print(es.getKey());
+                                                       psProps.print('=');
+                                                       psProps.println(es.getValue());
+                                               }
+                                               
+                                               for(Entry<String, String> es : creds.entrySet()) {
+                                                       psCredProps.print(es.getKey());
+                                                       psCredProps.print('=');
+                                                       psCredProps.println(es.getValue());
+                                               }
+                                               
                                                File newFile = new File(dir,rootFile+".props");
+                                               if(newFile.exists()) {
+                                                       File backup = new File(dir,rootFile+".props.backup");
+                                                       newFile.renameTo(backup);
+                                                       System.out.println("Backed up to " + backup.getCanonicalPath());
+                                               }
                                                fProps.renameTo(newFile);
                                                System.out.println("Created " + newFile.getCanonicalPath());
                                                fProps = newFile;
                                                
+                                               if(fSecureProps.exists()) {
+                                                       File backup = new File(dir,fSecureProps.getName()+".backup");
+                                                       fSecureProps.renameTo(backup);
+                                                       System.out.println("Backed up to " + backup.getCanonicalPath());
+                                               }
                                                fSecureTempProps.renameTo(fSecureProps);
                                                System.out.println("Created " + fSecureProps.getCanonicalPath());
                                                fProps = newFile;
@@ -797,7 +913,36 @@ public class Agent {
                        tt.done();
                }
        }
+
+       private static List<String> CRED_TAGS = Arrays.asList(new String[] {
+                       Config.CADI_KEYFILE,
+                       Config.AAF_APPID, Config.AAF_APPPASS,
+                       Config.CADI_KEYSTORE, Config.CADI_KEYSTORE_PASSWORD, Config.CADI_KEY_PASSWORD,
+                       Config.CADI_TRUSTSTORE,Config.CADI_TRUSTSTORE_PASSWORD,
+                       Config.CADI_ALIAS, Config.CADI_X509_ISSUERS
+                       });
+
+       private static List<String> LOC_TAGS = Arrays.asList(new String[] {Config.CADI_LATITUDE, Config.CADI_LONGITUDE});
        
+       private static void directedPut(final PropAccess orig, final Symm symm, final Map<String,String> main, final Map<String,String> secured, final String tag, final String value) throws IOException {
+               if(!LOC_TAGS.contains(tag)) { // Location already covered
+                       String val = value==null?orig.getProperty(tag):value;
+                       if(tag.endsWith("_password")) {
+                               if(val.length()>4) {
+                                       if(val.startsWith("enc:")) {
+                                               val = orig.decrypt(val, true);
+                                       }
+                                       val = "enc:" + symm.enpass(val);
+                               }
+                       }
+                       if(CRED_TAGS.contains(tag)) {
+                               secured.put(tag, val);
+                       } else {
+                               main.put(tag, val);
+                       }
+               }
+       }
+
        private static void validate(final PropAccess pa) throws LocatorException, CadiException, APIException {
                System.out.println("Validating Configuration...");
                final AAFCon<?> aafcon = new AAFConHttp(pa,Config.AAF_URL,new SecurityInfoC<HttpURLConnection>(pa));
@@ -872,13 +1017,13 @@ public class Agent {
                                                        String prop;                                            
                                                        File f;
        
-                                                       if((prop=props.getProperty(Config.CADI_KEYFILE))==null ||
+                                                       if((prop=trans.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);
+                                                               String ksf = trans.getProperty(Config.CADI_KEYSTORE);
+                                                               String ksps = trans.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());