From a77e3d6e9180c1722a9d18f7717034bb0650a130 Mon Sep 17 00:00:00 2001 From: Instrumental Date: Tue, 11 Jun 2019 19:40:45 -0500 Subject: [PATCH] Update for more Logging Info Issue-ID: AAF-853 Change-Id: I51e9160e2b53ebf74ba5f93c9a634a790f7ed848 Signed-off-by: Instrumental --- .../java/org/onap/aaf/auth/dao/cass/NsDAO.java | 1 + .../java/org/onap/aaf/auth/dao/cass/PermDAO.java | 28 +++- .../java/org/onap/aaf/auth/dao/cass/RoleDAO.java | 9 +- .../java/org/onap/aaf/auth/dao/hl/Question.java | 39 ++++- .../onap/aaf/auth/direct/DirectAAFUserPass.java | 15 +- .../org/onap/aaf/auth/dao/cass/JU_RoleDAO.java | 2 +- .../onap/aaf/auth/direct/test/JU_DirectAAFLur.java | 4 +- .../aaf/auth/direct/test/JU_DirectAAFUserPass.java | 2 +- .../java/org/onap/aaf/auth/env/AuthzTrans.java | 8 +- .../org/onap/aaf/auth/env/AuthzTransFilter.java | 16 +- .../java/org/onap/aaf/auth/env/AuthzTransImpl.java | 16 ++ .../main/java/org/onap/aaf/auth/env/NullTrans.java | 7 + .../java/org/onap/aaf/auth/rserv/TransFilter.java | 12 +- .../onap/aaf/auth/server/AbsServiceStarter.java | 2 +- .../aaf/auth/service/AuthzCassServiceImpl.java | 174 +++++++++++++++------ .../onap/aaf/auth/service/mapper/Mapper_2_0.java | 37 +++-- .../auth/service/validation/ServiceValidator.java | 4 +- .../java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java | 13 +- .../org/onap/aaf/cadi/obasic/OBasicHttpTaf.java | 18 +-- .../org/onap/aaf/cadi/filter/CadiHTTPManip.java | 42 +++-- .../java/org/onap/aaf/cadi/taf/AbsTafResp.java | 34 +++- .../org/onap/aaf/cadi/taf/LoginPageTafResp.java | 2 +- .../java/org/onap/aaf/cadi/taf/NullTafResp.java | 10 +- .../java/org/onap/aaf/cadi/taf/PuntTafResp.java | 10 +- .../main/java/org/onap/aaf/cadi/taf/TafResp.java | 5 + .../org/onap/aaf/cadi/taf/TrustNotTafResp.java | 10 +- .../java/org/onap/aaf/cadi/taf/TrustTafResp.java | 10 +- .../org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java | 11 +- .../onap/aaf/cadi/taf/basic/BasicHttpTafResp.java | 8 + .../java/org/onap/aaf/cadi/taf/cert/X509Taf.java | 1 + .../aaf/cadi/taf/dos/DenialOfServiceTafResp.java | 2 +- .../org/onap/aaf/cadi/taf/test/JU_AbsTafResp.java | 3 +- .../java/org/onap/aaf/cadi/taf/test/JU_EpiTaf.java | 2 + .../org/onap/aaf/misc/env/log4j/LogFileNamer.java | 14 +- 34 files changed, 431 insertions(+), 140 deletions(-) diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java index f769e38c..10e7844c 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/NsDAO.java @@ -64,6 +64,7 @@ public class NsDAO extends CassDAOImpl { public static final String TABLE = "ns"; public static final String TABLE_ATTRIB = "ns_attrib"; public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F + public static final int USER = 0; public static final int ROOT = 1; public static final int COMPANY=2; public static final int APP = 3; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java index 6e1057b8..3b77a577 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/PermDAO.java @@ -93,11 +93,26 @@ public class PermDAO extends CassDAOImpl { } public String fullType() { - return ns + '.' + type; + StringBuilder sb = new StringBuilder(); + if(ns==null) { + sb.append('.'); + } else { + sb.append(ns); + sb.append(ns.indexOf('@')<0?'.':':'); + } + sb.append(type); + return sb.toString(); } public String fullPerm() { - return ns + '.' + type + '|' + instance + '|' + action; + StringBuilder sb = new StringBuilder(ns); + sb.append(ns.indexOf('@')<0?'.':':'); + sb.append(type); + sb.append('|'); + sb.append(instance); + sb.append('|'); + sb.append(action); + return sb.toString(); } public String encode() { @@ -193,17 +208,26 @@ public class PermDAO extends CassDAOImpl { Data rv = new PermDAO.Data(); if (rdns.isOKhasData()) { switch(s.length) { + case 4: + rv.ns=s[0]; + rv.type=s[1]; + rv.instance=s[2]; + rv.action=s[3]; + break; case 3: + rv.ns=s[0]; rv.type=s[1]; rv.instance=s[2]; rv.action=s[3]; break; case 2: + rv.ns=s[0]; rv.type=s[1]; rv.instance=s[2]; rv.action=STAR; break; default: + rv.ns=s[0]; rv.type=s[1]; rv.instance = STAR; rv.action = STAR; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java index 127dd4e2..e31e1e6a 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/RoleDAO.java @@ -106,7 +106,14 @@ public class RoleDAO extends CassDAOImpl { } public String fullName() { - return ns + '.' + name; + StringBuilder sb = new StringBuilder(); + if(ns==null) { + sb.append('.'); + } else { + sb.append(ns.indexOf('@')<0?'.':':'); + } + sb.append(name); + return sb.toString(); } public String encode() { 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 2c98a9bc..7160edec 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 @@ -187,6 +187,7 @@ public class Question { private final CacheInfoDAO cacheInfoDAO; private final int cldays; + private final boolean alwaysSpecial; public Question(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException { PERMS = trans.slot("USER_PERMS"); @@ -220,6 +221,8 @@ public class Question { AbsCassDAO.primePSIs(trans); cldays = Integer.parseInt(trans.getProperty(Config.AAF_CRED_WARN_DAYS, Config.AAF_CRED_WARN_DAYS_DFT)); + + alwaysSpecial = Boolean.parseBoolean(trans.getProperty("aaf_always_special", Boolean.FALSE.toString())); } public void startTimers(AuthzEnv env) { @@ -612,6 +615,17 @@ public class Question { } public Result mayUser(AuthzTrans trans, String user,PermDAO.Data pdd, Access access) { + if(pdd.ns.indexOf('@')>-1) { + if(user.equals(pdd.ns)) { + NsDAO.Data ndd = new NsDAO.Data(); + ndd.name = user; + ndd.type = NsDAO.USER; + ndd.parent = ""; + return Result.ok(ndd); + } else { + return Result.err(Result.ERR_Security,"Only a User may modify User"); + } + } Result rnsd = deriveNs(trans, pdd.ns); if (rnsd.isOK()) { return mayUser(trans, user, rnsd.value, pdd, access); @@ -831,6 +845,7 @@ public class Question { byte[] md5=Hash.hashMD5(cred); if (Hash.compareTo(md5,dbcred)==0) { checkLessThanDays(trans,cldays,now,cdd); + trans.setTag(cdd.tag); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -844,6 +859,7 @@ public class Question { if (Hash.compareTo(hash,dbcred)==0) { checkLessThanDays(trans,cldays,now,cdd); + trans.setTag(cdd.tag); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -858,34 +874,41 @@ public class Question { } else { if (expired==null || expired.before(cdd.expires)) { expired = cdd.expires; + trans.setTag(cdd.tag); } } } // end for each - if (debug==null) { - trans.audit().printf("No cred matches ip=%s, user=%s\n",trans.ip(),user); - } else { - trans.audit().printf("No cred matches ip=%s, user=%s %s\n",trans.ip(),user,debug.toString()); - } + if (expired!=null) { // Note: this is only returned if there are no good Credentials rv = Result.err(Status.ERR_Security, - "Credentials %s from %s expired %s",trans.user(), trans.ip(), Chrono.dateTime(expired)); + "Credentials expired %s",Chrono.utcStamp(expired)); + } else { + if (debug==null && alwaysSpecial) { + debug = new StringBuilder(); + } + if (debug!=null) { + debug.append(trans.env().encryptor().encrypt(new String(cred))); + rv = Result.err(Status.ERR_Security,String.format("invalid password - %s",debug.toString())); + } } } } else { return Result.err(result); } - return rv == null ? Result.create((Date) null, Status.ERR_Security, "Wrong credential") : rv; + return rv == null ? Result.err(Status.ERR_Security, "Wrong credential") : rv; } private void load(StringBuilder debug, Data cdd) { - debug.append("DB Entry: user="); + debug.append("\nDB Entry: user="); debug.append(cdd.id); debug.append(",type="); debug.append(cdd.type); debug.append(",expires="); debug.append(Chrono.dateTime(cdd.expires)); + debug.append(",tag="); + debug.append(cdd.tag); debug.append('\n'); } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java index 3ef532b4..62e1592f 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/direct/DirectAAFUserPass.java @@ -52,8 +52,13 @@ public class DirectAAFUserPass implements CredVal { @Override public boolean validate(String user, Type type, byte[] pass, Object state) { + if(user==null || type==null || pass==null) { + return false; + } + try { AuthzTrans trans; + boolean transfer = false; if (state !=null) { if (state instanceof AuthzTrans) { trans = (AuthzTrans)state; @@ -61,19 +66,23 @@ public class DirectAAFUserPass implements CredVal { trans = env.newTransNoAvg(); if (state instanceof HttpServletRequest) { trans.set((HttpServletRequest)state); + transfer=true; } } } else { trans = env.newTransNoAvg(); } Result result = question.doesUserCredMatch(trans, user, pass); - trans.logAuditTrail(env.info()); + if(transfer) { + ((HttpServletRequest)state).setAttribute("CRED_TAG", trans.getTag()); + } + trans.logAuditTrail(env.debug()); switch(result.status) { case OK: return true; default: - String ip = trans.ip()==null?"":(", ip="+trans.ip()); - env.warn().log(user, "failed password validation" + ip + ':',result.errorString()); + String ip = trans.ip()==null?"":trans.ip(); + env.audit().printf("user=%s,tag=%s,ip=%s,msg=\"failed password validation: %s\"",user,trans.getTag(),ip,result.errorString()); } } catch (DAOException e) { env.error().log(e,"Cannot validate user/pass from cassandra"); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java index 16f05aa3..fa023af3 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/cass/JU_RoleDAO.java @@ -430,7 +430,7 @@ public class JU_RoleDAO { } @Test - public void testWasMOdified() { + public void testWasModified() { TimeTaken tt = Mockito.mock(TimeTaken.class); Mockito.doReturn(tt).when(trans).start("RoleDAO CREATE", Env.REMOTE); Mockito.doReturn(tt).when(trans).start("Clear Reset Deque", Env.SUB); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java index 05077438..f0f3c5d0 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFLur.java @@ -237,7 +237,7 @@ public class JU_DirectAAFLur { assertFalse(pp.match(null)); - pond = new AAFPermission("null.test", "name", "instance", "action"); - pp.match(pond); + pond = new AAFPermission("test.test", "test", "test", "test"); + assertTrue(pp.match(pond)); } } diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java index ca0a8917..c767aeb5 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/direct/test/JU_DirectAAFUserPass.java @@ -125,7 +125,7 @@ public class JU_DirectAAFUserPass { } boolean retVal = aafLocatorObj.validate(null, null, null, null); - assertTrue(retVal); + assertFalse(retVal); } @Test diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java index 0256c1bf..920f330f 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java @@ -39,8 +39,8 @@ public interface AuthzTrans extends TransStore { REQD_TYPE(int bit) { this.bit = bit; } - }; - + } + public abstract AuthzTrans set(HttpServletRequest req); public abstract HttpServletRequest hreq(); @@ -76,5 +76,9 @@ public interface AuthzTrans extends TransStore { public abstract void logAuditTrail(LogTarget lt); public abstract Date now(); + + public abstract void setTag(String tag); + + public abstract String getTag(); } \ No newline at end of file diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java index b08e0240..ec5e70de 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java @@ -85,9 +85,9 @@ public class AuthzTransFilter extends TransFilter { } @Override - protected void tallyHo(AuthzTrans trans) { + protected void tallyHo(AuthzTrans trans, String target) { Boolean b = trans.get(specialLogSlot, false); - LogTarget lt = b?trans.warn():trans.info(); + LogTarget lt = b?trans.warn():trans.debug(); if (lt.isLoggable()) { // Transaction is done, now post full Audit Trail @@ -131,8 +131,11 @@ public class AuthzTransFilter extends TransFilter { sb.append("user="); Principal p = trans.getUserPrincipal(); if (p==null) { - sb.append("n/a"); + lt=trans.warn(); + sb.append(target); + sb.append("[None]"); } else { + lt=trans.info(); sb.append(p.getName()); if (p instanceof TrustPrincipal) { sb.append('('); @@ -148,6 +151,11 @@ public class AuthzTransFilter extends TransFilter { sb.append(']'); } } + String tag = trans.getTag(); + if(tag!=null) { + sb.append(",tag="); + sb.append(tag); + } sb.append(",ip="); sb.append(trans.ip()); sb.append(",port="); @@ -176,7 +184,7 @@ public class AuthzTransFilter extends TransFilter { sb.append('"'); } - trans.warn().log(sb); + lt.log(sb); } } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java index ce947be9..a7bb24a5 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java @@ -42,10 +42,12 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { private Organization org; private int mask; private Date now; + private String tag; public AuthzTransImpl(AuthzEnv env) { super(env); org=null; mask=0; + tag=null; } /** @@ -213,4 +215,18 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { } return now; } + + /* + * (non-Javadoc) + * @see org.onap.aaf.auth.env.AuthzTrans#setTag(java.lang.String) + */ + @Override + public void setTag(String tag) { + this.tag = tag; + } + + @Override + public String getTag() { + return tag; + } } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java index 94a6aad5..54a8f484 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java @@ -236,5 +236,12 @@ public class NullTrans implements AuthzTrans { } return now; } + @Override + public void setTag(String tag) { + } + @Override + public String getTag() { + return null; + } } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java index d0fc1a3f..92c0fc24 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java @@ -33,6 +33,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.CadiWrap; @@ -88,7 +89,7 @@ public abstract class TransFilter implements Filter { protected abstract TRANS newTrans(HttpServletRequest request); protected abstract TimeTaken start(TRANS trans, ServletRequest request); protected abstract void authenticated(TRANS trans, Principal p); - protected abstract void tallyHo(TRANS trans); + protected abstract void tallyHo(TRANS trans, String target); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -98,6 +99,7 @@ public abstract class TransFilter implements Filter { TRANS trans = newTrans(req); TimeTaken overall = start(trans,request); + String target = "n/a"; try { request.setAttribute(TRANS_TAG, trans); @@ -116,6 +118,10 @@ public abstract class TransFilter implements Filter { CadiWrap cw = null; try { resp = cadi.validate(req,res,trans); + Object tag = req.getAttribute("CRED_TAG"); + if(tag!=null) { + ((AuthzTrans)trans).setTag(tag.toString()); + } switch(r=resp.isAuthenticated()) { case IS_AUTHENTICATED: cw = new CadiWrap(req,resp,cadi.getLur()); @@ -139,7 +145,7 @@ public abstract class TransFilter implements Filter { // use trans.checkpoint(resp.desc(),Env.ALWAYS); if (resp.isFailedAttempt()) { - trans.audit().log(resp.desc()); + target = resp.getTarget(); } } } catch (Exception e) { @@ -148,7 +154,7 @@ public abstract class TransFilter implements Filter { throw new ServletException(e); } finally { overall.done(); - tallyHo(trans); + tallyHo(trans,target); } } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java index 56eea435..23240cf1 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java @@ -97,7 +97,7 @@ public abstract class AbsServiceStarter to end:"); + System.out.print(" Hit to end\n:"); try { System.in.read(); System.exit(0); 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 e311513e..41c433f4 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 @@ -47,6 +47,9 @@ import javax.servlet.http.HttpServletRequest; import org.onap.aaf.auth.common.Define; import org.onap.aaf.auth.dao.DAOException; +import org.onap.aaf.auth.dao.cached.CachedPermDAO; +import org.onap.aaf.auth.dao.cached.CachedRoleDAO; +import org.onap.aaf.auth.dao.cached.CachedUserRoleDAO; import org.onap.aaf.auth.dao.cass.ApprovalDAO; import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.dao.cass.CredDAO; @@ -799,62 +802,129 @@ public class AuthzCassServiceImpl createPerm(final AuthzTrans trans,REQUEST rreq) { final Result newPd = mapper.perm(trans, rreq); - // Does Perm Type exist as a Namespace? - if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) { - return Result.err(Status.ERR_ConflictAlreadyExists, - "Permission Type exists as a Namespace"); - } - + final ServiceValidator v = new ServiceValidator(); if (v.perm(newPd).err()) { return Result.err(Status.ERR_BadData,v.errs()); } - - Result fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false, - new Mapper.Memo() { - @Override - public String get() { - return "Create Permission [" + - newPd.value.fullType() + '|' + - newPd.value.instance + '|' + - newPd.value.action + ']'; - } - }, - new MayChange() { - private Result nsd; - @Override - public Result mayChange() { - if (nsd==null) { - nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write); - } - return nsd; - } - }); - Result> nsr = ques.nsDAO().read(trans, newPd.value.ns); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); + + // User Permission mechanism + if(newPd.value.ns.indexOf('@')>0) { + PermDAO.Data pdd = newPd.value; + if(trans.user().equals(newPd.value.ns)) { + CachedPermDAO permDAO = ques.permDAO(); + Result> rlpdd = permDAO.read(trans, pdd); + if(rlpdd.notOK()) { + return Result.err(rlpdd); + } + if(!rlpdd.isEmpty()) { + return Result.err(Result.ERR_ConflictAlreadyExists,"Permission already exists"); + } + + RoleDAO.Data rdd = new RoleDAO.Data(); + rdd.ns = pdd.ns; + rdd.name = "user"; + + pdd.roles(true).add(rdd.encode()); + Result rpdd = permDAO.create(trans, pdd); + if(rpdd.notOK()) { + return Result.err(rpdd); + } + + CachedRoleDAO roleDAO = ques.roleDAO(); + Result> rlrdd = roleDAO.read(trans, rdd); + if(rlrdd.notOK()) { + return Result.err(rlrdd); + } else { + if(!rlrdd.isEmpty()) { + rdd = rlrdd.value.get(0); + } + } + + String eperm = pdd.encode(); + rdd.perms(true).add(eperm); + Result rv = roleDAO.update(trans, rdd); + if(rv.notOK()) { + return rv; + } + + CachedUserRoleDAO urDAO = ques.userRoleDAO(); + UserRoleDAO.Data urdd = new UserRoleDAO.Data(); + urdd.user = trans.user(); + urdd.ns = rdd.ns; + urdd.rname = rdd.name; + urdd.role = rdd.fullName(); + Result> rlurdd = urDAO.read(trans, urdd); + if(rlurdd.notOK()) { + return Result.err(rlrdd); + } else if(rlurdd.isEmpty()) { + GregorianCalendar gc = trans.org().expiration(null, Expiration.UserInRole); + if(gc==null) { + return Result.err(Result.ERR_Policy,"Organzation does not grant Expiration for UserRole"); + } else { + urdd.expires = gc.getTime(); + } + Result rurdd = urDAO.create(trans, urdd); + return Result.err(rurdd); + } + return rv; + } else { + return Result.err(Result.ERR_Security,"Only the User can create User Permissions"); + } + } else { + // Does Perm Type exist as a Namespace? + if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Permission Type exists as a Namespace"); + } + + Result fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false, + new Mapper.Memo() { + @Override + public String get() { + return "Create Permission [" + + newPd.value.fullType() + '|' + + newPd.value.instance + '|' + + newPd.value.action + ']'; + } + }, + new MayChange() { + private Result nsd; + @Override + public Result mayChange() { + if (nsd==null) { + nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write); + } + return nsd; + } + }); + + Result> nsr = ques.nsDAO().read(trans, newPd.value.ns); + if (nsr.notOKorIsEmpty()) { + return Result.err(nsr); + } + switch(fd.status) { + case OK: + Result rfc = func.createFuture(trans,fd.value, + newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action, + trans.user(), + nsr.value.get(0), + FUTURE_OP.C); + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", + newPd.value.ns, + newPd.value.type, + newPd.value.instance, + newPd.value.action); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + return func.createPerm(trans, newPd.value, true); + default: + return Result.err(fd); + } } - switch(fd.status) { - case OK: - Result rfc = func.createFuture(trans,fd.value, - newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action, - trans.user(), - nsr.value.get(0), - FUTURE_OP.C); - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", - newPd.value.ns, - newPd.value.type, - newPd.value.instance, - newPd.value.action); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - return func.createPerm(trans, newPd.value, true); - default: - return Result.err(fd); - } } @ApiDoc( @@ -1392,7 +1462,7 @@ public class AuthzCassServiceImpl fd = mapper.future(trans,PermDAO.TABLE,from,perm,false, new Mapper.Memo() { @Override diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java index 187f4e39..7a5d0c18 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java @@ -58,6 +58,7 @@ import org.onap.aaf.auth.org.Organization.Expiration; import org.onap.aaf.auth.rserv.Pair; import org.onap.aaf.auth.service.MayChange; import org.onap.aaf.cadi.aaf.marshal.CertsMarshal; +import org.onap.aaf.cadi.util.Split; import org.onap.aaf.cadi.util.Vars; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; @@ -364,18 +365,32 @@ public class Mapper_2_0 implements Mapper perm(AuthzTrans trans, Request req) { PermRequest from = (PermRequest)req; - Result nss = q.deriveNsSplit(trans, from.getType()); + String type = from.getType(); + if(type==null) { + return Result.err(Result.ERR_BadData, "Invalid Perm Type"); + } PermDAO.Data pd = new PermDAO.Data(); - if (nss.isOK()) { - pd.ns=nss.value.ns; - pd.type = nss.value.name; - pd.instance = from.getInstance(); - pd.action = from.getAction(); - pd.description = from.getDescription(); - trans.checkpoint(pd.fullPerm(), Env.ALWAYS); - return Result.ok(pd); - } else { - return Result.err(nss); + if(type.contains("@")) { + String[] split = Split.splitTrim(':', type); + pd.ns = split[0]; + pd.type=split.length>1?split[1]:""; + pd.instance = from.getInstance(); + pd.action = from.getAction(); + pd.description = from.getDescription(); + return Result.ok(pd); + } else { + Result nss = q.deriveNsSplit(trans, from.getType()); + if (nss.isOK()) { + pd.ns=nss.value.ns; + pd.type = nss.value.name; + pd.instance = from.getInstance(); + pd.action = from.getAction(); + pd.description = from.getDescription(); + trans.checkpoint(pd.fullPerm(), Env.ALWAYS); + return Result.ok(pd); + } else { + return Result.err(nss); + } } } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java index adff4612..fb7556ed 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java @@ -57,7 +57,9 @@ public class ServiceValidator extends Validator { if (pd==null) { msg("Perm Data is null."); } else { - ns(pd.ns); + if(!pd.ns.contains("@")) { + ns(pd.ns); + } permType(pd.type,pd.ns); permInstance(pd.instance); permAction(pd.action); diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java index 99c3c3fc..a25d2502 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java @@ -106,6 +106,7 @@ public class AAFTaf extends AbsUserCache implements HttpT // Note: Either Carbon or Silicon based LifeForms ok String authz = req.getHeader("Authorization"); + String target = "invalid"; if (authz != null && authz.startsWith("Basic ")) { if (warn&&!req.isSecure()) { aaf.access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); @@ -131,7 +132,7 @@ public class AAFTaf extends AbsUserCache implements HttpT Miss miss = missed(bp.getName(), bp.getCred()); if (miss!=null && !miss.mayContinue()) { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req, "User/Pass Retry limit exceeded"), RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true); } @@ -157,11 +158,11 @@ public class AAFTaf extends AbsUserCache implements HttpT // Note: AddMiss checks for miss==null, and is part of logic boolean rv= addMiss(bp.getName(),bp.getCred()); if (rv) { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req, "user/pass combo invalid via AAF from " + req.getRemoteAddr()), RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true); } else { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req, "user/pass combo invalid via AAF from " + req.getRemoteAddr() + " - Retry limit exceeded"), RESP.FAIL,resp,aaf.getRealm(),true); } @@ -172,7 +173,7 @@ public class AAFTaf extends AbsUserCache implements HttpT } catch (IOException e) { String msg = buildMsg(null,req,"Invalid Auth Token"); aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); - return new BasicHttpTafResp(aaf.access,null,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true); + return new BasicHttpTafResp(aaf.access,target,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true); } catch (Exception e) { String msg = buildMsg(null,req,"Authenticating Service unavailable"); try { @@ -181,10 +182,10 @@ public class AAFTaf extends AbsUserCache implements HttpT aaf.access.log(e1, "Error Invalidating Client"); } aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); - return new BasicHttpTafResp(aaf.access,null,msg, RESP.FAIL, resp, aaf.getRealm(),false); + return new BasicHttpTafResp(aaf.access,target,msg, RESP.FAIL, resp, aaf.getRealm(),false); } } - return new BasicHttpTafResp(aaf.access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false); + return new BasicHttpTafResp(aaf.access,target,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false); } private String buildMsg(Principal pr, HttpServletRequest req, Object... msg) { diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/obasic/OBasicHttpTaf.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/obasic/OBasicHttpTaf.java index 8c2cc82d..4ae8ba5f 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/obasic/OBasicHttpTaf.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/obasic/OBasicHttpTaf.java @@ -84,7 +84,7 @@ public class OBasicHttpTaf extends AbsOTafLur implements HttpTaf { */ public TafResp validate(Taf.LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { // See if Request implements BasicCred (aka CadiWrap or other), and if User/Pass has already been set separately - final String user; + String user = "invalid"; String password=null; byte[] cred=null; if (req instanceof BasicCred) { @@ -106,18 +106,18 @@ public class OBasicHttpTaf extends AbsOTafLur implements HttpTaf { } else { access.printf(Level.AUDIT,"Malformed BasicAuth entry ip=%s, entry=%s",req.getRemoteAddr(), access.encrypt(temp)); - return new BasicHttpTafResp(access,null,"Malformed BasicAuth entry",RESP.FAIL,resp,realm,false); + return new BasicHttpTafResp(access,user,"Malformed BasicAuth entry",RESP.FAIL,resp,realm,false); } if (!rbac.validate(user,Type.PASSWORD,password.getBytes(),req)) { - return new BasicHttpTafResp(access,null,buildMsg(null,req,"user/pass combo invalid for ",user,"from",req.getRemoteAddr()), + return new BasicHttpTafResp(access,user,buildMsg(null,req,"user/pass combo invalid for ",user,"from",req.getRemoteAddr()), RESP.TRY_AUTHENTICATING,resp,realm,true); } } catch (IOException e) { access.log(e, ERROR_GETTING_TOKEN_CLIENT); - return new BasicHttpTafResp(access,null,ERROR_GETTING_TOKEN_CLIENT,RESP.FAIL,resp,realm,false); + return new BasicHttpTafResp(access,user,ERROR_GETTING_TOKEN_CLIENT,RESP.FAIL,resp,realm,false); } } else { - return new BasicHttpTafResp(access,null,"Not a Basic Auth",RESP.TRY_ANOTHER_TAF,resp,realm,false); + return new BasicHttpTafResp(access,user,"Not a Basic Auth",RESP.TRY_ANOTHER_TAF,resp,realm,false); } } @@ -135,25 +135,25 @@ public class OBasicHttpTaf extends AbsOTafLur implements HttpTaf { Result rtt = pclient.content.getToken('B',scope); if (rtt.isOK()) { if (rtt.value.expired()) { - return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: Token Expired",RESP.FAIL,resp,realm,true); + return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: Token Expired",RESP.FAIL,resp,realm,true); } else { TimedToken tt = rtt.value; Result prin = tkMgr.toPrincipal(tt.getAccessToken(), cred); if (prin.isOK()) { return new BasicHttpTafResp(access,prin.value,"BasicAuth/OAuth Token Authentication",RESP.IS_AUTHENTICATED,resp,realm,true); } else { - return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: " + prin.code + ' ' + prin.error,RESP.FAIL,resp,realm,true); + return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: " + prin.code + ' ' + prin.error,RESP.FAIL,resp,realm,true); } } } else { - return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: " + rtt.code + ' ' + rtt.error,RESP.FAIL,resp,realm,true); + return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: " + rtt.code + ' ' + rtt.error,RESP.FAIL,resp,realm,true); } } finally { pclient.done(); } } catch (APIException | CadiException | LocatorException | NoSuchAlgorithmException e) { access.log(e, ERROR_GETTING_TOKEN_CLIENT); - return new BasicHttpTafResp(access,null,ERROR_GETTING_TOKEN_CLIENT,RESP.TRY_ANOTHER_TAF,resp,realm,false); + return new BasicHttpTafResp(access,user,ERROR_GETTING_TOKEN_CLIENT,RESP.TRY_ANOTHER_TAF,resp,realm,false); } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java index bab758ec..5920a260 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java @@ -55,7 +55,13 @@ import org.onap.aaf.cadi.util.UserChainManip; * */ public class CadiHTTPManip { - private static final String ACCESS_CADI_CONTROL = ".access|cadi|control"; + private static final String ACCESS_DENIED = "Access Denied"; + private static final String NO_TAF_WILL_AUTHORIZE = "No TAF will authorize"; + private static final String AUTHENTICATION_FAILURE = "Authentication Failure"; + private static final String AUTHENTICATING_VIA_REDIRECTION = "Authenticating via redirection"; + private static final String MSG_FMT = "user=%s,ip=%s:%d,msg=\"%s: %s\""; + private static final String AUTHENTICATED = "Authenticated"; + private static final String ACCESS_CADI_CONTROL = ".access|cadi|control"; private static final String METH = "OPTIONS"; private static final String CADI = "/cadi/"; private static final String CADI_CACHE_PRINT = "/cadi/cache/print"; @@ -120,40 +126,42 @@ public class CadiHTTPManip { TafResp tresp = taf.validate(Taf.LifeForm.LFN, hreq, hresp); switch(tresp.isAuthenticated()) { case IS_AUTHENTICATED: - access.printf(Level.INFO,"Authenticated: %s from %s:%d", - tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),AUTHENTICATED,tresp.desc()); break; case TRY_AUTHENTICATING: switch (tresp.authenticate()) { case IS_AUTHENTICATED: - access.printf(Level.INFO,"Authenticated: %s from %s:%d", - tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),AUTHENTICATED,tresp.desc()); break; case HTTP_REDIRECT_INVOKED: - access.log(Level.INFO,"Authenticating via redirection: ", tresp.desc()); + access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),AUTHENTICATING_VIA_REDIRECTION,tresp.desc()); break; case NO_FURTHER_PROCESSING: - access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d" - , tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); + access.printf(Level.AUDIT,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),AUTHENTICATION_FAILURE,tresp.desc()); hresp.sendError(403, tresp.desc()); // Forbidden break; default: - access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d" - , hreq.getRemoteAddr(), hreq.getRemotePort()); + access.printf(Level.AUDIT,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc()); hresp.sendError(403, tresp.desc()); // Forbidden } break; case NO_FURTHER_PROCESSING: - access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d", - tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort()); - hresp.sendError(403, "Access Denied"); // FORBIDDEN + access.printf(Level.AUDIT,MSG_FMT, tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc()); + hresp.sendError(403, ACCESS_DENIED); // FORBIDDEN break; default: - access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d" - , hreq.getRemoteAddr(), hreq.getRemotePort()); - hresp.sendError(403, "Access Denied"); // FORBIDDEN + access.printf(Level.AUDIT,MSG_FMT, tresp.getTarget(),hreq.getRemoteAddr(), + hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc()); + hresp.sendError(403, ACCESS_DENIED); // FORBIDDEN } + return tresp; } @@ -193,7 +201,7 @@ public class CadiHTTPManip { } return true; } - + public Lur getLur() { return lur; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java index b3ac0945..364a0728 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java @@ -37,7 +37,9 @@ public abstract class AbsTafResp implements TafResp { protected final Access access; protected final String tafName; + // Note: Valid Resp is based on Principal being non-null protected final TaggedPrincipal principal; + protected final String target; protected final String desc; private float timing; @@ -58,6 +60,28 @@ public abstract class AbsTafResp implements TafResp { this.access = access; this.tafName = tafname; this.principal = principal; + this.target = principal==null?"unknown":principal.getName(); + this.desc = description; + } + + /** + * AbsTafResp + * + * Set and hold + * Description (for logging) + * Principal (as created by derived class) + * Access (for access to underlying container, i.e. for Logging, auditing, ClassLoaders, etc) + * + * @param access + * @param tafname + * @param principal + * @param description + */ + public AbsTafResp(Access access, String tafname, String target, String description) { + this.access = access; + this.tafName = tafname; + this.principal = null; + this.target = target; this.desc = description; } @@ -102,7 +126,15 @@ public abstract class AbsTafResp implements TafResp { return principal; } - /** + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#getTarget() + */ + @Override + public String getTarget() { + return target; + } + + /** * getAccess() * * Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated. diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java index a5ce45b7..d64fbe0d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java @@ -37,7 +37,7 @@ public class LoginPageTafResp extends AbsTafResp { private final String loginPageURL; private LoginPageTafResp(Access access, final HttpServletResponse resp, String loginPageURL) { - super(access, "LoginPage", null, "Multiple Possible HTTP Logins available. Redirecting to Login Choice Page"); + super(access, "LoginPage","unknown", "Multiple Possible HTTP Logins available. Redirecting to Login Choice Page"); httpResp = resp; this.loginPageURL = loginPageURL; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java index a3c8f5bb..fb66ec08 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java @@ -60,7 +60,15 @@ class NullTafResp implements TafResp { return null; } - public Access getAccess() { + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#getTarget() + */ + @Override + public String getTarget() { + return "unknown"; + } + + public Access getAccess() { return Access.NULL; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java index e6555051..3bc278e5 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java @@ -63,7 +63,15 @@ public class PuntTafResp implements TafResp { return null; } - public Access getAccess() { + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#getTarget() + */ + @Override + public String getTarget() { + return "punt"; + } + + public Access getAccess() { return NullTafResp.singleton().getAccess(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java index f3afde72..6850a372 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java @@ -81,6 +81,11 @@ public interface TafResp { * @return */ public TaggedPrincipal getPrincipal(); + + /** Target - when Authentication Fails, need to know what ID was being attempted + * @return + */ + public String getTarget(); /** * get the Access object which created this object, allowing the responder to appropriate Log, etc diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java index 6b8adeb8..f397cbab 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java @@ -62,7 +62,15 @@ public class TrustNotTafResp implements TafResp { return delegate.getPrincipal(); } - @Override + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#getTarget() + */ + @Override + public String getTarget() { + return delegate.getTarget(); + } + + @Override public Access getAccess() { return delegate.getAccess(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java index 91f9f8c4..061d4e2f 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java @@ -64,7 +64,15 @@ public class TrustTafResp implements TafResp { return principal; } - @Override + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#getTarget() + */ + @Override + public String getTarget() { + return delegate.getTarget(); + } + + @Override public Access getAccess() { return delegate.getAccess(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java index d5c88464..dcd27d63 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java @@ -120,13 +120,15 @@ public class BasicHttpTaf implements HttpTaf { return new BasicHttpTafResp(access,bp,bp.getName()+" authenticated by password",RESP.IS_AUTHENTICATED,resp,realm,false); } else { //TODO may need timed retries in a given time period - return new BasicHttpTafResp(access,null,buildMsg(bp,req,"user/pass combo invalid for ",bc.getUser(),"from",req.getRemoteAddr()), + return new BasicHttpTafResp(access,bc.getUser(),buildMsg(bp,req,"user/pass combo invalid for ",bc.getUser(),"from",req.getRemoteAddr()), RESP.TRY_AUTHENTICATING,resp,realm,true); } } } // Get User/Password from Authorization Header value String authz = req.getHeader("Authorization"); + String target="unknown"; + if (authz != null && authz.startsWith("Basic ")) { if (warn&&!req.isSecure()) { access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); @@ -136,6 +138,7 @@ public class BasicHttpTaf implements HttpTaf { } try { CachedBasicPrincipal ba = new CachedBasicPrincipal(this,authz,realm,timeToLive); + target=ba.getName(); if (DenialOfServiceTaf.isDeniedID(ba.getName())!=null) { return DenialOfServiceTaf.respDenyID(access,ba.getName()); } @@ -152,16 +155,16 @@ public class BasicHttpTaf implements HttpTaf { return new BasicHttpTafResp(access,ba, ba.getName()+" authenticated by BasicAuth password",RESP.IS_AUTHENTICATED,resp,realm,false); } else { //TODO may need timed retries in a given time period - return new BasicHttpTafResp(access,null,buildMsg(ba,req,"user/pass combo invalid"), + return new BasicHttpTafResp(access,target,buildMsg(ba,req,"user/pass combo invalid"), RESP.TRY_AUTHENTICATING,resp,realm,true); } } catch (IOException e) { String msg = buildMsg(null,req,"Failed HTTP Basic Authorization (", e.getMessage(), ')'); access.log(Level.INFO,msg); - return new BasicHttpTafResp(access,null,msg, RESP.TRY_AUTHENTICATING, resp, realm,true); + return new BasicHttpTafResp(access,target,msg, RESP.TRY_AUTHENTICATING, resp, realm,true); } } - return new BasicHttpTafResp(access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false); + return new BasicHttpTafResp(access,target,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false); } protected String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) { diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java index d1acf5fe..e2174493 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java @@ -45,6 +45,14 @@ public class BasicHttpTafResp extends AbsTafResp implements TafResp { this.wasFailed = wasFailed; } + public BasicHttpTafResp(Access access, String target, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) { + super(access, tafName, target, description); + httpResp = resp; + this.realm = realm; + this.status = status; + this.wasFailed = wasFailed; + } + public RESP authenticate() throws IOException { httpResp.setStatus(401); // Unauthorized httpResp.setHeader("WWW-Authenticate", "Basic realm=\""+realm+'"'); diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java index fca99a31..5f5ff574 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java @@ -266,6 +266,7 @@ public class X509Taf implements HttpTaf { // if Principal is found, check for "AS_USER" and whether this entity is trusted to declare if (prin!=null) { + // Note: Tag for Certs is Fingerprint, but that takes computation... leaving off return new X509HttpTafResp( access, prin, diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java index 2fcd1553..2215a6f9 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java @@ -32,7 +32,7 @@ public class DenialOfServiceTafResp extends AbsTafResp { private RESP ect; // Homage to Arethra Franklin public DenialOfServiceTafResp(Access access, RESP resp, String description ) { - super(access, tafName, null, description); + super(access, tafName, "dos", description); ect = resp; } diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_AbsTafResp.java b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_AbsTafResp.java index bf5a15fb..4dba8edb 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_AbsTafResp.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_AbsTafResp.java @@ -73,7 +73,7 @@ public class JU_AbsTafResp { assertThat(tafResp.getAccess(), is(access)); assertThat(tafResp.isFailedAttempt(), is(false)); - tafResp = new AbsTafResp(null, JUNIT, null, null) { + tafResp = new AbsTafResp(null, JUNIT, "unknown", null) { @Override public RESP authenticate() throws IOException { return null; } @@ -82,6 +82,7 @@ public class JU_AbsTafResp { assertThat(tafResp.isValid(), is(false)); assertThat(tafResp.isAuthenticated(), is(RESP.TRY_ANOTHER_TAF)); assertThat(tafResp.getPrincipal(), is(nullValue())); + assertThat(tafResp.getTarget(), is("unknown")); assertThat(tafResp.getAccess(), is(nullValue())); assertThat(tafResp.taf(), is(JUNIT)); assertThat(tafResp.isFailedAttempt(), is(false)); diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_EpiTaf.java b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_EpiTaf.java index 08602cb0..8e103893 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_EpiTaf.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_EpiTaf.java @@ -76,6 +76,7 @@ public class JU_EpiTaf { @Override public RESP isAuthenticated() { return RESP.TRY_ANOTHER_TAF; } @Override public RESP authenticate() throws IOException { return null; } @Override public TaggedPrincipal getPrincipal() { return null; } + @Override public String getTarget() {return "unknown";} @Override public Access getAccess() { return null; } @Override public boolean isFailedAttempt() { return false; } @Override public float timing() { return 0; } @@ -93,6 +94,7 @@ public class JU_EpiTaf { @Override public RESP isAuthenticated() { return RESP.TRY_AUTHENTICATING; } @Override public RESP authenticate() throws IOException { return null; } @Override public TaggedPrincipal getPrincipal() { return null; } + @Override public String getTarget() {return "unknown";} @Override public Access getAccess() { return null; } @Override public boolean isFailedAttempt() { return false; } @Override public float timing() { return 0; } diff --git a/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java index 9a615fb8..85aae6f0 100644 --- a/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java +++ b/misc/log4j/src/main/java/org/onap/aaf/misc/env/log4j/LogFileNamer.java @@ -57,14 +57,20 @@ public class LogFileNamer { */ public String setAppender(String appender) throws IOException { File f = new File(String.format(FIRST_FILE_FORMAT_STR, dir, root, appender)); + File lock = new File(f.getAbsoluteFile()+".lock"); if(f.exists()) { - int i = 0; - while ((f = new File(String.format(FILE_FORMAT_STR, dir, root, appender, i))).exists()) { - ++i; - } + if(lock.exists()) { + int i = 0; + while ((f = new File(String.format(FILE_FORMAT_STR, dir, root, appender, i))).exists() && + (lock = new File(f.getAbsoluteFile()+".lock")).exists()) { + ++i; + } + } } try { + lock.createNewFile(); + lock.deleteOnExit(); f.createNewFile(); } catch (IOException e) { throw new IOException("Cannot create file '" + f.getCanonicalPath() + '\'', e); -- 2.16.6