X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cadi%2Faaf%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2Fconfigure%2FAgent.java;h=4dd86fe097c8417e4fa6befa1dd579adc76f07d2;hb=355b886d817295d2bca5af28f01576bf4a3ded18;hp=a26422213c0593c1b05da381ba54a3f1a80f0f39;hpb=7e966914050e66219689001ff4ab601a49eef0ac;p=aaf%2Fauthz.git diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/Agent.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/Agent.java index a2642221..4dd86fe0 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/Agent.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/Agent.java @@ -25,18 +25,18 @@ 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.URISyntaxException; 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.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.Deque; import java.util.GregorianCalendar; import java.util.HashMap; @@ -45,14 +45,13 @@ 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.Access; 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; @@ -60,6 +59,7 @@ import org.onap.aaf.cadi.client.Future; import org.onap.aaf.cadi.client.Rcli; import org.onap.aaf.cadi.client.Retryable; import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.RegistrationPropHolder; import org.onap.aaf.cadi.config.SecurityInfoC; import org.onap.aaf.cadi.http.HBasicAuthSS; import org.onap.aaf.cadi.locator.SingleEndpointLocator; @@ -108,6 +108,20 @@ public class Agent { private static boolean doExit; private static AAFCon aafcon; + + private static List 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 LOC_TAGS = Arrays.asList(new String[] { + Config.CADI_LATITUDE, Config.CADI_LONGITUDE + }); + // Note: This is set by loadURLs. Use that function as singleton, not directly. + private static Map aaf_urls = null; + public static void main(String[] args) { int exitCode = 0; @@ -140,7 +154,7 @@ public class Agent { public Properties process(String[] args, Properties props) { if (args.length>1) { if (!args[0].equals("keypairgen")) { - props.put("aaf_id", args[1]); + props.put(Config.AAF_APPID, args[1]); } } return props; @@ -157,10 +171,13 @@ public class Agent { env = new RosettaEnv(access.getProperties()); Deque cmds = new ArrayDeque(); for (String p : args) { + int eq; if ("-noexit".equalsIgnoreCase(p)) { doExit = false; - } else if (p.indexOf('=') < 0) { + } else if ((eq=p.indexOf('=')) < 0) { cmds.add(p); + } else { + access.setProperty(p.substring(0,eq), p.substring(eq+1)); } } @@ -218,11 +235,7 @@ public class Agent { 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); - } + /*urls=*/loadURLs(access); aafsso.writeFiles(); } @@ -255,13 +268,7 @@ public class Agent { 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); - } + config(trans,access,args,cmds); break; case "validate": validate(access); @@ -297,9 +304,63 @@ public class Agent { } } - private static synchronized AAFCon aafcon(PropAccess access) throws APIException, CadiException, LocatorException { + public synchronized static Map loadURLs(Access access) throws UnknownHostException, CadiException { + if(aaf_urls==null) { + Map rv = new HashMap<>(); + RegistrationPropHolder rph = new RegistrationPropHolder(access, 0); + String dot_le = access.getProperty(Config.AAF_LOCATOR_CONTAINER,null); + dot_le=dot_le==null?"":'.'+dot_le; + String version = access.getProperty(Config.AAF_API_VERSION,Config.AAF_DEFAULT_API_VERSION); + for(String u : new String[] {"aaf","locate","oauth","cm","gui","fs","hello","token","introspect"}) { + String tag; + String append=null; + switch(u) { + case "aaf": tag = Config.AAF_URL; break; + case "locate":tag = Config.AAF_LOCATE_URL; break; + case "oauth": tag = Config.AAF_URL_OAUTH; break; + case "token": tag = Config.AAF_OAUTH2_TOKEN_URL; append="/token"; break; + case "introspect": tag = Config.AAF_OAUTH2_INTROSPECT_URL; append="/introspect"; break; + case "cm": tag = Config.AAF_URL_CM; break; + case "gui": tag = Config.AAF_URL_GUI; break; + case "fs": tag = Config.AAF_URL_FS; break; + case "hello": tag = Config.AAF_URL_HELLO; break; + default: + tag = "aaf_url_" + u; + } + String value; + if((value=access.getProperty(tag,null))==null) { + String proto = "fs".equals(u)?"http://":"https://"; + String lhost; + if("locate".equals(u)) { + lhost=rph.default_fqdn; + } else { + lhost=Config.AAF_LOCATE_URL_TAG; + } + value = rph.replacements("Agent:loadURLs", + proto + lhost + "/%CNS.%AAF_NS." + ("aaf".equals(u)?"service":u) + ':' + version, + null,dot_le); + if(append!=null) { + value+=append; + } + } + rv.put(tag, value); + }; + aaf_urls = rv; + } + return aaf_urls; + } + + public static void fillMissing(PropAccess access, Map map) { + for(Entry es : map.entrySet()) { + if(access.getProperty(es.getKey())==null) { + access.setProperty(es.getKey(),es.getValue()); + } + } + } + + private static synchronized AAFCon aafcon(Access access) throws APIException, CadiException, LocatorException { if (aafcon==null) { - aafcon = new AAFConHttp(access,Config.CM_URL); + aafcon = new AAFConHttp(access,Config.AAF_URL_CM); } return aafcon; } @@ -626,6 +687,7 @@ public class Agent { } } } + PropHolder.writeAll(); } else { trans.error().log(errMsg.toMsg(acf)); } @@ -673,16 +735,19 @@ public class Agent { FileInputStream fis = new FileInputStream(new File(dir,a.getNs()+".cred.props")); try { props.load(fis); - fis.close(); - fis = new FileInputStream(new File(dir,a.getNs()+".chal")); - props.load(fis); + File chalFile = new File(dir,a.getNs()+".chal"); + if(chalFile.exists()) { + fis.close(); + fis = new FileInputStream(chalFile); + props.load(fis); + } } finally { fis.close(); } File f = new File(dir,a.getNs()+".keyfile"); if (f.exists()) { - Symm symm = Symm.obtain(f); + Symm symm = ArtifactDir.getSymm(f); for (Iterator> iter = props.entrySet().iterator(); iter.hasNext();) { Entry en = iter.next(); @@ -729,218 +794,168 @@ public class Agent { System.out.printf("Wrote %s\n", f.getCanonicalFile()); } - private static void config(Trans trans, PropAccess pa, AAFCon aafcon, Deque cmds) throws Exception { - final String fqi = fqi(cmds); - final String rootFile = FQI.reverseDomain(fqi); - final File dir = new File(pa.getProperty(Config.CADI_ETCDIR, ".")); - if (dir.exists()) { - System.out.println("Writing to " + dir.getCanonicalFile()); - } else if (dir.mkdirs()) { - System.out.println("Created directory " + dir.getCanonicalFile()); - } else { - System.err.println("Unable to create or write to " + dir.getCanonicalPath()); - return; - } - + private static void config(Trans trans, PropAccess propAccess, String[] args, Deque cmds) throws Exception { TimeTaken tt = trans.start("Get Configuration", Env.REMOTE); try { - boolean ok=false; - File fProps = File.createTempFile(rootFile, ".tmp",dir); - File fSecureTempProps = File.createTempFile(rootFile, ".cred.tmp",dir); - File fSecureProps = new File(dir,rootFile+".cred.props"); - PrintStream psProps; - - File fLocProps = new File(dir,rootFile + ".location.props"); - if (!fLocProps.exists()) { - psProps = new PrintStream(new FileOutputStream(fLocProps)); - try { - psProps.println(HASHES); - psProps.print("# Configuration File generated on "); - psProps.println(new Date().toString()); - psProps.println(HASHES); - for (String tag : LOC_TAGS) { - psProps.print(tag); - psProps.print('='); - psProps.println(getProperty(pa, trans, false, tag, "%s: ",tag)); - } - } finally { - psProps.close(); - } + final String fqi = fqi(cmds); + Artifact arti = new Artifact(); + arti.setDir(propAccess.getProperty(Config.CADI_ETCDIR, ".")); + arti.setNs(FQI.reverseDomain(fqi)); + PropHolder loc = PropHolder.get(arti, "location.props"); + PropHolder cred = PropHolder.get(arti,"cred.props"); + PropHolder app= PropHolder.get(arti,"props"); + for(String c : args) { + int idx = c.indexOf('='); + if(idx>0) { + app.add(c.substring(0,idx), c.substring(idx+1)); + } } + app.add(Config.CADI_PROP_FILES, loc.getPath()+':'+cred.getPath()); - psProps = new PrintStream(new FileOutputStream(fProps)); - try { - PrintStream psCredProps = new PrintStream(new FileOutputStream(fSecureTempProps)); - try { - psCredProps.println(HASHES); - psCredProps.print("# Configuration File generated on "); - psCredProps.println(new Date().toString()); - psCredProps.println(HASHES); + for (String tag : LOC_TAGS) { + loc.add(tag, getProperty(propAccess, trans, false, tag, "%s: ",tag)); + } + + cred.add(Config.CADI_KEYFILE, cred.getKeyPath()); + final String ssoAppID = propAccess.getProperty(Config.AAF_APPID); + if(fqi!=null && fqi.equals(ssoAppID)) { + cred.addEnc(Config.AAF_APPPASS, propAccess, null); + // only Ask for Password when starting scratch + } else if(propAccess.getProperty(Config.CADI_PROP_FILES)==null) { + char[] pwd = AAFSSO.cons.readPassword("Password for %s: ", fqi); + if(pwd.length>0) { + cred.addEnc(Config.AAF_APPPASS, new String(pwd)); + } + } + + // load all properties that are already setup. + Map aaf_urls = loadURLs(propAccess); + for(Entry es : aaf_urls.entrySet()) { + app.add(es.getKey(), es.getValue()); + } + + app.add(Config.AAF_LOCATE_URL, Config.getAAFLocateUrl(propAccess)); + app.add(Config.AAF_ENV,propAccess, "DEV"); + String release = propAccess.getProperty(Config.AAF_DEPLOYED_VERSION); + if(release==null) { + release = System.getProperty(Config.AAF_DEPLOYED_VERSION,null); + } + if(release!=null) { + app.add(Config.AAF_DEPLOYED_VERSION, release); + } + for(Entry aaf_loc_prop : propAccess.getProperties().entrySet()) { + String key = aaf_loc_prop.getKey().toString(); + if(key.startsWith("aaf_locator")) { + app.add(key, aaf_loc_prop.getValue().toString()); + } + } + + app.add(Config.AAF_APPID, fqi); - psProps.println(HASHES); - psProps.print("# Configuration File generated on "); - psProps.println(new Date().toString()); - psProps.println(HASHES); - - psProps.print(Config.CADI_PROP_FILES); - psProps.print('='); - psProps.print(fSecureProps.getCanonicalPath()); - psProps.print(File.pathSeparatorChar); - psProps.println(fLocProps.getCanonicalPath()); - - File fkf = new File(dir,rootFile+".keyfile"); - if (!fkf.exists()) { - CmdLine.main(new String[] {"keygen",fkf.toString()}); - } - Symm filesymm = Symm.obtain(fkf); - Map normal = new TreeMap<>(); - Map creds = new TreeMap<>(); + String cts = propAccess.getProperty(Config.CADI_TRUSTSTORE); + System.out.println("Passed in Truststore is " + cts); + if (cts!=null) { + File origTruststore = new File(cts); + File newTruststore = new File(app.getDir(),origTruststore.getName()); + if(!newTruststore.exists()) { + if (!origTruststore.exists()) { + // Try same directory as cadi_prop_files + String cpf = propAccess.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"); + } + } + + } + if (!newTruststore.exists() && origTruststore.exists()) { + Files.copy(origTruststore.toPath(), newTruststore.toPath()); + } + } - 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); + System.out.println("New Truststore is " + newTruststore); + cred.add(Config.CADI_TRUSTSTORE, newTruststore.getCanonicalPath()); + cred.add(Config.CADI_TRUSTSTORE_PASSWORD, "changeit" /* Java default */); - - 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"); - } + String cpf = propAccess.getProperty(Config.CADI_PROP_FILES); + if (cpf!=null){ + String[] propFiles = Split.splitTrim(File.pathSeparatorChar, cpf); + for (int pfi = propFiles.length-1;pfi>=0;--pfi) { + String f = propFiles[pfi]; + System.out.format("Reading %s\n",f); + FileInputStream fis = new FileInputStream(f); + try { + Properties props = new Properties(); + props.load(fis); + for (Entry prop : props.entrySet()) { + boolean lower = true; + String key = prop.getKey().toString(); + if(LOC_TAGS.contains(key)) { + break; + } + for(int i=0;lower && i acf = aafcon.client(new SingleEndpointLocator(locator)) - .read("/configure/"+fqi+"/aaf", configDF); - if (acf.get(TIMEOUT)) { - for (Props props : acf.value.getProps()) { - directedPut(pa, filesymm, normal,creds, props.getTag(),props.getValue()); - } - ok = true; - } else if (acf.code()==401){ - trans.error().log("Bad Password sent to AAF"); - } else { - trans.error().log(errMsg.toMsg(acf)); - } - } 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 prop : props.entrySet()) { - directedPut(pa, filesymm, normal,creds, prop.getKey().toString(),prop.getValue().toString()); - } - } finally { - fis.close(); - } - } - } - ok = true; - } - if (ok) { - for (Entry es : normal.entrySet()) { - psProps.print(es.getKey()); - psProps.print('='); - psProps.println(es.getValue()); - } - - for (Entry 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()); + for (Props props : aafProps(trans,aafcon,getProperty(propAccess,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: "),fqi)) { + PropHolder ph = CRED_TAGS.contains(props.getTag())?cred:app; + if(props.getTag().endsWith("_password")) { + ph.addEnc(props.getTag(), props.getValue()); + } else { + ph.add(props.getTag(), props.getValue()); + } } - 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; - } else { - fProps.delete(); - fSecureTempProps.delete(); + } - } finally { - psCredProps.close(); } - } finally { - psProps.close(); } + + PropHolder.writeAll(); } finally { tt.done(); } } - private static List 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 LOC_TAGS = Arrays.asList(new String[] {Config.CADI_LATITUDE, Config.CADI_LONGITUDE}); - - private static void directedPut(final PropAccess orig, final Symm symm, final Map main, final Map 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); - } + public static List aafProps(Trans trans, AAFCon aafcon, String locator, String fqi) throws CadiException, APIException, URISyntaxException { + Future acf = aafcon.client(new SingleEndpointLocator(locator)) + .read("/configure/"+fqi+"/aaf", configDF); + if (acf.get(TIMEOUT)) { + return acf.value.getProps(); + } else if (acf.code()==401){ + trans.error().log("Bad Password sent to AAF"); + } else if (acf.code()==404){ + trans.error().log("This version of AAF does not support remote Properties"); + } else { + trans.error().log(errMsg.toMsg(acf)); } + return new ArrayList<>(); } private static void validate(final PropAccess pa) throws LocatorException, CadiException, APIException { @@ -1028,8 +1043,9 @@ public class Agent { 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 { + Symm symm = ArtifactDir.getSymm(f); + KeyStore ks = KeyStore.getInstance("JKS"); - Symm symm = Symm.obtain(f); fis = new FileInputStream(ksf); try {