diff options
Diffstat (limited to 'cadi')
32 files changed, 454 insertions, 163 deletions
diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java index be1d3922..037ee8be 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java @@ -83,6 +83,9 @@ public class AAFPermission implements Permission { * If you want a simple field comparison, it is faster without REGEX */ public boolean match(Permission p) { + if(p==null) { + return false; + } String aafNS; String aafType; String aafInstance; diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/TestConnectivity.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/TestConnectivity.java index e5a0a28c..f02c17f8 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/TestConnectivity.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/TestConnectivity.java @@ -76,7 +76,7 @@ public class TestConnectivity { List<SecuritySetter<HttpURLConnection>> lss = loadSetters(access,si); ///////// String directAAFURL = aaf_urls.get(Config.AAF_URL); - if(directAAFURL!=null && !directAAFURL.contains("/locate/")) { + if(directAAFURL!=null && !directAAFURL.contains("/locate/") || !directAAFURL.contains("AAF_LOCATE_URL")) { print(true,"Test Connections by non-located aaf_url"); Locator<URI> locator = new SingleEndpointLocator(directAAFURL); connectTest(locator,new URI(directAAFURL)); diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java index 55421262..42efd89b 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java @@ -88,9 +88,13 @@ public class ErrMessage { public StringBuilder toMsg(StringBuilder sb, Error err) { sb.append(err.getMessageId()); sb.append(' '); - String[] vars = new String[err.getVariables().size()]; + Object[] vars = new String[err.getVariables().size()]; err.getVariables().toArray(vars); Vars.convert(sb, err.getText(),vars); return sb; } + + public Error getError(Future<?> future) throws APIException { + return errDF.newData().in(TYPE.JSON).load(future.body()).asObject(); + } } diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java index 606638a4..ec0875c1 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java @@ -117,7 +117,7 @@ public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> { return "AAF Inaccessible"; case UNVALIDATED: addUser(new User<AAFPermission>(user,bytes,con.timeout)); - return "User/Pass combo invalid for " + user; + return "user/pass combo invalid for " + user; case DENIED: return "AAF denies API for " + user; default: 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<CLIENT> extends AbsUserCache<AAFPermission> 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<CLIENT> extends AbsUserCache<AAFPermission> 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<CLIENT> extends AbsUserCache<AAFPermission> 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<CLIENT> extends AbsUserCache<AAFPermission> 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<CLIENT> extends AbsUserCache<AAFPermission> 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/aaf/v2_0/AbsAAFLocator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java index ac8168b9..e43250a0 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java @@ -122,6 +122,9 @@ public abstract class AbsAAFLocator<TRANS extends Trans> implements Locator<URI> } public static Locator<URI> create(final String name, final String version) throws LocatorException { + if(locatorCreator==null) { + throw new LocatorException("LocatorCreator is not set"); + } return locatorCreator.create(name, version); } @@ -234,7 +237,7 @@ public abstract class AbsAAFLocator<TRANS extends Trans> implements Locator<URI> @Override public Item best() throws LocatorException { if (!hasItems()) { - throw new LocatorException("No Entries found for '" + aaf_locator_uri.toString() + "/locate/" + name + ':' + version + '\''); + throw new LocatorException("No Entries found for '" + aaf_locator_uri.toString() + '/' + name + ':' + version + '\''); } List<EP> lep = new ArrayList<>(); EP first = null; 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 e50b52d8..98abfbf9 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 @@ -28,12 +28,14 @@ import java.io.IOException; 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.Deque; import java.util.GregorianCalendar; @@ -84,7 +86,8 @@ import locate.v1_1.Configuration; import locate.v1_1.Configuration.Props; public class Agent { - private static final String HASHES = "################################################################"; + private static final String AGENT_LOAD_URLS = "Agent:loadURLs"; + private static final String HASHES = "################################################################"; private static final String PRINT = "print"; private static final String FILE = "file"; public static final String PKCS12 = "pkcs12"; @@ -233,8 +236,7 @@ public class Agent { aafsso.setLogDefault(); aafsso.setStdErrDefault(); - Map<String, String> aaf_urls = loadURLs(access); - aafsso.addProp(Config.AAF_URL_CM, aaf_urls.get(Config.AAF_URL_CM)); + /*urls=*/loadURLs(access); aafsso.writeFiles(); } @@ -310,29 +312,41 @@ public class Agent { 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 proto = "fs".equals(u)?"http://":"https://"; - String lhost; - if("locate".equals(u)) { - lhost=rph.default_fqdn; - } else { - lhost=Config.AAF_LOCATE_URL_TAG; - } - String value = rph.replacements("Agent:loadURLs", - proto + lhost + "/%CNS.%AAF_NS." + ("aaf".equals(u)?"service":u) + ':' + version, - null,dot_le); + for(String u : new String[] {"locate","aaf","oauth","cm","gui","fs","hello","token","introspect"}) { + String tag; + String append=null; switch(u) { - case "aaf": rv.put(Config.AAF_URL, value); break; - case "locate": rv.put(Config.getAAFLocateUrl(access), value); break; - case "token": rv.put(Config.AAF_OAUTH2_TOKEN_URL, value); break; - case "introspect": rv.put(Config.AAF_OAUTH2_INTROSPECT_URL, value); break; - case "cm": rv.put(Config.AAF_URL_CM, value); break; - case "gui": rv.put(Config.AAF_URL_GUI, value); break; - case "fs": rv.put(Config.AAF_URL_FS, value); break; - case "hello": rv.put(Config.AAF_URL_HELLO, value); break; + 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: - rv.put("aaf_url_" + u, value); + 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_LOAD_URLS, + proto + lhost + "/%CNS.%AAF_NS." + ("aaf".equals(u)?"service":u) + ':' + version, + null,dot_le); + if(append!=null) { + value+=append; + } + } else { + value = rph.replacements(AGENT_LOAD_URLS, value,null,dot_le); } + rv.put(tag, value); }; aaf_urls = rv; } @@ -379,6 +393,9 @@ public class Agent { private static String fqi(Deque<String> cmds) { if (cmds.size()<1) { String alias = env.getProperty(Config.CADI_ALIAS); + if(alias==null) { + alias = env.getProperty(Config.AAF_APPID); + } return alias!=null?alias:AAFSSO.cons.readLine("AppID: "); } return cmds.removeFirst(); @@ -825,9 +842,12 @@ public class Agent { app.add(Config.AAF_LOCATE_URL, Config.getAAFLocateUrl(propAccess)); app.add(Config.AAF_ENV,propAccess, "DEV"); - String release = propAccess.getProperty(Config.AAF_RELEASE); + 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_RELEASE, release); + app.add(Config.AAF_DEPLOYED_VERSION, release); } for(Entry<Object, Object> aaf_loc_prop : propAccess.getProperties().entrySet()) { String key = aaf_loc_prop.getKey().toString(); @@ -910,26 +930,15 @@ public class Agent { } else { aafcon = aafcon(propAccess); if (aafcon!=null) { // get Properties from Remote AAF - final String locator = getProperty(propAccess,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: "); - - Future<Configuration> acf = aafcon.client(new SingleEndpointLocator(locator)) - .read("/configure/"+fqi+"/aaf", configDF); - if (acf.get(TIMEOUT)) { - for (Props props : acf.value.getProps()) { - 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()); - } - } - } 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)); + 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()); + } } + } } } @@ -940,6 +949,20 @@ public class Agent { } } + public static List<Props> aafProps(Trans trans, AAFCon<?> aafcon, String locator, String fqi) throws CadiException, APIException, URISyntaxException { + Future<Configuration> 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 { System.out.println("Validating Configuration..."); diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactInKeystore.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactInKeystore.java index 7256af40..67b3df09 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactInKeystore.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/configure/PlaceArtifactInKeystore.java @@ -66,17 +66,26 @@ public class PlaceArtifactInKeystore extends ArtifactDir { X509Certificate x509; List<X509Certificate> chainList = new ArrayList<>(); Set<X509Certificate> caSet = new HashSet<>(); + X509Certificate curr = null; for (Certificate c : certColl) { x509 = (X509Certificate)c; // Is a Root (self-signed, anyway) if (x509.getSubjectDN().equals(x509.getIssuerDN())) { caSet.add(x509); } else { - chainList.add(x509); + // Expect Certs in Trust Chain Order. + if(curr==null) { + chainList.add(x509); + curr=x509; + } else { + // Only Add Cert next on the list + if(curr.getIssuerDN().equals(x509.getSubjectDN())) { + chainList.add(x509); + curr=x509; + } + } } } -// chainList.addAll(caSet); - //Collections.reverse(chainList); // Properties, etc // Add CADI Keyfile Entry to Properties 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 b0c32942..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 @@ -29,6 +29,8 @@ import java.nio.file.Path; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -55,6 +57,7 @@ import aafoauth.v2_0.Token; public class TokenClientFactory extends Persist<Token,TimedToken> { private static TokenClientFactory instance; + private final Set<String> alts; private Map<String,AAFConHttp> aafcons = new ConcurrentHashMap<>(); private SecurityInfoC<HttpURLConnection> hsi; // Package on purpose @@ -62,14 +65,26 @@ public class TokenClientFactory extends Persist<Token,TimedToken> { private TokenClientFactory(Access pa) throws APIException, GeneralSecurityException, IOException, CadiException { super(pa, new RosettaEnv(pa.getProperties()),Token.class,"outgoing"); + Map<String, String> aaf_urls = Agent.loadURLs(pa); + alts = new TreeSet<>(); + if (access.getProperty(Config.AAF_OAUTH2_TOKEN_URL,null)==null) { access.getProperties().put(Config.AAF_OAUTH2_TOKEN_URL, aaf_urls.get(Config.AAF_OAUTH2_TOKEN_URL)); // Default to AAF } + if (access.getProperty(Config.AAF_OAUTH2_INTROSPECT_URL,null)==null) { access.getProperties().put(Config.AAF_OAUTH2_INTROSPECT_URL, aaf_urls.get(Config.AAF_OAUTH2_INTROSPECT_URL)); // Default to AAF); } - + + for(String tag : new String[] {Config.AAF_ALT_OAUTH2_TOKEN_URL, Config.AAF_ALT_OAUTH2_INTROSPECT_URL}) { + String value = access.getProperty(tag, null); + if(value!=null) { + alts.add(tag); + alts.add(value); + } + } + symm = Symm.encrypt.obtain(); hsi = SecurityInfoC.instance(access, HttpURLConnection.class); } @@ -105,15 +120,11 @@ public class TokenClientFactory extends Persist<Token,TimedToken> { } } char okind; - if ( Config.AAF_OAUTH2_TOKEN_URL.equals(tagOrURL) || - Config.AAF_OAUTH2_INTROSPECT_URL.equals(tagOrURL) || - tagOrURL.equals(access.getProperty(Config.AAF_OAUTH2_TOKEN_URL, null)) || - tagOrURL.equals(access.getProperty(Config.AAF_OAUTH2_INTROSPECT_URL, null)) - ) { - okind = Kind.AAF_OAUTH; - } else { - okind = Kind.OAUTH; - } + if (alts.contains(tagOrURL)) { + okind = Kind.OAUTH; + } else { + okind = Kind.AAF_OAUTH; + } TokenClient tci = new TokenClient( okind, this, 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<TimedToken> 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<OAuth2Principal> 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/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java index cbf0339b..8b879e4f 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java @@ -90,10 +90,11 @@ public class RegistrationCreator { } if(specificVersion!=null) { String split[] = Split.splitTrim('.', specificVersion); - locate.setPkg(split.length>3?Integer.parseInt(split[3]):0); - locate.setPatch(split.length>2?Integer.parseInt(split[2]):0); - locate.setMinor(split.length>1?Integer.parseInt(split[1]):0); - locate.setMajor(split.length>0?Integer.parseInt(split[0]):0); + String deply[]= Split.splitTrim('.', access.getProperty(Config.AAF_DEPLOYED_VERSION, "")); + locate.setMajor(best(split,deply,0)); + locate.setMinor(best(split,deply,1)); + locate.setPatch(best(split,deply,2)); + locate.setPkg(best(split,deply,3)); } String protocol = access.getProperty(Config.AAF_LOCATOR_PROTOCOL + dot_le, defProtocol); @@ -131,7 +132,39 @@ public class RegistrationCreator { return me; } - private StringBuilder print(StringBuilder sb, List<MgmtEndpoint> lme) { + /* + * Find the best version between Actual Interface and Deployed version + */ + private int best(String[] split, String[] deploy, int i) { + StringBuilder sb = new StringBuilder(); + char c; + String s; + if(split.length>i) { + s=split[i]; + for(int j=0;j<s.length();++j) { + if(Character.isDigit(c=s.charAt(j))) { + sb.append(c); + } else { + break; + } + } + } + + if(sb.length()==0 && deploy.length>i) { + s=deploy[i]; + for(int j=0;j<s.length();++j) { + if(Character.isDigit(c=s.charAt(j))) { + sb.append(c); + } else { + break; + } + } + } + + return sb.length()==0?0:Integer.parseInt(sb.toString()); + } + + private StringBuilder print(StringBuilder sb, List<MgmtEndpoint> lme) { int cnt = 0; for(MgmtEndpoint m : lme) { print(sb,cnt++,m); @@ -155,9 +188,9 @@ public class RegistrationCreator { out.append('.'); out.append(mep.getMinor()); out.append('.'); - out.append(mep.getPkg()); - out.append('.'); out.append(mep.getPatch()); + out.append('.'); + out.append(mep.getPkg()); out.append("\n\tPort: "); out.append(mep.getPort()); out.append("\n\tProtocol: "); @@ -201,8 +234,8 @@ public class RegistrationCreator { out.setLongitude(mep.getLongitude()); out.setMajor(mep.getMajor()); out.setMinor(mep.getMinor()); - out.setPkg(mep.getPkg()); out.setPatch(mep.getPatch()); + out.setPkg(mep.getPkg()); out.setPort(mep.getPort()); out.setProtocol(mep.getProtocol()); out.getSpecialPorts().addAll(mep.getSpecialPorts()); 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 10acc887..de31e661 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 @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; @@ -36,14 +37,24 @@ import java.util.Properties; import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.CadiException; +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.v2_0.AAFCon; +import org.onap.aaf.cadi.client.Future; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.configure.ArtifactDir; +import org.onap.aaf.cadi.locator.SingleEndpointLocator; import org.onap.aaf.cadi.util.MyConsole; import org.onap.aaf.cadi.util.SubStandardConsole; import org.onap.aaf.cadi.util.TheConsole; +import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.rosetta.env.RosettaDF; +import org.onap.aaf.misc.rosetta.env.RosettaEnv; + +import locate.v1_1.Configuration; +import locate.v1_1.Configuration.Props; public class AAFSSO { public static final MyConsole cons = TheConsole.implemented() ? new TheConsole() : new SubStandardConsole(); @@ -179,16 +190,20 @@ public class AAFSSO { appID=null; } + String aaf_container_ns = ""; if (appID!=null) { - diskprops.setProperty(Config.AAF_APPID,appID); if( access.getProperty(Config.AAF_APPPASS)==null) { - char[] password = cons.readPassword("Password for %s: ", appID); + appID = user = cons.readLine("Deployer ID [%s]: ", user); + access.setProperty(Config.AAF_APPID,appID); + char[] password = cons.readPassword("Password for %s: ", user); if(password.length>0) { String app_pass = access.encrypt(new String(password)); access.setProperty(Config.AAF_APPPASS,app_pass); diskprops.setProperty(Config.AAF_APPPASS,app_pass); } + aaf_container_ns = cons.readLine("Container Namespace (blank if none)? [\"\"]: ", aaf_container_ns); } + diskprops.setProperty(Config.AAF_APPID,appID); } String keystore=access.getProperty(Config.CADI_KEYSTORE); @@ -298,36 +313,6 @@ public class AAFSSO { err.append("-D" + Config.AAF_APPPASS + "=<passwd> "); } - String locateUrl = Config.getAAFLocateUrl(access); - if (locateUrl==null) { - locateUrl=AAFSSO.cons.readLine("AAF Locator URL=https://"); - if (locateUrl==null || locateUrl.length()==0) { - err = new StringBuilder(Config.AAF_LOCATE_URL); - err.append(" is required."); - ok = false; - return; - } else { - locateUrl="https://"+locateUrl; - } - access.setProperty(Config.AAF_LOCATE_URL, locateUrl); - addProp(Config.AAF_LOCATE_URL, locateUrl); - } - - final String apiVersion = access.getProperty(Config.AAF_API_VERSION, Config.AAF_DEFAULT_API_VERSION); - final String aaf_root_ns = access.getProperty(Config.AAF_ROOT_NS); - String locateRoot; - if(aaf_root_ns==null) { - locateRoot=Defaults.AAF_ROOT; - } else { - locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS." + aaf_root_ns; - } - if(access.getProperty(Config.AAF_URL)==null) { - - access.setProperty(Config.AAF_URL, locateRoot+".service:"+apiVersion); - } - if(access.getProperty(Config.AAF_URL_CM)==null) { - access.setProperty(Config.AAF_URL_CM, locateRoot+".cm:"+apiVersion); - } String cadiLatitude = access.getProperty(Config.CADI_LATITUDE); if (cadiLatitude==null) { System.out.println("# If you do not know your Global Coordinates, we suggest bing.com/maps"); @@ -381,6 +366,55 @@ public class AAFSSO { } ok = err==null; } + String locateUrl = Config.getAAFLocateUrl(access); + if (locateUrl==null) { + locateUrl=AAFSSO.cons.readLine("AAF Locator URL=https://"); + if (locateUrl==null || locateUrl.length()==0) { + err = new StringBuilder(Config.AAF_LOCATE_URL); + err.append(" is required."); + ok = false; + return; + } else { + locateUrl="https://"+locateUrl; + } + access.setProperty(Config.AAF_LOCATE_URL, locateUrl); + 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"); + } + AAFCon<?> aafCon = AAFCon.newInstance(access); + Future<Configuration> acf; + RosettaDF<Configuration> configDF = new RosettaEnv().newDataFactory(Configuration.class); + acf = aafCon.client(new SingleEndpointLocator(locateUrl)) + .read("/configure/"+user+"/aaf", configDF); + if (acf.get(aafCon.connTimeout)) { + for(Props p : acf.value.getProps()) { + addProp(p.getTag(),p.getValue()); + if(access.getProperty(p.getTag())==null) { + access.setProperty(p.getTag(), p.getValue()); + } + } + } else { + access.log(Level.INFO,acf.body()); + } + } catch (LocatorException | APIException | URISyntaxException e) { + access.log(e); + } + } + + final String apiVersion = access.getProperty(Config.AAF_API_VERSION, Config.AAF_DEFAULT_API_VERSION); + final String aaf_root_ns = access.getProperty(Config.AAF_ROOT_NS); + String locateRoot; + if(aaf_root_ns==null) { + locateRoot=Defaults.AAF_ROOT; + } else { + locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS." + aaf_root_ns; + } + if(access.getProperty(Config.AAF_URL)==null) { + access.setProperty(Config.AAF_URL, locateRoot+".service:"+apiVersion); + } + writeFiles(); } diff --git a/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/v2_0/JU_AAFAuthn.java b/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/v2_0/JU_AAFAuthn.java index 41b519b1..962397cc 100644 --- a/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/v2_0/JU_AAFAuthn.java +++ b/cadi/aaf/src/test/java/org/onap/aaf/cadi/aaf/v2_0/JU_AAFAuthn.java @@ -87,7 +87,7 @@ public class JU_AAFAuthn { Future<String> futureObj = Mockito.mock(Future.class); Mockito.doReturn(futureObj).when(rcliObj).read( "/authn/basicAuth","text/plain"); realm = authnObj.validate("test", "test","test"); - assertTrue(realm.contains("User/Pass combo invalid")); + assertTrue(realm.contains("user/pass combo invalid")); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/cadi/aaf/src/test/resources/cadi.properties b/cadi/aaf/src/test/resources/cadi.properties index ee0b719f..d0862909 100644 --- a/cadi/aaf/src/test/resources/cadi.properties +++ b/cadi/aaf/src/test/resources/cadi.properties @@ -23,7 +23,7 @@ AFT_LATITUDE=32.780140 AFT_LONGITUDE=-96.800451 AFT_ENVIRONMENT=AFTUAT -DEPLOYED_VERSION=2.0.MITHRIL +aaf_deployed_version=2.0.MITHRIL cadi_prop_files=/opt/app/aaf/common/com.att.aaf.props #cadi_keystore=/Volumes/Data/src/authz/common/cadiaaf.jks diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java index d6b8d56d..fac6a3f1 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java @@ -42,7 +42,11 @@ import org.onap.aaf.cadi.util.Split; public class PropAccess implements Access { // Sonar says cannot be static... it's ok. not too many PropAccesses created. - private final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + private final SimpleDateFormat iso8601 = newISO8601(); + + public static SimpleDateFormat newISO8601() { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + } public static final Level DEFAULT = Level.AUDIT; @@ -101,7 +105,7 @@ public class PropAccess implements Access { init(nprops); } - protected void init(Properties p) { + protected synchronized void init(Properties p) { // Make sure these two are set before any changes in Logging name = "cadi"; level=DEFAULT.maskOf(); @@ -258,10 +262,13 @@ public class PropAccess implements Access { } } - protected StringBuilder buildMsg(Level level, Object[] elements) { + public StringBuilder buildMsg(Level level, Object[] elements) { return buildMsg(name,iso8601,level,elements); } - + + /* + * Need to pass in DateFormat per thread, because not marked as thread safe + */ public static StringBuilder buildMsg(final String name, final DateFormat sdf, Level level, Object[] elements) { final StringBuilder sb; int end = elements.length; 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 66fbe847..2655b4ce 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 @@ -157,6 +157,7 @@ public class Config { public static final String AAF_LOCATE_URL = "aaf_locate_url"; //URL for AAF locator public static final String AAF_LOCATE_URL_TAG = "AAF_LOCATE_URL"; // Name of Above for use in Config Variables. public static final String AAF_DEFAULT_API_VERSION = "2.1"; + public static final String AAF_DEPLOYED_VERSION="aaf_deployed_version"; public static final String AAF_API_VERSION = "aaf_api_version"; public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration public static final String AAF_LOCATOR_CLASS = "aaf_locator_class"; @@ -219,8 +220,8 @@ public class Config { public static final String AAF_CERT_IDS = "aaf_cert_ids"; public static final String AAF_DEBUG_IDS = "aaf_debug_ids"; // comma delimited public static final String AAF_DATA_DIR = "aaf_data_dir"; // AAF processes and Components only. - public static final String AAF_RELEASE = "aaf_release"; + public static final String AAF_URL_OAUTH = "aaf_url_oauth"; public static final String AAF_URL_GUI="aaf_url_gui"; public static final String AAF_URL_FS="aaf_url_fs"; public static final String AAF_URL_CM = "aaf_url_cm"; @@ -564,7 +565,7 @@ public class Config { } access.log(Level.INIT, sb); - Locator<URI> locator = loadLocator(si, logProp(rph, Config.getAAFLocateUrl(access), null)); + Locator<URI> locator = loadLocator(si, aafURL); taf = new HttpEpiTaf(access,locator, tc, htarray); // ok to pass locator == null String level = logProp(access, CADI_LOGLEVEL, null); @@ -849,6 +850,36 @@ public class Config { if (_url==null) { access.log(Level.INIT,"No URL passed to 'loadLocator'. Disabled"); } else { + try { + Class<?> aalCls = Class.forName("org.onap.aaf.cadi.aaf.v2_0.AbsAAFLocator"); + Method aalMth = aalCls.getMethod("create", String.class,String.class); + int colon = _url.lastIndexOf(':'); + if(colon>=0) { + int slash = _url.indexOf('/',colon); + String version; + if(slash<0) { + version = _url.substring(colon+1); + } else { + version = _url.substring(colon+1,slash); + } + slash = _url.lastIndexOf('/',colon); + if(slash>=0) { + Object aal = aalMth.invoke(null/*static*/, _url.substring(slash+1, colon),version); + return (Locator<URI>)aal; + } + } + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + String msg; + char quote; + if(e.getCause()!=null) { + msg=e.getCause().getMessage(); + quote='"'; + } else { + msg = "-"; + quote=' '; + } + access.printf(Level.DEBUG, "Configured AbsAAFLocator not found%c%s%cContinuing Locator creation ",quote,msg,quote); + } // String url = _url.replace("/AAF_NS.", "/%C%CID%AAF_NS."); // String root_ns = access.getProperty(Config.AAF_ROOT_NS, null); String url; @@ -877,7 +908,7 @@ public class Config { Method meth = lcls.getMethod("create",Access.class,String.class); locator = (Locator<URI>)meth.invoke(null,access,url); } catch (Exception e) { - access.log(Level.TRACE, "(Not fatal) Cannot load by create(String)", e); + access.log(Level.NONE, "(Not fatal) Cannot load by create(String)", e); } if (locator==null) { URI locatorURI = new URI(url); diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/RegistrationPropHolder.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/RegistrationPropHolder.java index 50f17e88..2a8760f4 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/RegistrationPropHolder.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/RegistrationPropHolder.java @@ -263,9 +263,10 @@ public class RegistrationPropHolder { if(value.indexOf("%NS")>=0) { str = getNS(dot_le); if(str==null || str.isEmpty()) { - value = value.replace("%NS"+'.', str); + value = value.replace("%NS"+'.', ""); + } else { + value = value.replace("%NS", str); } - value = value.replace("%NS", str); } // aaf_root_ns diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java index 285c45ec..5d1d23fa 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java @@ -91,12 +91,6 @@ public class SecurityInfo { this.access = access; // reuse DME2 Properties for convenience if specific Properties don't exist - msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, "")); - initializeKeyManager(); - - msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, "")); - initializeTrustManager(); - String str = access.getProperty(Config.CADI_ALIAS, null); if(str==null || str.isEmpty()) { defaultAlias = null; @@ -113,7 +107,14 @@ public class SecurityInfo { } else { defaultClientAlias = str; } + + msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, "")); + initializeKeyManager(); + msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, "")); + initializeTrustManager(); + + msgHelp = String.format(INITIALIZING_ERR_FMT,"Trustmasks", access.getProperty(Config.CADI_TRUST_MASKS, "")); initializeTrustMasks(); @@ -239,13 +240,51 @@ public class SecurityInfo { } } } + + StringBuilder sb = null; for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) { if (keyManager instanceof X509KeyManager) { - keyManagers.add((X509KeyManager)keyManager); + X509KeyManager xkm = (X509KeyManager)keyManager; + keyManagers.add(xkm); + if(defaultAlias!=null) { + sb=new StringBuilder("X509 Chain\n"); + x509Info(sb,xkm.getCertificateChain(defaultAlias)); + } + if(defaultClientAlias!=null && !defaultClientAlias.equals(defaultAlias)) { + if(sb==null) { + sb = new StringBuilder(); + } else { + sb.append('\n'); + } + sb.append("X509 Client Chain\n"); + x509Info(sb,xkm.getCertificateChain(defaultAlias)); + } } } x509KeyManager = new X509KeyManager[keyManagers.size()]; keyManagers.toArray(x509KeyManager); + + if(sb!=null) { + access.log(Level.INIT, sb); + } + } + + private void x509Info(StringBuilder sb, X509Certificate[] chain) { + if(chain!=null) { + int i=0; + for(X509Certificate x : chain) { + sb.append(" "); + sb.append(i++); + sb.append(')'); + sb.append("\n Subject: "); + sb.append(x.getSubjectDN()); + sb.append("\n Issuer : "); + sb.append(x.getIssuerDN()); + sb.append("\n Expires: "); + sb.append(x.getNotAfter()); + sb.append('\n'); + } + } } protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException { 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; } |