diff options
21 files changed, 327 insertions, 184 deletions
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java index 37501967..d64cff29 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java @@ -265,6 +265,16 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { hd.memo = memo ? String.format("%s by %s", override[0], hd.user) : (modified.name() + "d credential for " + data.id); + String spacer = ": "; + if(data.notes!=null) { + hd.memo+=spacer + data.notes; + spacer = ", "; + } + + if(data.tag!=null) { + hd.memo+=spacer + data.tag; + } + // Detail? if (modified==CRUD.delete) { try { diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java index 3fde5123..c59312c0 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java @@ -628,7 +628,12 @@ public class Function { return Result.err(Status.ERR_DependencyExists, sb.toString()); } - if (move && (parent == null || parent.type == NsType.COMPANY.type)) { + if (move && parent == null) { + return Result + .err(Status.ERR_DependencyExists, + "Cannot move users, roles or permissions - parent is missing.\nDelete dependencies and try again"); + } + else if (move && parent.type == NsType.COMPANY.type) { return Result .err(Status.ERR_DependencyExists, "Cannot move users, roles or permissions to [%s].\nDelete dependencies and try again", diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java index 3abad1a5..22b14cb4 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java @@ -1178,9 +1178,9 @@ public class Question { } public boolean isAdmin(AuthzTrans trans, String user, String ns) { - Date now = new Date(); Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_ADMIN); if (rur.isOKhasData()) { + Date now = new Date(); for (UserRoleDAO.Data urdd : rur.value){ if (urdd.expires.after(now)) { return true; @@ -1192,8 +1192,8 @@ public class Question { public boolean isOwner(AuthzTrans trans, String user, String ns) { Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER); - Date now = new Date(); if (rur.isOKhasData()) {for (UserRoleDAO.Data urdd : rur.value){ + Date now = new Date(); if (urdd.expires.after(now)) { return true; } diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java index 1f2b0880..85424de1 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java @@ -60,6 +60,7 @@ import org.onap.aaf.auth.org.Organization.Identity; import org.onap.aaf.auth.org.OrganizationException; import org.onap.aaf.cadi.Hash; import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.aaf.AAFPermission; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.configure.Factory; @@ -88,6 +89,7 @@ public class CMService { private final CredDAO credDAO; private final ArtiDAO artiDAO; private AAF_CM certManager; + private Boolean allowIgnoreIPs; // @SuppressWarnings("unchecked") public CMService(final AuthzTrans trans, AAF_CM certman) throws APIException, IOException { @@ -108,6 +110,10 @@ public class CMService { "*", "read" ); + allowIgnoreIPs = Boolean.valueOf(certman.access.getProperty(Config.CM_ALLOW_IGNORE_IPS, "false")); + if(allowIgnoreIPs) { + trans.env().access().log(Level.INIT, "Allowing DNS Evaluation to be turned off with <ns>.certman|<ca name>|"+IGNORE_IPS); + } } public Result<CertResp> requestCert(final AuthzTrans trans, final Result<CertReq> req, final CA ca) { @@ -133,7 +139,13 @@ public class CMService { try { Organization org = trans.org(); - boolean ignoreIPs = trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), IGNORE_IPS)); + boolean ignoreIPs; + if(allowIgnoreIPs) { + ignoreIPs = trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), IGNORE_IPS)); + } else { + ignoreIPs = false; + } + InetAddress primary = null; // Organize incoming information to get to appropriate Artifact @@ -164,8 +176,8 @@ public class CMService { } } else { - for (String cn : req.value.fqdns) { - if (!ignoreIPs) { + if (!ignoreIPs) { + for (String cn : req.value.fqdns) { try { InetAddress[] ias = InetAddress.getAllByName(cn); Set<String> potentialSanNames = new HashSet<>(); diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java index 8fcea294..01d001fd 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java @@ -94,10 +94,6 @@ public class AAFcli { this(access,new AuthzEnv(access.getProperties()),wtr,hman, si,ss); } - public AuthzEnv env() { - return env; - } - public AAFcli(Access access, AuthzEnv env, Writer wtr, HMangr hman, SecurityInfoC<HttpURLConnection> si, SecuritySetter<HttpURLConnection> ss) throws APIException { this.env = env; this.access = access; @@ -127,7 +123,11 @@ public class AAFcli { cmds.add(new Mgmt(this)); } - public static int timeout() { + public AuthzEnv env() { + return env; + } + + public static int timeout() { return TIMEOUT; } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java index add5aed8..e1252d87 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java @@ -26,6 +26,7 @@ import java.util.Comparator; import org.onap.aaf.auth.cmd.BaseCmd; import org.onap.aaf.auth.cmd.DeprecatedCMD; +import org.onap.aaf.auth.common.Define; import org.onap.aaf.cadi.client.Future; import org.onap.aaf.misc.env.util.Chrono; @@ -162,15 +163,8 @@ public class List extends BaseCmd<NS> { if ((type=u.getType())==null) { type = 9999; } - switch(type) { - case 0: return "NoCrd"; - case 1: return "U/P"; - case 2: return "U/P2"; - case 10: return "FQI"; - case 200: return "x509"; - default: - return "n/a"; - } + return Define.getCredType(type); } + } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java index 1dfcc17f..2d626d4e 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java @@ -122,7 +122,7 @@ public class Cred extends Cmd { pw().println(']'); } else if (fp.code()==202) { pw().println("Credential Action Accepted, but requires Approvals before actualizing"); - } else if (fp.code()==300) { + } else if (fp.code()==300 || fp.code()==406) { Error err = em.getError(fp); String text = err.getText(); List<String> vars = err.getVariables(); diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java index 46d5d052..71d61f79 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java @@ -35,7 +35,6 @@ import org.onap.aaf.misc.env.APIException; import aaf.v2_0.CredRequest; public class ID extends Cmd { - public static final String ATTEMPT_FAILED_SPECIFICS_WITHELD = "Attempt Failed. Specifics witheld."; private static final String CRED_PATH = "/authn/cred"; private static final String[] options = {"add","del"}; public ID(User parent) { @@ -98,7 +97,7 @@ public class ID extends Cmd { } else if (fp.code()==406 && option==1) { pw().println("FQI does not exist"); } else { - pw().println(ATTEMPT_FAILED_SPECIFICS_WITHELD); + pw().println(Cred.ATTEMPT_FAILED_SPECIFICS_WITHELD); } return fp.code(); } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java index 7daa51fb..444a82ab 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java @@ -48,7 +48,6 @@ public class List extends BaseCmd<User> { void report(Users users, boolean count, String ... str) { reportHead(str); - int idx = 0; java.util.List<aaf.v2_0.Users.User> sorted = users.getUser(); Collections.sort(sorted, (Comparator<aaf.v2_0.Users.User>) (u1, u2) -> { if (u1==null || u2 == null) { @@ -56,11 +55,11 @@ public class List extends BaseCmd<User> { } return u1.getId().compareTo(u2.getId()); }); - String format = reportColHead("%-48s %-5s %-11s %-16s\n","User","Type","Expires","Tag"); + String format = reportColHead("%-36s %-5s %-20s %-16s\n","User","Type","Expires","Tag"); String date = "XXXX-XX-XX"; for (aaf.v2_0.Users.User user : sorted) { if (!aafcli.isTest()) { - date = Chrono.dateOnlyStamp(user.getExpires()); + date = Chrono.niceUTCStamp(user.getExpires()); } String tag=user.getTag(); Integer type = user.getType(); @@ -70,7 +69,7 @@ public class List extends BaseCmd<User> { tag = "\n\tfingerprint: " + tag; } pw().format(format, - count? (Integer.valueOf(++idx) + ") " + user.getId()): user.getId(), + user.getId(), org.onap.aaf.auth.cmd.ns.List.getType(user), date, tag); diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java index e9c36017..800a8472 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java @@ -24,8 +24,8 @@ package org.onap.aaf.auth.common; import java.util.Map.Entry; import org.onap.aaf.cadi.Access; -import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.config.Config; public class Define { @@ -91,4 +91,16 @@ public class Define { return initialized; } + public static String getCredType(int type) { + switch(type) { + case 0: return "NoCrd"; + case 1: return "U/P"; + case 2: return "U/P2"; + case 10: return "FQI"; + case 200: return "x509"; + default: + return "n/a"; + } + } + } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java index 9a6ef7e3..295db4ac 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java @@ -2821,7 +2821,7 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE //Need to do the "Pick Entry" mechanism // Note, this sorts - Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, "extend"); + Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.EXTEND); if (ri.notOK()) { return Result.err(ri); } @@ -2835,8 +2835,11 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE cd.type = found.type; cd.ns = found.ns; cd.notes = "Extended"; - cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime(); cd.tag = found.tag; + cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime(); + if(cd.expires.before(found.expires)) { + return Result.err(Result.ERR_BadData,String.format("Credential's expiration date is more than %s days in the future",days)); + } cred = ques.credDAO().create(trans, cd); if (cred.isOK()) { @@ -2887,63 +2890,72 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } boolean isLastCred = rlcd.value.size()==1; - int entry = -1; - int fentry = entry; - if(cred.value.type==CredDAO.FQI) { - entry = -1; - for(CredDAO.Data cdd : rlcd.value) { - ++fentry; - if(cdd.type == CredDAO.FQI) { - entry = fentry; - break; - } + int entry; + CredRequest cr = (CredRequest)from; + if(isLastCred) { + if(cr.getEntry()==null || "1".equals(cr.getEntry())) { + entry = 0; + } else { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); } } else { - if (!doForce) { - if (rlcd.value.size() > 1) { - CredRequest cr = (CredRequest)from; - String inputOption = cr.getEntry(); - if (inputOption == null) { - List<CredDAO.Data> list = filterList(rlcd.value,CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256,CredDAO.CERT_SHA256_RSA); - String message = selectCredFromList(list, MayChangeCred.DELETE); - Object[] variables = buildVariables(list); - return Result.err(Status.ERR_ChoiceNeeded, message, variables); - } else { - try { - if (inputOption.length()>5) { // should be a date - Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); - for (CredDAO.Data cd : rlcd.value) { - ++fentry; - if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { - entry = fentry; - break; - } - } - } else { - entry = Integer.parseInt(inputOption) - 1; - int count = 0; - for (CredDAO.Data cd : rlcd.value) { - if(cd.type!=CredDAO.BASIC_AUTH && cd.type!=CredDAO.BASIC_AUTH_SHA256 && cd.type!=CredDAO.CERT_SHA256_RSA) { - ++entry; - } - if(++count>entry) { - break; - } - } - } - } catch (NullPointerException e) { - return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); - } catch (NumberFormatException e) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - isLastCred = (entry==-1)?true:false; - } else { - isLastCred = true; - } - if (entry < -1 || entry >= rlcd.value.size()) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } + entry = -1; + int fentry = entry; + if(cred.value.type==CredDAO.FQI) { + entry = -1; + for(CredDAO.Data cdd : rlcd.value) { + ++fentry; + if(cdd.type == CredDAO.FQI) { + entry = fentry; + break; + } + } + } else { + if (!doForce) { + if (rlcd.value.size() > 1) { + String inputOption = cr.getEntry(); + if (inputOption == null) { + List<CredDAO.Data> list = filterList(rlcd.value,CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256,CredDAO.CERT_SHA256_RSA); + String message = selectCredFromList(list, MayChangeCred.DELETE); + Object[] variables = buildVariables(list); + return Result.err(Status.ERR_ChoiceNeeded, message, variables); + } else { + try { + if (inputOption.length()>5) { // should be a date + Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); + for (CredDAO.Data cd : rlcd.value) { + ++fentry; + if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { + entry = fentry; + break; + } + } + } else { + entry = Integer.parseInt(inputOption) - 1; + int count = 0; + for (CredDAO.Data cd : rlcd.value) { + if(cd.type!=CredDAO.BASIC_AUTH && cd.type!=CredDAO.BASIC_AUTH_SHA256 && cd.type!=CredDAO.CERT_SHA256_RSA) { + ++entry; + } + if(++count>entry) { + break; + } + } + } + } catch (NullPointerException e) { + return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); + } catch (NumberFormatException e) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + isLastCred = (entry==-1)?true:false; + } else { + isLastCred = true; + } + if (entry < -1 || entry >= rlcd.value.size()) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } } } @@ -3020,6 +3032,32 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE Object[] variables = buildVariables(lcd); return Result.err(Status.ERR_ChoiceNeeded, message, variables); } else { + if(MayChangeCred.EXTEND.equals(action)) { + // might be Tag + if(inputOption.length()>4) { //Tag is at least 12 + int e = 0; + CredDAO.Data last = null; + int lastIdx = -1; + for(CredDAO.Data cdd : lcd) { + if(inputOption.equals(cdd.tag)) { + if(last==null) { + last = cdd; + lastIdx = e; + } else { + if(last.expires.before(cdd.expires)) { + last = cdd; + lastIdx = e; + } + } + } + ++e; + } + if(last!=null) { + return Result.ok(lastIdx); + } + return Result.err(Status.ERR_BadData, "User chose unknown Tag"); + } + } entry = Integer.parseInt(inputOption) - 1; } if (entry < 0 || entry >= lcd.size()) { @@ -3040,20 +3078,23 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } } } + Collections.sort(rv, (o1,o2) -> { + if(o1.type==o2.type) { + return o1.expires.compareTo(o2.expires); + } else { + return o1.type.compareTo(o2.type); + } + }); return rv; } private String[] buildVariables(List<CredDAO.Data> value) { - // ensure credentials are sorted so we can fully automate Cred regression test - Collections.sort(value, (cred1, cred2) -> - cred1.type==cred2.type?cred2.expires.compareTo(cred1.expires): - cred1.type<cred2.type?-1:1); String [] vars = new String[value.size()]; CredDAO.Data cdd; for (int i = 0; i < value.size(); i++) { cdd = value.get(i); - vars[i] = cdd.id + TWO_SPACE + cdd.type + TWO_SPACE + (cdd.type<10?TWO_SPACE:"")+ cdd.expires + TWO_SPACE + cdd.tag; + vars[i] = cdd.id + TWO_SPACE + Define.getCredType(cdd.type) + TWO_SPACE + Chrono.niceUTCStamp(cdd.expires) + TWO_SPACE + cdd.tag; } return vars; } @@ -3070,12 +3111,15 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE for (int i = 0; i < numSpaces; i++) { errMessage.append(' '); } - errMessage.append(" Type Expires Tag " + '\n'); + errMessage.append(" Type Expires Tag " + '\n'); for (int i=0;i<value.size();++i) { errMessage.append(" %s\n"); } - errMessage.append("Run same command again with chosen entry as last parameter"); - + if(MayChangeCred.EXTEND.equals(action)) { + errMessage.append("Run same command again with chosen entry or Tag as last parameter"); + } else { + errMessage.append("Run same command again with chosen entry as last parameter"); + } return errMessage.toString(); } diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java index 9e21f6cd..e40743da 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java @@ -126,43 +126,47 @@ public abstract class AAFCon<CLIENT> implements Connector { if (mechid==null) { mechid=access.getProperty(Config.OAUTH_CLIENT_ID,null); } - String encpass = access.getProperty(Config.AAF_APPPASS, null); - if (encpass==null) { - encpass = access.getProperty(Config.OAUTH_CLIENT_SECRET,null); - } - if (encpass==null) { - String alias = access.getProperty(Config.CADI_ALIAS, mechid); - if (alias==null) { - access.printf(Access.Level.WARN,"%s, %s or %s required before use.", Config.CADI_ALIAS, Config.AAF_APPID, Config.OAUTH_CLIENT_ID); - set(si.defSS); - } else { - si.defSS=x509Alias(alias); - set(si.defSS); - } + String alias = access.getProperty(Config.CADI_ALIAS, null); + if(alias != null) { + si.defSS=x509Alias(alias); + set(si.defSS); } else { - if (mechid!=null) { - si.defSS=basicAuth(mechid, encpass); - set(si.defSS); - } else { - si.defSS=new SecuritySetter<CLIENT>() { - - @Override - public String getID() { - return ""; - } - - @Override - public void setSecurity(CLIENT client) throws CadiException { - throw new CadiException("AAFCon has not been initialized with Credentials (SecuritySetter)"); - } - @Override - public int setLastResponse(int respCode) { - return 0; - } - }; - set(si.defSS); - } + String encpass = access.getProperty(Config.AAF_APPPASS, null); + if (encpass==null) { + encpass = access.getProperty(Config.OAUTH_CLIENT_SECRET,null); + } + + if (encpass==null) { + if (alias==null) { + access.printf(Access.Level.WARN,"%s, %s or %s required before use.", Config.CADI_ALIAS, Config.AAF_APPID, Config.OAUTH_CLIENT_ID); + set(si.defSS); + } + } else { + if (mechid!=null) { + si.defSS=basicAuth(mechid, encpass); + set(si.defSS); + } else { + si.defSS=new SecuritySetter<CLIENT>() { + + @Override + public String getID() { + return ""; + } + + @Override + public void setSecurity(CLIENT client) throws CadiException { + throw new CadiException("AAFCon has not been initialized with Credentials (SecuritySetter)"); + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } + }; + set(si.defSS); + } + } } } diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java index d39fc1d6..e60b5d8a 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java @@ -60,31 +60,26 @@ public class AAFConHttp extends AAFCon<HttpURLConnection> { public AAFConHttp(Access access, String tag) throws CadiException, LocatorException { super(access,tag,SecurityInfoC.instance(access, HttpURLConnection.class)); - bestSS(si); hman = new HMangr(access,Config.loadLocator(si, access.getProperty(tag,tag/*try the content itself*/))); } public AAFConHttp(Access access, String urlTag, SecurityInfoC<HttpURLConnection> si) throws CadiException, LocatorException { super(access,urlTag,si); - bestSS(si); hman = new HMangr(access,Config.loadLocator(si, access.getProperty(urlTag,null))); } public AAFConHttp(Access access, Locator<URI> locator) throws CadiException, LocatorException { super(access,Config.AAF_URL,SecurityInfoC.instance(access, HttpURLConnection.class)); - bestSS(si); hman = new HMangr(access,locator); } public AAFConHttp(Access access, Locator<URI> locator, SecurityInfoC<HttpURLConnection> si) throws CadiException, LocatorException, APIException { super(access,Config.AAF_URL,si); - bestSS(si); hman = new HMangr(access,locator); } public AAFConHttp(Access access, Locator<URI> locator, SecurityInfoC<HttpURLConnection> si, String tag) throws CadiException, LocatorException, APIException { super(access,tag,si); - bestSS(si); hman = new HMangr(access, locator); } 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 98abfbf9..aa9bf138 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 @@ -140,28 +140,75 @@ public class Agent { } else { try { AAFSSO aafsso=null; - PropAccess access; + PropAccess access=null; - 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(Config.AAF_APPID, args[1]); - } - } - return props; - } - }); - access = aafsso.access(); + String hasEtc = null; + for(String a : args) { + if(a.startsWith(Config.CADI_PROP_FILES)) { + access = new PropAccess(args); + break; + } else if(a.startsWith(Config.CADI_ETCDIR)) { + int idx = a.indexOf('='); + if(idx>=0 && idx<a.length()) { + hasEtc = a.substring(idx+1); + } + } + } + + if(access==null) { + if(args.length>1 && args[1].contains("@")) { + String domain = FQI.reverseDomain(args[1]); + if(domain!=null) { + if(hasEtc==null) { + hasEtc = "."; + } + File etc = new File(hasEtc); + if(etc.exists()) { + File nsprops = new File(etc,domain+".props"); + if(nsprops.exists()) { + access = new PropAccess(new String[] {Config.CADI_PROP_FILES+'='+nsprops.getAbsolutePath()}); + } + } + } + } + } + + if(access==null) { + for(Entry<Object, Object> es : System.getProperties().entrySet()) { + if(Config.CADI_PROP_FILES.equals(es.getKey())) { + access = new PropAccess(); + } + } + } + + // When using Config file, check if Cred Exists, and if not, work with Deployer. + if(access!=null && !"config".equals(args[0]) && access.getProperty(Config.AAF_APPPASS)==null && access.getProperty(Config.CADI_ALIAS)==null) { + // not enough credentials to use Props. Use AAFSSO + access = null; + } + + if(access==null) { + 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(Config.AAF_APPID, args[1]); + } + } + return props; + } + }); + access = aafsso.access(); + } } if (aafsso!=null && aafsso.loginOnly()) { @@ -805,7 +852,7 @@ public class Agent { try { final String fqi = fqi(cmds); Artifact arti = new Artifact(); - arti.setDir(propAccess.getProperty(Config.CADI_ETCDIR, ".")); + arti.setDir(propAccess.getProperty(Config.CADI_ETCDIR, System.getProperty("user.dir"))); arti.setNs(FQI.reverseDomain(fqi)); PropHolder loc = PropHolder.get(arti, "location.props"); PropHolder cred = PropHolder.get(arti,"cred.props"); @@ -822,13 +869,20 @@ public class Agent { loc.add(tag, getProperty(propAccess, trans, false, tag, "%s: ",tag)); } + String keyfile = cred.getKeyPath(); + if(keyfile!=null) { + File fkeyfile = new File(keyfile); + if(!fkeyfile.exists()) { + ArtifactDir.write(fkeyfile,Chmod.to400,Symm.keygen()); + } + } 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); + char[] pwd = AAFSSO.cons.readPassword("Password for %s (leave blank for NO password): ", fqi); if(pwd.length>0) { cred.addEnc(Config.AAF_APPPASS, new String(pwd)); } diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactScripts.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactScripts.java index 5ee1abe2..123bb9df 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactScripts.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactScripts.java @@ -24,6 +24,8 @@ package org.onap.aaf.cadi.configure; import java.io.File; import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.aaf.Defaults; +import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.util.Chmod; import org.onap.aaf.misc.env.Trans; import org.onap.aaf.misc.env.util.Chrono; @@ -55,7 +57,7 @@ public class PlaceArtifactScripts extends ArtifactDir { classpath.append(File.pathSeparatorChar); } File f = new File(pth); - classpath.append(f.getCanonicalPath().replaceAll("[0-9]+\\.[0-9]+\\.[0-9]+","*")); + classpath.append(f.getCanonicalPath().replaceAll("[0-9]+\\.[0-9]+\\.[0-9]+",Defaults.AAF_VERSION+".*")); } write(f1,Chmod.to644, @@ -63,10 +65,15 @@ public class PlaceArtifactScripts extends ArtifactDir { "# Certificate Manager Check Script\n", "# Check on Certificate, and renew if needed.\n", "# Generated by Certificate Manager " + Chrono.timeStamp()+'\n', + "# by Deployer " + trans.getProperty(Config.AAF_APPID,"") + '\n', + "#\n", "DIR="+arti.getDir()+'\n', + "APP_ID=" + arti.getMechid() + '\n', + "FQDN=" + arti.getMachine()+ '\n', "APP="+arti.getNs()+'\n', - "EMAIL="+email, - "CP=\""+classpath.toString()+"\"\n", + "EMAIL="+email+ '\n', + "JAR=\""+classpath.toString()+"\"\n", + "JAVA=\""+javaHome() + "/bin/" +"java\"\n", checkScript ); @@ -100,7 +107,6 @@ public class PlaceArtifactScripts extends ArtifactDir { return rc==null?System.getProperty("java.home"):rc; } private final static String checkScript = - "> $DIR/$APP.msg\n\n" + "function mailit {\n" + " if [ -e /bin/mail ]; then\n" + " MAILER=/bin/mail\n" + @@ -115,9 +121,8 @@ public class PlaceArtifactScripts extends ArtifactDir { " printf \"$*\" | $MAILER -s \"AAF Certman Notification for `uname -n`\" $EMAIL\n"+ " fi\n" + "}\n\n" + - javaHome() + "/bin/" +"java -cp $CP " + - Agent.class.getName() + - " cadi_prop_files=$DIR/$APP.props check 2> $DIR/$APP.STDERR > $DIR/$APP.STDOUT\n" + + "> $DIR/$APP.msg\n\n" + + "$JAVA -jar $JAR check $APP_ID $FQDN cadi_prop_files=$DIR/$APP.props 2> $DIR/$APP.STDERR > $DIR/$APP.STDOUT\n" + "case \"$?\" in\n" + " 0)\n" + " # Note: Validation will be mailed only the first day after any modification\n" + diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/oauth/TokenClientFactory.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/oauth/TokenClientFactory.java index b3cf266e..14cf0f62 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/oauth/TokenClientFactory.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/oauth/TokenClientFactory.java @@ -152,15 +152,17 @@ public class TokenClientFactory extends Persist<Token,TimedToken> { } sb.append('_'); sb.append(tokenSource); - byte[] tohash=scope.getBytes(); - if (hash!=null && hash.length>0) { - byte temp[] = new byte[hash.length+tohash.length]; - System.arraycopy(tohash, 0, temp, 0, tohash.length); - System.arraycopy(hash, 0, temp, tohash.length, hash.length); - tohash = temp; - } - if (scope!=null && scope.length()>0) { - sb.append(Hash.toHexNo0x(Hash.hashSHA256(tohash))); + if (scope!=null) { + byte[] tohash=scope.getBytes(); + if (hash!=null && hash.length>0) { + byte temp[] = new byte[hash.length+tohash.length]; + System.arraycopy(tohash, 0, temp, 0, tohash.length); + System.arraycopy(hash, 0, temp, tohash.length, hash.length); + tohash = temp; + } + if (scope.length()>0) { + sb.append(Hash.toHexNo0x(Hash.hashSHA256(tohash))); + } } return sb.toString(); } catch (NoSuchAlgorithmException e) { diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java index de31e661..c0ac43e9 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java @@ -381,7 +381,7 @@ public class AAFSSO { addProp(Config.AAF_LOCATE_URL, locateUrl); try { if(access.getProperty(Config.AAF_URL)==null) { - access.setProperty(Config.AAF_URL, "https://AAF_LOCATE/AAF_NS.service:2.1"); + access.setProperty(Config.AAF_URL, Defaults.AAF_ROOT+".service:"+Defaults.AAF_VERSION); } AAFCon<?> aafCon = AAFCon.newInstance(access); Future<Configuration> acf; diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java index 68a8db05..0a1f38db 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java @@ -113,7 +113,8 @@ public class CmdLine { // Jonathan. Oh, well, Deployment services need this behavior. I will put this code in, but leave it undocumented. // One still needs access to the keyfile to read. // July 2016 - thought of a tool "CMPass" to regurgitate from properties, but only if allowed. - } else if ("regurgitate".equalsIgnoreCase(args[0]) && args.length>2) { + } else if (("regurgitate".equalsIgnoreCase(args[0]) || "undigest".equalsIgnoreCase(args[0])) + && args.length>2) { try { Symm symm; FileInputStream fis = new FileInputStream(args[2]); @@ -188,7 +189,7 @@ public class CmdLine { System.out.flush(); return; } catch (IOException e) { - System.err.println("Cannot regurgitate password"); + System.err.println("Cannot undigest password"); System.err.println(" \""+ e.getMessage() + '"'); } } else if ("encode64".equalsIgnoreCase(args[0]) && args.length>1) { @@ -334,6 +335,7 @@ public class CmdLine { System.out.println(" digest [<passwd>|-i|] <keyfile> (Encrypts Password with \"keyfile\""); System.out.println(" if passwd = -i, will read StdIn"); System.out.println(" if passwd is blank, will ask securely)"); + System.out.println(" undigest <enc:...> <keyfile> (Decrypts Encoded with \"keyfile\")"); System.out.println(" passgen <digits> (Generate Password of given size)"); System.out.println(" urlgen <digits> (Generate URL field of given size)"); System.out.println(" encode64 <your text> (Encodes to Base64)"); diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java index 2655b4ce..48f5e2d1 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java @@ -228,6 +228,9 @@ public class Config { public static final String AAF_URL_CM_DEF = "https://AAF_LOCATE_URL/AAF_NS.cm:"+AAF_DEFAULT_API_VERSION; public static final String AAF_URL_HELLO = "aaf_url_hello"; public static final String CM_TRUSTED_CAS = "cm_trusted_cas"; + // let NS Owners choose with <ns>.certman aaf ignoreIPs" to ignoreIP Check for Configs + // Probably only want to allow in a DEV Env. + public static final String CM_ALLOW_IGNORE_IPS="cm_allow_ignore_ips"; public static final String PATHFILTER_URLPATTERN = "pathfilter_urlpattern"; public static final String PATHFILTER_STACK = "pathfilter_stack"; diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_CmdLine.java b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_CmdLine.java index 967bf221..859f9a25 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_CmdLine.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_CmdLine.java @@ -235,6 +235,7 @@ public class JU_CmdLine { " digest [<passwd>|-i|] <keyfile> (Encrypts Password with \"keyfile\"" + lineSeparator + " if passwd = -i, will read StdIn" + lineSeparator + " if passwd is blank, will ask securely)" + lineSeparator + + " undigest <enc:...> <keyfile> (Decrypts Encoded with \"keyfile\")" + lineSeparator + " passgen <digits> (Generate Password of given size)" + lineSeparator + " urlgen <digits> (Generate URL field of given size)" + lineSeparator + " encode64 <your text> (Encodes to Base64)" + lineSeparator + diff --git a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java index 6c868378..2d93bb49 100644 --- a/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java +++ b/misc/rosetta/src/main/java/org/onap/aaf/misc/rosetta/OutJson.java @@ -39,13 +39,13 @@ public class OutJson extends Out { } else { ipw = null; } - + // If it's a fragment, print first Object Name. If root Object, skip first name Stack<LevelStack> jsonLevel = new Stack<LevelStack>(); jsonLevel.push(new LevelStack(options.length>1 && options[1])); boolean print = true, hadData=false; char afterName=0, beforeName=0, maybe = 0, prev=0; - + int count = 0; while ((p = prs.parse(in,p.reuse())).valid()) { ++count; @@ -112,18 +112,20 @@ public class OutJson extends Out { default: print = true; } - + if (maybe!=0) { if (ipw==null)writer.append(maybe); else ipw.println(maybe); maybe = 0; } - - if (beforeName!=0) { - if (ipw==null)writer.append(beforeName); - else ipw.println(beforeName); - beforeName = 0; - } + + // commented out unreachable code (as it is, beforeName is never + // assigned any value except 0 + //if (beforeName!=0) { + // if (ipw==null)writer.append(beforeName); + // else ipw.println(beforeName); + // beforeName = 0; + //} if (print) { if (p.hasName()) { writer.append('"'); |