diff options
author | Instrumental <jonathan.gathman@att.com> | 2018-09-07 12:21:34 -0500 |
---|---|---|
committer | Instrumental <jonathan.gathman@att.com> | 2018-09-07 12:22:50 -0500 |
commit | 4b5a7d721d994a49057e9bfb403c7bff1b376660 (patch) | |
tree | a36d03227b63a3e60346d6c3ca87b061087dae85 /cadi/core/src/main | |
parent | 824dc7b5fc0e1ccdf7f460479aff344727f0f01e (diff) |
Mass removal of all Tabs (Style Warnings)
Issue-ID: AAF-473
Change-Id: Iaf0ef8120882937959bb0065f2f6ba74a021940f
Signed-off-by: Instrumental <jonathan.gathman@att.com>
Diffstat (limited to 'cadi/core/src/main')
101 files changed, 8239 insertions, 8239 deletions
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/AES.java b/cadi/core/src/main/java/org/onap/aaf/cadi/AES.java index 3ef3355a..142dde26 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/AES.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/AES.java @@ -52,80 +52,80 @@ import org.onap.aaf.cadi.util.Chmod; * */ public class AES implements Encryption { - public static final String AES = AES.class.getSimpleName(); - public static final int AES_KEY_SIZE = 128; // 256 isn't supported on all JDKs. - - private SecretKeySpec aeskeySpec; + public static final String AES = AES.class.getSimpleName(); + public static final int AES_KEY_SIZE = 128; // 256 isn't supported on all JDKs. + + private SecretKeySpec aeskeySpec; - public static SecretKey newKey() throws NoSuchAlgorithmException { - KeyGenerator kgen = KeyGenerator.getInstance(AES); - kgen.init(AES_KEY_SIZE); - return kgen.generateKey(); - } + public static SecretKey newKey() throws NoSuchAlgorithmException { + KeyGenerator kgen = KeyGenerator.getInstance(AES); + kgen.init(AES_KEY_SIZE); + return kgen.generateKey(); + } - public AES(byte[] aeskey, int offset, int len) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { - aeskeySpec = new SecretKeySpec(aeskey,offset,len,AES); - } - - public byte[] encrypt(byte[] in) throws CadiException { - try { - Cipher c = Cipher.getInstance(AES); - c.init(Cipher.ENCRYPT_MODE,aeskeySpec); - return c.doFinal(in); - } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException e) { - throw new CadiException(e); - } - } - - public byte[] decrypt(byte[] in) throws CadiException { - try { - Cipher c = Cipher.getInstance(AES); - c.init(Cipher.DECRYPT_MODE,aeskeySpec); - return c.doFinal(in); - } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException e) { - throw new CadiException(e); - } - } - - public void save(File keyfile) throws IOException { - FileOutputStream fis = new FileOutputStream(keyfile); - try { - fis.write(aeskeySpec.getEncoded()); - } finally { - fis.close(); - } - Chmod.to400.chmod(keyfile); - } + public AES(byte[] aeskey, int offset, int len) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { + aeskeySpec = new SecretKeySpec(aeskey,offset,len,AES); + } + + public byte[] encrypt(byte[] in) throws CadiException { + try { + Cipher c = Cipher.getInstance(AES); + c.init(Cipher.ENCRYPT_MODE,aeskeySpec); + return c.doFinal(in); + } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new CadiException(e); + } + } + + public byte[] decrypt(byte[] in) throws CadiException { + try { + Cipher c = Cipher.getInstance(AES); + c.init(Cipher.DECRYPT_MODE,aeskeySpec); + return c.doFinal(in); + } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException e) { + throw new CadiException(e); + } + } + + public void save(File keyfile) throws IOException { + FileOutputStream fis = new FileOutputStream(keyfile); + try { + fis.write(aeskeySpec.getEncoded()); + } finally { + fis.close(); + } + Chmod.to400.chmod(keyfile); + } - public CipherOutputStream outputStream(OutputStream os, boolean encrypt) { - try { - Cipher c = Cipher.getInstance(AES); - if(encrypt) { - c.init(Cipher.ENCRYPT_MODE,aeskeySpec); - } else { - c.init(Cipher.DECRYPT_MODE,aeskeySpec); - } - return new CipherOutputStream(os,c); - } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) { - // Cannot add Exception to this API. throw Runtime - System.err.println("Error creating Aes CipherOutputStream"); - return null; // should never get here. - } - } - - public CipherInputStream inputStream(InputStream is, boolean encrypt) { - try { - Cipher c = Cipher.getInstance(AES); - if(encrypt) { - c.init(Cipher.ENCRYPT_MODE,aeskeySpec); - } else { - c.init(Cipher.DECRYPT_MODE,aeskeySpec); - } - return new CipherInputStream(is,c); - } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) { - // Cannot add Exception to this API. throw Runtime - System.err.println("Error creating Aes CipherInputStream"); - return null; // should never get here. - } - } + public CipherOutputStream outputStream(OutputStream os, boolean encrypt) { + try { + Cipher c = Cipher.getInstance(AES); + if(encrypt) { + c.init(Cipher.ENCRYPT_MODE,aeskeySpec); + } else { + c.init(Cipher.DECRYPT_MODE,aeskeySpec); + } + return new CipherOutputStream(os,c); + } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) { + // Cannot add Exception to this API. throw Runtime + System.err.println("Error creating Aes CipherOutputStream"); + return null; // should never get here. + } + } + + public CipherInputStream inputStream(InputStream is, boolean encrypt) { + try { + Cipher c = Cipher.getInstance(AES); + if(encrypt) { + c.init(Cipher.ENCRYPT_MODE,aeskeySpec); + } else { + c.init(Cipher.DECRYPT_MODE,aeskeySpec); + } + return new CipherInputStream(is,c); + } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) { + // Cannot add Exception to this API. throw Runtime + System.err.println("Error creating Aes CipherInputStream"); + return null; // should never get here. + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java b/cadi/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java index 39631894..d9d4474d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java @@ -48,420 +48,420 @@ import org.onap.aaf.cadi.principal.CachedBasicPrincipal; * */ public abstract class AbsUserCache<PERM extends Permission> { - // Need an obvious key for when there is no Authentication Cred - private static final String NO_CRED = "NoCred"; - static final int MIN_INTERVAL = 1000*60; // Min 1 min - static final int MAX_INTERVAL = 1000*60*60*4; // 4 hour max - private static Timer timer; - // Map of userName to User - private final Map<String, User<PERM>> userMap; - private static final Map<String, Miss> missMap = new TreeMap<>(); - private final Symm missEncrypt; - - private Clean clean; - protected Access access; - - protected AbsUserCache(Access access, long cleanInterval, int highCount, int usageCount) { - this.access = access; - Symm s; - try { - byte[] gennedKey = Symm.keygen(); - s = Symm.obtain(new ByteArrayInputStream(gennedKey)); - } catch (IOException e) { - access.log(e); - s = Symm.base64noSplit; - } - missEncrypt = s; - - userMap = new ConcurrentHashMap<>(); + // Need an obvious key for when there is no Authentication Cred + private static final String NO_CRED = "NoCred"; + static final int MIN_INTERVAL = 1000*60; // Min 1 min + static final int MAX_INTERVAL = 1000*60*60*4; // 4 hour max + private static Timer timer; + // Map of userName to User + private final Map<String, User<PERM>> userMap; + private static final Map<String, Miss> missMap = new TreeMap<>(); + private final Symm missEncrypt; + + private Clean clean; + protected Access access; + + protected AbsUserCache(Access access, long cleanInterval, int highCount, int usageCount) { + this.access = access; + Symm s; + try { + byte[] gennedKey = Symm.keygen(); + s = Symm.obtain(new ByteArrayInputStream(gennedKey)); + } catch (IOException e) { + access.log(e); + s = Symm.base64noSplit; + } + missEncrypt = s; + + userMap = new ConcurrentHashMap<>(); - - if(cleanInterval>0) { - cleanInterval = Math.max(MIN_INTERVAL, cleanInterval); - synchronized(AbsUserCache.class) { // Lazy instantiate.. in case there is no cleanup needed - if(timer==null) { - timer = new Timer("CADI Cleanup Timer",true); - } - - timer.schedule(clean = new Clean(access, cleanInterval, highCount, usageCount), cleanInterval, cleanInterval); - access.log(Access.Level.INIT, "Cleaning Thread initialized with interval of",cleanInterval, "ms and max objects of", highCount); - } - } - } - - @SuppressWarnings("unchecked") - public AbsUserCache(AbsUserCache<PERM> cache) { - this.access = cache.access; - userMap = cache.userMap; - missEncrypt = cache.missEncrypt; - - synchronized(AbsUserCache.class) { - if(cache.clean!=null && cache.clean.lur==null && this instanceof CachingLur) { - cache.clean.lur=(CachingLur<PERM>)this; - } - } - } + + if(cleanInterval>0) { + cleanInterval = Math.max(MIN_INTERVAL, cleanInterval); + synchronized(AbsUserCache.class) { // Lazy instantiate.. in case there is no cleanup needed + if(timer==null) { + timer = new Timer("CADI Cleanup Timer",true); + } + + timer.schedule(clean = new Clean(access, cleanInterval, highCount, usageCount), cleanInterval, cleanInterval); + access.log(Access.Level.INIT, "Cleaning Thread initialized with interval of",cleanInterval, "ms and max objects of", highCount); + } + } + } + + @SuppressWarnings("unchecked") + public AbsUserCache(AbsUserCache<PERM> cache) { + this.access = cache.access; + userMap = cache.userMap; + missEncrypt = cache.missEncrypt; + + synchronized(AbsUserCache.class) { + if(cache.clean!=null && cache.clean.lur==null && this instanceof CachingLur) { + cache.clean.lur=(CachingLur<PERM>)this; + } + } + } - protected void setLur(CachingLur<PERM> lur) { - if(clean!=null)clean.lur = lur; - - } - - protected void addUser(User<PERM> user) { - Principal p = user.principal; - String key; - try { - if(p instanceof GetCred) { - key = missKey(p.getName(), ((GetCred)p).getCred()); - } else { - byte[] cred; - if((cred=user.getCred())==null) { - key = user.name + NO_CRED; - } else { - key = missKey(user.name,cred); - } - } - } catch (IOException e) { - access.log(e); - return; - } - userMap.put(key, user); - } + protected void setLur(CachingLur<PERM> lur) { + if(clean!=null)clean.lur = lur; + + } + + protected void addUser(User<PERM> user) { + Principal p = user.principal; + String key; + try { + if(p instanceof GetCred) { + key = missKey(p.getName(), ((GetCred)p).getCred()); + } else { + byte[] cred; + if((cred=user.getCred())==null) { + key = user.name + NO_CRED; + } else { + key = missKey(user.name,cred); + } + } + } catch (IOException e) { + access.log(e); + return; + } + userMap.put(key, user); + } - // Useful for looking up by WebToken, etc. - protected void addUser(String key, User<PERM> user) { - userMap.put(key, user); - } - - /** - * Add miss to missMap. If Miss exists, or too many tries, returns false. - * - * otherwise, returns true to allow another attempt. - * - * @param key - * @param bs - * @return - * @throws IOException - */ - protected synchronized boolean addMiss(String key, byte[] bs) { - String mkey; - try { - mkey = missKey(key,bs); - } catch (IOException e) { - access.log(e); - return false; - } - Miss miss = missMap.get(mkey); - if(miss==null) { - missMap.put(mkey, new Miss(bs,clean==null?MIN_INTERVAL:clean.timeInterval,key)); - return true; - } - return miss.mayContinue(); - } + // Useful for looking up by WebToken, etc. + protected void addUser(String key, User<PERM> user) { + userMap.put(key, user); + } + + /** + * Add miss to missMap. If Miss exists, or too many tries, returns false. + * + * otherwise, returns true to allow another attempt. + * + * @param key + * @param bs + * @return + * @throws IOException + */ + protected synchronized boolean addMiss(String key, byte[] bs) { + String mkey; + try { + mkey = missKey(key,bs); + } catch (IOException e) { + access.log(e); + return false; + } + Miss miss = missMap.get(mkey); + if(miss==null) { + missMap.put(mkey, new Miss(bs,clean==null?MIN_INTERVAL:clean.timeInterval,key)); + return true; + } + return miss.mayContinue(); + } - protected Miss missed(String key, byte[] bs) throws IOException { - return missMap.get(missKey(key,bs)); - } + protected Miss missed(String key, byte[] bs) throws IOException { + return missMap.get(missKey(key,bs)); + } - protected User<PERM> getUser(Principal principal) { - String key; - if(principal instanceof GetCred) { - GetCred gc = (GetCred)principal; - try { - key = missKey(principal.getName(), gc.getCred()); - } catch (IOException e) { - access.log(e, "Error getting key from Principal"); - key = principal.getName(); - } - } else { - key = principal.getName()+NO_CRED; - } - User<PERM> u = userMap.get(key); - if(u!=null) { - u.incCount(); - } - return u; - } - - protected User<PERM> getUser(CachedBasicPrincipal cbp) { - return getUser(cbp.getName(), cbp.getCred()); - } - - protected User<PERM> getUser(String user, byte[] cred) { - User<PERM> u; - String key=null; - try { - key =missKey(user,cred); - } catch (IOException e) { - access.log(e); - return null; - } - u = userMap.get(key); - if(u!=null) { - if(u.permExpired()) { - userMap.remove(key); - u=null; - } else { - u.incCount(); - } - } - return u; - } - - /** - * Removes User from the Cache - * @param user - */ - protected void remove(User<PERM> user) { - userMap.remove(user.principal.getName()); - } - - /** - * Removes user from the Cache - * - * @param user - */ - public void remove(String user) { - Object o = userMap.remove(user); - if(o!=null) { - access.log(Level.INFO, user,"removed from Client Cache by Request"); - } - } - - /** - * Clear all Users from the Client Cache - */ - public void clearAll() { - userMap.clear(); - } - - public final List<DumpInfo> dumpInfo() { - List<DumpInfo> rv = new ArrayList<>(); - for(User<PERM> user : userMap.values()) { - rv.add(new DumpInfo(user)); - } - return rv; - } + protected User<PERM> getUser(Principal principal) { + String key; + if(principal instanceof GetCred) { + GetCred gc = (GetCred)principal; + try { + key = missKey(principal.getName(), gc.getCred()); + } catch (IOException e) { + access.log(e, "Error getting key from Principal"); + key = principal.getName(); + } + } else { + key = principal.getName()+NO_CRED; + } + User<PERM> u = userMap.get(key); + if(u!=null) { + u.incCount(); + } + return u; + } + + protected User<PERM> getUser(CachedBasicPrincipal cbp) { + return getUser(cbp.getName(), cbp.getCred()); + } + + protected User<PERM> getUser(String user, byte[] cred) { + User<PERM> u; + String key=null; + try { + key =missKey(user,cred); + } catch (IOException e) { + access.log(e); + return null; + } + u = userMap.get(key); + if(u!=null) { + if(u.permExpired()) { + userMap.remove(key); + u=null; + } else { + u.incCount(); + } + } + return u; + } + + /** + * Removes User from the Cache + * @param user + */ + protected void remove(User<PERM> user) { + userMap.remove(user.principal.getName()); + } + + /** + * Removes user from the Cache + * + * @param user + */ + public void remove(String user) { + Object o = userMap.remove(user); + if(o!=null) { + access.log(Level.INFO, user,"removed from Client Cache by Request"); + } + } + + /** + * Clear all Users from the Client Cache + */ + public void clearAll() { + userMap.clear(); + } + + public final List<DumpInfo> dumpInfo() { + List<DumpInfo> rv = new ArrayList<>(); + for(User<PERM> user : userMap.values()) { + rv.add(new DumpInfo(user)); + } + return rv; + } - /** - * The default behavior of a LUR is to not handle something exclusively. - */ - public boolean handlesExclusively(Permission ... pond) { - return false; - } - - /** - * Container calls when cleaning up... - * - * If overloading in Derived class, be sure to call "super.destroy()" - */ - public void destroy() { - if(timer!=null) { - timer.purge(); - timer.cancel(); - } - } - - + /** + * The default behavior of a LUR is to not handle something exclusively. + */ + public boolean handlesExclusively(Permission ... pond) { + return false; + } + + /** + * Container calls when cleaning up... + * + * If overloading in Derived class, be sure to call "super.destroy()" + */ + public void destroy() { + if(timer!=null) { + timer.purge(); + timer.cancel(); + } + } + + - // Simple map of Group name to a set of User Names - // private Map<String, Set<String>> groupMap = new HashMap<>(); + // Simple map of Group name to a set of User Names + // private Map<String, Set<String>> groupMap = new HashMap<>(); - /** - * Class to hold a small subset of the data, because we don't want to expose actual Permission or User Objects - */ - public final class DumpInfo { - public String user; - public List<String> perms; - - public DumpInfo(User<PERM> user) { - this.user = user.principal.getName(); - perms = new ArrayList<>(user.perms.keySet()); - } - } - - /** - * Clean will examine resources, and remove those that have expired. - * - * If "highs" have been exceeded, then we'll expire 10% more the next time. This will adjust after each run - * without checking contents more than once, making a good average "high" in the minimum speed. - * - * @author Jonathan - * - */ - private final class Clean extends TimerTask { - private final Access access; - private CachingLur<PERM> lur; - - // The idea here is to not be too restrictive on a high, but to Expire more items by - // shortening the time to expire. This is done by judiciously incrementing "advance" - // when the "highs" are exceeded. This effectively reduces numbers of cached items quickly. - private final int high; - private long advance; - private final long timeInterval; - private final int usageTriggerCount; - - public Clean(Access access, long cleanInterval, int highCount, int usageTriggerCount) { - this.access = access; - lur = null; - high = highCount; - timeInterval = cleanInterval; - advance = 0; - this.usageTriggerCount=usageTriggerCount; - } - public void run() { - int renewed = 0; - int count = 0; - int total = 0; - try { - // look at now. If we need to expire more by increasing "now" by "advance" - ArrayList<User<PERM>> al = new ArrayList<>(userMap.values().size()); - al.addAll(0, userMap.values()); - long now = System.currentTimeMillis() + advance; - for(User<PERM> user : al) { - ++total; - if(user.count>usageTriggerCount) { - boolean touched = false, removed=false; - if(user.principal instanceof CachedPrincipal) { - CachedPrincipal cp = (CachedPrincipal)user.principal; - if(cp.expires() < now) { - switch(cp.revalidate(null)) { - case INACCESSIBLE: - access.log(Level.AUDIT, "AAF Inaccessible. Keeping credentials"); - break; - case REVALIDATED: - user.resetCount(); - touched = true; - break; - default: - user.resetCount(); - remove(user); - ++count; - removed = true; - break; - } - } - } - - if(!removed && lur!=null && user.permExpires<= now ) { - if(lur.reload(user).equals(Resp.REVALIDATED)) { - user.renewPerm(); - access.log(Level.DEBUG, "Reloaded Perms for",user); - touched = true; - } - } - user.resetCount(); - if(touched) { - ++renewed; - } - - } else { - if(user.permExpired()) { - remove(user); - ++count; - } - } - } - - // Clean out Misses - int missTotal = missMap.keySet().size(); - int miss = 0; - if(missTotal>0) { - ArrayList<String> keys = new ArrayList<>(missTotal); - keys.addAll(missMap.keySet()); - for(String key : keys) { - Miss m = missMap.get(key); - if(m!=null) { - long timeLeft = m.timestamp - System.currentTimeMillis(); - if(timeLeft<0) { - synchronized(missMap) { - missMap.remove(key); - } - access.log(Level.INFO, m.name, " has been removed from Missed Credential Map (" + m.tries + " invalid tries)"); - ++miss; - } else { - access.log(Level.INFO, m.name, " remains in Missed Credential Map (" + m.tries + " invalid tries) for " + (timeLeft/1000) + " more seconds"); - } - } - } - } - - if(count+renewed+miss>0) { - access.log(Level.INFO, (lur==null?"Cache":lur.getClass().getSimpleName()), "removed",count, - "and renewed",renewed,"expired Permissions out of", total,"and removed", miss, "password misses out of",missTotal); - } - - // If High (total) is reached during this period, increase the number of expired services removed for next time. - // There's no point doing it again here, as there should have been cleaned items. - if(total>high) { - // advance cleanup by 10%, without getting greater than timeInterval. - advance = Math.min(timeInterval, advance+(timeInterval/10)); - } else { - // reduce advance by 10%, without getting lower than 0. - advance = Math.max(0, advance-(timeInterval/10)); - } - } catch (Exception e) { - access.log(Level.ERROR,e.getMessage()); - } - } - } + /** + * Class to hold a small subset of the data, because we don't want to expose actual Permission or User Objects + */ + public final class DumpInfo { + public String user; + public List<String> perms; + + public DumpInfo(User<PERM> user) { + this.user = user.principal.getName(); + perms = new ArrayList<>(user.perms.keySet()); + } + } + + /** + * Clean will examine resources, and remove those that have expired. + * + * If "highs" have been exceeded, then we'll expire 10% more the next time. This will adjust after each run + * without checking contents more than once, making a good average "high" in the minimum speed. + * + * @author Jonathan + * + */ + private final class Clean extends TimerTask { + private final Access access; + private CachingLur<PERM> lur; + + // The idea here is to not be too restrictive on a high, but to Expire more items by + // shortening the time to expire. This is done by judiciously incrementing "advance" + // when the "highs" are exceeded. This effectively reduces numbers of cached items quickly. + private final int high; + private long advance; + private final long timeInterval; + private final int usageTriggerCount; + + public Clean(Access access, long cleanInterval, int highCount, int usageTriggerCount) { + this.access = access; + lur = null; + high = highCount; + timeInterval = cleanInterval; + advance = 0; + this.usageTriggerCount=usageTriggerCount; + } + public void run() { + int renewed = 0; + int count = 0; + int total = 0; + try { + // look at now. If we need to expire more by increasing "now" by "advance" + ArrayList<User<PERM>> al = new ArrayList<>(userMap.values().size()); + al.addAll(0, userMap.values()); + long now = System.currentTimeMillis() + advance; + for(User<PERM> user : al) { + ++total; + if(user.count>usageTriggerCount) { + boolean touched = false, removed=false; + if(user.principal instanceof CachedPrincipal) { + CachedPrincipal cp = (CachedPrincipal)user.principal; + if(cp.expires() < now) { + switch(cp.revalidate(null)) { + case INACCESSIBLE: + access.log(Level.AUDIT, "AAF Inaccessible. Keeping credentials"); + break; + case REVALIDATED: + user.resetCount(); + touched = true; + break; + default: + user.resetCount(); + remove(user); + ++count; + removed = true; + break; + } + } + } + + if(!removed && lur!=null && user.permExpires<= now ) { + if(lur.reload(user).equals(Resp.REVALIDATED)) { + user.renewPerm(); + access.log(Level.DEBUG, "Reloaded Perms for",user); + touched = true; + } + } + user.resetCount(); + if(touched) { + ++renewed; + } + + } else { + if(user.permExpired()) { + remove(user); + ++count; + } + } + } + + // Clean out Misses + int missTotal = missMap.keySet().size(); + int miss = 0; + if(missTotal>0) { + ArrayList<String> keys = new ArrayList<>(missTotal); + keys.addAll(missMap.keySet()); + for(String key : keys) { + Miss m = missMap.get(key); + if(m!=null) { + long timeLeft = m.timestamp - System.currentTimeMillis(); + if(timeLeft<0) { + synchronized(missMap) { + missMap.remove(key); + } + access.log(Level.INFO, m.name, " has been removed from Missed Credential Map (" + m.tries + " invalid tries)"); + ++miss; + } else { + access.log(Level.INFO, m.name, " remains in Missed Credential Map (" + m.tries + " invalid tries) for " + (timeLeft/1000) + " more seconds"); + } + } + } + } + + if(count+renewed+miss>0) { + access.log(Level.INFO, (lur==null?"Cache":lur.getClass().getSimpleName()), "removed",count, + "and renewed",renewed,"expired Permissions out of", total,"and removed", miss, "password misses out of",missTotal); + } + + // If High (total) is reached during this period, increase the number of expired services removed for next time. + // There's no point doing it again here, as there should have been cleaned items. + if(total>high) { + // advance cleanup by 10%, without getting greater than timeInterval. + advance = Math.min(timeInterval, advance+(timeInterval/10)); + } else { + // reduce advance by 10%, without getting lower than 0. + advance = Math.max(0, advance-(timeInterval/10)); + } + } catch (Exception e) { + access.log(Level.ERROR,e.getMessage()); + } + } + } - private String missKey(String name, byte[] bs) throws IOException { - return name + Hash.toHex(missEncrypt.encode(bs)); - } + private String missKey(String name, byte[] bs) throws IOException { + return name + Hash.toHex(missEncrypt.encode(bs)); + } - protected static class Miss { - private static final int MAX_TRIES = 3; + protected static class Miss { + private static final int MAX_TRIES = 3; - long timestamp; + long timestamp; - private long timetolive; + private long timetolive; - private long tries; + private long tries; - private final String name; - - public Miss(final byte[] first, final long timeInterval, final String name) { - timestamp = System.currentTimeMillis() + timeInterval; - this.timetolive = timeInterval; - tries = 0L; - this.name = name; - } - - - public synchronized boolean mayContinue() { - long ts = System.currentTimeMillis(); - if(ts>timestamp) { - tries = 0; - timestamp = ts + timetolive; - } else if(MAX_TRIES <= ++tries) { - return false; - } - return true; - } - - } - - /** - * Report on state - */ - public String toString() { - return getClass().getSimpleName() + - " Cache:\n Users Cached: " + - userMap.size() + - "\n Misses Saved: " + - missMap.size() + - '\n'; - - } + private final String name; + + public Miss(final byte[] first, final long timeInterval, final String name) { + timestamp = System.currentTimeMillis() + timeInterval; + this.timetolive = timeInterval; + tries = 0L; + this.name = name; + } + + + public synchronized boolean mayContinue() { + long ts = System.currentTimeMillis(); + if(ts>timestamp) { + tries = 0; + timestamp = ts + timetolive; + } else if(MAX_TRIES <= ++tries) { + return false; + } + return true; + } + + } + + /** + * Report on state + */ + public String toString() { + return getClass().getSimpleName() + + " Cache:\n Users Cached: " + + userMap.size() + + "\n Misses Saved: " + + missMap.size() + + '\n'; + + } - public void clear(Principal p, StringBuilder sb) { - sb.append(toString()); - userMap.clear(); - missMap.clear(); - access.log(Level.AUDIT, p.getName(),"has cleared User Cache in",getClass().getSimpleName()); - sb.append("Now cleared\n"); - } + public void clear(Principal p, StringBuilder sb) { + sb.append(toString()); + userMap.clear(); + missMap.clear(); + access.log(Level.AUDIT, p.getName(),"has cleared User Cache in",getClass().getSimpleName()); + sb.append("Now cleared\n"); + } }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Access.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Access.java index 83127238..76d9bb2a 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Access.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Access.java @@ -35,146 +35,146 @@ import java.util.Properties; * */ public interface Access { - // levels to use - public enum Level { - DEBUG(0x1), INFO(0x10), AUDIT(0x100), WARN(0x2000), ERROR(0x4000), INIT(0x8000),TRACE(0x10000),NONE(0XFFFF); - private final int bit; - - Level(int ord) { - bit = ord; - } - - public boolean inMask(int mask) { - return (mask & bit) == bit; - } - - public int addToMask(int mask) { - return mask | bit; - } - - public int delFromMask(int mask) { - return mask & ~bit; - } - - public int toggle(int mask) { - if(inMask(mask)) { - return delFromMask(mask); - } else { - return addToMask(mask); - } - } - - - public int maskOf() { - int mask=0; - for(Level l : values()) { - if(ordinal()<=l.ordinal() && l!=NONE) { - mask|=l.bit; - } - } - return mask; - } - } - - /** - * Write a variable list of Object's text via the toString() method with appropriate space, etc. - * @param elements - */ - public void log(Level level, Object ... elements); - - /** - * Printf mechanism for Access - * @param level - * @param fmt - * @param elements - */ - public void printf(Level level, String fmt, Object ... elements); - - /** - * Check if message will log before constructing - * @param level - * @return - */ - public boolean willLog(Level level); - - /** - * Write the contents of an exception, followed by a variable list of Object's text via the - * toString() method with appropriate space, etc. - * - * The Loglevel is always "ERROR" - * - * @param elements - */ - public void log(Exception e, Object ... elements); - - /** - * Set the Level to compare logging too - */ - public void setLogLevel(Level level); - - /** - * It is important in some cases to create a class from within the same Classloader that created - * Security Objects. Specifically, it's pretty typical for Web Containers to separate classloaders - * so as to allow Apps with different dependencies. - * @return - */ - public ClassLoader classLoader(); - - public String getProperty(String string, String def); - - public Properties getProperties(); - - public void load(InputStream is) throws IOException; - - /** - * if "anytext" is true, then decryption will always be attempted. Otherwise, only if starts with - * Symm.ENC - * @param encrypted - * @param anytext - * @return - * @throws IOException - */ - public String decrypt(String encrypted, boolean anytext) throws IOException; - - public static final Access NULL = new Access() { - public void log(Level level, Object... elements) { - } - - @Override - public void printf(Level level, String fmt, Object... elements) { - } - - public void log(Exception e, Object... elements) { - } - - public ClassLoader classLoader() { - return ClassLoader.getSystemClassLoader(); - } - - public String getProperty(String string, String def) { - return null; - } - - public void load(InputStream is) throws IOException { - } - - public void setLogLevel(Level level) { - } - - public String decrypt(String encrypted, boolean anytext) throws IOException { - return encrypted; - } - - @Override - public boolean willLog(Level level) { - return false; - } - - @Override - public Properties getProperties() { - return new Properties(); - } - }; + // levels to use + public enum Level { + DEBUG(0x1), INFO(0x10), AUDIT(0x100), WARN(0x2000), ERROR(0x4000), INIT(0x8000),TRACE(0x10000),NONE(0XFFFF); + private final int bit; + + Level(int ord) { + bit = ord; + } + + public boolean inMask(int mask) { + return (mask & bit) == bit; + } + + public int addToMask(int mask) { + return mask | bit; + } + + public int delFromMask(int mask) { + return mask & ~bit; + } + + public int toggle(int mask) { + if(inMask(mask)) { + return delFromMask(mask); + } else { + return addToMask(mask); + } + } + + + public int maskOf() { + int mask=0; + for(Level l : values()) { + if(ordinal()<=l.ordinal() && l!=NONE) { + mask|=l.bit; + } + } + return mask; + } + } + + /** + * Write a variable list of Object's text via the toString() method with appropriate space, etc. + * @param elements + */ + public void log(Level level, Object ... elements); + + /** + * Printf mechanism for Access + * @param level + * @param fmt + * @param elements + */ + public void printf(Level level, String fmt, Object ... elements); + + /** + * Check if message will log before constructing + * @param level + * @return + */ + public boolean willLog(Level level); + + /** + * Write the contents of an exception, followed by a variable list of Object's text via the + * toString() method with appropriate space, etc. + * + * The Loglevel is always "ERROR" + * + * @param elements + */ + public void log(Exception e, Object ... elements); + + /** + * Set the Level to compare logging too + */ + public void setLogLevel(Level level); + + /** + * It is important in some cases to create a class from within the same Classloader that created + * Security Objects. Specifically, it's pretty typical for Web Containers to separate classloaders + * so as to allow Apps with different dependencies. + * @return + */ + public ClassLoader classLoader(); + + public String getProperty(String string, String def); + + public Properties getProperties(); + + public void load(InputStream is) throws IOException; + + /** + * if "anytext" is true, then decryption will always be attempted. Otherwise, only if starts with + * Symm.ENC + * @param encrypted + * @param anytext + * @return + * @throws IOException + */ + public String decrypt(String encrypted, boolean anytext) throws IOException; + + public static final Access NULL = new Access() { + public void log(Level level, Object... elements) { + } + + @Override + public void printf(Level level, String fmt, Object... elements) { + } + + public void log(Exception e, Object... elements) { + } + + public ClassLoader classLoader() { + return ClassLoader.getSystemClassLoader(); + } + + public String getProperty(String string, String def) { + return null; + } + + public void load(InputStream is) throws IOException { + } + + public void setLogLevel(Level level) { + } + + public String decrypt(String encrypted, boolean anytext) throws IOException { + return encrypted; + } + + @Override + public boolean willLog(Level level) { + return false; + } + + @Override + public Properties getProperties() { + return new Properties(); + } + }; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/BasicCred.java b/cadi/core/src/main/java/org/onap/aaf/cadi/BasicCred.java index b80cda89..ebb41aba 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/BasicCred.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/BasicCred.java @@ -30,7 +30,7 @@ package org.onap.aaf.cadi; * */ public interface BasicCred extends GetCred { - public void setUser(String user); - public void setCred(byte[] passwd); - public String getUser(); + public void setUser(String user); + public void setCred(byte[] passwd); + public String getUser(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/BufferedServletInputStream.java b/cadi/core/src/main/java/org/onap/aaf/cadi/BufferedServletInputStream.java index 2df01cda..3f47351b 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/BufferedServletInputStream.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/BufferedServletInputStream.java @@ -47,154 +47,154 @@ import javax.servlet.ServletInputStream; * */ public class BufferedServletInputStream extends ServletInputStream { - private static final int NONE = 0; - private static final int STORE = 1; - private static final int READ = 2; - - private InputStream is; - private int state = NONE; - private Capacitor capacitor; - - public BufferedServletInputStream(InputStream is) { - this.is = is; - capacitor = null; - } - - - public int read() throws IOException { - int value=-1; - if(capacitor==null) { - value=is.read(); - } else { - switch(state) { - case STORE: - value = is.read(); - if(value>=0) { - capacitor.put((byte)value); - } - break; - case READ: - value = capacitor.read(); - if(value<0) { - capacitor.done(); - capacitor=null; // all done with buffer - value = is.read(); - } - } - } - return value; - } - - public int read(byte[] b) throws IOException { - return read(b,0,b.length); - } - - - public int read(byte[] b, int off, int len) throws IOException { - int count = -1; - if(capacitor==null) { - count = is.read(b,off,len); - } else { - switch(state) { - case STORE: - count = is.read(b, off, len); - if(count>0) { - capacitor.put(b, off, count); - } - break; - case READ: - count = capacitor.read(b, off, len); - if(count<=0) { - capacitor.done(); - capacitor=null; // all done with buffer - } - if(count<len) { - int temp = is.read(b, count, len-count); - if(temp>0) { // watch for -1 - count+=temp; - } else if(count<=0) { + private static final int NONE = 0; + private static final int STORE = 1; + private static final int READ = 2; + + private InputStream is; + private int state = NONE; + private Capacitor capacitor; + + public BufferedServletInputStream(InputStream is) { + this.is = is; + capacitor = null; + } + + + public int read() throws IOException { + int value=-1; + if(capacitor==null) { + value=is.read(); + } else { + switch(state) { + case STORE: + value = is.read(); + if(value>=0) { + capacitor.put((byte)value); + } + break; + case READ: + value = capacitor.read(); + if(value<0) { + capacitor.done(); + capacitor=null; // all done with buffer + value = is.read(); + } + } + } + return value; + } + + public int read(byte[] b) throws IOException { + return read(b,0,b.length); + } + + + public int read(byte[] b, int off, int len) throws IOException { + int count = -1; + if(capacitor==null) { + count = is.read(b,off,len); + } else { + switch(state) { + case STORE: + count = is.read(b, off, len); + if(count>0) { + capacitor.put(b, off, count); + } + break; + case READ: + count = capacitor.read(b, off, len); + if(count<=0) { + capacitor.done(); + capacitor=null; // all done with buffer + } + if(count<len) { + int temp = is.read(b, count, len-count); + if(temp>0) { // watch for -1 + count+=temp; + } else if(count<=0) { count = temp; // must account for Stream coming back -1 - } - } - break; - } - } - return count; - } - - public long skip(long n) throws IOException { - long skipped = capacitor.skip(n); - if(skipped<n) { - skipped += is.skip(n-skipped); - } - return skipped; - } - - - public int available() throws IOException { - int count = is.available(); - if(capacitor!=null)count+=capacitor.available(); - return count; - } - - /** - * Return just amount buffered (for debugging purposes, mostly) - * @return - */ - public int buffered() { - return capacitor.available(); - } - - - public void close() throws IOException { - if(capacitor!=null) { - capacitor.done(); - capacitor=null; - } - is.close(); - } - - - /** - * Note: Readlimit is ignored in this implementation, because the need was for unknown buffer size which wouldn't - * require allocating and dumping huge chunks of memory every use, or risk overflow. - */ - public synchronized void mark(int readlimit) { - switch(state) { - case NONE: - capacitor = new Capacitor(); - break; - case READ: - capacitor.done(); - break; - } - state = STORE; - } - - - /** - * Reset Stream - * - * Calling this twice is not supported in typical Stream situations, but it is allowed in this service. The caveat is that it can only reset - * the data read in since Mark has been called. The data integrity is only valid if you have not continued to read past what is stored. - * - */ - public synchronized void reset() throws IOException { - switch(state) { - case STORE: - capacitor.setForRead(); - state = READ; - break; - case READ: - capacitor.reset(); - break; - case NONE: - throw new IOException("InputStream has not been marked"); - } - } - - - public boolean markSupported() { - return true; - } + } + } + break; + } + } + return count; + } + + public long skip(long n) throws IOException { + long skipped = capacitor.skip(n); + if(skipped<n) { + skipped += is.skip(n-skipped); + } + return skipped; + } + + + public int available() throws IOException { + int count = is.available(); + if(capacitor!=null)count+=capacitor.available(); + return count; + } + + /** + * Return just amount buffered (for debugging purposes, mostly) + * @return + */ + public int buffered() { + return capacitor.available(); + } + + + public void close() throws IOException { + if(capacitor!=null) { + capacitor.done(); + capacitor=null; + } + is.close(); + } + + + /** + * Note: Readlimit is ignored in this implementation, because the need was for unknown buffer size which wouldn't + * require allocating and dumping huge chunks of memory every use, or risk overflow. + */ + public synchronized void mark(int readlimit) { + switch(state) { + case NONE: + capacitor = new Capacitor(); + break; + case READ: + capacitor.done(); + break; + } + state = STORE; + } + + + /** + * Reset Stream + * + * Calling this twice is not supported in typical Stream situations, but it is allowed in this service. The caveat is that it can only reset + * the data read in since Mark has been called. The data integrity is only valid if you have not continued to read past what is stored. + * + */ + public synchronized void reset() throws IOException { + switch(state) { + case STORE: + capacitor.setForRead(); + state = READ; + break; + case READ: + capacitor.reset(); + break; + case NONE: + throw new IOException("InputStream has not been marked"); + } + } + + + public boolean markSupported() { + return true; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CachedPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CachedPrincipal.java index 2bb3db32..6f3fe126 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CachedPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CachedPrincipal.java @@ -30,18 +30,18 @@ import java.security.Principal; * */ public interface CachedPrincipal extends Principal { - public enum Resp {NOT_MINE,UNVALIDATED,REVALIDATED,INACCESSIBLE,DENIED}; - - /** - * Re-validate with Creator - * - * @return - */ - public abstract Resp revalidate(Object state); - - /** - * Store when last updated. - * @return - */ - public abstract long expires(); + public enum Resp {NOT_MINE,UNVALIDATED,REVALIDATED,INACCESSIBLE,DENIED}; + + /** + * Re-validate with Creator + * + * @return + */ + public abstract Resp revalidate(Object state); + + /** + * Store when last updated. + * @return + */ + public abstract long expires(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CachingLur.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CachingLur.java index e083f4ed..c790f39e 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CachingLur.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CachingLur.java @@ -27,8 +27,8 @@ import org.onap.aaf.cadi.CachedPrincipal.Resp; public interface CachingLur<PERM extends Permission> extends Lur { - public abstract void remove(String user); - public abstract Resp reload(User<PERM> user); - public abstract void setDebug(String commaDelimIDsOrNull); - public abstract void clear(Principal p, StringBuilder sb); + public abstract void remove(String user); + public abstract Resp reload(User<PERM> user); + public abstract void setDebug(String commaDelimIDsOrNull); + public abstract void clear(Principal p, StringBuilder sb); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CadiException.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CadiException.java index 0f250b36..96a55f93 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CadiException.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CadiException.java @@ -26,25 +26,25 @@ package org.onap.aaf.cadi; * @author Jonathan */ public class CadiException extends Exception { - /** - * Generated ID - */ - private static final long serialVersionUID = -4180145363107742619L; + /** + * Generated ID + */ + private static final long serialVersionUID = -4180145363107742619L; - public CadiException() { - super(); - } + public CadiException() { + super(); + } - public CadiException(String message) { - super(message); - } + public CadiException(String message) { + super(message); + } - public CadiException(Throwable cause) { - super(cause); - } + public CadiException(Throwable cause) { + super(cause); + } - public CadiException(String message, Throwable cause) { - super(message, cause); - } + public CadiException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java index 6f4d5cc7..647cd8a6 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java @@ -51,150 +51,150 @@ import org.onap.aaf.cadi.util.Timing; * */ public class CadiWrap extends HttpServletRequestWrapper implements HttpServletRequest, BasicCred { - private TaggedPrincipal principal; - private Lur lur; - private String user; // used to set user/pass from brain-dead protocols like WSSE - private byte[] password; - private PermConverter pconv; - private Access access; - - /** - * Standard Wrapper constructor for Delegate pattern - * @param request - */ - public CadiWrap(HttpServletRequest request, TafResp tafResp, Lur lur) { - super(request); - principal = tafResp.getPrincipal(); - access = tafResp.getAccess(); - this.lur = lur; - pconv = NullPermConverter.singleton(); - } - - /** - * Standard Wrapper constructor for Delegate pattern, with PermConverter - * @param request - */ - public CadiWrap(HttpServletRequest request, TafResp tafResp, Lur lur, PermConverter pc) { - super(request); - principal = tafResp.getPrincipal(); - access = tafResp.getAccess(); - this.lur = lur; - pconv = pc; - } - - - /** - * Part of the HTTP Security API. Declare the User associated with this HTTP Transaction. - * CADI does this by reporting the name associated with the Principal obtained, if any. - */ - @Override - public String getRemoteUser() { - return principal==null?null:principal.getName(); - } - - /** - * Part of the HTTP Security API. Return the User Principal associated with this HTTP - * Transaction. - */ - @Override - public Principal getUserPrincipal() { - return principal; - } - - /** - * This is the key API call for AUTHZ in J2EE. Given a Role (String passed in), is the user - * associated with this HTTP Transaction allowed to function in this Role? - * - * For CADI, we pass the responsibility for determining this to the "LUR", which may be - * determined by the Enterprise. - * - * Note: Role check is also done in "CadiRealm" in certain cases... - * - * - */ - @Override - public boolean isUserInRole(String perm) { - return perm==null?false:checkPerm(access,"isUserInRole",principal,pconv,lur,perm); - } - - public static boolean checkPerm(Access access, String caller, Principal principal, PermConverter pconv, Lur lur, String perm) { - if(principal== null) { - access.log(Level.AUDIT,caller, "No Principal in Transaction"); - return false; - } else { - final long start = System.nanoTime(); - perm = pconv.convert(perm); - if(lur.fish(principal,lur.createPerm(perm))) { - access.printf(Level.DEBUG,"%s: %s has %s, %f ms", caller, principal.getName(), perm, Timing.millis(start)); - return true; - } else { - access.printf(Level.DEBUG,"%s: %s does not have %s, %f ms", caller, principal.getName(), perm, Timing.millis(start)); - return false; - } - } - - } - - /** - * CADI Function (Non J2EE standard). GetPermissions will read the Permissions from AAF (if configured) and Roles from Local Lur, etc - * as implemented with lur.fishAll - * - * To utilize, the Request must be a "CadiWrap" object, then call. - */ - public List<Permission> getPermissions(Principal p) { - List<Permission> perms = new ArrayList<>(); - lur.fishAll(p, perms); - return perms; - } - /** - * Allow setting of tafResp and lur after construction - * - * This can happen if the CadiWrap is constructed in a Valve other than CadiValve - */ - public void set(TafResp tafResp, Lur lur) { - principal = tafResp.getPrincipal(); - access = tafResp.getAccess(); - this.lur = lur; - } - - public String getUser() { - if(user==null && principal!=null) { - user = principal.getName(); - } - return user; - } - - public byte[] getCred() { - return password; - } - - public void setUser(String user) { - this.user = user; - } - - public void setCred(byte[] passwd) { - password = passwd; - } - - public CadiWrap setPermConverter(PermConverter pc) { - pconv = pc; - return this; - } - - // Add a feature - public void invalidate(String id) { - if(lur instanceof EpiLur) { - ((EpiLur)lur).remove(id); - } else if(lur instanceof CachingLur) { - ((CachingLur<?>)lur).remove(id); - } - } - - public Lur getLur() { - return lur; - } - - public Access access() { - return access; - } + private TaggedPrincipal principal; + private Lur lur; + private String user; // used to set user/pass from brain-dead protocols like WSSE + private byte[] password; + private PermConverter pconv; + private Access access; + + /** + * Standard Wrapper constructor for Delegate pattern + * @param request + */ + public CadiWrap(HttpServletRequest request, TafResp tafResp, Lur lur) { + super(request); + principal = tafResp.getPrincipal(); + access = tafResp.getAccess(); + this.lur = lur; + pconv = NullPermConverter.singleton(); + } + + /** + * Standard Wrapper constructor for Delegate pattern, with PermConverter + * @param request + */ + public CadiWrap(HttpServletRequest request, TafResp tafResp, Lur lur, PermConverter pc) { + super(request); + principal = tafResp.getPrincipal(); + access = tafResp.getAccess(); + this.lur = lur; + pconv = pc; + } + + + /** + * Part of the HTTP Security API. Declare the User associated with this HTTP Transaction. + * CADI does this by reporting the name associated with the Principal obtained, if any. + */ + @Override + public String getRemoteUser() { + return principal==null?null:principal.getName(); + } + + /** + * Part of the HTTP Security API. Return the User Principal associated with this HTTP + * Transaction. + */ + @Override + public Principal getUserPrincipal() { + return principal; + } + + /** + * This is the key API call for AUTHZ in J2EE. Given a Role (String passed in), is the user + * associated with this HTTP Transaction allowed to function in this Role? + * + * For CADI, we pass the responsibility for determining this to the "LUR", which may be + * determined by the Enterprise. + * + * Note: Role check is also done in "CadiRealm" in certain cases... + * + * + */ + @Override + public boolean isUserInRole(String perm) { + return perm==null?false:checkPerm(access,"isUserInRole",principal,pconv,lur,perm); + } + + public static boolean checkPerm(Access access, String caller, Principal principal, PermConverter pconv, Lur lur, String perm) { + if(principal== null) { + access.log(Level.AUDIT,caller, "No Principal in Transaction"); + return false; + } else { + final long start = System.nanoTime(); + perm = pconv.convert(perm); + if(lur.fish(principal,lur.createPerm(perm))) { + access.printf(Level.DEBUG,"%s: %s has %s, %f ms", caller, principal.getName(), perm, Timing.millis(start)); + return true; + } else { + access.printf(Level.DEBUG,"%s: %s does not have %s, %f ms", caller, principal.getName(), perm, Timing.millis(start)); + return false; + } + } + + } + + /** + * CADI Function (Non J2EE standard). GetPermissions will read the Permissions from AAF (if configured) and Roles from Local Lur, etc + * as implemented with lur.fishAll + * + * To utilize, the Request must be a "CadiWrap" object, then call. + */ + public List<Permission> getPermissions(Principal p) { + List<Permission> perms = new ArrayList<>(); + lur.fishAll(p, perms); + return perms; + } + /** + * Allow setting of tafResp and lur after construction + * + * This can happen if the CadiWrap is constructed in a Valve other than CadiValve + */ + public void set(TafResp tafResp, Lur lur) { + principal = tafResp.getPrincipal(); + access = tafResp.getAccess(); + this.lur = lur; + } + + public String getUser() { + if(user==null && principal!=null) { + user = principal.getName(); + } + return user; + } + + public byte[] getCred() { + return password; + } + + public void setUser(String user) { + this.user = user; + } + + public void setCred(byte[] passwd) { + password = passwd; + } + + public CadiWrap setPermConverter(PermConverter pc) { + pconv = pc; + return this; + } + + // Add a feature + public void invalidate(String id) { + if(lur instanceof EpiLur) { + ((EpiLur)lur).remove(id); + } else if(lur instanceof CachingLur) { + ((CachingLur<?>)lur).remove(id); + } + } + + public Lur getLur() { + return lur; + } + + public Access access() { + return access; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Capacitor.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Capacitor.java index 935e4f14..5ca1ce30 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Capacitor.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Capacitor.java @@ -35,207 +35,207 @@ import java.util.ArrayList; * */ public class Capacitor { - private static final int DEFAULT_CHUNK = 256; - private ArrayList<ByteBuffer> bbs = new ArrayList<>(); - private ByteBuffer curr = null; - private int idx; - - // Maintain a private RingBuffer for Memory, for efficiency - private static ByteBuffer[] ring = new ByteBuffer[16]; - private static int start, end; - - - public void put(byte b) { - if(curr == null || curr.remaining()==0) { // ensure we have a "curr" buffer ready for data - curr = ringGet(); - bbs.add(curr); - } - curr.put(b); - } + private static final int DEFAULT_CHUNK = 256; + private ArrayList<ByteBuffer> bbs = new ArrayList<>(); + private ByteBuffer curr = null; + private int idx; + + // Maintain a private RingBuffer for Memory, for efficiency + private static ByteBuffer[] ring = new ByteBuffer[16]; + private static int start, end; + + + public void put(byte b) { + if(curr == null || curr.remaining()==0) { // ensure we have a "curr" buffer ready for data + curr = ringGet(); + bbs.add(curr); + } + curr.put(b); + } - public int read() { - if(curr!=null) { - if(curr.remaining()>0) { // have a buffer, use it! - return curr.get(); - } else if(idx<bbs.size()){ // Buffer not enough, get next one from array - curr=bbs.get(idx++); - return curr.get(); - } - } // if no curr buffer, treat as end of stream - return -1; - } - - /** - * read into an array like Streams - * - * @param array - * @param offset - * @param length - * @return - */ - public int read(byte[] array, int offset, int length) { - if(curr==null)return -1; - int len; - int count=0; - while(length>0) { // loop through while there's data needed - if((len=curr.remaining())>length) { // if enough data in curr buffer, use this code - curr.get(array,offset,length); - count+=length; - length=0; - } else { // get data from curr, mark how much is needed to fulfil, and loop for next curr. - curr.get(array,offset,len); - count+=len; - offset+=len; - length-=len; - if(idx<bbs.size()) { - curr=bbs.get(idx++); - } else { - length=0; // stop, and return the count of how many we were able to load - } - } - } - return count; - } + public int read() { + if(curr!=null) { + if(curr.remaining()>0) { // have a buffer, use it! + return curr.get(); + } else if(idx<bbs.size()){ // Buffer not enough, get next one from array + curr=bbs.get(idx++); + return curr.get(); + } + } // if no curr buffer, treat as end of stream + return -1; + } + + /** + * read into an array like Streams + * + * @param array + * @param offset + * @param length + * @return + */ + public int read(byte[] array, int offset, int length) { + if(curr==null)return -1; + int len; + int count=0; + while(length>0) { // loop through while there's data needed + if((len=curr.remaining())>length) { // if enough data in curr buffer, use this code + curr.get(array,offset,length); + count+=length; + length=0; + } else { // get data from curr, mark how much is needed to fulfil, and loop for next curr. + curr.get(array,offset,len); + count+=len; + offset+=len; + length-=len; + if(idx<bbs.size()) { + curr=bbs.get(idx++); + } else { + length=0; // stop, and return the count of how many we were able to load + } + } + } + return count; + } - /** - * Put an array of data into Capacitor - * - * @param array - * @param offset - * @param length - */ - public void put(byte[] array, int offset, int length) { - if(curr == null || curr.remaining()==0) { - curr = ringGet(); - bbs.add(curr); - } - - int len; - while(length>0) { - if((len=curr.remaining())>length) { - curr.put(array,offset,length); - length=0; - } else { -// System.out.println(new String(array)); - curr.put(array,offset,len); - length-=len; - offset+=len; - curr = ringGet(); - bbs.add(curr); - } - } - } - - /** - * Move state from Storage mode into Read mode, changing all internal buffers to read mode, etc - */ - public void setForRead() { - for(ByteBuffer bb : bbs) { - bb.flip(); - } - if(bbs.isEmpty()) { - curr = null; - idx = 0; - } else { - curr=bbs.get(0); - idx=1; - } - } - - /** - * reuse all the buffers - */ - public void done() { - for(ByteBuffer bb : bbs) { - ringPut(bb); - } - bbs.clear(); - curr = null; - } - - /** - * Declare amount of data available to be read at once. - * - * @return - */ - public int available() { - int count = 0; - for(ByteBuffer bb : bbs) { - count+=bb.remaining(); - } - return count; - } - - /** - * Returns how many are left that were not skipped - * @param n - * @return - */ - public long skip(long n) { - long skipped=0L; - int skip; - if(curr==null) { - return 0; - } - while(n>0) { - if(n<(skip=curr.remaining())) { - curr.position(curr.position()+(int)n); - skipped+=skip; - n=0; - } else { - curr.position(curr.limit()); - - skipped-=skip; - if(idx<bbs.size()) { - curr=bbs.get(idx++); - n-=skip; - } else { - n=0; - } - } - } - return skipped > 0 ? skipped : 0; - } - /** - * Be able to re-read data that is stored that has already been re-read. This is not a standard Stream behavior, but can be useful - * in a standalone mode. - */ - public void reset() { - for(ByteBuffer bb : bbs) { - bb.position(0); - } - if(bbs.isEmpty()) { - curr = null; - idx = 0; - } else { - curr=bbs.get(0); - idx=1; - } - } + /** + * Put an array of data into Capacitor + * + * @param array + * @param offset + * @param length + */ + public void put(byte[] array, int offset, int length) { + if(curr == null || curr.remaining()==0) { + curr = ringGet(); + bbs.add(curr); + } + + int len; + while(length>0) { + if((len=curr.remaining())>length) { + curr.put(array,offset,length); + length=0; + } else { +// System.out.println(new String(array)); + curr.put(array,offset,len); + length-=len; + offset+=len; + curr = ringGet(); + bbs.add(curr); + } + } + } + + /** + * Move state from Storage mode into Read mode, changing all internal buffers to read mode, etc + */ + public void setForRead() { + for(ByteBuffer bb : bbs) { + bb.flip(); + } + if(bbs.isEmpty()) { + curr = null; + idx = 0; + } else { + curr=bbs.get(0); + idx=1; + } + } + + /** + * reuse all the buffers + */ + public void done() { + for(ByteBuffer bb : bbs) { + ringPut(bb); + } + bbs.clear(); + curr = null; + } + + /** + * Declare amount of data available to be read at once. + * + * @return + */ + public int available() { + int count = 0; + for(ByteBuffer bb : bbs) { + count+=bb.remaining(); + } + return count; + } + + /** + * Returns how many are left that were not skipped + * @param n + * @return + */ + public long skip(long n) { + long skipped=0L; + int skip; + if(curr==null) { + return 0; + } + while(n>0) { + if(n<(skip=curr.remaining())) { + curr.position(curr.position()+(int)n); + skipped+=skip; + n=0; + } else { + curr.position(curr.limit()); + + skipped-=skip; + if(idx<bbs.size()) { + curr=bbs.get(idx++); + n-=skip; + } else { + n=0; + } + } + } + return skipped > 0 ? skipped : 0; + } + /** + * Be able to re-read data that is stored that has already been re-read. This is not a standard Stream behavior, but can be useful + * in a standalone mode. + */ + public void reset() { + for(ByteBuffer bb : bbs) { + bb.position(0); + } + if(bbs.isEmpty()) { + curr = null; + idx = 0; + } else { + curr=bbs.get(0); + idx=1; + } + } - /* - * Ring Functions. Reuse allocated memory - */ - private ByteBuffer ringGet() { - ByteBuffer bb = null; - synchronized(ring) { - bb=ring[start]; - ring[start]=null; - if(bb!=null && ++start>15)start=0; - } - if(bb==null) { - bb=ByteBuffer.allocate(DEFAULT_CHUNK); - } else { - bb.clear();// refresh reused buffer - } - return bb; - } - - private void ringPut(ByteBuffer bb) { - synchronized(ring) { - ring[end]=bb; // if null or not, BB will just be Garbage collected - if(++end>15)end=0; - } - } + /* + * Ring Functions. Reuse allocated memory + */ + private ByteBuffer ringGet() { + ByteBuffer bb = null; + synchronized(ring) { + bb=ring[start]; + ring[start]=null; + if(bb!=null && ++start>15)start=0; + } + if(bb==null) { + bb=ByteBuffer.allocate(DEFAULT_CHUNK); + } else { + bb.clear();// refresh reused buffer + } + return bb; + } + + private void ringPut(ByteBuffer bb) { + synchronized(ring) { + ring[end]=bb; // if null or not, BB will just be Garbage collected + if(++end>15)end=0; + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java index 9444cfac..7ca9fac2 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CmdLine.java @@ -43,313 +43,313 @@ import org.onap.aaf.cadi.util.JsonOutputStream; */ public class CmdLine { - private static boolean systemExit = true; - /** - * @param args - */ - public static void main(String[] args) { - if(args.length>0) { - if("digest".equalsIgnoreCase(args[0]) && (args.length>2 || (args.length>1 && System.console()!=null))) { - String keyfile; - String password; - if(args.length>2) { - password = args[1]; - keyfile = args[2]; - if("-i".equals(password)) { - int c; - StringBuilder sb = new StringBuilder(); - try { - while((c=System.in.read())>=0) { - sb.append((char)c); - } - } catch (IOException e) { - e.printStackTrace(); - } - password = sb.toString(); - } - } else { - keyfile = args[1]; - password = new String(System.console().readPassword("Type here (keystrokes hidden): ")); - } + private static boolean systemExit = true; + /** + * @param args + */ + public static void main(String[] args) { + if(args.length>0) { + if("digest".equalsIgnoreCase(args[0]) && (args.length>2 || (args.length>1 && System.console()!=null))) { + String keyfile; + String password; + if(args.length>2) { + password = args[1]; + keyfile = args[2]; + if("-i".equals(password)) { + int c; + StringBuilder sb = new StringBuilder(); + try { + while((c=System.in.read())>=0) { + sb.append((char)c); + } + } catch (IOException e) { + e.printStackTrace(); + } + password = sb.toString(); + } + } else { + keyfile = args[1]; + password = new String(System.console().readPassword("Type here (keystrokes hidden): ")); + } - try { - Symm symm; - FileInputStream fis = new FileInputStream(keyfile); - try { - symm = Symm.obtain(fis); - } finally { - fis.close(); - } - symm.enpass(password, System.out); - System.out.println(); - System.out.flush(); - return; - /* testing code... don't want it exposed - System.out.println(" ******** Testing *********"); - for(int i=0;i<100000;++i) { - System.out.println(args[1]); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - b64.enpass(args[1], baos); - String pass; - System.out.println(pass=new String(baos.toByteArray())); - ByteArrayOutputStream reconstituted = new ByteArrayOutputStream(); - b64.depass(pass, reconstituted); - String r = reconstituted.toString(); - System.out.println(r); - if(!r.equals(args[1])) { - System.err.println("!!!!! STOP - ERROR !!!!!"); - return; - } - System.out.println(); - } - System.out.flush(); - */ - - } catch (IOException e) { - System.err.println("Cannot digest password"); - System.err.println(" \""+ e.getMessage() + '"'); - } + try { + Symm symm; + FileInputStream fis = new FileInputStream(keyfile); + try { + symm = Symm.obtain(fis); + } finally { + fis.close(); + } + symm.enpass(password, System.out); + System.out.println(); + System.out.flush(); + return; + /* testing code... don't want it exposed + System.out.println(" ******** Testing *********"); + for(int i=0;i<100000;++i) { + System.out.println(args[1]); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + b64.enpass(args[1], baos); + String pass; + System.out.println(pass=new String(baos.toByteArray())); + ByteArrayOutputStream reconstituted = new ByteArrayOutputStream(); + b64.depass(pass, reconstituted); + String r = reconstituted.toString(); + System.out.println(r); + if(!r.equals(args[1])) { + System.err.println("!!!!! STOP - ERROR !!!!!"); + return; + } + System.out.println(); + } + System.out.flush(); + */ + + } catch (IOException e) { + System.err.println("Cannot digest password"); + System.err.println(" \""+ e.getMessage() + '"'); + } // DO NOT LEAVE THIS METHOD Compiled IN CODE... Do not want looking at passwords on disk too easy // Jonathan. Oh, well, Deployment services need this behavior. I will put this code in, but leave it undocumented. // One still needs access to the keyfile to read. // July 2016 - thought of a tool "CMPass" to regurgitate from properties, but only if allowed. - } else if("regurgitate".equalsIgnoreCase(args[0]) && args.length>2) { - try { - Symm symm; - FileInputStream fis = new FileInputStream(args[2]); - try { - symm = Symm.obtain(fis); - } finally { - fis.close(); - } - boolean isFile = false; - if("-i".equals(args[1]) || (isFile="-f".equals(args[1]))) { - BufferedReader br; - if(isFile) { - if(args.length<4) { - System.err.println("Filename in 4th position"); - return; - } - br = new BufferedReader(new FileReader(args[3])); - } else { - br = new BufferedReader(new InputStreamReader(System.in)); - } - try { - String line; - boolean cont = false; - StringBuffer sb = new StringBuffer(); - JsonOutputStream jw = new JsonOutputStream(System.out); - while((line=br.readLine())!=null) { - if(cont) { - int end; - if((end=line.indexOf('"'))>=0) { - sb.append(line,0,end); - cont=false; - } else { - sb.append(line); - } - } else { - int idx; - if((idx = line.indexOf(' '))>=0 - && (idx = line.indexOf(' ',++idx))>0 - && (idx = line.indexOf('=',++idx))>0 - ) { - System.out.println(line.substring(0, idx-5)); - int start = idx+2; - int end; - if((end=line.indexOf('"',start))<0) { - end = line.length(); - cont = true; - } - sb.append(line,start,end); - } - } - if(sb.length()>0) { - symm.depass(sb.toString(),jw); - if(!cont) { - System.out.println(); - } - } - System.out.flush(); - sb.setLength(0); - if(!cont) { - jw.resetIndent(); - } - } - } finally { - if(isFile) { - br.close(); - } - } - } else { - symm.depass(args[1], System.out); - } - System.out.println(); - System.out.flush(); - return; - } catch (IOException e) { - System.err.println("Cannot regurgitate password"); - System.err.println(" \""+ e.getMessage() + '"'); - } - } else if("encode64".equalsIgnoreCase(args[0]) && args.length>1) { - try { - Symm.base64.encode(args[1], System.out); - System.out.println(); - System.out.flush(); - return; - } catch (IOException e) { - System.err.println("Cannot encode Base64 with " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - } else if("decode64".equalsIgnoreCase(args[0]) && args.length>1) { - try { - Symm.base64.decode(args[1], System.out); - System.out.println(); - System.out.flush(); - return; - } catch (IOException e) { - System.err.println("Cannot decode Base64 text from " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - } else if("encode64url".equalsIgnoreCase(args[0]) && args.length>1) { - try { - Symm.base64url.encode(args[1], System.out); - System.out.println(); - System.out.flush(); - return; - } catch (IOException e) { - System.err.println("Cannot encode Base64url with " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - } else if("decode64url".equalsIgnoreCase(args[0]) && args.length>1) { - try { - Symm.base64url.decode(args[1], System.out); - System.out.println(); - System.out.flush(); - return; - } catch (IOException e) { - System.err.println("Cannot decode Base64url text from " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - } else if("md5".equalsIgnoreCase(args[0]) && args.length>1) { - try { - System.out.println(Hash.hashMD5asStringHex(args[1])); - System.out.flush(); - } catch (NoSuchAlgorithmException e) { - System.err.println("Cannot hash MD5 from " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - return; - } else if("sha256".equalsIgnoreCase(args[0]) && args.length>1) { - try { - if(args.length>2) { - int max = args.length>7?7:args.length; - for(int i=2;i<max;++i) { - int salt = Integer.parseInt(args[i]); - System.out.println(Hash.hashSHA256asStringHex(args[1],salt)); - } - } else { - System.out.println(Hash.hashSHA256asStringHex(args[1])); - } - } catch (NoSuchAlgorithmException e) { - System.err.println("Cannot hash SHA256 text from " + args[1]); - System.err.println(" \""+ e.getMessage() + '"'); - } - System.out.flush(); - return; - } else if("keygen".equalsIgnoreCase(args[0])) { - try { - if(args.length>1) { - File f = new File(args[1]); - FileOutputStream fos = new FileOutputStream(f); - try { - fos.write(Symm.keygen()); - fos.flush(); - } finally { - fos.close(); - Chmod.to400.chmod(f); - } - } else { - // create a Symmetric Key out of same characters found in base64 - System.out.write(Symm.keygen()); - System.out.flush(); - } - return; - } catch (IOException e) { - System.err.println("Cannot create a key " + args[0]); - System.err.println(" \""+ e.getMessage() + '"'); - } - - } else if("passgen".equalsIgnoreCase(args[0])) { - int numDigits; - if(args.length <= 1) { - numDigits = 24; - } else { - numDigits = Integer.parseInt(args[1]); - if(numDigits<8)numDigits = 8; - } - String pass; - boolean noLower,noUpper,noDigits,noSpecial,repeatingChars,missingChars; - do { - pass = Symm.randomGen(numDigits); - missingChars=noLower=noUpper=noDigits=noSpecial=true; - repeatingChars=false; - int c=-1,last; - for(int i=0;i<numDigits;++i) { - last = c; - c = pass.charAt(i); - if(c==last) { - repeatingChars=true; - break; - } - if(noLower) { - noLower=!(c>=0x61 && c<=0x7A); - } - if(noUpper) { - noUpper=!(c>=0x41 && c<=0x5A); - } - if(noDigits) { - noDigits=!(c>=0x30 && c<=0x39); - } - if(noSpecial) { - noSpecial = "+!@#$%^&*(){}[]?:;,.".indexOf(c)<0; - } - - missingChars = (noLower || noUpper || noDigits || noSpecial); - } - } while(missingChars || repeatingChars); - System.out.println(pass.substring(0,numDigits)); - } else if("urlgen".equalsIgnoreCase(args[0])) { - int numDigits; - if(args.length <= 1) { - numDigits = 24; - } else { - numDigits = Integer.parseInt(args[1]); - } - System.out.println(Symm.randomGen(Symm.base64url.codeset, numDigits).substring(0,numDigits)); - } - } else { - System.out.println("Usage: java -jar <this jar> ..."); - System.out.println(" keygen [<keyfile>] (Generates Key on file, or Std Out)"); - System.out.println(" digest [<passwd>|-i|] <keyfile> (Encrypts Password with \"keyfile\""); - System.out.println(" if passwd = -i, will read StdIn"); - System.out.println(" if passwd is blank, will ask securely)"); - System.out.println(" passgen <digits> (Generate Password of given size)"); - System.out.println(" urlgen <digits> (Generate URL field of given size)"); - System.out.println(" encode64 <your text> (Encodes to Base64)"); - System.out.println(" decode64 <base64 encoded text> (Decodes from Base64)"); - System.out.println(" encode64url <your text> (Encodes to Base64 URL charset)"); - System.out.println(" decode64url <base64url encoded text> (Decodes from Base64 URL charset)"); - System.out.println(" sha256 <text> <salts(s)> (Digest String into SHA256 Hash)"); - System.out.println(" md5 <text> (Digest String into MD5 Hash)"); - } - if (systemExit) { - System.exit(1); - } - } - - public static void setSystemExit(boolean shouldExit) { - systemExit = shouldExit; - } - + } else if("regurgitate".equalsIgnoreCase(args[0]) && args.length>2) { + try { + Symm symm; + FileInputStream fis = new FileInputStream(args[2]); + try { + symm = Symm.obtain(fis); + } finally { + fis.close(); + } + boolean isFile = false; + if("-i".equals(args[1]) || (isFile="-f".equals(args[1]))) { + BufferedReader br; + if(isFile) { + if(args.length<4) { + System.err.println("Filename in 4th position"); + return; + } + br = new BufferedReader(new FileReader(args[3])); + } else { + br = new BufferedReader(new InputStreamReader(System.in)); + } + try { + String line; + boolean cont = false; + StringBuffer sb = new StringBuffer(); + JsonOutputStream jw = new JsonOutputStream(System.out); + while((line=br.readLine())!=null) { + if(cont) { + int end; + if((end=line.indexOf('"'))>=0) { + sb.append(line,0,end); + cont=false; + } else { + sb.append(line); + } + } else { + int idx; + if((idx = line.indexOf(' '))>=0 + && (idx = line.indexOf(' ',++idx))>0 + && (idx = line.indexOf('=',++idx))>0 + ) { + System.out.println(line.substring(0, idx-5)); + int start = idx+2; + int end; + if((end=line.indexOf('"',start))<0) { + end = line.length(); + cont = true; + } + sb.append(line,start,end); + } + } + if(sb.length()>0) { + symm.depass(sb.toString(),jw); + if(!cont) { + System.out.println(); + } + } + System.out.flush(); + sb.setLength(0); + if(!cont) { + jw.resetIndent(); + } + } + } finally { + if(isFile) { + br.close(); + } + } + } else { + symm.depass(args[1], System.out); + } + System.out.println(); + System.out.flush(); + return; + } catch (IOException e) { + System.err.println("Cannot regurgitate password"); + System.err.println(" \""+ e.getMessage() + '"'); + } + } else if("encode64".equalsIgnoreCase(args[0]) && args.length>1) { + try { + Symm.base64.encode(args[1], System.out); + System.out.println(); + System.out.flush(); + return; + } catch (IOException e) { + System.err.println("Cannot encode Base64 with " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + } else if("decode64".equalsIgnoreCase(args[0]) && args.length>1) { + try { + Symm.base64.decode(args[1], System.out); + System.out.println(); + System.out.flush(); + return; + } catch (IOException e) { + System.err.println("Cannot decode Base64 text from " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + } else if("encode64url".equalsIgnoreCase(args[0]) && args.length>1) { + try { + Symm.base64url.encode(args[1], System.out); + System.out.println(); + System.out.flush(); + return; + } catch (IOException e) { + System.err.println("Cannot encode Base64url with " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + } else if("decode64url".equalsIgnoreCase(args[0]) && args.length>1) { + try { + Symm.base64url.decode(args[1], System.out); + System.out.println(); + System.out.flush(); + return; + } catch (IOException e) { + System.err.println("Cannot decode Base64url text from " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + } else if("md5".equalsIgnoreCase(args[0]) && args.length>1) { + try { + System.out.println(Hash.hashMD5asStringHex(args[1])); + System.out.flush(); + } catch (NoSuchAlgorithmException e) { + System.err.println("Cannot hash MD5 from " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + return; + } else if("sha256".equalsIgnoreCase(args[0]) && args.length>1) { + try { + if(args.length>2) { + int max = args.length>7?7:args.length; + for(int i=2;i<max;++i) { + int salt = Integer.parseInt(args[i]); + System.out.println(Hash.hashSHA256asStringHex(args[1],salt)); + } + } else { + System.out.println(Hash.hashSHA256asStringHex(args[1])); + } + } catch (NoSuchAlgorithmException e) { + System.err.println("Cannot hash SHA256 text from " + args[1]); + System.err.println(" \""+ e.getMessage() + '"'); + } + System.out.flush(); + return; + } else if("keygen".equalsIgnoreCase(args[0])) { + try { + if(args.length>1) { + File f = new File(args[1]); + FileOutputStream fos = new FileOutputStream(f); + try { + fos.write(Symm.keygen()); + fos.flush(); + } finally { + fos.close(); + Chmod.to400.chmod(f); + } + } else { + // create a Symmetric Key out of same characters found in base64 + System.out.write(Symm.keygen()); + System.out.flush(); + } + return; + } catch (IOException e) { + System.err.println("Cannot create a key " + args[0]); + System.err.println(" \""+ e.getMessage() + '"'); + } + + } else if("passgen".equalsIgnoreCase(args[0])) { + int numDigits; + if(args.length <= 1) { + numDigits = 24; + } else { + numDigits = Integer.parseInt(args[1]); + if(numDigits<8)numDigits = 8; + } + String pass; + boolean noLower,noUpper,noDigits,noSpecial,repeatingChars,missingChars; + do { + pass = Symm.randomGen(numDigits); + missingChars=noLower=noUpper=noDigits=noSpecial=true; + repeatingChars=false; + int c=-1,last; + for(int i=0;i<numDigits;++i) { + last = c; + c = pass.charAt(i); + if(c==last) { + repeatingChars=true; + break; + } + if(noLower) { + noLower=!(c>=0x61 && c<=0x7A); + } + if(noUpper) { + noUpper=!(c>=0x41 && c<=0x5A); + } + if(noDigits) { + noDigits=!(c>=0x30 && c<=0x39); + } + if(noSpecial) { + noSpecial = "+!@#$%^&*(){}[]?:;,.".indexOf(c)<0; + } + + missingChars = (noLower || noUpper || noDigits || noSpecial); + } + } while(missingChars || repeatingChars); + System.out.println(pass.substring(0,numDigits)); + } else if("urlgen".equalsIgnoreCase(args[0])) { + int numDigits; + if(args.length <= 1) { + numDigits = 24; + } else { + numDigits = Integer.parseInt(args[1]); + } + System.out.println(Symm.randomGen(Symm.base64url.codeset, numDigits).substring(0,numDigits)); + } + } else { + System.out.println("Usage: java -jar <this jar> ..."); + System.out.println(" keygen [<keyfile>] (Generates Key on file, or Std Out)"); + System.out.println(" digest [<passwd>|-i|] <keyfile> (Encrypts Password with \"keyfile\""); + System.out.println(" if passwd = -i, will read StdIn"); + System.out.println(" if passwd is blank, will ask securely)"); + System.out.println(" passgen <digits> (Generate Password of given size)"); + System.out.println(" urlgen <digits> (Generate URL field of given size)"); + System.out.println(" encode64 <your text> (Encodes to Base64)"); + System.out.println(" decode64 <base64 encoded text> (Decodes from Base64)"); + System.out.println(" encode64url <your text> (Encodes to Base64 URL charset)"); + System.out.println(" decode64url <base64url encoded text> (Decodes from Base64 URL charset)"); + System.out.println(" sha256 <text> <salts(s)> (Digest String into SHA256 Hash)"); + System.out.println(" md5 <text> (Digest String into MD5 Hash)"); + } + if (systemExit) { + System.exit(1); + } + } + + public static void setSystemExit(boolean shouldExit) { + systemExit = shouldExit; + } + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Connector.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Connector.java index 7f47ce78..f88c3fbe 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Connector.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Connector.java @@ -22,5 +22,5 @@ package org.onap.aaf.cadi; public interface Connector { - public Lur newLur() throws CadiException; + public Lur newLur() throws CadiException; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CredVal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CredVal.java index 4e42a5fb..6019f551 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CredVal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CredVal.java @@ -31,12 +31,12 @@ package org.onap.aaf.cadi; * @author Jonathan */ public interface CredVal { - public enum Type{PASSWORD}; - /** - * Validate if the User/Password combination matches records - * @param user - * @param pass - * @return - */ - public boolean validate(String user, Type type, byte[] cred, Object state); + public enum Type{PASSWORD}; + /** + * Validate if the User/Password combination matches records + * @param user + * @param pass + * @return + */ + public boolean validate(String user, Type type, byte[] cred, Object state); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/CredValDomain.java b/cadi/core/src/main/java/org/onap/aaf/cadi/CredValDomain.java index e8a5c54b..db5ab0f2 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/CredValDomain.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/CredValDomain.java @@ -21,5 +21,5 @@ package org.onap.aaf.cadi; public interface CredValDomain extends CredVal { - public String domain(); + public String domain(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/GetCred.java b/cadi/core/src/main/java/org/onap/aaf/cadi/GetCred.java index e64f0dd4..039ba8f7 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/GetCred.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/GetCred.java @@ -22,5 +22,5 @@ package org.onap.aaf.cadi; public interface GetCred { - byte[] getCred(); + byte[] getCred(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Hash.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Hash.java index 6babb4c9..acd45019 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Hash.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Hash.java @@ -26,233 +26,233 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Hash { - private static char hexDigit[] = "0123456789abcdef".toCharArray(); - + private static char hexDigit[] = "0123456789abcdef".toCharArray(); + ///////////////////////////////// // MD5 ///////////////////////////////// - /** - * Encrypt MD5 from Byte Array to Byte Array - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static byte[] hashMD5 (byte[] input) throws NoSuchAlgorithmException { - // Note: Protect against Multi-thread issues with new MessageDigest - MessageDigest md = MessageDigest.getInstance("MD5"); - md.update(input); - return md.digest(); - } + /** + * Encrypt MD5 from Byte Array to Byte Array + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static byte[] hashMD5 (byte[] input) throws NoSuchAlgorithmException { + // Note: Protect against Multi-thread issues with new MessageDigest + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(input); + return md.digest(); + } - /** - * Encrypt MD5 from Byte Array to Byte Array - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static byte[] hashMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException { - // Note: Protect against Multi-thread issues with new MessageDigest - MessageDigest md = MessageDigest.getInstance("MD5"); - md.update(input,offset,length); - return md.digest(); - } + /** + * Encrypt MD5 from Byte Array to Byte Array + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static byte[] hashMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException { + // Note: Protect against Multi-thread issues with new MessageDigest + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(input,offset,length); + return md.digest(); + } - /** - * Convenience Function: Encrypt MD5 from String to String Hex representation - * - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static String hashMD5asStringHex(String input) throws NoSuchAlgorithmException { - byte[] output = hashMD5(input.getBytes()); - StringBuilder sb = new StringBuilder("0x"); - for (byte b : output) { - sb.append(hexDigit[(b >> 4) & 0x0f]); - sb.append(hexDigit[b & 0x0f]); - } - return sb.toString(); - } + /** + * Convenience Function: Encrypt MD5 from String to String Hex representation + * + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static String hashMD5asStringHex(String input) throws NoSuchAlgorithmException { + byte[] output = hashMD5(input.getBytes()); + StringBuilder sb = new StringBuilder("0x"); + for (byte b : output) { + sb.append(hexDigit[(b >> 4) & 0x0f]); + sb.append(hexDigit[b & 0x0f]); + } + return sb.toString(); + } ///////////////////////////////// // SHA256 ///////////////////////////////// - /** - * SHA256 Hashing - */ - public static byte[] hashSHA256(byte[] input) throws NoSuchAlgorithmException { - // Note: Protect against Multi-thread issues with new MessageDigest - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(input); - return md.digest(); - } + /** + * SHA256 Hashing + */ + public static byte[] hashSHA256(byte[] input) throws NoSuchAlgorithmException { + // Note: Protect against Multi-thread issues with new MessageDigest + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(input); + return md.digest(); + } - /** - * SHA256 Hashing - */ - public static byte[] hashSHA256(byte[] input, int offset, int length) throws NoSuchAlgorithmException { - // Note: Protect against Multi-thread issues with new MessageDigest - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(input,offset,length); - return md.digest(); - } - - /** - * Convenience Function: Hash from String to String Hex representation - * - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static String hashSHA256asStringHex(String input) throws NoSuchAlgorithmException { - return toHex(hashSHA256(input.getBytes())); - } + /** + * SHA256 Hashing + */ + public static byte[] hashSHA256(byte[] input, int offset, int length) throws NoSuchAlgorithmException { + // Note: Protect against Multi-thread issues with new MessageDigest + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(input,offset,length); + return md.digest(); + } + + /** + * Convenience Function: Hash from String to String Hex representation + * + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static String hashSHA256asStringHex(String input) throws NoSuchAlgorithmException { + return toHex(hashSHA256(input.getBytes())); + } - /** - * Convenience Function: Hash from String to String Hex representation - * - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static String hashSHA256asStringHex(String input, int salt) throws NoSuchAlgorithmException { - byte[] in = input.getBytes(); - ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + in.length); - bb.putInt(salt); - bb.put(input.getBytes()); - return toHex(Hash.hashSHA256(bb.array())); - } - - /** - * Compare two byte arrays for equivalency - * @param ba1 - * @param ba2 - * @return - */ - public static boolean isEqual(byte ba1[], byte ba2[]) { - if(ba1.length!=ba2.length)return false; - for(int i = 0;i<ba1.length; ++i) { - if(ba1[i]!=ba2[i])return false; - } - return true; - } + /** + * Convenience Function: Hash from String to String Hex representation + * + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static String hashSHA256asStringHex(String input, int salt) throws NoSuchAlgorithmException { + byte[] in = input.getBytes(); + ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + in.length); + bb.putInt(salt); + bb.put(input.getBytes()); + return toHex(Hash.hashSHA256(bb.array())); + } + + /** + * Compare two byte arrays for equivalency + * @param ba1 + * @param ba2 + * @return + */ + public static boolean isEqual(byte ba1[], byte ba2[]) { + if(ba1.length!=ba2.length)return false; + for(int i = 0;i<ba1.length; ++i) { + if(ba1[i]!=ba2[i])return false; + } + return true; + } - public static int compareTo(byte[] a, byte[] b) { - int end = Math.min(a.length, b.length); - int compare = 0; - for(int i=0;compare == 0 && i<end;++i) { - compare = a[i]-b[i]; - } - if(compare==0)compare=a.length-b.length; - return compare; - } + public static int compareTo(byte[] a, byte[] b) { + int end = Math.min(a.length, b.length); + int compare = 0; + for(int i=0;compare == 0 && i<end;++i) { + compare = a[i]-b[i]; + } + if(compare==0)compare=a.length-b.length; + return compare; + } - public static String toHexNo0x(byte[] ba) { - StringBuilder sb = new StringBuilder(); - for (byte b : ba) { - sb.append(hexDigit[(b >> 4) & 0x0f]); - sb.append(hexDigit[b & 0x0f]); - } - return sb.toString(); - } + public static String toHexNo0x(byte[] ba) { + StringBuilder sb = new StringBuilder(); + for (byte b : ba) { + sb.append(hexDigit[(b >> 4) & 0x0f]); + sb.append(hexDigit[b & 0x0f]); + } + return sb.toString(); + } - public static String toHex(byte[] ba) { - StringBuilder sb = new StringBuilder("0x"); - for (byte b : ba) { - sb.append(hexDigit[(b >> 4) & 0x0f]); - sb.append(hexDigit[b & 0x0f]); - } - return sb.toString(); - } - - public static String toHex(byte[] ba, int start, int length) { - StringBuilder sb = new StringBuilder("0x"); - for (int i=start;i<length;++i) { - sb.append(hexDigit[(ba[i] >> 4) & 0x0f]); - sb.append(hexDigit[ba[i] & 0x0f]); - } - return sb.toString(); - } + public static String toHex(byte[] ba) { + StringBuilder sb = new StringBuilder("0x"); + for (byte b : ba) { + sb.append(hexDigit[(b >> 4) & 0x0f]); + sb.append(hexDigit[b & 0x0f]); + } + return sb.toString(); + } + + public static String toHex(byte[] ba, int start, int length) { + StringBuilder sb = new StringBuilder("0x"); + for (int i=start;i<length;++i) { + sb.append(hexDigit[(ba[i] >> 4) & 0x0f]); + sb.append(hexDigit[ba[i] & 0x0f]); + } + return sb.toString(); + } - - public static byte[] fromHex(String s) throws CadiException{ - if(!s.startsWith("0x")) { - throw new CadiException("HexString must start with \"0x\""); - } - boolean high = true; - int c; - byte b; - byte[] ba = new byte[(s.length()-2)/2]; - int idx; - for(int i=2;i<s.length();++i) { - c = s.charAt(i); - if(c>=0x30 && c<=0x39) { - b=(byte)(c-0x30); - } else if(c>=0x61 && c<=0x66) { - b=(byte)(c-0x57); // account for "A" - } else if(c>=0x41 && c<=0x46) { - b=(byte)(c-0x37); - } else { - throw new CadiException("Invalid char '" + c + "' in HexString"); - } - idx = (i-2)/2; - if(high) { - ba[idx]=(byte)(b<<4); - high = false; - } else { - ba[idx]|=b; - high = true; - } - } - return ba; - } + + public static byte[] fromHex(String s) throws CadiException{ + if(!s.startsWith("0x")) { + throw new CadiException("HexString must start with \"0x\""); + } + boolean high = true; + int c; + byte b; + byte[] ba = new byte[(s.length()-2)/2]; + int idx; + for(int i=2;i<s.length();++i) { + c = s.charAt(i); + if(c>=0x30 && c<=0x39) { + b=(byte)(c-0x30); + } else if(c>=0x61 && c<=0x66) { + b=(byte)(c-0x57); // account for "A" + } else if(c>=0x41 && c<=0x46) { + b=(byte)(c-0x37); + } else { + throw new CadiException("Invalid char '" + c + "' in HexString"); + } + idx = (i-2)/2; + if(high) { + ba[idx]=(byte)(b<<4); + high = false; + } else { + ba[idx]|=b; + high = true; + } + } + return ba; + } - /** - * Does not expect to start with "0x" - * if Any Character doesn't match, it returns null; - * - * @param s - * @return - */ - public static byte[] fromHexNo0x(String s) { - int c; - byte b; - byte[] ba; - boolean high; - int start; - if(s.length()%2==0) { - ba = new byte[s.length()/2]; - high=true; - start=0; - } else { - ba = new byte[(s.length()/2)+1]; - high = false; - start=1; - } - int idx; - for(int i=start;i<s.length();++i) { - c = s.charAt((i-start)); - if(c>=0x30 && c<=0x39) { - b=(byte)(c-0x30); - } else if(c>=0x61 && c<=0x66) { - b=(byte)(c-0x57); // account for "A" - } else if(c>=0x41 && c<=0x46) { - b=(byte)(c-0x37); - } else { - return null; - } - idx = i/2; - if(high) { - ba[idx]=(byte)(b<<4); - high = false; - } else { - ba[idx]|=b; - high = true; - } - } - return ba; - } + /** + * Does not expect to start with "0x" + * if Any Character doesn't match, it returns null; + * + * @param s + * @return + */ + public static byte[] fromHexNo0x(String s) { + int c; + byte b; + byte[] ba; + boolean high; + int start; + if(s.length()%2==0) { + ba = new byte[s.length()/2]; + high=true; + start=0; + } else { + ba = new byte[(s.length()/2)+1]; + high = false; + start=1; + } + int idx; + for(int i=start;i<s.length();++i) { + c = s.charAt((i-start)); + if(c>=0x30 && c<=0x39) { + b=(byte)(c-0x30); + } else if(c>=0x61 && c<=0x66) { + b=(byte)(c-0x57); // account for "A" + } else if(c>=0x41 && c<=0x46) { + b=(byte)(c-0x37); + } else { + return null; + } + idx = i/2; + if(high) { + ba[idx]=(byte)(b<<4); + high = false; + } else { + ba[idx]|=b; + high = true; + } + } + return ba; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Locator.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Locator.java index 22258d12..c40cb998 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Locator.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Locator.java @@ -22,15 +22,15 @@ package org.onap.aaf.cadi; public interface Locator<T> { - public T get(Locator.Item item) throws LocatorException; - public boolean hasItems(); - public void invalidate(Locator.Item item) throws LocatorException; - public Locator.Item best() throws LocatorException; - public Item first() throws LocatorException; - public Item next(Item item) throws LocatorException; - public boolean refresh(); - public void destroy(); - - public interface Item {} + public T get(Locator.Item item) throws LocatorException; + public boolean hasItems(); + public void invalidate(Locator.Item item) throws LocatorException; + public Locator.Item best() throws LocatorException; + public Item first() throws LocatorException; + public Item next(Item item) throws LocatorException; + public boolean refresh(); + public void destroy(); + + public interface Item {} } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/LocatorException.java b/cadi/core/src/main/java/org/onap/aaf/cadi/LocatorException.java index f14fba70..da56d4b2 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/LocatorException.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/LocatorException.java @@ -22,25 +22,25 @@ package org.onap.aaf.cadi; public class LocatorException extends Exception { - /** - * - */ - private static final long serialVersionUID = -4267929804321134469L; + /** + * + */ + private static final long serialVersionUID = -4267929804321134469L; - public LocatorException(String arg0) { - super(arg0); - } + public LocatorException(String arg0) { + super(arg0); + } - public LocatorException(Throwable arg0) { - super(arg0); - } + public LocatorException(Throwable arg0) { + super(arg0); + } - public LocatorException(String arg0, Throwable arg1) { - super(arg0, arg1); - } + public LocatorException(String arg0, Throwable arg1) { + super(arg0, arg1); + } - public LocatorException(CharSequence cs) { - super(cs.toString()); - } + public LocatorException(CharSequence cs) { + super(cs.toString()); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Lur.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Lur.java index 0beb4856..bdc9f643 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Lur.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Lur.java @@ -39,54 +39,54 @@ import java.util.List; * */ public interface Lur { - /** - * Allow the Lur, which has correct Permission access, to create and hand back. - */ - public Permission createPerm(String p); - - /** - * Fish for Principals in a Pond - * - * or more boringly, is the User identified within a named collection representing permission. - * - * @param principalName - * @return - */ - public boolean fish(Principal bait, Permission ... pond); + /** + * Allow the Lur, which has correct Permission access, to create and hand back. + */ + public Permission createPerm(String p); + + /** + * Fish for Principals in a Pond + * + * or more boringly, is the User identified within a named collection representing permission. + * + * @param principalName + * @return + */ + public boolean fish(Principal bait, Permission ... pond); - /** - * Fish all the Principals out a Pond - * - * For additional humor, pronounce the following with a Southern Drawl, "FishOil" - * - * or more boringly, load the List with Permissions found for Principal - * - * @param principalName - * @return - */ - public void fishAll(Principal bait, List<Permission> permissions); + /** + * Fish all the Principals out a Pond + * + * For additional humor, pronounce the following with a Southern Drawl, "FishOil" + * + * or more boringly, load the List with Permissions found for Principal + * + * @param principalName + * @return + */ + public void fishAll(Principal bait, List<Permission> permissions); - /** - * Allow implementations to disconnect, or cleanup resources if unneeded - */ - public void destroy(); + /** + * Allow implementations to disconnect, or cleanup resources if unneeded + */ + public void destroy(); - /** - * Does this LUR handle this pond exclusively? Important for EpiLUR to determine whether - * to try another (more expensive) LUR - * @param pond - * @return - */ - public boolean handlesExclusively(Permission ... pond); - - /** - * Does the LUR support a particular kind of Principal - * This can be used to check name's domain, like above, or Principal type - */ - public boolean handles(Principal principal); - - /** - * Clear: Clear any Caching, if exists - */ - public void clear(Principal p, StringBuilder report); + /** + * Does this LUR handle this pond exclusively? Important for EpiLUR to determine whether + * to try another (more expensive) LUR + * @param pond + * @return + */ + public boolean handlesExclusively(Permission ... pond); + + /** + * Does the LUR support a particular kind of Principal + * This can be used to check name's domain, like above, or Principal type + */ + public boolean handles(Principal principal); + + /** + * Clear: Clear any Caching, if exists + */ + public void clear(Principal p, StringBuilder report); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Permission.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Permission.java index f8061290..2537c386 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Permission.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Permission.java @@ -22,7 +22,7 @@ package org.onap.aaf.cadi; public interface Permission { - public String permType(); - public String getKey(); - public boolean match(Permission p); + public String permType(); + public String getKey(); + public boolean match(Permission p); } 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 3d15b09d..a35777f8 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 @@ -37,365 +37,365 @@ import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.config.SecurityInfo; 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"); + // 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"); - public static final Level DEFAULT = Level.AUDIT; - - private Symm symm; - private int level; - private Properties props; - private List<String> recursionProtection = null; - private LogIt logIt; - private String name; + public static final Level DEFAULT = Level.AUDIT; + + private Symm symm; + private int level; + private Properties props; + private List<String> recursionProtection = null; + private LogIt logIt; + private String name; - public PropAccess() { - logIt = new StreamLogIt(System.out); - init(null); - } - - /** - * This Constructor soly exists to instantiate Servlet Context Based Logging that will call "init" later. - * @param sc - */ - protected PropAccess(Object o) { - logIt = new StreamLogIt(System.out); - props = new Properties(); - } - - public PropAccess(String ... args) { - this(System.out,args); - } - - public PropAccess(PrintStream ps, String[] args) { - logIt = new StreamLogIt(ps==null?System.out:ps); - init(logIt,args); - } - - public PropAccess(LogIt logit, String[] args) { - init(logit, args); - } - - public PropAccess(Properties p) { - this(System.out,p); - } - - public PropAccess(PrintStream ps, Properties p) { - logIt = new StreamLogIt(ps==null?System.out:ps); - init(p); - } - - protected void init(final LogIt logIt, final String[] args) { - this.logIt = logIt; - Properties nprops=new Properties(); - int eq; - for(String arg : args) { - if((eq=arg.indexOf('='))>0) { - nprops.setProperty(arg.substring(0, eq),arg.substring(eq+1)); - } - } - init(nprops); - } - - protected void init(Properties p) { - // Make sure these two are set before any changes in Logging - name = "cadi"; - level=DEFAULT.maskOf(); - - props = new Properties(); - // First, load related System Properties - for(Entry<Object,Object> es : System.getProperties().entrySet()) { - String key = es.getKey().toString(); - for(String start : new String[] {"cadi_","aaf_","cm_"}) { - if(key.startsWith(start)) { - props.put(key, es.getValue()); - } - } - } - // Second, overlay or fill in with Passed in Props - if(p!=null) { - props.putAll(p); - } - - // Third, load any Chained Property Files - load(props.getProperty(Config.CADI_PROP_FILES)); - - String sLevel = props.getProperty(Config.CADI_LOGLEVEL); - if(sLevel!=null) { - level=Level.valueOf(sLevel).maskOf(); - } - // Setup local Symmetrical key encryption - if(symm==null) { - try { - symm = Symm.obtain(this); - } catch (CadiException e) { - System.err.append("FATAL ERROR: Cannot obtain Key Information."); - e.printStackTrace(System.err); - System.exit(1); - } - } - - name = props.getProperty(Config.CADI_LOGNAME, name); - - specialConversions(); - } + public PropAccess() { + logIt = new StreamLogIt(System.out); + init(null); + } + + /** + * This Constructor soly exists to instantiate Servlet Context Based Logging that will call "init" later. + * @param sc + */ + protected PropAccess(Object o) { + logIt = new StreamLogIt(System.out); + props = new Properties(); + } + + public PropAccess(String ... args) { + this(System.out,args); + } + + public PropAccess(PrintStream ps, String[] args) { + logIt = new StreamLogIt(ps==null?System.out:ps); + init(logIt,args); + } + + public PropAccess(LogIt logit, String[] args) { + init(logit, args); + } + + public PropAccess(Properties p) { + this(System.out,p); + } + + public PropAccess(PrintStream ps, Properties p) { + logIt = new StreamLogIt(ps==null?System.out:ps); + init(p); + } + + protected void init(final LogIt logIt, final String[] args) { + this.logIt = logIt; + Properties nprops=new Properties(); + int eq; + for(String arg : args) { + if((eq=arg.indexOf('='))>0) { + nprops.setProperty(arg.substring(0, eq),arg.substring(eq+1)); + } + } + init(nprops); + } + + protected void init(Properties p) { + // Make sure these two are set before any changes in Logging + name = "cadi"; + level=DEFAULT.maskOf(); + + props = new Properties(); + // First, load related System Properties + for(Entry<Object,Object> es : System.getProperties().entrySet()) { + String key = es.getKey().toString(); + for(String start : new String[] {"cadi_","aaf_","cm_"}) { + if(key.startsWith(start)) { + props.put(key, es.getValue()); + } + } + } + // Second, overlay or fill in with Passed in Props + if(p!=null) { + props.putAll(p); + } + + // Third, load any Chained Property Files + load(props.getProperty(Config.CADI_PROP_FILES)); + + String sLevel = props.getProperty(Config.CADI_LOGLEVEL); + if(sLevel!=null) { + level=Level.valueOf(sLevel).maskOf(); + } + // Setup local Symmetrical key encryption + if(symm==null) { + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } + } + + name = props.getProperty(Config.CADI_LOGNAME, name); + + specialConversions(); + } - private void specialConversions() { - // Critical - if no Security Protocols set, then set it. We'll just get messed up if not - if(props.get(Config.CADI_PROTOCOLS)==null) { - props.setProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT); - } - - Object temp; - temp=props.get(Config.CADI_PROTOCOLS); - if(props.get(Config.HTTPS_PROTOCOLS)==null && temp!=null) { - props.put(Config.HTTPS_PROTOCOLS, temp); - } - - if(temp!=null) { - if("1.7".equals(System.getProperty("java.specification.version")) - && (temp==null || (temp instanceof String && ((String)temp).contains("TLSv1.2")))) { - System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); - } - } - } + private void specialConversions() { + // Critical - if no Security Protocols set, then set it. We'll just get messed up if not + if(props.get(Config.CADI_PROTOCOLS)==null) { + props.setProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT); + } + + Object temp; + temp=props.get(Config.CADI_PROTOCOLS); + if(props.get(Config.HTTPS_PROTOCOLS)==null && temp!=null) { + props.put(Config.HTTPS_PROTOCOLS, temp); + } + + if(temp!=null) { + if("1.7".equals(System.getProperty("java.specification.version")) + && (temp==null || (temp instanceof String && ((String)temp).contains("TLSv1.2")))) { + System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); + } + } + } - private void load(String cadi_prop_files) { - if(cadi_prop_files==null) { - return; - } - String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); - int prev = 0, end = cadi_prop_files.length(); - int idx; - String filename; - while(prev<end) { - idx = cadi_prop_files.indexOf(File.pathSeparatorChar,prev); - if(idx<0) { - idx = end; - } - File file = new File(filename=cadi_prop_files.substring(prev,idx)); - if(file.exists()) { - printf(Level.INIT,"Loading CADI Properties from %s",file.getAbsolutePath()); - try { - FileInputStream fis = new FileInputStream(file); - try { - props.load(fis); - // Recursively Load - String chainProp = props.getProperty(Config.CADI_PROP_FILES); - if(chainProp!=null) { - if(recursionProtection==null) { - recursionProtection = new ArrayList<>(); - recursionProtection.add(cadi_prop_files); - } - if(!recursionProtection.contains(chainProp)) { - recursionProtection.add(chainProp); - load(chainProp); // recurse - } - } - } finally { - fis.close(); - } - } catch (Exception e) { - log(e,filename,"cannot be opened"); - } - } else { - printf(Level.WARN,"Warning: recursive CADI Property %s does not exist",file.getAbsolutePath()); - } - prev = idx+1; - } - - // Trim - for(Entry<Object, Object> es : props.entrySet()) { - Object value = es.getValue(); - if(value instanceof String) { - String trim = ((String)value).trim(); - // Remove Beginning/End Quotes, which might be there if mixed with Bash Props - int s = 0, e=trim.length()-1; - if(s<e && trim.charAt(s)=='"' && trim.charAt(e)=='"') { - trim=trim.substring(s+1,e); - } - if(trim!=value) { // Yes, I want OBJECT equals - props.setProperty((String)es.getKey(), trim); - } - } - } - // Reset Symm if Keyfile Changes: - String newKeyFile = props.getProperty(Config.CADI_KEYFILE); - if((prevKeyFile!=null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) { - try { - symm = Symm.obtain(this); - } catch (CadiException e) { - System.err.append("FATAL ERROR: Cannot obtain Key Information."); - e.printStackTrace(System.err); - System.exit(1); - } + private void load(String cadi_prop_files) { + if(cadi_prop_files==null) { + return; + } + String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); + int prev = 0, end = cadi_prop_files.length(); + int idx; + String filename; + while(prev<end) { + idx = cadi_prop_files.indexOf(File.pathSeparatorChar,prev); + if(idx<0) { + idx = end; + } + File file = new File(filename=cadi_prop_files.substring(prev,idx)); + if(file.exists()) { + printf(Level.INIT,"Loading CADI Properties from %s",file.getAbsolutePath()); + try { + FileInputStream fis = new FileInputStream(file); + try { + props.load(fis); + // Recursively Load + String chainProp = props.getProperty(Config.CADI_PROP_FILES); + if(chainProp!=null) { + if(recursionProtection==null) { + recursionProtection = new ArrayList<>(); + recursionProtection.add(cadi_prop_files); + } + if(!recursionProtection.contains(chainProp)) { + recursionProtection.add(chainProp); + load(chainProp); // recurse + } + } + } finally { + fis.close(); + } + } catch (Exception e) { + log(e,filename,"cannot be opened"); + } + } else { + printf(Level.WARN,"Warning: recursive CADI Property %s does not exist",file.getAbsolutePath()); + } + prev = idx+1; + } + + // Trim + for(Entry<Object, Object> es : props.entrySet()) { + Object value = es.getValue(); + if(value instanceof String) { + String trim = ((String)value).trim(); + // Remove Beginning/End Quotes, which might be there if mixed with Bash Props + int s = 0, e=trim.length()-1; + if(s<e && trim.charAt(s)=='"' && trim.charAt(e)=='"') { + trim=trim.substring(s+1,e); + } + if(trim!=value) { // Yes, I want OBJECT equals + props.setProperty((String)es.getKey(), trim); + } + } + } + // Reset Symm if Keyfile Changes: + String newKeyFile = props.getProperty(Config.CADI_KEYFILE); + if((prevKeyFile!=null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) { + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } - prevKeyFile=newKeyFile; - } - - String loglevel = props.getProperty(Config.CADI_LOGLEVEL); - if(loglevel!=null) { - try { - level=Level.valueOf(loglevel).maskOf(); - } catch (IllegalArgumentException e) { - printf(Level.ERROR,"%s=%s is an Invalid Log Level",Config.CADI_LOGLEVEL,loglevel); - } - } - - specialConversions(); - } - - @Override - public void load(InputStream is) throws IOException { - props.load(is); - load(props.getProperty(Config.CADI_PROP_FILES)); - } + prevKeyFile=newKeyFile; + } + + String loglevel = props.getProperty(Config.CADI_LOGLEVEL); + if(loglevel!=null) { + try { + level=Level.valueOf(loglevel).maskOf(); + } catch (IllegalArgumentException e) { + printf(Level.ERROR,"%s=%s is an Invalid Log Level",Config.CADI_LOGLEVEL,loglevel); + } + } + + specialConversions(); + } + + @Override + public void load(InputStream is) throws IOException { + props.load(is); + load(props.getProperty(Config.CADI_PROP_FILES)); + } - @Override - public void log(Level level, Object ... elements) { - if(willLog(level)) { - logIt.push(level,elements); - } - } + @Override + public void log(Level level, Object ... elements) { + if(willLog(level)) { + logIt.push(level,elements); + } + } - protected StringBuilder buildMsg(Level level, Object[] elements) { - return buildMsg(name,iso8601,level,elements); - } + protected StringBuilder buildMsg(Level level, Object[] elements) { + return buildMsg(name,iso8601,level,elements); + } - public static StringBuilder buildMsg(final String name, final SimpleDateFormat sdf, Level level, Object[] elements) { - StringBuilder sb = new StringBuilder(sdf.format(new Date())); - sb.append(' '); - sb.append(level.name()); - sb.append(" ["); - sb.append(name); - - int end = elements.length; - if(end<=0) { - sb.append("] "); - } else { - int idx = 0; - if(elements[idx] instanceof Integer) { - sb.append('-'); - sb.append(elements[idx]); - ++idx; - } - sb.append("] "); - String s; - boolean first = true; - for(Object o : elements) { - if(o!=null) { - s=o.toString(); - if(first) { - first = false; - } else { - int l = s.length(); - if(l>0) { - switch(s.charAt(l-1)) { - case ' ': - break; - default: - sb.append(' '); - } - } - } - sb.append(s); - } - } - } - return sb; - } + public static StringBuilder buildMsg(final String name, final SimpleDateFormat sdf, Level level, Object[] elements) { + StringBuilder sb = new StringBuilder(sdf.format(new Date())); + sb.append(' '); + sb.append(level.name()); + sb.append(" ["); + sb.append(name); + + int end = elements.length; + if(end<=0) { + sb.append("] "); + } else { + int idx = 0; + if(elements[idx] instanceof Integer) { + sb.append('-'); + sb.append(elements[idx]); + ++idx; + } + sb.append("] "); + String s; + boolean first = true; + for(Object o : elements) { + if(o!=null) { + s=o.toString(); + if(first) { + first = false; + } else { + int l = s.length(); + if(l>0) { + switch(s.charAt(l-1)) { + case ' ': + break; + default: + sb.append(' '); + } + } + } + sb.append(s); + } + } + } + return sb; + } - @Override - public void log(Exception e, Object... elements) { - log(Level.ERROR,e.getMessage(),elements); - e.printStackTrace(System.err); - } + @Override + public void log(Exception e, Object... elements) { + log(Level.ERROR,e.getMessage(),elements); + e.printStackTrace(System.err); + } - @Override - public void printf(Level level, String fmt, Object... elements) { - if(willLog(level)) { - log(level,String.format(fmt, elements)); - } - } + @Override + public void printf(Level level, String fmt, Object... elements) { + if(willLog(level)) { + log(level,String.format(fmt, elements)); + } + } - @Override - public void setLogLevel(Level level) { - this.level = level.maskOf(); - } + @Override + public void setLogLevel(Level level) { + this.level = level.maskOf(); + } - @Override - public boolean willLog(Level level) { - return level.inMask(this.level); - } + @Override + public boolean willLog(Level level) { + return level.inMask(this.level); + } - @Override - public ClassLoader classLoader() { - return ClassLoader.getSystemClassLoader(); - } + @Override + public ClassLoader classLoader() { + return ClassLoader.getSystemClassLoader(); + } - @Override - public String getProperty(String tag, String def) { - return props.getProperty(tag,def); - } + @Override + public String getProperty(String tag, String def) { + return props.getProperty(tag,def); + } - @Override - public String decrypt(String encrypted, boolean anytext) throws IOException { - return (encrypted!=null && (anytext==true || encrypted.startsWith(Symm.ENC))) - ? symm.depass(encrypted) - : encrypted; - } - - public String encrypt(String unencrypted) throws IOException { - return Symm.ENC+symm.enpass(unencrypted); - } + @Override + public String decrypt(String encrypted, boolean anytext) throws IOException { + return (encrypted!=null && (anytext==true || encrypted.startsWith(Symm.ENC))) + ? symm.depass(encrypted) + : encrypted; + } + + public String encrypt(String unencrypted) throws IOException { + return Symm.ENC+symm.enpass(unencrypted); + } - ////////////////// - // Additional - ////////////////// - public String getProperty(String tag) { - return props.getProperty(tag); - } - + ////////////////// + // Additional + ////////////////// + public String getProperty(String tag) { + return props.getProperty(tag); + } + - public Properties getProperties() { - return props; - } + public Properties getProperties() { + return props; + } - public void setProperty(String tag, String value) { - if(value!=null) { - props.put(tag, value); - if(Config.CADI_KEYFILE.equals(tag)) { - // reset decryption too - try { - symm = Symm.obtain(this); - } catch (CadiException e) { - System.err.append("FATAL ERROR: Cannot obtain Key Information."); - e.printStackTrace(System.err); - System.exit(1); - } - } - } - } + public void setProperty(String tag, String value) { + if(value!=null) { + props.put(tag, value); + if(Config.CADI_KEYFILE.equals(tag)) { + // reset decryption too + try { + symm = Symm.obtain(this); + } catch (CadiException e) { + System.err.append("FATAL ERROR: Cannot obtain Key Information."); + e.printStackTrace(System.err); + System.exit(1); + } + } + } + } - public interface LogIt { - public void push(Level level, Object ... elements) ; - } - - private class StreamLogIt implements LogIt { - private PrintStream ps; - - public StreamLogIt(PrintStream ps) { - this.ps = ps; - } - @Override - public void push(Level level, Object ... elements) { - ps.println(buildMsg(level,elements)); - ps.flush(); - } - - } + public interface LogIt { + public void push(Level level, Object ... elements) ; + } + + private class StreamLogIt implements LogIt { + private PrintStream ps; + + public StreamLogIt(PrintStream ps) { + this.ps = ps; + } + @Override + public void push(Level level, Object ... elements) { + ps.println(buildMsg(level,elements)); + ps.flush(); + } + + } - public void set(LogIt logit) { - logIt = logit; - } + public void set(LogIt logit) { + logIt = logit; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Revalidator.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Revalidator.java index 125ac24c..66ba86ae 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Revalidator.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Revalidator.java @@ -23,12 +23,12 @@ package org.onap.aaf.cadi; public interface Revalidator<TRANS> { - /** - * Re-Validate Credential - * - * @param prin - * @return - */ - public CachedPrincipal.Resp revalidate(TRANS trans, CachedPrincipal prin); + /** + * Re-Validate Credential + * + * @param prin + * @return + */ + public CachedPrincipal.Resp revalidate(TRANS trans, CachedPrincipal prin); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java index 31563017..194712e0 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java @@ -31,14 +31,14 @@ package org.onap.aaf.cadi; * */ public interface SecuritySetter<CT> { - public String getID(); - - public void setSecurity(CT client) throws CadiException; - - /** - * Returns number of bad logins registered - * @param respCode - * @return - */ - public int setLastResponse(int respCode); + public String getID(); + + public void setSecurity(CT client) throws CadiException; + + /** + * Returns number of bad logins registered + * @param respCode + * @return + */ + public int setLastResponse(int respCode); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java b/cadi/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java index 38a01a09..518ea6dd 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java @@ -28,40 +28,40 @@ import javax.servlet.ServletContext; public class ServletContextAccess extends PropAccess { - private ServletContext context; + private ServletContext context; - public ServletContextAccess(FilterConfig filterConfig) { - super(filterConfig); // protected constructor... does not have "init" called. - context = filterConfig.getServletContext(); + public ServletContextAccess(FilterConfig filterConfig) { + super(filterConfig); // protected constructor... does not have "init" called. + context = filterConfig.getServletContext(); - for(Enumeration<?> en = filterConfig.getInitParameterNames();en.hasMoreElements();) { - String name = (String)en.nextElement(); - setProperty(name, filterConfig.getInitParameter(name)); - } - init(getProperties()); - } + for(Enumeration<?> en = filterConfig.getInitParameterNames();en.hasMoreElements();) { + String name = (String)en.nextElement(); + setProperty(name, filterConfig.getInitParameter(name)); + } + init(getProperties()); + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.PropAccess#log(org.onap.aaf.cadi.Access.Level, java.lang.Object[]) - */ - @Override - public void log(Level level, Object... elements) { - if(willLog(level)) { - StringBuilder sb = buildMsg(level, elements); - context.log(sb.toString()); - } - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.PropAccess#log(org.onap.aaf.cadi.Access.Level, java.lang.Object[]) + */ + @Override + public void log(Level level, Object... elements) { + if(willLog(level)) { + StringBuilder sb = buildMsg(level, elements); + context.log(sb.toString()); + } + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.PropAccess#log(java.lang.Exception, java.lang.Object[]) - */ - @Override - public void log(Exception e, Object... elements) { - StringBuilder sb = buildMsg(Level.ERROR, elements); - context.log(sb.toString(),e); - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.PropAccess#log(java.lang.Exception, java.lang.Object[]) + */ + @Override + public void log(Exception e, Object... elements) { + StringBuilder sb = buildMsg(Level.ERROR, elements); + context.log(sb.toString(),e); + } - public ServletContext context() { - return context; - } + public ServletContext context() { + return context; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java index afc1d979..fd60b0c1 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Symm.java @@ -69,184 +69,184 @@ import org.onap.aaf.cadi.config.Config; * */ public class Symm { - private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; - public static final String ENC = "enc:"; - private static final Object LOCK = new Object(); - private static final SecureRandom random = new SecureRandom(); - - public final char[] codeset; - private final int splitLinesAt; - private final String encoding; - private final Convert convert; - private final boolean endEquals; - private byte[] keyBytes = null; - //Note: AES Encryption is not Thread Safe. It is Synchronized - //private AES aes = null; // only initialized from File, and only if needed for Passwords - - /** - * This is the standard base64 Key Set. - * RFC 2045 - */ - public static final Symm base64 = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() - ,76, Config.UTF_8,true); - - public static final Symm base64noSplit = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() - ,Integer.MAX_VALUE, Config.UTF_8,true); - - /** - * This is the standard base64 set suitable for URLs and Filenames - * RFC 4648 - */ - public static final Symm base64url = new Symm( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray() - ,76, Config.UTF_8,true); - - /** - * A Password set, using US-ASCII - * RFC 4648 - */ - public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false); - private static final byte[] EMPTY = new byte[0]; - - /** - * A typical set of Password Chars - * Note, this is too large to fit into the algorithm. Only use with PassGen - */ - private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray(); - - - private static Symm internalOnly = null; - - /** - * Use this to create special case Case Sets and/or Line breaks - * - * If you don't know why you need this, use the Singleton Method - * - * @param codeset - * @param split - */ - public Symm(char[] codeset, int split, String charset, boolean useEndEquals) { - this.codeset = codeset; - splitLinesAt = split; - encoding = charset; - endEquals = useEndEquals; - char prev = 0, curr=0, first = 0; - int offset=Integer.SIZE; // something that's out of range for integer array - - // There can be time efficiencies gained when the underlying keyset consists mainly of ordered - // data (i.e. abcde...). Therefore, we'll quickly analyze the keyset. If it proves to have - // too much entropy, the "Unordered" algorithm, which is faster in such cases is used. - ArrayList<int[]> la = new ArrayList<>(); - for(int i=0;i<codeset.length;++i) { - curr = codeset[i]; - if(prev+1==curr) { // is next character in set - prev = curr; - } else { - if(offset!=Integer.SIZE) { // add previous range - la.add(new int[]{first,prev,offset}); - } - first = prev = curr; - offset = curr-i; - } - } - la.add(new int[]{first,curr,offset}); - if(la.size()>codeset.length/3) { - convert = new Unordered(codeset); - } else { // too random to get speed enhancement from range algorithm - int[][] range = new int[la.size()][]; - la.toArray(range); - convert = new Ordered(range); - } - } - - public Symm copy(int lines) { - return new Symm(codeset,lines,encoding,endEquals); - } - - // Only used by keygen, which is intentionally randomized. Therefore, always use unordered - private Symm(char[] codeset, Symm parent) { - this.codeset = codeset; - splitLinesAt = parent.splitLinesAt; - endEquals = parent.endEquals; - encoding = parent.encoding; - convert = new Unordered(codeset); - } - - /** - * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. - * @return - */ - @Deprecated - public static final Symm base64() { - return base64; - } - - /** - * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. - * No Line Splitting - * @return - */ - @Deprecated - public static final Symm base64noSplit() { - return base64noSplit; - } - - /** - * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/") - */ - @Deprecated - public static final Symm base64url() { - return base64url; - } - - /** - * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/") - */ - public static final Symm baseCrypt() { - return encrypt; - } - - public <T> T exec(SyncExec<T> exec) throws Exception { - synchronized(LOCK) { - if(keyBytes == null) { - keyBytes = new byte[AES.AES_KEY_SIZE/8]; - int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length); - for(int i=0;i<keyBytes.length;++i) { - keyBytes[i] = (byte)codeset[i+offset]; - } - } - } - return exec.exec(new AES(keyBytes,0,keyBytes.length)); - } - - public interface Encryption { - public CipherOutputStream outputStream(OutputStream os, boolean encrypt); - public CipherInputStream inputStream(InputStream is, boolean encrypt); - } - - public static interface SyncExec<T> { - public T exec(Encryption enc) throws IOException, Exception; - } - + private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; + public static final String ENC = "enc:"; + private static final Object LOCK = new Object(); + private static final SecureRandom random = new SecureRandom(); + + public final char[] codeset; + private final int splitLinesAt; + private final String encoding; + private final Convert convert; + private final boolean endEquals; + private byte[] keyBytes = null; + //Note: AES Encryption is not Thread Safe. It is Synchronized + //private AES aes = null; // only initialized from File, and only if needed for Passwords + + /** + * This is the standard base64 Key Set. + * RFC 2045 + */ + public static final Symm base64 = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() + ,76, Config.UTF_8,true); + + public static final Symm base64noSplit = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray() + ,Integer.MAX_VALUE, Config.UTF_8,true); + + /** + * This is the standard base64 set suitable for URLs and Filenames + * RFC 4648 + */ + public static final Symm base64url = new Symm( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray() + ,76, Config.UTF_8,true); + + /** + * A Password set, using US-ASCII + * RFC 4648 + */ + public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false); + private static final byte[] EMPTY = new byte[0]; + + /** + * A typical set of Password Chars + * Note, this is too large to fit into the algorithm. Only use with PassGen + */ + private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray(); + + + private static Symm internalOnly = null; + + /** + * Use this to create special case Case Sets and/or Line breaks + * + * If you don't know why you need this, use the Singleton Method + * + * @param codeset + * @param split + */ + public Symm(char[] codeset, int split, String charset, boolean useEndEquals) { + this.codeset = codeset; + splitLinesAt = split; + encoding = charset; + endEquals = useEndEquals; + char prev = 0, curr=0, first = 0; + int offset=Integer.SIZE; // something that's out of range for integer array + + // There can be time efficiencies gained when the underlying keyset consists mainly of ordered + // data (i.e. abcde...). Therefore, we'll quickly analyze the keyset. If it proves to have + // too much entropy, the "Unordered" algorithm, which is faster in such cases is used. + ArrayList<int[]> la = new ArrayList<>(); + for(int i=0;i<codeset.length;++i) { + curr = codeset[i]; + if(prev+1==curr) { // is next character in set + prev = curr; + } else { + if(offset!=Integer.SIZE) { // add previous range + la.add(new int[]{first,prev,offset}); + } + first = prev = curr; + offset = curr-i; + } + } + la.add(new int[]{first,curr,offset}); + if(la.size()>codeset.length/3) { + convert = new Unordered(codeset); + } else { // too random to get speed enhancement from range algorithm + int[][] range = new int[la.size()][]; + la.toArray(range); + convert = new Ordered(range); + } + } + + public Symm copy(int lines) { + return new Symm(codeset,lines,encoding,endEquals); + } + + // Only used by keygen, which is intentionally randomized. Therefore, always use unordered + private Symm(char[] codeset, Symm parent) { + this.codeset = codeset; + splitLinesAt = parent.splitLinesAt; + endEquals = parent.endEquals; + encoding = parent.encoding; + convert = new Unordered(codeset); + } + + /** + * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. + * @return + */ + @Deprecated + public static final Symm base64() { + return base64; + } + + /** + * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc. + * No Line Splitting + * @return + */ + @Deprecated + public static final Symm base64noSplit() { + return base64noSplit; + } + + /** + * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/") + */ + @Deprecated + public static final Symm base64url() { + return base64url; + } + + /** + * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/") + */ + public static final Symm baseCrypt() { + return encrypt; + } + + public <T> T exec(SyncExec<T> exec) throws Exception { + synchronized(LOCK) { + if(keyBytes == null) { + keyBytes = new byte[AES.AES_KEY_SIZE/8]; + int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length); + for(int i=0;i<keyBytes.length;++i) { + keyBytes[i] = (byte)codeset[i+offset]; + } + } + } + return exec.exec(new AES(keyBytes,0,keyBytes.length)); + } + + public interface Encryption { + public CipherOutputStream outputStream(OutputStream os, boolean encrypt); + public CipherInputStream inputStream(InputStream is, boolean encrypt); + } + + public static interface SyncExec<T> { + public T exec(Encryption enc) throws IOException, Exception; + } + public byte[] encode(byte[] toEncrypt) throws IOException { - if(toEncrypt==null) { - return EMPTY; - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25)); - encode(new ByteArrayInputStream(toEncrypt),baos); - return baos.toByteArray(); - } - } + if(toEncrypt==null) { + return EMPTY; + } else { + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25)); + encode(new ByteArrayInputStream(toEncrypt),baos); + return baos.toByteArray(); + } + } public byte[] decode(byte[] encrypted) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25)); - decode(new ByteArrayInputStream(encrypted),baos); - return baos.toByteArray(); - } + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25)); + decode(new ByteArrayInputStream(encrypted),baos); + return baos.toByteArray(); + } - /** + /** * Helper function for String API of "Encode" * use "getBytes" with appropriate char encoding, etc. * @@ -255,22 +255,22 @@ public class Symm { * @throws IOException */ public String encode(String str) throws IOException { - byte[] array; - boolean useDefaultEncoding = false; - try { - array = str.getBytes(encoding); - } catch (IOException e) { - array = str.getBytes(); // take default - useDefaultEncoding = true; - } - // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more - - encode(new ByteArrayInputStream(array),baos); - if (useDefaultEncoding) { - return baos.toString(); - } - return baos.toString(encoding); + byte[] array; + boolean useDefaultEncoding = false; + try { + array = str.getBytes(encoding); + } catch (IOException e) { + array = str.getBytes(); // take default + useDefaultEncoding = true; + } + // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more + + encode(new ByteArrayInputStream(array),baos); + if (useDefaultEncoding) { + return baos.toString(); + } + return baos.toString(encoding); } /** @@ -281,24 +281,24 @@ public class Symm { * @throws IOException */ public String decode(String str) throws IOException { - byte[] array; - boolean useDefaultEncoding = false; - try { - array = str.getBytes(encoding); - } catch (IOException e) { - array = str.getBytes(); // take default - useDefaultEncoding = true; - } - // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4. Allocate slightly more than 3/4s - decode(new ByteArrayInputStream(array), baos); - if (useDefaultEncoding) { - return baos.toString(); - } - return baos.toString(encoding); - } - - /** + byte[] array; + boolean useDefaultEncoding = false; + try { + array = str.getBytes(encoding); + } catch (IOException e) { + array = str.getBytes(); // take default + useDefaultEncoding = true; + } + // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4. Allocate slightly more than 3/4s + decode(new ByteArrayInputStream(array), baos); + if (useDefaultEncoding) { + return baos.toString(); + } + return baos.toString(encoding); + } + + /** * Convenience Function * * encode String into InputStream and call encode(InputStream, OutputStream) @@ -307,29 +307,29 @@ public class Symm { * @param out * @throws IOException */ - public void encode(String string, OutputStream out) throws IOException { - encode(new ByteArrayInputStream(string.getBytes()),out); - } - - /** - * Convenience Function - * - * encode String into InputStream and call decode(InputStream, OutputStream) - * - * @param string - * @param out - * @throws IOException - */ - public void decode(String string, OutputStream out) throws IOException { - decode(new ByteArrayInputStream(string.getBytes()),out); - } + public void encode(String string, OutputStream out) throws IOException { + encode(new ByteArrayInputStream(string.getBytes()),out); + } + + /** + * Convenience Function + * + * encode String into InputStream and call decode(InputStream, OutputStream) + * + * @param string + * @param out + * @throws IOException + */ + public void decode(String string, OutputStream out) throws IOException { + decode(new ByteArrayInputStream(string.getBytes()),out); + } public void encode(InputStream is, OutputStream os, byte[] prefix) throws IOException { - os.write(prefix); - encode(is,os); + os.write(prefix); + encode(is,os); } - /** + /** * encode InputStream onto Output Stream * * @param is @@ -338,95 +338,95 @@ public class Symm { * @throws IOException */ public void encode(InputStream is, OutputStream os) throws IOException { - // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times - int prev=0; - int read, idx=0, line=0; - boolean go; - do { - read = is.read(); - if(go = read>=0) { - if(line>=splitLinesAt) { - os.write('\n'); - line = 0; - } - switch(++idx) { // 1 based reading, slightly faster ++ - case 1: // ptr is the first 6 bits of read - os.write(codeset[read>>2]); - prev = read; - break; - case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read - os.write(codeset[((prev & 0x03)<<4) | (read>>4)]); - prev = read; - break; - default: //(3+) - // Char 1 is last 4 bits of prev plus the first 2 bits of read - // Char 2 is the last 6 bits of read - os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]); - if(line==splitLinesAt) { // deal with line splitting for two characters - os.write('\n'); - line=0; - } - os.write(codeset[(read & 0x3F)]); - ++line; - idx = 0; - prev = 0; - } - ++line; - } else { // deal with any remaining bits from Prev, then pad - switch(idx) { - case 1: // just the last 2 bits of prev - os.write(codeset[(prev & 0x03)<<4]); - if(endEquals)os.write(DOUBLE_EQ); - break; - case 2: // just the last 4 bits of prev - os.write(codeset[(prev & 0xF)<<2]); - if(endEquals)os.write('='); - break; - } - idx = 0; - } - - } while(go); + // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times + int prev=0; + int read, idx=0, line=0; + boolean go; + do { + read = is.read(); + if(go = read>=0) { + if(line>=splitLinesAt) { + os.write('\n'); + line = 0; + } + switch(++idx) { // 1 based reading, slightly faster ++ + case 1: // ptr is the first 6 bits of read + os.write(codeset[read>>2]); + prev = read; + break; + case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read + os.write(codeset[((prev & 0x03)<<4) | (read>>4)]); + prev = read; + break; + default: //(3+) + // Char 1 is last 4 bits of prev plus the first 2 bits of read + // Char 2 is the last 6 bits of read + os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]); + if(line==splitLinesAt) { // deal with line splitting for two characters + os.write('\n'); + line=0; + } + os.write(codeset[(read & 0x3F)]); + ++line; + idx = 0; + prev = 0; + } + ++line; + } else { // deal with any remaining bits from Prev, then pad + switch(idx) { + case 1: // just the last 2 bits of prev + os.write(codeset[(prev & 0x03)<<4]); + if(endEquals)os.write(DOUBLE_EQ); + break; + case 2: // just the last 4 bits of prev + os.write(codeset[(prev & 0xF)<<2]); + if(endEquals)os.write('='); + break; + } + idx = 0; + } + + } while(go); } public void decode(InputStream is, OutputStream os, int skip) throws IOException { - if(is.skip(skip)!=skip) { - throw new IOException("Error skipping on IOStream in Symm"); - } - decode(is,os); + if(is.skip(skip)!=skip) { + throw new IOException("Error skipping on IOStream in Symm"); + } + decode(is,os); } /** - * Decode InputStream onto OutputStream - * @param is - * @param os - * @throws IOException - */ + * Decode InputStream onto OutputStream + * @param is + * @param os + * @throws IOException + */ public void decode(InputStream is, OutputStream os) throws IOException { - int read, idx=0; - int prev=0, index; - while((read = is.read())>=0) { - index = convert.convert(read); - if(index>=0) { - switch(++idx) { // 1 based cases, slightly faster ++ - case 1: // index goes into first 6 bits of prev - prev = index<<2; - break; - case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev - os.write((byte)(prev|(index>>4))); - prev = index<<4; - break; - case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev - os.write((byte)(prev|(index>>2))); - prev = index<<6; - break; - default: // (3+) | prev and last six of index - os.write((byte)(prev|(index&0x3F))); - idx = prev = 0; - } - } - }; - os.flush(); + int read, idx=0; + int prev=0, index; + while((read = is.read())>=0) { + index = convert.convert(read); + if(index>=0) { + switch(++idx) { // 1 based cases, slightly faster ++ + case 1: // index goes into first 6 bits of prev + prev = index<<2; + break; + case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev + os.write((byte)(prev|(index>>4))); + prev = index<<4; + break; + case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev + os.write((byte)(prev|(index>>2))); + prev = index<<6; + break; + default: // (3+) | prev and last six of index + os.write((byte)(prev|(index&0x3F))); + idx = prev = 0; + } + } + }; + os.flush(); } /** @@ -435,7 +435,7 @@ public class Symm { * */ private interface Convert { - public int convert(int read) throws IOException; + public int convert(int read) throws IOException; } /** @@ -445,27 +445,27 @@ public class Symm { * */ private static final class Ordered implements Convert { - private int[][] range; - public Ordered(int[][] range) { - this.range = range; - } - public int convert(int read) throws IOException { - // System.out.print((char)read); - switch(read) { - case -1: - case '=': - case ' ': - case '\n': - case '\r': - return -1; - } - for(int i=0;i<range.length;++i) { - if(read >= range[i][0] && read<=range[i][1]) { - return read-range[i][2]; - } - } - throw new IOException("Unacceptable Character in Stream"); - } + private int[][] range; + public Ordered(int[][] range) { + this.range = range; + } + public int convert(int read) throws IOException { + // System.out.print((char)read); + switch(read) { + case -1: + case '=': + case ' ': + case '\n': + case '\r': + return -1; + } + for(int i=0;i<range.length;++i) { + if(read >= range[i][0] && read<=range[i][1]) { + return read-range[i][2]; + } + } + throw new IOException("Unacceptable Character in Stream"); + } } /** @@ -475,24 +475,24 @@ public class Symm { * */ private static final class Unordered implements Convert { - private char[] codec; - public Unordered(char[] codec) { - this.codec = codec; - } - public int convert(int read) throws IOException { - switch(read) { - case -1: - case '=': - case '\n': - case '\r': - return -1; - } - for(int i=0;i<codec.length;++i) { - if(codec[i]==read)return i; - } - // don't give clue in Encryption mode - throw new IOException("Unacceptable Character in Stream"); - } + private char[] codec; + public Unordered(char[] codec) { + this.codec = codec; + } + public int convert(int read) throws IOException { + switch(read) { + case -1: + case '=': + case '\n': + case '\r': + return -1; + } + for(int i=0;i<codec.length;++i) { + if(codec[i]==read)return i; + } + // don't give clue in Encryption mode + throw new IOException("Unacceptable Character in Stream"); + } } /** @@ -502,34 +502,34 @@ public class Symm { * @throws IOException */ public static byte[] keygen() throws IOException { - byte inkey[] = new byte[0x600]; - new SecureRandom().nextBytes(inkey); - ByteArrayOutputStream baos = new ByteArrayOutputStream(0x800); - base64url.encode(new ByteArrayInputStream(inkey), baos); - return baos.toByteArray(); + byte inkey[] = new byte[0x600]; + new SecureRandom().nextBytes(inkey); + ByteArrayOutputStream baos = new ByteArrayOutputStream(0x800); + base64url.encode(new ByteArrayInputStream(inkey), baos); + return baos.toByteArray(); } // A class allowing us to be less predictable about significant digits (i.e. not picking them up from the // beginning, and not picking them up in an ordered row. Gives a nice 2048 with no visible patterns. private class Obtain { - private int last; - private int skip; - private int length; - private byte[] key; + private int last; + private int skip; + private int length; + private byte[] key; - private Obtain(Symm b64, byte[] key) { - skip = Math.abs(key[key.length-13]%key.length); - if((key.length&0x1) == (skip&0x1)) { // if both are odd or both are even - ++skip; - } - length = b64.codeset.length; - last = 17+length%59; // never start at beginning - this.key = key; - } - - private int next() { - return Math.abs(key[(++last*skip)%key.length])%length; - } + private Obtain(Symm b64, byte[] key) { + skip = Math.abs(key[key.length-13]%key.length); + if((key.length&0x1) == (skip&0x1)) { // if both are odd or both are even + ++skip; + } + length = b64.codeset.length; + last = 17+length%59; // never start at beginning + this.key = key; + } + + private int next() { + return Math.abs(key[(++last*skip)%key.length])%length; + } }; /** @@ -541,55 +541,55 @@ public class Symm { * @throws CadiException */ public static Symm obtain(Access access) throws CadiException { - String keyfile = access.getProperty(Config.CADI_KEYFILE,null); - if(keyfile!=null) { - Symm symm = Symm.baseCrypt(); - - File file = new File(keyfile); - try { - access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getCanonicalPath()); - } catch (IOException e1) { - access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getAbsolutePath()); - } - if(file.exists()) { - try { - FileInputStream fis = new FileInputStream(file); - try { - symm = Symm.obtain(fis); - } finally { - try { - fis.close(); - } catch (IOException e) { - } - } - } catch (IOException e) { - access.log(e, "Cannot load keyfile"); - } - } else { - String filename; - try { - filename = file.getCanonicalPath(); - } catch (IOException e) { - filename = file.getAbsolutePath(); - } - throw new CadiException("ERROR: " + filename + " does not exist!"); - } - return symm; - } else { - try { - return internalOnly(); - } catch (IOException e) { - throw new CadiException(e); - } - } + String keyfile = access.getProperty(Config.CADI_KEYFILE,null); + if(keyfile!=null) { + Symm symm = Symm.baseCrypt(); + + File file = new File(keyfile); + try { + access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getCanonicalPath()); + } catch (IOException e1) { + access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getAbsolutePath()); + } + if(file.exists()) { + try { + FileInputStream fis = new FileInputStream(file); + try { + symm = Symm.obtain(fis); + } finally { + try { + fis.close(); + } catch (IOException e) { + } + } + } catch (IOException e) { + access.log(e, "Cannot load keyfile"); + } + } else { + String filename; + try { + filename = file.getCanonicalPath(); + } catch (IOException e) { + filename = file.getAbsolutePath(); + } + throw new CadiException("ERROR: " + filename + " does not exist!"); + } + return symm; + } else { + try { + return internalOnly(); + } catch (IOException e) { + throw new CadiException(e); + } + } } /** * Create a new random key */ public Symm obtain() throws IOException { - byte inkey[] = new byte[0x800]; - new SecureRandom().nextBytes(inkey); - return obtain(inkey); + byte inkey[] = new byte[0x800]; + new SecureRandom().nextBytes(inkey); + return obtain(inkey); } /** @@ -600,7 +600,7 @@ public class Symm { * @throws IOException */ public static Symm obtain(String key) throws IOException { - return obtain(new ByteArrayInputStream(key.getBytes())); + return obtain(new ByteArrayInputStream(key.getBytes())); } /** @@ -611,18 +611,18 @@ public class Symm { * @throws IOException */ public static Symm obtain(InputStream is) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - base64url.decode(is, baos); - } catch (IOException e) { - // don't give clue - throw new IOException("Invalid Key"); - } - byte[] bkey = baos.toByteArray(); - if(bkey.length<0x88) { // 2048 bit key - throw new IOException("Invalid key"); - } - return baseCrypt().obtain(bkey); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + base64url.decode(is, baos); + } catch (IOException e) { + // don't give clue + throw new IOException("Invalid Key"); + } + byte[] bkey = baos.toByteArray(); + if(bkey.length<0x88) { // 2048 bit key + throw new IOException("Invalid key"); + } + return baseCrypt().obtain(bkey); } /** @@ -633,12 +633,12 @@ public class Symm { * @throws IOException */ public static Symm obtain(File f) throws IOException { - FileInputStream fis = new FileInputStream(f); - try { - return obtain(fis); - } finally { - fis.close(); - } + FileInputStream fis = new FileInputStream(f); + try { + return obtain(fis); + } finally { + fis.close(); + } } /** * Decrypt into a String @@ -650,9 +650,9 @@ public class Symm { * @throws IOException */ public String enpass(String password) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - enpass(password,baos); - return new String(baos.toByteArray()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + enpass(password,baos); + return new String(baos.toByteArray()); } /** @@ -663,65 +663,65 @@ public class Symm { * @throws IOException */ public void enpass(final String password, final OutputStream os) throws IOException { - if(password==null) { - throw new IOException("Invalid password passed"); - } - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - byte[] bytes = password.getBytes(); - if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization - dos.write(bytes); - } else { - - Random r = new SecureRandom(); - int start = 0; - byte b; - for(int i=0;i<3;++i) { - dos.writeByte(b=(byte)r.nextInt()); - start+=Math.abs(b); - } - start%=0x7; - for(int i=0;i<start;++i) { - dos.writeByte(r.nextInt()); - } - dos.writeInt((int)System.currentTimeMillis()); - int minlength = Math.min(0x9,bytes.length); - dos.writeByte(minlength); // expect truncation - if(bytes.length<0x9) { - for(int i=0;i<bytes.length;++i) { - dos.writeByte(r.nextInt()); - dos.writeByte(bytes[i]); - } - // make sure it's long enough - for(int i=bytes.length;i<0x9;++i) { - dos.writeByte(r.nextInt()); - } - } else { - dos.write(bytes); - } - } - - // 7/21/2016 Jonathan add AES Encryption to the mix - try { - exec(new SyncExec<Void>() { - @Override - public Void exec(Encryption enc) throws Exception { - CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true); - try { - encode(cis,os); - } finally { - os.flush(); - cis.close(); - } - return null; - } - }); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - } + if(password==null) { + throw new IOException("Invalid password passed"); + } + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(baos); + byte[] bytes = password.getBytes(); + if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization + dos.write(bytes); + } else { + + Random r = new SecureRandom(); + int start = 0; + byte b; + for(int i=0;i<3;++i) { + dos.writeByte(b=(byte)r.nextInt()); + start+=Math.abs(b); + } + start%=0x7; + for(int i=0;i<start;++i) { + dos.writeByte(r.nextInt()); + } + dos.writeInt((int)System.currentTimeMillis()); + int minlength = Math.min(0x9,bytes.length); + dos.writeByte(minlength); // expect truncation + if(bytes.length<0x9) { + for(int i=0;i<bytes.length;++i) { + dos.writeByte(r.nextInt()); + dos.writeByte(bytes[i]); + } + // make sure it's long enough + for(int i=bytes.length;i<0x9;++i) { + dos.writeByte(r.nextInt()); + } + } else { + dos.write(bytes); + } + } + + // 7/21/2016 Jonathan add AES Encryption to the mix + try { + exec(new SyncExec<Void>() { + @Override + public Void exec(Encryption enc) throws Exception { + CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true); + try { + encode(cis,os); + } finally { + os.flush(); + cis.close(); + } + return null; + } + }); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e); + } + } /** * Decrypt a password into a String @@ -733,10 +733,10 @@ public class Symm { * @throws IOException */ public String depass(String password) throws IOException { - if(password==null)return null; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - depass(password,baos); - return new String(baos.toByteArray()); + if(password==null)return null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + depass(password,baos); + return new String(baos.toByteArray()); } /** @@ -750,68 +750,68 @@ public class Symm { * @throws IOException */ public long depass(final String password, final OutputStream os) throws IOException { - int offset = password.startsWith(ENC)?4:0; - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final ByteArrayInputStream bais = new ByteArrayInputStream(password.getBytes(),offset,password.length()-offset); - try { - exec(new SyncExec<Void>() { - @Override - public Void exec(Encryption enc) throws IOException { - CipherOutputStream cos = enc.outputStream(baos, false); - decode(bais,cos); - cos.close(); // flush - return null; - } - }); - } catch (IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - - byte[] bytes = baos.toByteArray(); - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes)); - long time; - if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization - os.write(bytes); - time = 0L; - } else { - int start=0; - for(int i=0;i<3;++i) { - start+=Math.abs(dis.readByte()); - } - start%=0x7; - for(int i=0;i<start;++i) { - dis.readByte(); - } - time = (dis.readInt() & 0xFFFF)|(System.currentTimeMillis()&0xFFFF0000); - int minlength = dis.readByte(); - if(minlength<0x9){ - DataOutputStream dos = new DataOutputStream(os); - for(int i=0;i<minlength;++i) { - dis.readByte(); - dos.writeByte(dis.readByte()); - } - } else { - int pre =((Byte.SIZE*3+Integer.SIZE+Byte.SIZE)/Byte.SIZE)+start; - os.write(bytes, pre, bytes.length-pre); - } - } - return time; + int offset = password.startsWith(ENC)?4:0; + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ByteArrayInputStream bais = new ByteArrayInputStream(password.getBytes(),offset,password.length()-offset); + try { + exec(new SyncExec<Void>() { + @Override + public Void exec(Encryption enc) throws IOException { + CipherOutputStream cos = enc.outputStream(baos, false); + decode(bais,cos); + cos.close(); // flush + return null; + } + }); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException(e); + } + + byte[] bytes = baos.toByteArray(); + DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes)); + long time; + if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization + os.write(bytes); + time = 0L; + } else { + int start=0; + for(int i=0;i<3;++i) { + start+=Math.abs(dis.readByte()); + } + start%=0x7; + for(int i=0;i<start;++i) { + dis.readByte(); + } + time = (dis.readInt() & 0xFFFF)|(System.currentTimeMillis()&0xFFFF0000); + int minlength = dis.readByte(); + if(minlength<0x9){ + DataOutputStream dos = new DataOutputStream(os); + for(int i=0;i<minlength;++i) { + dis.readByte(); + dos.writeByte(dis.readByte()); + } + } else { + int pre =((Byte.SIZE*3+Integer.SIZE+Byte.SIZE)/Byte.SIZE)+start; + os.write(bytes, pre, bytes.length-pre); + } + } + return time; } public static String randomGen(int numBytes) { - return randomGen(passChars,numBytes); + return randomGen(passChars,numBytes); } public static String randomGen(char[] chars ,int numBytes) { - int rint; - StringBuilder sb = new StringBuilder(numBytes); - for(int i=0;i<numBytes;++i) { - rint = random.nextInt(chars.length); - sb.append(chars[rint]); - } - return sb.toString(); + int rint; + StringBuilder sb = new StringBuilder(numBytes); + for(int i=0;i<numBytes;++i) { + rint = random.nextInt(chars.length); + sb.append(chars[rint]); + } + return sb.toString(); } // Internal mechanism for helping to randomize placement of characters within a Symm codeset // Based on an incoming data stream (originally created randomly, but can be recreated within @@ -821,52 +821,52 @@ public class Symm { // shuffled for a good spread. It is, however, repeatable, given the same number set, allowing for // quick recreation when the official stream is actually obtained. public Symm obtain(byte[] key) throws IOException { - int filled = codeset.length; - char[] seq = new char[filled]; - int end = filled--; - - boolean right = true; - int index; - Obtain o = new Obtain(this,key); - - while(filled>=0) { - index = o.next(); - if(index<0 || index>=codeset.length) { - System.out.println("uh, oh"); - } - if(right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) - for(int j=index;j<end;++j) { - if(seq[j]==0) { - seq[j]=codeset[filled]; - --filled; - break; - } - } - right = false; - } else { - for(int j=index;j>=0;--j) { - if(seq[j]==0) { - seq[j]=codeset[filled]; - --filled; - break; - } - } - right = true; - } - } - Symm newSymm = new Symm(seq,this); - // Set the KeyBytes - try { - newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8]; - int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length); - for(int i=0;i<newSymm.keyBytes.length;++i) { - newSymm.keyBytes[i] = key[i+offset]; - } - } catch (Exception e) { - throw new IOException(e); - } - - return newSymm; + int filled = codeset.length; + char[] seq = new char[filled]; + int end = filled--; + + boolean right = true; + int index; + Obtain o = new Obtain(this,key); + + while(filled>=0) { + index = o.next(); + if(index<0 || index>=codeset.length) { + System.out.println("uh, oh"); + } + if(right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) + for(int j=index;j<end;++j) { + if(seq[j]==0) { + seq[j]=codeset[filled]; + --filled; + break; + } + } + right = false; + } else { + for(int j=index;j>=0;--j) { + if(seq[j]==0) { + seq[j]=codeset[filled]; + --filled; + break; + } + } + right = true; + } + } + Symm newSymm = new Symm(seq,this); + // Set the KeyBytes + try { + newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8]; + int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length); + for(int i=0;i<newSymm.keyBytes.length;++i) { + newSymm.keyBytes[i] = key[i+offset]; + } + } catch (Exception e) { + throw new IOException(e); + } + + return newSymm; } /** @@ -876,14 +876,14 @@ public class Symm { * @throws IOException */ public static synchronized Symm internalOnly() throws IOException { - if(internalOnly==null) { - ByteArrayInputStream baos = new ByteArrayInputStream(keygen()); - try { - internalOnly = Symm.obtain(baos); - } finally { - baos.close(); - } - } - return internalOnly; + if(internalOnly==null) { + ByteArrayInputStream baos = new ByteArrayInputStream(keygen()); + try { + internalOnly = Symm.obtain(baos); + } finally { + baos.close(); + } + } + return internalOnly; } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Taf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Taf.java index 1767258c..771ebcf4 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Taf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Taf.java @@ -36,22 +36,22 @@ import org.onap.aaf.cadi.taf.TafResp; * */ public interface Taf { - enum LifeForm {CBLF, SBLF, LFN}; - /** - * The lifeForm param is a humorous way of describing whether the interaction is proceeding from direct Human Interaction via a browser - * or App which can directly query a memorized password, key sequence, bio-feedback, from that user, or a machine mechanism for which identity - * can more easily be determined by Certificate, Mechanical ID/Password etc. Popularized in modern culture and Science Fiction (especially - * Star Trek), we (starting with Robert Garskof) use the terms "Carbon Based Life Form" (CBLF) for mechanisms with people at the end of them, or - * "Silicon Based Life Forms" (SBLF) to indicate machine only interactions. I have added "LFN" for (Life-Form Neutral) to aid identifying - * processes for which it doesn't matter whether there is a human at the immediate end of the chain, or cannot be determined mechanically. - * - * The variable parameter is not necessarily ideal, but with too many unknown Tafs to be created, flexibility, - * is unfortunately required at this point. Future versions could lock this down more. Jonathan 10/18/2012 - * - * @param lifeForm - * @param info - * @return - */ - public TafResp validate(LifeForm reading, String ... info); - + enum LifeForm {CBLF, SBLF, LFN}; + /** + * The lifeForm param is a humorous way of describing whether the interaction is proceeding from direct Human Interaction via a browser + * or App which can directly query a memorized password, key sequence, bio-feedback, from that user, or a machine mechanism for which identity + * can more easily be determined by Certificate, Mechanical ID/Password etc. Popularized in modern culture and Science Fiction (especially + * Star Trek), we (starting with Robert Garskof) use the terms "Carbon Based Life Form" (CBLF) for mechanisms with people at the end of them, or + * "Silicon Based Life Forms" (SBLF) to indicate machine only interactions. I have added "LFN" for (Life-Form Neutral) to aid identifying + * processes for which it doesn't matter whether there is a human at the immediate end of the chain, or cannot be determined mechanically. + * + * The variable parameter is not necessarily ideal, but with too many unknown Tafs to be created, flexibility, + * is unfortunately required at this point. Future versions could lock this down more. Jonathan 10/18/2012 + * + * @param lifeForm + * @param info + * @return + */ + public TafResp validate(LifeForm reading, String ... info); + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/Transmutate.java b/cadi/core/src/main/java/org/onap/aaf/cadi/Transmutate.java index 63722253..1203b8d2 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/Transmutate.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/Transmutate.java @@ -35,11 +35,11 @@ import java.security.Principal; * */ public interface Transmutate<T> { - /** - * Mutate the (assumed validated) Principal into the expected Principal name to be used to construct - * - * @param p - * @return - */ - public T mutate(Principal p); + /** + * Mutate the (assumed validated) Principal into the expected Principal name to be used to construct + * + * @param p + * @return + */ + public T mutate(Principal p); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java b/cadi/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java index fabec0b0..6b1433f4 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java @@ -32,21 +32,21 @@ import org.onap.aaf.cadi.taf.TafResp; * */ public interface TrustChecker { - public TafResp mayTrust(TafResp tresp, HttpServletRequest req); - - /** - * A class that trusts no-one else, so just return same TResp - */ - public static TrustChecker NOTRUST = new TrustChecker() { - @Override - public TafResp mayTrust(TafResp tresp, HttpServletRequest req) { - return tresp; - } + public TafResp mayTrust(TafResp tresp, HttpServletRequest req); + + /** + * A class that trusts no-one else, so just return same TResp + */ + public static TrustChecker NOTRUST = new TrustChecker() { + @Override + public TafResp mayTrust(TafResp tresp, HttpServletRequest req) { + return tresp; + } - @Override - public void setLur(Lur lur) { - } - }; + @Override + public void setLur(Lur lur) { + } + }; - public void setLur(Lur lur); + public void setLur(Lur lur); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/User.java b/cadi/core/src/main/java/org/onap/aaf/cadi/User.java index 34aaf170..512f2e6a 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/User.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/User.java @@ -36,142 +36,142 @@ import org.onap.aaf.cadi.lur.LocalPermission; * */ public final class User<PERM extends Permission> { - private static final Map<String,Permission> NULL_MAP = new HashMap<>(); - public String name; - private byte[] cred; - public Principal principal; - Map<String, Permission> perms ; - long permExpires; - private final long interval; - int count; - - // Note: This should only be used for Local RBAC (in memory) - public User(Principal principal) { - this.principal = principal; - name = principal.getName(); - perms = NULL_MAP; - permExpires = Long.MAX_VALUE; // Never. Well, until 64 bits of millis since 1970 expires... - interval = 0L; - count = 0; - } - - public User(String name, byte[] cred) { - this.principal = null; - this.name = name; - this.cred = cred; - perms = NULL_MAP; - permExpires = Long.MAX_VALUE; // Never. Well, until 64 bits of millis since 1970 expires... - interval = 0L; - count = 0; - } - - public User(Principal principal, long expireInterval) { - this.principal = principal; - this.name = principal.getName(); - perms = NULL_MAP; - expireInterval = Math.max(expireInterval, 0); // avoid < 1 - interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); - count = 0; - renewPerm(); - renewPerm(); - } - - public User(String name, byte[] cred, long expireInterval) { - this.principal = null; - this.name = name; - this.cred = cred; - perms = NULL_MAP; - expireInterval = Math.max(expireInterval, 0); // avoid < 1 - interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); - count = 0; - renewPerm(); - } - - public void renewPerm() { - permExpires = System.currentTimeMillis()+interval; - } - - public long permExpires() { - return permExpires; - } - - public boolean permExpired() { - return System.currentTimeMillis() > permExpires; - } - - public boolean noPerms() { - return perms==null || perms==NULL_MAP || perms.values().size()==0; - } - - public synchronized void setNoPerms() { - perms=NULL_MAP; - renewPerm(); - } - - public boolean permsUnloaded() { - return perms==null || perms==NULL_MAP; - } - - public synchronized void incCount() { - ++count; - } - - public synchronized void resetCount() { - count=0; - } - - public Map<String,Permission> newMap() { - return new ConcurrentHashMap<>(); - } - - public void add(LocalPermission permission) { - if(perms==NULL_MAP) { - perms=newMap(); - } - perms.put(permission.getKey(),permission); - } - - public void add(Map<String, Permission> newMap, PERM permission) { - newMap.put(permission.getKey(),permission); - } - - public synchronized void setMap(Map<String, Permission> newMap) { - perms = newMap; - renewPerm(); - } - - public boolean contains(Permission perm) { - for (Permission p : perms.values()) { - if (p.match(perm)) return true; - } - return false; - } - - public void copyPermsTo(List<Permission> sink) { - sink.addAll(perms.values()); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(principal.getName()); - sb.append('|'); - boolean first = true; - synchronized(perms) { - for(Permission gp : perms.values()) { - if(first) { - first = false; - sb.append(':'); - } else { - sb.append(','); - } - sb.append(gp.getKey()); - } - } - return sb.toString(); - } - - public byte[] getCred() { - return cred; - } + private static final Map<String,Permission> NULL_MAP = new HashMap<>(); + public String name; + private byte[] cred; + public Principal principal; + Map<String, Permission> perms ; + long permExpires; + private final long interval; + int count; + + // Note: This should only be used for Local RBAC (in memory) + public User(Principal principal) { + this.principal = principal; + name = principal.getName(); + perms = NULL_MAP; + permExpires = Long.MAX_VALUE; // Never. Well, until 64 bits of millis since 1970 expires... + interval = 0L; + count = 0; + } + + public User(String name, byte[] cred) { + this.principal = null; + this.name = name; + this.cred = cred; + perms = NULL_MAP; + permExpires = Long.MAX_VALUE; // Never. Well, until 64 bits of millis since 1970 expires... + interval = 0L; + count = 0; + } + + public User(Principal principal, long expireInterval) { + this.principal = principal; + this.name = principal.getName(); + perms = NULL_MAP; + expireInterval = Math.max(expireInterval, 0); // avoid < 1 + interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); + count = 0; + renewPerm(); + renewPerm(); + } + + public User(String name, byte[] cred, long expireInterval) { + this.principal = null; + this.name = name; + this.cred = cred; + perms = NULL_MAP; + expireInterval = Math.max(expireInterval, 0); // avoid < 1 + interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); + count = 0; + renewPerm(); + } + + public void renewPerm() { + permExpires = System.currentTimeMillis()+interval; + } + + public long permExpires() { + return permExpires; + } + + public boolean permExpired() { + return System.currentTimeMillis() > permExpires; + } + + public boolean noPerms() { + return perms==null || perms==NULL_MAP || perms.values().size()==0; + } + + public synchronized void setNoPerms() { + perms=NULL_MAP; + renewPerm(); + } + + public boolean permsUnloaded() { + return perms==null || perms==NULL_MAP; + } + + public synchronized void incCount() { + ++count; + } + + public synchronized void resetCount() { + count=0; + } + + public Map<String,Permission> newMap() { + return new ConcurrentHashMap<>(); + } + + public void add(LocalPermission permission) { + if(perms==NULL_MAP) { + perms=newMap(); + } + perms.put(permission.getKey(),permission); + } + + public void add(Map<String, Permission> newMap, PERM permission) { + newMap.put(permission.getKey(),permission); + } + + public synchronized void setMap(Map<String, Permission> newMap) { + perms = newMap; + renewPerm(); + } + + public boolean contains(Permission perm) { + for (Permission p : perms.values()) { + if (p.match(perm)) return true; + } + return false; + } + + public void copyPermsTo(List<Permission> sink) { + sink.addAll(perms.values()); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(principal.getName()); + sb.append('|'); + boolean first = true; + synchronized(perms) { + for(Permission gp : perms.values()) { + if(first) { + first = false; + sb.append(':'); + } else { + sb.append(','); + } + sb.append(gp.getKey()); + } + } + return sb.toString(); + } + + public byte[] getCred() { + return cred; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/UserChain.java b/cadi/core/src/main/java/org/onap/aaf/cadi/UserChain.java index 9d8f2b04..f6a98085 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/UserChain.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/UserChain.java @@ -38,6 +38,6 @@ package org.onap.aaf.cadi; * */ public interface UserChain { - public enum Protocol {BasicAuth,Cookie,Cert,OAuth}; - public String userChain(); + public enum Protocol {BasicAuth,Cookie,Cert,OAuth}; + public String userChain(); } 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 8cb6ae06..4784d1ee 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 @@ -67,739 +67,739 @@ import org.onap.aaf.cadi.taf.dos.DenialOfServiceTaf; */ public class Config { - private static final String AAF_V2_0 = "org.onap.aaf.cadi.aaf.v2_0"; - private static final String AAF_V2_0_AAFCON = AAF_V2_0+".AAFCon"; - private static final String AAF_V2_0_AAF_LUR_PERM = AAF_V2_0+".AAFLurPerm"; - private static final String OAUTH = "org.onap.auth.oauth"; - private static final String OAUTH_TOKEN_MGR = OAUTH+".TokenMgr"; - private static final String OAUTH_HTTP_TAF = OAUTH+".OAuth2HttpTaf"; - private static final String OAUTH_DIRECT_TAF = OAUTH+".OAuthDirectTAF"; - public static final String UTF_8 = "UTF-8"; - - // Property Names associated with configurations. - // As of 1.0.2, these have had the dots removed so as to be compatible with JavaBean style - // configurations as well as property list style. - public static final String HOSTNAME = "hostname"; - public static final String CADI_PROP_FILES = "cadi_prop_files"; // Additional Properties files (separate with ;) - public static final String CADI_LOGLEVEL = "cadi_loglevel"; - public static final String CADI_LOGDIR = "cadi_log_dir"; - public static final String CADI_ETCDIR = "cadi_etc_dir"; - public static final String CADI_LOGNAME = "cadi_logname"; - public static final String CADI_KEYFILE = "cadi_keyfile"; - public static final String CADI_KEYSTORE = "cadi_keystore"; - public static final String CADI_KEYSTORE_PASSWORD = "cadi_keystore_password"; - public static final String CADI_ALIAS = "cadi_alias"; - public static final String CADI_LOGINPAGE_URL = "cadi_loginpage_url"; - public static final String CADI_LATITUDE = "cadi_latitude"; - public static final String CADI_LONGITUDE = "cadi_longitude"; - - - public static final String CADI_KEY_PASSWORD = "cadi_key_password"; - public static final String CADI_TRUSTSTORE = "cadi_truststore"; - public static final String CADI_TRUSTSTORE_PASSWORD = "cadi_truststore_password"; - public static final String CADI_X509_ISSUERS = "cadi_x509_issuers"; - public static final String CADI_TRUST_MASKS="cadi_trust_masks"; - public static final String CADI_TRUST_PERM="cadi_trust_perm"; // IDs with this perm can utilize the "AS " user concept - public static final String CADI_PROTOCOLS = "cadi_protocols"; - public static final String CADI_NOAUTHN = "cadi_noauthn"; - public static final String CADI_LOC_LIST = "cadi_loc_list"; - - public static final String CADI_USER_CHAIN_TAG = "cadi_user_chain"; - public static final String CADI_USER_CHAIN = "USER_CHAIN"; - - public static final String CADI_OAUTH2_URL="cadi_oauth2_url"; - public static final String CADI_TOKEN_DIR = "cadi_token_dir"; + private static final String AAF_V2_0 = "org.onap.aaf.cadi.aaf.v2_0"; + private static final String AAF_V2_0_AAFCON = AAF_V2_0+".AAFCon"; + private static final String AAF_V2_0_AAF_LUR_PERM = AAF_V2_0+".AAFLurPerm"; + private static final String OAUTH = "org.onap.auth.oauth"; + private static final String OAUTH_TOKEN_MGR = OAUTH+".TokenMgr"; + private static final String OAUTH_HTTP_TAF = OAUTH+".OAuth2HttpTaf"; + private static final String OAUTH_DIRECT_TAF = OAUTH+".OAuthDirectTAF"; + public static final String UTF_8 = "UTF-8"; + + // Property Names associated with configurations. + // As of 1.0.2, these have had the dots removed so as to be compatible with JavaBean style + // configurations as well as property list style. + public static final String HOSTNAME = "hostname"; + public static final String CADI_PROP_FILES = "cadi_prop_files"; // Additional Properties files (separate with ;) + public static final String CADI_LOGLEVEL = "cadi_loglevel"; + public static final String CADI_LOGDIR = "cadi_log_dir"; + public static final String CADI_ETCDIR = "cadi_etc_dir"; + public static final String CADI_LOGNAME = "cadi_logname"; + public static final String CADI_KEYFILE = "cadi_keyfile"; + public static final String CADI_KEYSTORE = "cadi_keystore"; + public static final String CADI_KEYSTORE_PASSWORD = "cadi_keystore_password"; + public static final String CADI_ALIAS = "cadi_alias"; + public static final String CADI_LOGINPAGE_URL = "cadi_loginpage_url"; + public static final String CADI_LATITUDE = "cadi_latitude"; + public static final String CADI_LONGITUDE = "cadi_longitude"; + + + public static final String CADI_KEY_PASSWORD = "cadi_key_password"; + public static final String CADI_TRUSTSTORE = "cadi_truststore"; + public static final String CADI_TRUSTSTORE_PASSWORD = "cadi_truststore_password"; + public static final String CADI_X509_ISSUERS = "cadi_x509_issuers"; + public static final String CADI_TRUST_MASKS="cadi_trust_masks"; + public static final String CADI_TRUST_PERM="cadi_trust_perm"; // IDs with this perm can utilize the "AS " user concept + public static final String CADI_PROTOCOLS = "cadi_protocols"; + public static final String CADI_NOAUTHN = "cadi_noauthn"; + public static final String CADI_LOC_LIST = "cadi_loc_list"; + + public static final String CADI_USER_CHAIN_TAG = "cadi_user_chain"; + public static final String CADI_USER_CHAIN = "USER_CHAIN"; + + public static final String CADI_OAUTH2_URL="cadi_oauth2_url"; + public static final String CADI_TOKEN_DIR = "cadi_token_dir"; public static final String HTTPS_PROTOCOLS = "https.protocols"; public static final String HTTPS_CIPHER_SUITES = "https.cipherSuites"; public static final String HTTPS_CLIENT_PROTOCOLS="jdk.tls.client.protocols"; public static final String HTTPS_CIPHER_SUITES_DEFAULT="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," - + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," - + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA," - + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_ECDH_ECDSA_WITH_RC4_128_SHA," - + "TLS_ECDH_RSA_WITH_RC4_128_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," - + "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - - - public static final String LOCALHOST_ALLOW = "localhost_allow"; - public static final String LOCALHOST_DENY = "localhost_deny"; - - public static final String BASIC_REALM = "basic_realm"; // what is sent to the client - public static final String BASIC_WARN = "basic_warn"; // Warning of insecure channel - public static final String USERS = "local_users"; - public static final String GROUPS = "local_groups"; - public static final String WRITE_TO = "local_writeto"; // dump RBAC to local file in Tomcat Style (some apps use) - - public static final String OAUTH_CLIENT_ID="client_id"; - public static final String OAUTH_CLIENT_SECRET="client_secret"; - - public static final String AAF_ENV = "aaf_env"; - public static final String AAF_ROOT_NS = "aaf_root_ns"; - public static final String AAF_ROOT_NS_DEF = "org.osaaf.aaf"; - public static final String AAF_ROOT_COMPANY = "aaf_root_company"; - public static final String AAF_LOCATE_URL = "aaf_locate_url"; //URL for AAF locator - private static final String AAF_LOCATE_URL_TAG = "AAF_LOCATE_URL"; // Name of Above for use in Config Variables. - public static final String AAF_DEFAULT_VERSION = "2.1"; - public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration - public static final String AAF_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.service:" + AAF_DEFAULT_VERSION; - public static final String GUI_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.gui:" + AAF_DEFAULT_VERSION; - public static final String CM_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.cm:" + AAF_DEFAULT_VERSION; - public static final String FS_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.fs:" + AAF_DEFAULT_VERSION; - public static final String HELLO_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.hello:" + AAF_DEFAULT_VERSION; - public static final String OAUTH2_TOKEN_URL = "https://AAF_LOCATE_URL/AAF_NS.token:" + AAF_DEFAULT_VERSION; - public static final String OAUTH2_INTROSPECT_URL = "https://AAF_LOCATE_URL/AAF_NS.introspect:" + AAF_DEFAULT_VERSION; - - public static final String AAF_REGISTER_AS = "aaf_register_as"; - public static final String AAF_APPID = "aaf_id"; - public static final String AAF_APPPASS = "aaf_password"; - public static final String AAF_LUR_CLASS = "aaf_lur_class"; - public static final String AAF_TAF_CLASS = "aaf_taf_class"; - public static final String AAF_CONNECTOR_CLASS = "aaf_connector_class"; - public static final String AAF_LOCATOR_CLASS = "aaf_locator_class"; - public static final String AAF_CONN_TIMEOUT = "aaf_conn_timeout"; - public static final String AAF_CONN_TIMEOUT_DEF = "3000"; - public static final String AAF_CONN_IDLE_TIMEOUT = "aaf_conn_idle_timeout"; // only for Direct Jetty Access. - public static final String AAF_CONN_IDLE_TIMEOUT_DEF = "10000"; // only for Direct Jetty Access. - - // Default Classes: These are for Class loading to avoid direct compile links - public static final String AAF_TAF_CLASS_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFTaf"; - public static final String AAF_LOCATOR_CLASS_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFLocator"; - public static final String CADI_OLUR_CLASS_DEF = "org.onap.aaf.cadi.olur.OLur"; - public static final String CADI_OBASIC_HTTP_TAF_DEF = "org.onap.aaf.cadi.obasic.OBasicHttpTaf"; - public static final String CADI_AAF_CON_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFCon"; - - public static final String AAF_CALL_TIMEOUT = "aaf_timeout"; - public static final String AAF_CALL_TIMEOUT_DEF = "5000"; - public static final String AAF_USER_EXPIRES = "aaf_user_expires"; - public static final String AAF_USER_EXPIRES_DEF = "600000"; // Default is 10 mins - public static final String AAF_CLEAN_INTERVAL = "aaf_clean_interval"; - public static final String AAF_CLEAN_INTERVAL_DEF = "30000"; // Default is 30 seconds - public static final String AAF_REFRESH_TRIGGER_COUNT = "aaf_refresh_trigger_count"; - public static final String AAF_REFRESH_TRIGGER_COUNT_DEF = "3"; // Default is 10 mins - - public static final String AAF_HIGH_COUNT = "aaf_high_count"; - public static final String AAF_HIGH_COUNT_DEF = "1000"; // Default is 1000 entries - public static final String AAF_PERM_MAP = "aaf_perm_map"; - public static final String AAF_COMPONENT = "aaf_component"; - 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 GW_URL = "gw_url"; - public static final String CM_URL = "cm_url"; - public static final String CM_TRUSTED_CAS = "cm_trusted_cas"; - - public static final String PATHFILTER_URLPATTERN = "pathfilter_urlpattern"; - public static final String PATHFILTER_STACK = "pathfilter_stack"; - public static final String PATHFILTER_NS = "pathfilter_ns"; - public static final String PATHFILTER_NOT_AUTHORIZED_MSG = "pathfilter_not_authorized_msg"; - - // This one should go unpublic - public static final String AAF_DEFAULT_REALM = "aaf_default_realm"; - private static String defaultRealm="none"; - - public static final String AAF_DOMAIN_SUPPORT = "aaf_domain_support"; - public static final String AAF_DOMAIN_SUPPORT_DEF = ".com:.org"; - - // OAUTH2 - public static final String AAF_OAUTH2_TOKEN_URL = "aaf_oauth2_token_url"; - public static final String AAF_OAUTH2_INTROSPECT_URL = "aaf_oauth2_introspect_url"; - public static final String AAF_ALT_OAUTH2_TOKEN_URL = "aaf_alt_oauth2_token_url"; - public static final String AAF_ALT_OAUTH2_INTROSPECT_URL = "aaf_alt_oauth2_introspect_url"; - public static final String AAF_ALT_OAUTH2_DOMAIN = "aaf_alt_oauth2_domain"; - public static final String AAF_ALT_CLIENT_ID = "aaf_alt_oauth2_client_id"; - public static final String AAF_ALT_CLIENT_SECRET = "aaf_alt_oauth2_client_secret"; - public static final String AAF_OAUTH2_HELLO_URL = "aaf_oauth2_hello_url"; - - private static final String AAF_V2_0_AAF_CON_HTTP = "org.onap.aaf.cadi.aaf.v2_0.AAFConHttp"; - - - public static void setDefaultRealm(Access access) { - try { - defaultRealm = logProp(access,Config.AAF_DEFAULT_REALM, - logProp(access,Config.BASIC_REALM, - logProp(access,HOSTNAME,InetAddress.getLocalHost().getHostName()) - ) - ); - } catch (UnknownHostException e) { - access.log(Level.INIT, "Unable to determine Hostname",e); - } - } - - public static HttpTaf configHttpTaf(Connector con, SecurityInfoC<HttpURLConnection> si, TrustChecker tc, CredVal up, Lur lur, Object ... additionalTafLurs) throws CadiException, LocatorException { - Access access = si.access; - ///////////////////////////////////////////////////// - // Setup AAFCon for any following - ///////////////////////////////////////////////////// - Class<?> aafConClass = loadClass(access,CADI_AAF_CON_DEF); - Object aafcon = null; - if(con!=null && aafConClass!=null && aafConClass.isAssignableFrom(con.getClass())) { - aafcon = con; - } else if(lur != null) { - Field f; - try { - f = lur.getClass().getField("aaf"); - aafcon = f.get(lur); - } catch (Exception e) { - access.log(Level.INIT, e); - } - } - - boolean hasDirectAAF = hasDirect("DirectAAFLur",additionalTafLurs); - // IMPORTANT! Don't attempt to load AAF Connector if there is no AAF URL - String aafURL = access.getProperty(AAF_URL,null); - if(!hasDirectAAF && aafcon==null && aafURL!=null) { - aafcon = loadAAFConnector(si, aafURL); - } - - HttpTaf taf; - // Setup Host, in case Network reports an unusable Hostname (i.e. VTiers, VPNs, etc) - String hostname = logProp(access, HOSTNAME,null); - if(hostname==null) { - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e1) { - throw new CadiException("Unable to determine Hostname",e1); - } - } - - access.log(Level.INIT, "Hostname set to",hostname); - // Get appropriate TAFs - ArrayList<HttpTaf> htlist = new ArrayList<>(); - - ///////////////////////////////////////////////////// - // Add a Denial of Service TAF - // Note: how IPs and IDs are added are up to service type. - // They call "DenialOfServiceTaf.denyIP(String) or denyID(String) - ///////////////////////////////////////////////////// - htlist.add(new DenialOfServiceTaf(access)); - - ///////////////////////////////////////////////////// - // Configure Client Cert TAF - ///////////////////////////////////////////////////// - X509Taf x509TAF = null; - String truststore = logProp(access, CADI_TRUSTSTORE,null); - if(truststore!=null) { - String truststorePwd = access.getProperty(CADI_TRUSTSTORE_PASSWORD,null); - if(truststorePwd!=null) { - if(truststorePwd.startsWith(Symm.ENC)) { - try { - access.decrypt(truststorePwd,false); - } catch (IOException e) { - throw new CadiException(CADI_TRUSTSTORE_PASSWORD + " cannot be decrypted",e); - } - } - try { - x509TAF=new X509Taf(access,lur); - htlist.add(x509TAF); - access.log(Level.INIT,"Certificate Authorization enabled"); - } catch (SecurityException | IllegalArgumentException e) { - access.log(Level.INIT,"AAFListedCertIdentity cannot be instantiated. Certificate Authorization is now disabled",e); - } catch (CertificateException e) { - access.log(Level.INIT,"Certificate Authorization failed, it is disabled",e); - } catch (NoSuchAlgorithmException e) { - access.log(Level.INIT,"Certificate Authorization failed, wrong Security Algorithm",e); - } - } - } else { - access.log(Level.INIT,"Certificate Authorization not enabled"); - } - - ///////////////////////////////////////////////////// - // Configure Basic Auth (local content) - ///////////////////////////////////////////////////// - boolean hasOAuthDirectTAF = hasDirect("DirectOAuthTAF", additionalTafLurs); - String basicRealm = logProp(access, BASIC_REALM,null); - String aafCleanup = logProp(access, AAF_USER_EXPIRES,AAF_USER_EXPIRES_DEF); // Default is 10 mins - long userExp = Long.parseLong(aafCleanup); - boolean basicWarn = "TRUE".equals(access.getProperty(BASIC_WARN,"FALSE")); - - if(!hasDirectAAF) { - HttpTaf aaftaf=null; - if(!hasOAuthDirectTAF) { - if(basicRealm!=null) { - @SuppressWarnings("unchecked") - Class<HttpTaf> obasicCls = (Class<HttpTaf>)loadClass(access,CADI_OBASIC_HTTP_TAF_DEF); - if(obasicCls!=null) { - try { - String tokenurl = logProp(access,Config.AAF_OAUTH2_TOKEN_URL, null); - String introspecturl = logProp(access,Config.AAF_OAUTH2_INTROSPECT_URL, null); - if(tokenurl==null || introspecturl==null) { - access.log(Level.INIT,"Both tokenurl and introspecturl are required. Oauth Authorization is disabled."); - } - Constructor<HttpTaf> obasicConst = obasicCls.getConstructor(PropAccess.class,String.class, String.class, String.class); - htlist.add(obasicConst.newInstance(access,basicRealm,tokenurl,introspecturl)); - access.log(Level.INIT,"Oauth supported Basic Authorization is enabled"); - } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - access.log(Level.INIT, e); - } - } else if(up!=null) { - access.log(Level.INIT,"Basic Authorization is enabled using realm",basicRealm); - // Allow warning about insecure channel to be turned off - if(!basicWarn) { - access.log(Level.INIT, "WARNING! The basicWarn property has been set to false.", - " There will be no additional warning if Basic Auth is used on an insecure channel"); - } - BasicHttpTaf bht = new BasicHttpTaf(access, up, basicRealm, userExp, basicWarn); - for(Object o : additionalTafLurs) { - if(o instanceof CredValDomain) { - bht.add((CredValDomain)o); - } - } - if(x509TAF!=null) { - x509TAF.add(bht); - } - htlist.add(bht); - access.log(Level.INIT,"Basic Authorization is enabled"); - } - } else { - access.log(Level.INIT,"Local Basic Authorization is disabled. Enable by setting basicRealm=<appropriate realm, i.e. my.att.com>"); - } - - ///////////////////////////////////////////////////// - // Configure AAF Driven Basic Auth - ///////////////////////////////////////////////////// - if(aafcon==null) { - access.log(Level.INIT,"AAF Connection (AAFcon) is null. Cannot create an AAF TAF"); - } else if(aafURL==null) { - access.log(Level.INIT,"No AAF URL in properties, Cannot create an AAF TAF"); - } else {// There's an AAF_URL... try to configure an AAF - String aafTafClassName = logProp(access, AAF_TAF_CLASS,AAF_TAF_CLASS_DEF); - // Only 2.0 available at this time - if(AAF_TAF_CLASS_DEF.equals(aafTafClassName)) { - try { - Class<?> aafTafClass = loadClass(access,aafTafClassName); - if(aafTafClass!=null) { - Constructor<?> cstr = aafTafClass.getConstructor(Connector.class,boolean.class,AbsUserCache.class); - if(cstr!=null) { - if(lur instanceof AbsUserCache) { - aaftaf = (HttpTaf)cstr.newInstance(aafcon,basicWarn,lur); - } else { - cstr = aafTafClass.getConstructor(Connector.class,boolean.class); - if(cstr!=null) { - aaftaf = (HttpTaf)cstr.newInstance(aafcon,basicWarn); - } - } - if(aaftaf==null) { - access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured"); - } else { - access.log(Level.INIT,"AAF TAF Configured to ",aafURL); - // Note: will add later, after all others configured - } - } - } else { - access.log(Level.INIT, "There is no AAF TAF class available: %s. AAF TAF not configured.",aafTafClassName); - } - } catch(Exception e) { - access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured",e); - } - } - } - } - - ///////////////////////////////////////////////////// - // Configure OAuth TAF - ///////////////////////////////////////////////////// - if(!hasOAuthDirectTAF) { - String oauthTokenUrl = logProp(access,Config.AAF_OAUTH2_TOKEN_URL,null); - Class<?> oadtClss; - try { - oadtClss = Class.forName(OAUTH_DIRECT_TAF); - } catch (ClassNotFoundException e1) { - oadtClss = null; - access.log(Level.INIT, e1); - } - if(additionalTafLurs!=null && additionalTafLurs.length>0 && (oadtClss!=null && additionalTafLurs[0].getClass().isAssignableFrom(oadtClss))) { - htlist.add((HttpTaf)additionalTafLurs[0]); - String[] array= new String[additionalTafLurs.length-1]; - if(array.length>0) { - System.arraycopy(htlist, 1, array, 0, array.length); - } - additionalTafLurs = array; - access.log(Level.INIT,"OAuth2 Direct is enabled"); - } else if(oauthTokenUrl!=null) { - String oauthIntrospectUrl = logProp(access,Config.AAF_OAUTH2_INTROSPECT_URL,null); - @SuppressWarnings("unchecked") - Class<HttpTaf> oaTCls = (Class<HttpTaf>)loadClass(access,OAUTH_HTTP_TAF); - if(oaTCls!=null) { - Class<?> oaTTmgrCls = loadClass(access, OAUTH_TOKEN_MGR); - if(oaTTmgrCls!=null) { - try { - Method oaTTmgrGI = oaTTmgrCls.getMethod("getInstance",PropAccess.class,String.class,String.class); - Object oaTTmgr = oaTTmgrGI.invoke(null /*this is static method*/,access,oauthTokenUrl,oauthIntrospectUrl); - Constructor<HttpTaf> oaTConst = oaTCls.getConstructor(Access.class,oaTTmgrCls); - htlist.add(oaTConst.newInstance(access,oaTTmgr)); - access.log(Level.INIT,"OAuth2 TAF is enabled"); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { - access.log(Level.INIT,"OAuth2HttpTaf cannot be instantiated. OAuth2 is disabled",e); - } - } - } - } else { - access.log(Level.INIT,"OAuth TAF is not configured"); - } - } - - ///////////////////////////////////////////////////// - // Adding BasicAuth (AAF) last, after other primary Cookie Based - // Needs to be before Cert... see below - ///////////////////////////////////////////////////// - if(aaftaf!=null) { - htlist.add(aaftaf); - } - } - - ///////////////////////////////////////////////////// - // Any Additional Lurs passed in Constructor - ///////////////////////////////////////////////////// - if(additionalTafLurs!=null) { - for(Object additional : additionalTafLurs) { - if(additional instanceof BasicHttpTaf) { - BasicHttpTaf ht = (BasicHttpTaf)additional; - for(Object cv : additionalTafLurs) { - if(cv instanceof CredValDomain) { - ht.add((CredValDomain)cv); - access.printf(Level.INIT,"%s Authentication is enabled",cv); - } - } - htlist.add(ht); - } else if(additional instanceof HttpTaf) { - HttpTaf ht = (HttpTaf)additional; - htlist.add(ht); - access.printf(Level.INIT,"%s Authentication is enabled",additional.getClass().getSimpleName()); - } else if(hasOAuthDirectTAF) { - Class<?> daupCls; - try { - daupCls = Class.forName("org.onap.aaf.auth.direct.DirectAAFUserPass"); - } catch (ClassNotFoundException e) { - daupCls = null; - access.log(Level.INIT, e); - } - if(daupCls != null && additional.getClass().isAssignableFrom(daupCls)) { - htlist.add(new BasicHttpTaf(access, (CredVal)additional , basicRealm, userExp, basicWarn)); - access.printf(Level.INIT,"Direct BasicAuth Authentication is enabled",additional.getClass().getSimpleName()); - } - } - } - } - - // Add BasicAuth, if any, to x509Taf - if(x509TAF!=null) { - for( HttpTaf ht : htlist) { - if(ht instanceof BasicHttpTaf) { - x509TAF.add((BasicHttpTaf)ht); - } - } - } - ///////////////////////////////////////////////////// - // Create EpiTaf from configured TAFs - ///////////////////////////////////////////////////// - if(htlist.size()==1) { - // just return the one - taf = htlist.get(0); - } else { - HttpTaf[] htarray = new HttpTaf[htlist.size()]; - htlist.toArray(htarray); - Locator<URI> locator = loadLocator(si, logProp(access, AAF_LOCATE_URL, null)); - - taf = new HttpEpiTaf(access,locator, tc, htarray); // ok to pass locator == null - String level = logProp(access, CADI_LOGLEVEL, null); - if(level!=null) { - access.setLogLevel(Level.valueOf(level)); - } - } - - return taf; - } - - public static String logProp(Access access,String tag, String def) { - String rv = access.getProperty(tag, def); - if(rv == null) { - access.log(Level.INIT,tag,"is not explicitly set"); - } else { - access.log(Level.INIT,tag,"is set to",rv); - } - return rv; - } - - public static Lur configLur(SecurityInfoC<HttpURLConnection> si, Connector con, Object ... additionalTafLurs) throws CadiException { - Access access = si.access; - List<Lur> lurs = new ArrayList<>(); - - ///////////////////////////////////////////////////// - // Configure a Local Property Based RBAC/LUR - ///////////////////////////////////////////////////// - try { - String users = access.getProperty(USERS,null); - String groups = access.getProperty(GROUPS,null); - - if(groups!=null || users!=null) { - LocalLur ll = new LocalLur(access, users, groups); // note b64==null is ok.. just means no encryption. - lurs.add(ll); - - String writeto = access.getProperty(WRITE_TO,null); - if(writeto!=null) { - String msg = UsersDump.updateUsers(writeto, ll); - if(msg!=null) { - access.log(Level.INIT,"ERROR! Error Updating ",writeto,"with roles and users:",msg); - } - } - } - } catch (IOException e) { - throw new CadiException(e); - } - - ///////////////////////////////////////////////////// - // Configure the OAuth Lur (if any) - ///////////////////////////////////////////////////// - String tokenUrl = logProp(access,AAF_OAUTH2_TOKEN_URL, null); - String introspectUrl = logProp(access,AAF_OAUTH2_INTROSPECT_URL, null); - if(tokenUrl!=null && introspectUrl !=null) { - try { - Class<?> olurCls = loadClass(access, CADI_OLUR_CLASS_DEF); - if(olurCls!=null) { - Constructor<?> olurCnst = olurCls.getConstructor(PropAccess.class,String.class,String.class); - Lur olur = (Lur)olurCnst.newInstance(access,tokenUrl,introspectUrl); - lurs.add(olur); - access.log(Level.INIT, "OAuth2 LUR enabled"); - } else { - access.log(Level.INIT,"AAF/OAuth LUR plugin is not available."); - } - } catch (NoSuchMethodException| SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - String msg = e.getMessage(); - if(msg==null && e.getCause()!=null) { - msg = e.getCause().getMessage(); - } - access.log(Level.INIT,"AAF/OAuth LUR is not instantiated.",msg,e); - } - } else { - access.log(Level.INIT, "OAuth2 Lur disabled"); - } - - if(con!=null) { // try to reutilize connector - lurs.add(con.newLur()); - } else { - ///////////////////////////////////////////////////// - // Configure the AAF Lur (if any) - ///////////////////////////////////////////////////// - String aafURL = logProp(access,AAF_URL,null); // Trigger Property - String aafEnv = access.getProperty(AAF_ENV,null); - if(aafEnv == null && aafURL!=null && access instanceof PropAccess) { // set AAF_ENV from AAF_URL - int ec = aafURL.indexOf("envContext="); - if(ec>0) { - ec += 11; // length of envContext= - int slash = aafURL.indexOf('/', ec); - if(slash>0) { - aafEnv = aafURL.substring(ec, slash); - ((PropAccess)access).setProperty(AAF_ENV, aafEnv); - access.printf(Level.INIT, "Setting aafEnv to %s from aaf_url value",aafEnv); - } - } - } - - // Don't configure AAF if it is using DirectAccess - if(!hasDirect("DirectAAFLur",additionalTafLurs)) { - if(aafURL==null) { - access.log(Level.INIT,"No AAF LUR properties, AAF will not be loaded"); - } else {// There's an AAF_URL... try to configure an AAF - String aafLurClassStr = logProp(access,AAF_LUR_CLASS,AAF_V2_0_AAF_LUR_PERM); - ////////////AAF Lur 2.0 ///////////// - if(aafLurClassStr!=null && aafLurClassStr.startsWith(AAF_V2_0)) { - try { - Object aafcon = loadAAFConnector(si, aafURL); - if(aafcon==null) { - access.log(Level.INIT,"AAF LUR class,",aafLurClassStr,"cannot be constructed without valid AAFCon object."); - } else { - Class<?> aafAbsAAFCon = loadClass(access, AAF_V2_0_AAFCON); - if(aafAbsAAFCon!=null) { - Method mNewLur = aafAbsAAFCon.getMethod("newLur"); - Object aaflur = mNewLur.invoke(aafcon); - - if(aaflur==null) { - access.log(Level.INIT,"ERROR! AAF LUR Failed construction. NOT Configured"); - } else { - access.log(Level.INIT,"AAF LUR Configured to ",aafURL); - lurs.add((Lur)aaflur); - String debugIDs = logProp(access,Config.AAF_DEBUG_IDS, null); - if(debugIDs !=null && aaflur instanceof CachingLur) { - ((CachingLur<?>)aaflur).setDebug(debugIDs); - } - } - } - } - } catch (Exception e) { - access.log(e,"AAF LUR class,",aafLurClassStr,"could not be constructed with given Constructors."); - } - } - } - } - } - - ///////////////////////////////////////////////////// - // Any Additional passed in Constructor - ///////////////////////////////////////////////////// - if(additionalTafLurs!=null) { - for(Object additional : additionalTafLurs) { - if(additional instanceof Lur) { - lurs.add((Lur)additional); - access.log(Level.INIT, additional); - } - } - } - - ///////////////////////////////////////////////////// - // Return a Lur based on how many there are... - ///////////////////////////////////////////////////// - switch(lurs.size()) { - case 0: - access.log(Level.INIT,"WARNING! No CADI LURs configured"); - // Return a NULL Lur that does nothing. - return new NullLur(); - case 1: - return lurs.get(0); // Only one, just return it, save processing - default: - // Multiple Lurs, use EpiLUR to handle - Lur[] la = new Lur[lurs.size()]; - lurs.toArray(la); - return new EpiLur(la); - } - } - - private static boolean hasDirect(String simpleClassName, Object[] additionalTafLurs) { - if(additionalTafLurs!=null) { - for(Object tf : additionalTafLurs) { - if(tf.getClass().getSimpleName().equals(simpleClassName)) { - return true; - } - } - } - return false; - } - - public static Object loadAAFConnector(SecurityInfoC<HttpURLConnection> si, String aafURL) { - Access access = si.access; - Object aafcon = null; - Class<?> aafConClass = null; - - try { - if (aafURL!=null) { - String aafConnector = access.getProperty(AAF_CONNECTOR_CLASS, AAF_V2_0_AAF_CON_HTTP); - if (AAF_V2_0_AAF_CON_HTTP.equals(aafConnector)) { - aafConClass = loadClass(access, AAF_V2_0_AAF_CON_HTTP); - if (aafConClass != null) { - for (Constructor<?> c : aafConClass.getConstructors()) { - List<Object> lo = new ArrayList<>(); - for (Class<?> pc : c.getParameterTypes()) { - if (pc.equals(Access.class)) { - lo.add(access); - } else if (pc.equals(Locator.class)) { - lo.add(loadLocator(si, aafURL)); - } - } - if (c.getParameterTypes().length != lo.size()) { - continue; // back to another Constructor - } else { - aafcon = c.newInstance(lo.toArray()); - } - break; - } - } - } - if (aafcon != null) { - String mechid = logProp(access, Config.AAF_APPID, null); - String pass = access.getProperty(Config.AAF_APPPASS, null); - if (mechid != null && pass != null) { - try { - Method basicAuth = aafConClass.getMethod("basicAuth", String.class, String.class); - basicAuth.invoke(aafcon, mechid, pass); - } catch (NoSuchMethodException nsme) { - access.log(Level.NONE, nsme); - // it's ok, don't use - } - } - } - } - } catch (Exception e) { - access.log(e, "AAF Connector could not be constructed with given Constructors."); - } - - return aafcon; - } - - public static Class<?> loadClass(Access access, String className) { - Class<?> cls=null; - try { - cls = access.classLoader().loadClass(className); - } catch (ClassNotFoundException cnfe) { - access.log(Level.NONE, cnfe); - try { - cls = access.getClass().getClassLoader().loadClass(className); - } catch (ClassNotFoundException cnfe2) { - access.log(Level.NONE, cnfe2); - // just return null - } - } - return cls; - } - - @SuppressWarnings("unchecked") - public static Locator<URI> loadLocator(SecurityInfoC<HttpURLConnection> si, final String _url) throws LocatorException { - Access access = si.access; - Locator<URI> locator = null; - if(_url==null) { - access.log(Level.INIT,"No URL passed to 'loadLocator'. Disabled"); - } else { - String url = _url; - String replacement; - int idxAAFLocateUrl; - if((idxAAFLocateUrl=_url.indexOf(AAF_LOCATE_URL_TAG))>0 && ((replacement=access.getProperty(AAF_LOCATE_URL, null))!=null)) { - StringBuilder sb = new StringBuilder(replacement); - if(!replacement.endsWith("/locate")) { - sb.append("/locate"); - } - sb.append(_url,idxAAFLocateUrl+AAF_LOCATE_URL_TAG.length(),_url.length()); - url = sb.toString(); - } - - try { - Class<?> lcls = loadClass(access,AAF_LOCATOR_CLASS_DEF); - if(lcls==null) { - throw new CadiException("Need to include aaf-cadi-aaf jar for AAFLocator"); - } - // First check for preloaded - try { - Method meth = lcls.getMethod("create",String.class); - locator = (Locator<URI>)meth.invoke(null,url); - } catch (Exception e) { - access.log(Level.INIT, e); - } - if(locator==null) { - URI locatorURI = new URI(url); - Constructor<?> cnst = lcls.getConstructor(SecurityInfoC.class,URI.class); - locator = (Locator<URI>)cnst.newInstance(new Object[] {si,locatorURI}); - int port = locatorURI.getPort(); - String portS = port<0?"":(":"+locatorURI.getPort()); - - access.log(Level.INFO, "AAFLocator enabled using " + locatorURI.getScheme() +"://"+locatorURI.getHost() + portS); - } else { - access.log(Level.INFO, "AAFLocator enabled using preloaded " + locator.getClass().getSimpleName()); - } - } catch (InvocationTargetException e) { - if(e.getTargetException() instanceof LocatorException) { - throw (LocatorException)e.getTargetException(); - } - access.log(Level.INIT,e.getTargetException().getMessage(),"AAFLocator for",url,"could not be created.",e); - } catch (Exception e) { - access.log(Level.INIT,"AAFLocator for",url,"could not be created.",e); - } - } - return locator; - } - - // Set by CSP, or is hostname. - public static String getDefaultRealm() { - return defaultRealm; - } + + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_ECDH_ECDSA_WITH_RC4_128_SHA," + + "TLS_ECDH_RSA_WITH_RC4_128_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + + "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; + + + public static final String LOCALHOST_ALLOW = "localhost_allow"; + public static final String LOCALHOST_DENY = "localhost_deny"; + + public static final String BASIC_REALM = "basic_realm"; // what is sent to the client + public static final String BASIC_WARN = "basic_warn"; // Warning of insecure channel + public static final String USERS = "local_users"; + public static final String GROUPS = "local_groups"; + public static final String WRITE_TO = "local_writeto"; // dump RBAC to local file in Tomcat Style (some apps use) + + public static final String OAUTH_CLIENT_ID="client_id"; + public static final String OAUTH_CLIENT_SECRET="client_secret"; + + public static final String AAF_ENV = "aaf_env"; + public static final String AAF_ROOT_NS = "aaf_root_ns"; + public static final String AAF_ROOT_NS_DEF = "org.osaaf.aaf"; + public static final String AAF_ROOT_COMPANY = "aaf_root_company"; + public static final String AAF_LOCATE_URL = "aaf_locate_url"; //URL for AAF locator + private static final String AAF_LOCATE_URL_TAG = "AAF_LOCATE_URL"; // Name of Above for use in Config Variables. + public static final String AAF_DEFAULT_VERSION = "2.1"; + public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration + public static final String AAF_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.service:" + AAF_DEFAULT_VERSION; + public static final String GUI_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.gui:" + AAF_DEFAULT_VERSION; + public static final String CM_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.cm:" + AAF_DEFAULT_VERSION; + public static final String FS_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.fs:" + AAF_DEFAULT_VERSION; + public static final String HELLO_URL_DEF = "https://AAF_LOCATE_URL/AAF_NS.hello:" + AAF_DEFAULT_VERSION; + public static final String OAUTH2_TOKEN_URL = "https://AAF_LOCATE_URL/AAF_NS.token:" + AAF_DEFAULT_VERSION; + public static final String OAUTH2_INTROSPECT_URL = "https://AAF_LOCATE_URL/AAF_NS.introspect:" + AAF_DEFAULT_VERSION; + + public static final String AAF_REGISTER_AS = "aaf_register_as"; + public static final String AAF_APPID = "aaf_id"; + public static final String AAF_APPPASS = "aaf_password"; + public static final String AAF_LUR_CLASS = "aaf_lur_class"; + public static final String AAF_TAF_CLASS = "aaf_taf_class"; + public static final String AAF_CONNECTOR_CLASS = "aaf_connector_class"; + public static final String AAF_LOCATOR_CLASS = "aaf_locator_class"; + public static final String AAF_CONN_TIMEOUT = "aaf_conn_timeout"; + public static final String AAF_CONN_TIMEOUT_DEF = "3000"; + public static final String AAF_CONN_IDLE_TIMEOUT = "aaf_conn_idle_timeout"; // only for Direct Jetty Access. + public static final String AAF_CONN_IDLE_TIMEOUT_DEF = "10000"; // only for Direct Jetty Access. + + // Default Classes: These are for Class loading to avoid direct compile links + public static final String AAF_TAF_CLASS_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFTaf"; + public static final String AAF_LOCATOR_CLASS_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFLocator"; + public static final String CADI_OLUR_CLASS_DEF = "org.onap.aaf.cadi.olur.OLur"; + public static final String CADI_OBASIC_HTTP_TAF_DEF = "org.onap.aaf.cadi.obasic.OBasicHttpTaf"; + public static final String CADI_AAF_CON_DEF = "org.onap.aaf.cadi.aaf.v2_0.AAFCon"; + + public static final String AAF_CALL_TIMEOUT = "aaf_timeout"; + public static final String AAF_CALL_TIMEOUT_DEF = "5000"; + public static final String AAF_USER_EXPIRES = "aaf_user_expires"; + public static final String AAF_USER_EXPIRES_DEF = "600000"; // Default is 10 mins + public static final String AAF_CLEAN_INTERVAL = "aaf_clean_interval"; + public static final String AAF_CLEAN_INTERVAL_DEF = "30000"; // Default is 30 seconds + public static final String AAF_REFRESH_TRIGGER_COUNT = "aaf_refresh_trigger_count"; + public static final String AAF_REFRESH_TRIGGER_COUNT_DEF = "3"; // Default is 10 mins + + public static final String AAF_HIGH_COUNT = "aaf_high_count"; + public static final String AAF_HIGH_COUNT_DEF = "1000"; // Default is 1000 entries + public static final String AAF_PERM_MAP = "aaf_perm_map"; + public static final String AAF_COMPONENT = "aaf_component"; + 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 GW_URL = "gw_url"; + public static final String CM_URL = "cm_url"; + public static final String CM_TRUSTED_CAS = "cm_trusted_cas"; + + public static final String PATHFILTER_URLPATTERN = "pathfilter_urlpattern"; + public static final String PATHFILTER_STACK = "pathfilter_stack"; + public static final String PATHFILTER_NS = "pathfilter_ns"; + public static final String PATHFILTER_NOT_AUTHORIZED_MSG = "pathfilter_not_authorized_msg"; + + // This one should go unpublic + public static final String AAF_DEFAULT_REALM = "aaf_default_realm"; + private static String defaultRealm="none"; + + public static final String AAF_DOMAIN_SUPPORT = "aaf_domain_support"; + public static final String AAF_DOMAIN_SUPPORT_DEF = ".com:.org"; + + // OAUTH2 + public static final String AAF_OAUTH2_TOKEN_URL = "aaf_oauth2_token_url"; + public static final String AAF_OAUTH2_INTROSPECT_URL = "aaf_oauth2_introspect_url"; + public static final String AAF_ALT_OAUTH2_TOKEN_URL = "aaf_alt_oauth2_token_url"; + public static final String AAF_ALT_OAUTH2_INTROSPECT_URL = "aaf_alt_oauth2_introspect_url"; + public static final String AAF_ALT_OAUTH2_DOMAIN = "aaf_alt_oauth2_domain"; + public static final String AAF_ALT_CLIENT_ID = "aaf_alt_oauth2_client_id"; + public static final String AAF_ALT_CLIENT_SECRET = "aaf_alt_oauth2_client_secret"; + public static final String AAF_OAUTH2_HELLO_URL = "aaf_oauth2_hello_url"; + + private static final String AAF_V2_0_AAF_CON_HTTP = "org.onap.aaf.cadi.aaf.v2_0.AAFConHttp"; + + + public static void setDefaultRealm(Access access) { + try { + defaultRealm = logProp(access,Config.AAF_DEFAULT_REALM, + logProp(access,Config.BASIC_REALM, + logProp(access,HOSTNAME,InetAddress.getLocalHost().getHostName()) + ) + ); + } catch (UnknownHostException e) { + access.log(Level.INIT, "Unable to determine Hostname",e); + } + } + + public static HttpTaf configHttpTaf(Connector con, SecurityInfoC<HttpURLConnection> si, TrustChecker tc, CredVal up, Lur lur, Object ... additionalTafLurs) throws CadiException, LocatorException { + Access access = si.access; + ///////////////////////////////////////////////////// + // Setup AAFCon for any following + ///////////////////////////////////////////////////// + Class<?> aafConClass = loadClass(access,CADI_AAF_CON_DEF); + Object aafcon = null; + if(con!=null && aafConClass!=null && aafConClass.isAssignableFrom(con.getClass())) { + aafcon = con; + } else if(lur != null) { + Field f; + try { + f = lur.getClass().getField("aaf"); + aafcon = f.get(lur); + } catch (Exception e) { + access.log(Level.INIT, e); + } + } + + boolean hasDirectAAF = hasDirect("DirectAAFLur",additionalTafLurs); + // IMPORTANT! Don't attempt to load AAF Connector if there is no AAF URL + String aafURL = access.getProperty(AAF_URL,null); + if(!hasDirectAAF && aafcon==null && aafURL!=null) { + aafcon = loadAAFConnector(si, aafURL); + } + + HttpTaf taf; + // Setup Host, in case Network reports an unusable Hostname (i.e. VTiers, VPNs, etc) + String hostname = logProp(access, HOSTNAME,null); + if(hostname==null) { + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e1) { + throw new CadiException("Unable to determine Hostname",e1); + } + } + + access.log(Level.INIT, "Hostname set to",hostname); + // Get appropriate TAFs + ArrayList<HttpTaf> htlist = new ArrayList<>(); + + ///////////////////////////////////////////////////// + // Add a Denial of Service TAF + // Note: how IPs and IDs are added are up to service type. + // They call "DenialOfServiceTaf.denyIP(String) or denyID(String) + ///////////////////////////////////////////////////// + htlist.add(new DenialOfServiceTaf(access)); + + ///////////////////////////////////////////////////// + // Configure Client Cert TAF + ///////////////////////////////////////////////////// + X509Taf x509TAF = null; + String truststore = logProp(access, CADI_TRUSTSTORE,null); + if(truststore!=null) { + String truststorePwd = access.getProperty(CADI_TRUSTSTORE_PASSWORD,null); + if(truststorePwd!=null) { + if(truststorePwd.startsWith(Symm.ENC)) { + try { + access.decrypt(truststorePwd,false); + } catch (IOException e) { + throw new CadiException(CADI_TRUSTSTORE_PASSWORD + " cannot be decrypted",e); + } + } + try { + x509TAF=new X509Taf(access,lur); + htlist.add(x509TAF); + access.log(Level.INIT,"Certificate Authorization enabled"); + } catch (SecurityException | IllegalArgumentException e) { + access.log(Level.INIT,"AAFListedCertIdentity cannot be instantiated. Certificate Authorization is now disabled",e); + } catch (CertificateException e) { + access.log(Level.INIT,"Certificate Authorization failed, it is disabled",e); + } catch (NoSuchAlgorithmException e) { + access.log(Level.INIT,"Certificate Authorization failed, wrong Security Algorithm",e); + } + } + } else { + access.log(Level.INIT,"Certificate Authorization not enabled"); + } + + ///////////////////////////////////////////////////// + // Configure Basic Auth (local content) + ///////////////////////////////////////////////////// + boolean hasOAuthDirectTAF = hasDirect("DirectOAuthTAF", additionalTafLurs); + String basicRealm = logProp(access, BASIC_REALM,null); + String aafCleanup = logProp(access, AAF_USER_EXPIRES,AAF_USER_EXPIRES_DEF); // Default is 10 mins + long userExp = Long.parseLong(aafCleanup); + boolean basicWarn = "TRUE".equals(access.getProperty(BASIC_WARN,"FALSE")); + + if(!hasDirectAAF) { + HttpTaf aaftaf=null; + if(!hasOAuthDirectTAF) { + if(basicRealm!=null) { + @SuppressWarnings("unchecked") + Class<HttpTaf> obasicCls = (Class<HttpTaf>)loadClass(access,CADI_OBASIC_HTTP_TAF_DEF); + if(obasicCls!=null) { + try { + String tokenurl = logProp(access,Config.AAF_OAUTH2_TOKEN_URL, null); + String introspecturl = logProp(access,Config.AAF_OAUTH2_INTROSPECT_URL, null); + if(tokenurl==null || introspecturl==null) { + access.log(Level.INIT,"Both tokenurl and introspecturl are required. Oauth Authorization is disabled."); + } + Constructor<HttpTaf> obasicConst = obasicCls.getConstructor(PropAccess.class,String.class, String.class, String.class); + htlist.add(obasicConst.newInstance(access,basicRealm,tokenurl,introspecturl)); + access.log(Level.INIT,"Oauth supported Basic Authorization is enabled"); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + access.log(Level.INIT, e); + } + } else if(up!=null) { + access.log(Level.INIT,"Basic Authorization is enabled using realm",basicRealm); + // Allow warning about insecure channel to be turned off + if(!basicWarn) { + access.log(Level.INIT, "WARNING! The basicWarn property has been set to false.", + " There will be no additional warning if Basic Auth is used on an insecure channel"); + } + BasicHttpTaf bht = new BasicHttpTaf(access, up, basicRealm, userExp, basicWarn); + for(Object o : additionalTafLurs) { + if(o instanceof CredValDomain) { + bht.add((CredValDomain)o); + } + } + if(x509TAF!=null) { + x509TAF.add(bht); + } + htlist.add(bht); + access.log(Level.INIT,"Basic Authorization is enabled"); + } + } else { + access.log(Level.INIT,"Local Basic Authorization is disabled. Enable by setting basicRealm=<appropriate realm, i.e. my.att.com>"); + } + + ///////////////////////////////////////////////////// + // Configure AAF Driven Basic Auth + ///////////////////////////////////////////////////// + if(aafcon==null) { + access.log(Level.INIT,"AAF Connection (AAFcon) is null. Cannot create an AAF TAF"); + } else if(aafURL==null) { + access.log(Level.INIT,"No AAF URL in properties, Cannot create an AAF TAF"); + } else {// There's an AAF_URL... try to configure an AAF + String aafTafClassName = logProp(access, AAF_TAF_CLASS,AAF_TAF_CLASS_DEF); + // Only 2.0 available at this time + if(AAF_TAF_CLASS_DEF.equals(aafTafClassName)) { + try { + Class<?> aafTafClass = loadClass(access,aafTafClassName); + if(aafTafClass!=null) { + Constructor<?> cstr = aafTafClass.getConstructor(Connector.class,boolean.class,AbsUserCache.class); + if(cstr!=null) { + if(lur instanceof AbsUserCache) { + aaftaf = (HttpTaf)cstr.newInstance(aafcon,basicWarn,lur); + } else { + cstr = aafTafClass.getConstructor(Connector.class,boolean.class); + if(cstr!=null) { + aaftaf = (HttpTaf)cstr.newInstance(aafcon,basicWarn); + } + } + if(aaftaf==null) { + access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured"); + } else { + access.log(Level.INIT,"AAF TAF Configured to ",aafURL); + // Note: will add later, after all others configured + } + } + } else { + access.log(Level.INIT, "There is no AAF TAF class available: %s. AAF TAF not configured.",aafTafClassName); + } + } catch(Exception e) { + access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured",e); + } + } + } + } + + ///////////////////////////////////////////////////// + // Configure OAuth TAF + ///////////////////////////////////////////////////// + if(!hasOAuthDirectTAF) { + String oauthTokenUrl = logProp(access,Config.AAF_OAUTH2_TOKEN_URL,null); + Class<?> oadtClss; + try { + oadtClss = Class.forName(OAUTH_DIRECT_TAF); + } catch (ClassNotFoundException e1) { + oadtClss = null; + access.log(Level.INIT, e1); + } + if(additionalTafLurs!=null && additionalTafLurs.length>0 && (oadtClss!=null && additionalTafLurs[0].getClass().isAssignableFrom(oadtClss))) { + htlist.add((HttpTaf)additionalTafLurs[0]); + String[] array= new String[additionalTafLurs.length-1]; + if(array.length>0) { + System.arraycopy(htlist, 1, array, 0, array.length); + } + additionalTafLurs = array; + access.log(Level.INIT,"OAuth2 Direct is enabled"); + } else if(oauthTokenUrl!=null) { + String oauthIntrospectUrl = logProp(access,Config.AAF_OAUTH2_INTROSPECT_URL,null); + @SuppressWarnings("unchecked") + Class<HttpTaf> oaTCls = (Class<HttpTaf>)loadClass(access,OAUTH_HTTP_TAF); + if(oaTCls!=null) { + Class<?> oaTTmgrCls = loadClass(access, OAUTH_TOKEN_MGR); + if(oaTTmgrCls!=null) { + try { + Method oaTTmgrGI = oaTTmgrCls.getMethod("getInstance",PropAccess.class,String.class,String.class); + Object oaTTmgr = oaTTmgrGI.invoke(null /*this is static method*/,access,oauthTokenUrl,oauthIntrospectUrl); + Constructor<HttpTaf> oaTConst = oaTCls.getConstructor(Access.class,oaTTmgrCls); + htlist.add(oaTConst.newInstance(access,oaTTmgr)); + access.log(Level.INIT,"OAuth2 TAF is enabled"); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { + access.log(Level.INIT,"OAuth2HttpTaf cannot be instantiated. OAuth2 is disabled",e); + } + } + } + } else { + access.log(Level.INIT,"OAuth TAF is not configured"); + } + } + + ///////////////////////////////////////////////////// + // Adding BasicAuth (AAF) last, after other primary Cookie Based + // Needs to be before Cert... see below + ///////////////////////////////////////////////////// + if(aaftaf!=null) { + htlist.add(aaftaf); + } + } + + ///////////////////////////////////////////////////// + // Any Additional Lurs passed in Constructor + ///////////////////////////////////////////////////// + if(additionalTafLurs!=null) { + for(Object additional : additionalTafLurs) { + if(additional instanceof BasicHttpTaf) { + BasicHttpTaf ht = (BasicHttpTaf)additional; + for(Object cv : additionalTafLurs) { + if(cv instanceof CredValDomain) { + ht.add((CredValDomain)cv); + access.printf(Level.INIT,"%s Authentication is enabled",cv); + } + } + htlist.add(ht); + } else if(additional instanceof HttpTaf) { + HttpTaf ht = (HttpTaf)additional; + htlist.add(ht); + access.printf(Level.INIT,"%s Authentication is enabled",additional.getClass().getSimpleName()); + } else if(hasOAuthDirectTAF) { + Class<?> daupCls; + try { + daupCls = Class.forName("org.onap.aaf.auth.direct.DirectAAFUserPass"); + } catch (ClassNotFoundException e) { + daupCls = null; + access.log(Level.INIT, e); + } + if(daupCls != null && additional.getClass().isAssignableFrom(daupCls)) { + htlist.add(new BasicHttpTaf(access, (CredVal)additional , basicRealm, userExp, basicWarn)); + access.printf(Level.INIT,"Direct BasicAuth Authentication is enabled",additional.getClass().getSimpleName()); + } + } + } + } + + // Add BasicAuth, if any, to x509Taf + if(x509TAF!=null) { + for( HttpTaf ht : htlist) { + if(ht instanceof BasicHttpTaf) { + x509TAF.add((BasicHttpTaf)ht); + } + } + } + ///////////////////////////////////////////////////// + // Create EpiTaf from configured TAFs + ///////////////////////////////////////////////////// + if(htlist.size()==1) { + // just return the one + taf = htlist.get(0); + } else { + HttpTaf[] htarray = new HttpTaf[htlist.size()]; + htlist.toArray(htarray); + Locator<URI> locator = loadLocator(si, logProp(access, AAF_LOCATE_URL, null)); + + taf = new HttpEpiTaf(access,locator, tc, htarray); // ok to pass locator == null + String level = logProp(access, CADI_LOGLEVEL, null); + if(level!=null) { + access.setLogLevel(Level.valueOf(level)); + } + } + + return taf; + } + + public static String logProp(Access access,String tag, String def) { + String rv = access.getProperty(tag, def); + if(rv == null) { + access.log(Level.INIT,tag,"is not explicitly set"); + } else { + access.log(Level.INIT,tag,"is set to",rv); + } + return rv; + } + + public static Lur configLur(SecurityInfoC<HttpURLConnection> si, Connector con, Object ... additionalTafLurs) throws CadiException { + Access access = si.access; + List<Lur> lurs = new ArrayList<>(); + + ///////////////////////////////////////////////////// + // Configure a Local Property Based RBAC/LUR + ///////////////////////////////////////////////////// + try { + String users = access.getProperty(USERS,null); + String groups = access.getProperty(GROUPS,null); + + if(groups!=null || users!=null) { + LocalLur ll = new LocalLur(access, users, groups); // note b64==null is ok.. just means no encryption. + lurs.add(ll); + + String writeto = access.getProperty(WRITE_TO,null); + if(writeto!=null) { + String msg = UsersDump.updateUsers(writeto, ll); + if(msg!=null) { + access.log(Level.INIT,"ERROR! Error Updating ",writeto,"with roles and users:",msg); + } + } + } + } catch (IOException e) { + throw new CadiException(e); + } + + ///////////////////////////////////////////////////// + // Configure the OAuth Lur (if any) + ///////////////////////////////////////////////////// + String tokenUrl = logProp(access,AAF_OAUTH2_TOKEN_URL, null); + String introspectUrl = logProp(access,AAF_OAUTH2_INTROSPECT_URL, null); + if(tokenUrl!=null && introspectUrl !=null) { + try { + Class<?> olurCls = loadClass(access, CADI_OLUR_CLASS_DEF); + if(olurCls!=null) { + Constructor<?> olurCnst = olurCls.getConstructor(PropAccess.class,String.class,String.class); + Lur olur = (Lur)olurCnst.newInstance(access,tokenUrl,introspectUrl); + lurs.add(olur); + access.log(Level.INIT, "OAuth2 LUR enabled"); + } else { + access.log(Level.INIT,"AAF/OAuth LUR plugin is not available."); + } + } catch (NoSuchMethodException| SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + String msg = e.getMessage(); + if(msg==null && e.getCause()!=null) { + msg = e.getCause().getMessage(); + } + access.log(Level.INIT,"AAF/OAuth LUR is not instantiated.",msg,e); + } + } else { + access.log(Level.INIT, "OAuth2 Lur disabled"); + } + + if(con!=null) { // try to reutilize connector + lurs.add(con.newLur()); + } else { + ///////////////////////////////////////////////////// + // Configure the AAF Lur (if any) + ///////////////////////////////////////////////////// + String aafURL = logProp(access,AAF_URL,null); // Trigger Property + String aafEnv = access.getProperty(AAF_ENV,null); + if(aafEnv == null && aafURL!=null && access instanceof PropAccess) { // set AAF_ENV from AAF_URL + int ec = aafURL.indexOf("envContext="); + if(ec>0) { + ec += 11; // length of envContext= + int slash = aafURL.indexOf('/', ec); + if(slash>0) { + aafEnv = aafURL.substring(ec, slash); + ((PropAccess)access).setProperty(AAF_ENV, aafEnv); + access.printf(Level.INIT, "Setting aafEnv to %s from aaf_url value",aafEnv); + } + } + } + + // Don't configure AAF if it is using DirectAccess + if(!hasDirect("DirectAAFLur",additionalTafLurs)) { + if(aafURL==null) { + access.log(Level.INIT,"No AAF LUR properties, AAF will not be loaded"); + } else {// There's an AAF_URL... try to configure an AAF + String aafLurClassStr = logProp(access,AAF_LUR_CLASS,AAF_V2_0_AAF_LUR_PERM); + ////////////AAF Lur 2.0 ///////////// + if(aafLurClassStr!=null && aafLurClassStr.startsWith(AAF_V2_0)) { + try { + Object aafcon = loadAAFConnector(si, aafURL); + if(aafcon==null) { + access.log(Level.INIT,"AAF LUR class,",aafLurClassStr,"cannot be constructed without valid AAFCon object."); + } else { + Class<?> aafAbsAAFCon = loadClass(access, AAF_V2_0_AAFCON); + if(aafAbsAAFCon!=null) { + Method mNewLur = aafAbsAAFCon.getMethod("newLur"); + Object aaflur = mNewLur.invoke(aafcon); + + if(aaflur==null) { + access.log(Level.INIT,"ERROR! AAF LUR Failed construction. NOT Configured"); + } else { + access.log(Level.INIT,"AAF LUR Configured to ",aafURL); + lurs.add((Lur)aaflur); + String debugIDs = logProp(access,Config.AAF_DEBUG_IDS, null); + if(debugIDs !=null && aaflur instanceof CachingLur) { + ((CachingLur<?>)aaflur).setDebug(debugIDs); + } + } + } + } + } catch (Exception e) { + access.log(e,"AAF LUR class,",aafLurClassStr,"could not be constructed with given Constructors."); + } + } + } + } + } + + ///////////////////////////////////////////////////// + // Any Additional passed in Constructor + ///////////////////////////////////////////////////// + if(additionalTafLurs!=null) { + for(Object additional : additionalTafLurs) { + if(additional instanceof Lur) { + lurs.add((Lur)additional); + access.log(Level.INIT, additional); + } + } + } + + ///////////////////////////////////////////////////// + // Return a Lur based on how many there are... + ///////////////////////////////////////////////////// + switch(lurs.size()) { + case 0: + access.log(Level.INIT,"WARNING! No CADI LURs configured"); + // Return a NULL Lur that does nothing. + return new NullLur(); + case 1: + return lurs.get(0); // Only one, just return it, save processing + default: + // Multiple Lurs, use EpiLUR to handle + Lur[] la = new Lur[lurs.size()]; + lurs.toArray(la); + return new EpiLur(la); + } + } + + private static boolean hasDirect(String simpleClassName, Object[] additionalTafLurs) { + if(additionalTafLurs!=null) { + for(Object tf : additionalTafLurs) { + if(tf.getClass().getSimpleName().equals(simpleClassName)) { + return true; + } + } + } + return false; + } + + public static Object loadAAFConnector(SecurityInfoC<HttpURLConnection> si, String aafURL) { + Access access = si.access; + Object aafcon = null; + Class<?> aafConClass = null; + + try { + if (aafURL!=null) { + String aafConnector = access.getProperty(AAF_CONNECTOR_CLASS, AAF_V2_0_AAF_CON_HTTP); + if (AAF_V2_0_AAF_CON_HTTP.equals(aafConnector)) { + aafConClass = loadClass(access, AAF_V2_0_AAF_CON_HTTP); + if (aafConClass != null) { + for (Constructor<?> c : aafConClass.getConstructors()) { + List<Object> lo = new ArrayList<>(); + for (Class<?> pc : c.getParameterTypes()) { + if (pc.equals(Access.class)) { + lo.add(access); + } else if (pc.equals(Locator.class)) { + lo.add(loadLocator(si, aafURL)); + } + } + if (c.getParameterTypes().length != lo.size()) { + continue; // back to another Constructor + } else { + aafcon = c.newInstance(lo.toArray()); + } + break; + } + } + } + if (aafcon != null) { + String mechid = logProp(access, Config.AAF_APPID, null); + String pass = access.getProperty(Config.AAF_APPPASS, null); + if (mechid != null && pass != null) { + try { + Method basicAuth = aafConClass.getMethod("basicAuth", String.class, String.class); + basicAuth.invoke(aafcon, mechid, pass); + } catch (NoSuchMethodException nsme) { + access.log(Level.NONE, nsme); + // it's ok, don't use + } + } + } + } + } catch (Exception e) { + access.log(e, "AAF Connector could not be constructed with given Constructors."); + } + + return aafcon; + } + + public static Class<?> loadClass(Access access, String className) { + Class<?> cls=null; + try { + cls = access.classLoader().loadClass(className); + } catch (ClassNotFoundException cnfe) { + access.log(Level.NONE, cnfe); + try { + cls = access.getClass().getClassLoader().loadClass(className); + } catch (ClassNotFoundException cnfe2) { + access.log(Level.NONE, cnfe2); + // just return null + } + } + return cls; + } + + @SuppressWarnings("unchecked") + public static Locator<URI> loadLocator(SecurityInfoC<HttpURLConnection> si, final String _url) throws LocatorException { + Access access = si.access; + Locator<URI> locator = null; + if(_url==null) { + access.log(Level.INIT,"No URL passed to 'loadLocator'. Disabled"); + } else { + String url = _url; + String replacement; + int idxAAFLocateUrl; + if((idxAAFLocateUrl=_url.indexOf(AAF_LOCATE_URL_TAG))>0 && ((replacement=access.getProperty(AAF_LOCATE_URL, null))!=null)) { + StringBuilder sb = new StringBuilder(replacement); + if(!replacement.endsWith("/locate")) { + sb.append("/locate"); + } + sb.append(_url,idxAAFLocateUrl+AAF_LOCATE_URL_TAG.length(),_url.length()); + url = sb.toString(); + } + + try { + Class<?> lcls = loadClass(access,AAF_LOCATOR_CLASS_DEF); + if(lcls==null) { + throw new CadiException("Need to include aaf-cadi-aaf jar for AAFLocator"); + } + // First check for preloaded + try { + Method meth = lcls.getMethod("create",String.class); + locator = (Locator<URI>)meth.invoke(null,url); + } catch (Exception e) { + access.log(Level.INIT, e); + } + if(locator==null) { + URI locatorURI = new URI(url); + Constructor<?> cnst = lcls.getConstructor(SecurityInfoC.class,URI.class); + locator = (Locator<URI>)cnst.newInstance(new Object[] {si,locatorURI}); + int port = locatorURI.getPort(); + String portS = port<0?"":(":"+locatorURI.getPort()); + + access.log(Level.INFO, "AAFLocator enabled using " + locatorURI.getScheme() +"://"+locatorURI.getHost() + portS); + } else { + access.log(Level.INFO, "AAFLocator enabled using preloaded " + locator.getClass().getSimpleName()); + } + } catch (InvocationTargetException e) { + if(e.getTargetException() instanceof LocatorException) { + throw (LocatorException)e.getTargetException(); + } + access.log(Level.INIT,e.getTargetException().getMessage(),"AAFLocator for",url,"could not be created.",e); + } catch (Exception e) { + access.log(Level.INIT,"AAFLocator for",url,"could not be created.",e); + } + } + return locator; + } + + // Set by CSP, or is hostname. + public static String getDefaultRealm() { + return defaultRealm; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Get.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Get.java index dfb7b4d3..56ac4dd5 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Get.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Get.java @@ -27,71 +27,71 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.Access.Level; public interface Get { - public String get(String name, String def, boolean print); - - - /** - * A class for Getting info out of "JavaBean" format - * @author Jonathan - * - */ - public static class Bean implements Get { - private Object bean; - private Class<?> bc; - private Class<?>[] params; - private Object[] args; - - public Bean(Object bean) { - this.bean = bean; - bc = bean.getClass(); - params = new Class<?>[0]; // note, this will allow to go out of scope after config - args = new Object[0]; - } - - public String get(String name, String def, boolean print) { - String str = null; - String gname = "get"+Character.toUpperCase(name.charAt(0))+name.substring(1); - try { - Method meth = bc.getMethod(gname, params); - Object obj = meth.invoke(bean, args); - str = obj==null?null:obj.toString(); // easy string convert... - } catch (Exception e) { - } - - // Take def if nothing else - if(str==null) { - str = def; - // don't log defaults - } else { - str = str.trim(); // this is vital in Property File based values, as spaces can hide easily - } - // Note: Can't log during configuration - return str; - } - } + public String get(String name, String def, boolean print); + + + /** + * A class for Getting info out of "JavaBean" format + * @author Jonathan + * + */ + public static class Bean implements Get { + private Object bean; + private Class<?> bc; + private Class<?>[] params; + private Object[] args; + + public Bean(Object bean) { + this.bean = bean; + bc = bean.getClass(); + params = new Class<?>[0]; // note, this will allow to go out of scope after config + args = new Object[0]; + } + + public String get(String name, String def, boolean print) { + String str = null; + String gname = "get"+Character.toUpperCase(name.charAt(0))+name.substring(1); + try { + Method meth = bc.getMethod(gname, params); + Object obj = meth.invoke(bean, args); + str = obj==null?null:obj.toString(); // easy string convert... + } catch (Exception e) { + } + + // Take def if nothing else + if(str==null) { + str = def; + // don't log defaults + } else { + str = str.trim(); // this is vital in Property File based values, as spaces can hide easily + } + // Note: Can't log during configuration + return str; + } + } - public static Get NULL = new Get() { - public String get(String name, String def, boolean print) { - return def; - } - }; + public static Get NULL = new Get() { + public String get(String name, String def, boolean print) { + return def; + } + }; - public static class AccessGet implements Get { - private Access access; - public AccessGet(Access access) { - this.access = access; - } - public String get(String name, String def, boolean print) { - String gotten = access.getProperty(name, def); - if(print) { - if(gotten == null) { - access.log(Level.INIT,name, "is not set"); - } else { - access.log(Level.INIT,name, "is set to", gotten); - } - } - return gotten; - } - } + public static class AccessGet implements Get { + private Access access; + public AccessGet(Access access) { + this.access = access; + } + public String get(String name, String def, boolean print) { + String gotten = access.getProperty(name, def); + if(print) { + if(gotten == null) { + access.log(Level.INIT,name, "is not set"); + } else { + access.log(Level.INIT,name, "is set to", gotten); + } + } + return gotten; + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java index b44de05f..4655dfa1 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java @@ -24,34 +24,34 @@ package org.onap.aaf.cadi.config; import org.onap.aaf.cadi.PropAccess; public class GetAccess extends PropAccess { - private final Get getter; - - public GetAccess(Get getter) { - super(new String[]{"cadi_prop_files="+getter.get("cadi_prop_files", null, true)}); - this.getter = getter; - } - - /* (non-Javadoc) - * @see org.onap.aaf.cadi.PropAccess#getProperty(java.lang.String, java.lang.String) - */ - @Override - public String getProperty(String tag, String def) { - String rv; - rv = super.getProperty(tag, null); - if(rv==null && getter!=null) { - rv = getter.get(tag, null, true); - } - return rv==null?def:rv; - } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.PropAccess#getProperty(java.lang.String) - */ - @Override - public String getProperty(String tag) { - return getProperty(tag, null); - } + private final Get getter; + + public GetAccess(Get getter) { + super(new String[]{"cadi_prop_files="+getter.get("cadi_prop_files", null, true)}); + this.getter = getter; + } + + /* (non-Javadoc) + * @see org.onap.aaf.cadi.PropAccess#getProperty(java.lang.String, java.lang.String) + */ + @Override + public String getProperty(String tag, String def) { + String rv; + rv = super.getProperty(tag, null); + if(rv==null && getter!=null) { + rv = getter.get(tag, null, true); + } + return rv==null?def:rv; + } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.PropAccess#getProperty(java.lang.String) + */ + @Override + public String getProperty(String tag) { + return getProperty(tag, null); + } - public Get get() { - return getter; - } + public Get get() { + return getter; + } } 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 f63de20c..bb9981bf 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 @@ -55,230 +55,230 @@ import org.onap.aaf.cadi.util.MaskFormatException; import org.onap.aaf.cadi.util.NetMask; public class SecurityInfo { - private static final String SECURITY_ALGO = "RSA"; - private static final String HTTPS_PROTOCOLS = "https.protocols"; - private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols"; + private static final String SECURITY_ALGO = "RSA"; + private static final String HTTPS_PROTOCOLS = "https.protocols"; + private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols"; - public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; - public static final String REGEX_COMMA = "\\s*,\\s*"; - public static final String SSL_KEY_MANAGER_FACTORY_ALGORITHM; - - private SSLSocketFactory socketFactory; - private X509KeyManager[] x509KeyManager; - private X509TrustManager[] x509TrustManager; - public final String defaultAlias; - private NetMask[] trustMasks; - private SSLContext context; - private HostnameVerifier maskHV; - public final Access access; + public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; + public static final String REGEX_COMMA = "\\s*,\\s*"; + public static final String SSL_KEY_MANAGER_FACTORY_ALGORITHM; + + private SSLSocketFactory socketFactory; + private X509KeyManager[] x509KeyManager; + private X509TrustManager[] x509TrustManager; + public final String defaultAlias; + private NetMask[] trustMasks; + private SSLContext context; + private HostnameVerifier maskHV; + public final Access access; - // Change Key Algorithms for IBM's VM. Could put in others, if needed. - static { - if ("IBM Corporation".equalsIgnoreCase(System.getProperty("java.vm.vendor"))) { - SSL_KEY_MANAGER_FACTORY_ALGORITHM = "IbmX509"; - } else { - SSL_KEY_MANAGER_FACTORY_ALGORITHM = "SunX509"; - } - } - + // Change Key Algorithms for IBM's VM. Could put in others, if needed. + static { + if ("IBM Corporation".equalsIgnoreCase(System.getProperty("java.vm.vendor"))) { + SSL_KEY_MANAGER_FACTORY_ALGORITHM = "IbmX509"; + } else { + SSL_KEY_MANAGER_FACTORY_ALGORITHM = "SunX509"; + } + } + - public SecurityInfo(final Access access) throws CadiException { - try { - this.access = access; - // reuse DME2 Properties for convenience if specific Properties don't exist - - initializeKeyManager(); - - initializeTrustManager(); - - defaultAlias = access.getProperty(Config.CADI_ALIAS, null); - - initializeTrustMasks(); + public SecurityInfo(final Access access) throws CadiException { + try { + this.access = access; + // reuse DME2 Properties for convenience if specific Properties don't exist + + initializeKeyManager(); + + initializeTrustManager(); + + defaultAlias = access.getProperty(Config.CADI_ALIAS, null); + + initializeTrustMasks(); - String httpsProtocols = Config.logProp(access, Config.CADI_PROTOCOLS, - access.getProperty(HTTPS_PROTOCOLS, HTTPS_PROTOCOLS_DEFAULT) - ); - System.setProperty(HTTPS_PROTOCOLS, httpsProtocols); - System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, httpsProtocols); - if ("1.7".equals(System.getProperty("java.specification.version")) && httpsProtocols.contains("TLSv1.2")) { - System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); - } + String httpsProtocols = Config.logProp(access, Config.CADI_PROTOCOLS, + access.getProperty(HTTPS_PROTOCOLS, HTTPS_PROTOCOLS_DEFAULT) + ); + System.setProperty(HTTPS_PROTOCOLS, httpsProtocols); + System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, httpsProtocols); + if ("1.7".equals(System.getProperty("java.specification.version")) && httpsProtocols.contains("TLSv1.2")) { + System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); + } - context = SSLContext.getInstance("TLS"); - context.init(x509KeyManager, x509TrustManager, null); - SSLContext.setDefault(context); - socketFactory = context.getSocketFactory(); - } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) { - throw new CadiException(e); - } - } + context = SSLContext.getInstance("TLS"); + context.init(x509KeyManager, x509TrustManager, null); + SSLContext.setDefault(context); + socketFactory = context.getSocketFactory(); + } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) { + throw new CadiException(e); + } + } - /** - * @return the scf - */ - public SSLSocketFactory getSSLSocketFactory() { - return socketFactory; - } + /** + * @return the scf + */ + public SSLSocketFactory getSSLSocketFactory() { + return socketFactory; + } - public SSLContext getSSLContext() { - return context; - } + public SSLContext getSSLContext() { + return context; + } - /** - * @return the km - */ - public X509KeyManager[] getKeyManagers() { - return x509KeyManager; - } + /** + * @return the km + */ + public X509KeyManager[] getKeyManagers() { + return x509KeyManager; + } - public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException { - for (X509TrustManager xtm : x509TrustManager) { - xtm.checkClientTrusted(certarr, SECURITY_ALGO); - } - } + public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException { + for (X509TrustManager xtm : x509TrustManager) { + xtm.checkClientTrusted(certarr, SECURITY_ALGO); + } + } - public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException { - for (X509TrustManager xtm : x509TrustManager) { - xtm.checkServerTrusted(certarr, SECURITY_ALGO); - } - } + public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException { + for (X509TrustManager xtm : x509TrustManager) { + xtm.checkServerTrusted(certarr, SECURITY_ALGO); + } + } - public void setSocketFactoryOn(HttpsURLConnection hsuc) { - hsuc.setSSLSocketFactory(socketFactory); - if (maskHV != null && !maskHV.equals(hsuc.getHostnameVerifier())) { - hsuc.setHostnameVerifier(maskHV); - } - } - - protected void initializeKeyManager() throws CadiException, IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException { - String keyStore = access.getProperty(Config.CADI_KEYSTORE, null); - if (keyStore != null && !new File(keyStore).exists()) { - throw new CadiException(keyStore + " does not exist"); - } + public void setSocketFactoryOn(HttpsURLConnection hsuc) { + hsuc.setSSLSocketFactory(socketFactory); + if (maskHV != null && !maskHV.equals(hsuc.getHostnameVerifier())) { + hsuc.setHostnameVerifier(maskHV); + } + } + + protected void initializeKeyManager() throws CadiException, IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException { + String keyStore = access.getProperty(Config.CADI_KEYSTORE, null); + if (keyStore != null && !new File(keyStore).exists()) { + throw new CadiException(keyStore + " does not exist"); + } - String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null); - keyStorePasswd = (keyStorePasswd == null) ? null : access.decrypt(keyStorePasswd, false); - if (keyStore == null || keyStorePasswd == null) { - x509KeyManager = new X509KeyManager[0]; - return; - } + String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null); + keyStorePasswd = (keyStorePasswd == null) ? null : access.decrypt(keyStorePasswd, false); + if (keyStore == null || keyStorePasswd == null) { + x509KeyManager = new X509KeyManager[0]; + return; + } - String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD, null); - keyPasswd = (keyPasswd == null) ? keyStorePasswd : access.decrypt(keyPasswd, false); + String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD, null); + keyPasswd = (keyPasswd == null) ? keyStorePasswd : access.decrypt(keyPasswd, false); - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM); - ArrayList<X509KeyManager> keyManagers = new ArrayList<>(); - File file; - for (String ksname : keyStore.split(REGEX_COMMA)) { - String keystoreFormat; - if (ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) { - keystoreFormat = "PKCS12"; - } else { - keystoreFormat = "JKS"; - } + ArrayList<X509KeyManager> keyManagers = new ArrayList<>(); + File file; + for (String ksname : keyStore.split(REGEX_COMMA)) { + String keystoreFormat; + if (ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) { + keystoreFormat = "PKCS12"; + } else { + keystoreFormat = "JKS"; + } - file = new File(ksname); - if (file.exists()) { - FileInputStream fis = new FileInputStream(file); - try { - KeyStore ks = KeyStore.getInstance(keystoreFormat); - ks.load(fis, keyStorePasswd.toCharArray()); - keyManagerFactory.init(ks, keyPasswd.toCharArray()); - } finally { - fis.close(); - } - } - } - for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) { - if (keyManager instanceof X509KeyManager) { - keyManagers.add((X509KeyManager)keyManager); - } - } - x509KeyManager = new X509KeyManager[keyManagers.size()]; - keyManagers.toArray(x509KeyManager); - } + file = new File(ksname); + if (file.exists()) { + FileInputStream fis = new FileInputStream(file); + try { + KeyStore ks = KeyStore.getInstance(keystoreFormat); + ks.load(fis, keyStorePasswd.toCharArray()); + keyManagerFactory.init(ks, keyPasswd.toCharArray()); + } finally { + fis.close(); + } + } + } + for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) { + if (keyManager instanceof X509KeyManager) { + keyManagers.add((X509KeyManager)keyManager); + } + } + x509KeyManager = new X509KeyManager[keyManagers.size()]; + keyManagers.toArray(x509KeyManager); + } - protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException { - String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null); - if (trustStore != null && !new File(trustStore).exists()) { - throw new CadiException(trustStore + " does not exist"); - } + protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException { + String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null); + if (trustStore != null && !new File(trustStore).exists()) { + throw new CadiException(trustStore + " does not exist"); + } - if (trustStore == null) { - return; - } + if (trustStore == null) { + return; + } - String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null); - trustStorePasswd = (trustStorePasswd == null) ? "changeit"/*defacto Java Trust Pass*/ : access.decrypt(trustStorePasswd, false); + String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null); + trustStorePasswd = (trustStorePasswd == null) ? "changeit"/*defacto Java Trust Pass*/ : access.decrypt(trustStorePasswd, false); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM); - File file; - for (String trustStoreName : trustStore.split(REGEX_COMMA)) { - file = new File(trustStoreName); - if (file.exists()) { - FileInputStream fis = new FileInputStream(file); - try { - KeyStore ts = KeyStore.getInstance("JKS"); - ts.load(fis, trustStorePasswd.toCharArray()); - trustManagerFactory.init(ts); - } finally { - fis.close(); - } - } - } + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM); + File file; + for (String trustStoreName : trustStore.split(REGEX_COMMA)) { + file = new File(trustStoreName); + if (file.exists()) { + FileInputStream fis = new FileInputStream(file); + try { + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(fis, trustStorePasswd.toCharArray()); + trustManagerFactory.init(ts); + } finally { + fis.close(); + } + } + } - TrustManager trustManagers[] = trustManagerFactory.getTrustManagers(); - if (trustManagers == null || trustManagers.length == 0) { - return; - } + TrustManager trustManagers[] = trustManagerFactory.getTrustManagers(); + if (trustManagers == null || trustManagers.length == 0) { + return; + } - x509TrustManager = new X509TrustManager[trustManagers.length]; - for (int i = 0; i < trustManagers.length; ++i) { - try { - x509TrustManager[i] = (X509TrustManager)trustManagers[i]; - } catch (ClassCastException e) { - access.log(Level.WARN, "Non X509 TrustManager", x509TrustManager[i].getClass().getName(), "skipped in SecurityInfo"); - } - } - } - - protected void initializeTrustMasks() throws AccessException { - String tips = access.getProperty(Config.CADI_TRUST_MASKS, null); - if (tips == null) { - return; - } + x509TrustManager = new X509TrustManager[trustManagers.length]; + for (int i = 0; i < trustManagers.length; ++i) { + try { + x509TrustManager[i] = (X509TrustManager)trustManagers[i]; + } catch (ClassCastException e) { + access.log(Level.WARN, "Non X509 TrustManager", x509TrustManager[i].getClass().getName(), "skipped in SecurityInfo"); + } + } + } + + protected void initializeTrustMasks() throws AccessException { + String tips = access.getProperty(Config.CADI_TRUST_MASKS, null); + if (tips == null) { + return; + } - access.log(Level.INIT, "Explicitly accepting valid X509s from", tips); - String[] ipsplit = tips.split(REGEX_COMMA); - trustMasks = new NetMask[ipsplit.length]; - for (int i = 0; i < ipsplit.length; ++i) { - try { - trustMasks[i] = new NetMask(ipsplit[i]); - } catch (MaskFormatException e) { - throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS, e); - } - } - - final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier(); - maskHV = new HostnameVerifier() { - @Override - public boolean verify(final String urlHostName, final SSLSession session) { - try { - // This will pick up /etc/host entries as well as DNS - InetAddress ia = InetAddress.getByName(session.getPeerHost()); - for (NetMask tmask : trustMasks) { - if (tmask.isInNet(ia.getHostAddress())) { - return true; - } - } - } catch (UnknownHostException e) { - // It's ok. do normal Verify - } - return origHV.verify(urlHostName, session); - }; - }; - HttpsURLConnection.setDefaultHostnameVerifier(maskHV); - } - + access.log(Level.INIT, "Explicitly accepting valid X509s from", tips); + String[] ipsplit = tips.split(REGEX_COMMA); + trustMasks = new NetMask[ipsplit.length]; + for (int i = 0; i < ipsplit.length; ++i) { + try { + trustMasks[i] = new NetMask(ipsplit[i]); + } catch (MaskFormatException e) { + throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS, e); + } + } + + final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier(); + maskHV = new HostnameVerifier() { + @Override + public boolean verify(final String urlHostName, final SSLSession session) { + try { + // This will pick up /etc/host entries as well as DNS + InetAddress ia = InetAddress.getByName(session.getPeerHost()); + for (NetMask tmask : trustMasks) { + if (tmask.isInNet(ia.getHostAddress())) { + return true; + } + } + } catch (UnknownHostException e) { + // It's ok. do normal Verify + } + return origHV.verify(urlHostName, session); + }; + }; + HttpsURLConnection.setDefaultHostnameVerifier(maskHV); + } + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoC.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoC.java index 8e5faf4c..45e1dd1c 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoC.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoC.java @@ -31,64 +31,64 @@ import org.onap.aaf.cadi.SecuritySetter; public class SecurityInfoC<CLIENT> extends SecurityInfo { - public static final String DEF_ID = "ID not Set"; - private static Map<Class<?>,SecurityInfoC<?>> sicMap = new HashMap<>(); - public SecuritySetter<CLIENT> defSS; + public static final String DEF_ID = "ID not Set"; + private static Map<Class<?>,SecurityInfoC<?>> sicMap = new HashMap<>(); + public SecuritySetter<CLIENT> defSS; - public SecurityInfoC(Access access) throws CadiException { - super(access); - defSS = new DEFSS<CLIENT>(); - } - - @SuppressWarnings("unchecked") - public static synchronized <CLIENT> SecurityInfoC<CLIENT> instance(Access access, Class<CLIENT> cls) throws CadiException { - SecurityInfoInit<CLIENT> sii; - if(cls.isAssignableFrom(HttpURLConnection.class)) { - try { - @SuppressWarnings("rawtypes") - Class<SecurityInfoInit> initCls = (Class<SecurityInfoInit>)Class.forName("org.onap.aaf.cadi.http.HSecurityInfoInit"); - sii = initCls.newInstance(); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { - throw new CadiException("CADI using HttpURLConnection requires cadi-client jar",e); - } - } else { - sii = new SecurityInfoInit<CLIENT>() { - @Override - public SecuritySetter<CLIENT> bestDefault(SecurityInfoC<CLIENT> si) throws CadiException { - return new DEFSS<CLIENT>(); - } - }; - } - - SecurityInfoC<CLIENT> sic = (SecurityInfoC<CLIENT>) sicMap.get(cls); - if(sic==null) { - sic = new SecurityInfoC<CLIENT>(access); - sic.set(sii.bestDefault(sic)); - sicMap.put(cls, sic); - } - return sic; - } + public SecurityInfoC(Access access) throws CadiException { + super(access); + defSS = new DEFSS<CLIENT>(); + } + + @SuppressWarnings("unchecked") + public static synchronized <CLIENT> SecurityInfoC<CLIENT> instance(Access access, Class<CLIENT> cls) throws CadiException { + SecurityInfoInit<CLIENT> sii; + if(cls.isAssignableFrom(HttpURLConnection.class)) { + try { + @SuppressWarnings("rawtypes") + Class<SecurityInfoInit> initCls = (Class<SecurityInfoInit>)Class.forName("org.onap.aaf.cadi.http.HSecurityInfoInit"); + sii = initCls.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + throw new CadiException("CADI using HttpURLConnection requires cadi-client jar",e); + } + } else { + sii = new SecurityInfoInit<CLIENT>() { + @Override + public SecuritySetter<CLIENT> bestDefault(SecurityInfoC<CLIENT> si) throws CadiException { + return new DEFSS<CLIENT>(); + } + }; + } + + SecurityInfoC<CLIENT> sic = (SecurityInfoC<CLIENT>) sicMap.get(cls); + if(sic==null) { + sic = new SecurityInfoC<CLIENT>(access); + sic.set(sii.bestDefault(sic)); + sicMap.put(cls, sic); + } + return sic; + } - public SecurityInfoC<CLIENT> set(SecuritySetter<CLIENT> defSS) { - this.defSS = defSS; - return this; - } + public SecurityInfoC<CLIENT> set(SecuritySetter<CLIENT> defSS) { + this.defSS = defSS; + return this; + } - private static class DEFSS<C> implements SecuritySetter<C> { - @Override - public String getID() { - return DEF_ID; - } + private static class DEFSS<C> implements SecuritySetter<C> { + @Override + public String getID() { + return DEF_ID; + } - @Override - public void setSecurity(C client) throws CadiException { - throw new CadiException("No Client Credentials set."); - } + @Override + public void setSecurity(C client) throws CadiException { + throw new CadiException("No Client Credentials set."); + } - @Override - public int setLastResponse(int respCode) { - return 0; - } - }; + @Override + public int setLastResponse(int respCode) { + return 0; + } + }; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoInit.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoInit.java index d77a7196..614f363b 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoInit.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoInit.java @@ -24,5 +24,5 @@ import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.SecuritySetter; public interface SecurityInfoInit<CLIENT> { - public SecuritySetter<CLIENT> bestDefault(SecurityInfoC<CLIENT> si) throws CadiException; + public SecuritySetter<CLIENT> bestDefault(SecurityInfoC<CLIENT> si) throws CadiException; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java index 5aea719e..de25cb7f 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java @@ -36,127 +36,127 @@ import org.onap.aaf.cadi.lur.LocalLur; public class UsersDump { - /** - * @param args - */ - public static boolean write(OutputStream os, AbsUserCache<?> lur) { - PrintStream ps; - if(os instanceof PrintStream) { - ps = (PrintStream)os; - } else { - ps = new PrintStream(os); - } - try { - ps.println("<?xml version='1.0' encoding='utf-8'?>"); - ps.println("<!--"); - ps.print( " Code Generated Tomcat Users and Roles from AT&T LUR on "); - ps.println(new Date()); - ps.println( "-->"); - ps.println("<tomcat-users>"); + /** + * @param args + */ + public static boolean write(OutputStream os, AbsUserCache<?> lur) { + PrintStream ps; + if(os instanceof PrintStream) { + ps = (PrintStream)os; + } else { + ps = new PrintStream(os); + } + try { + ps.println("<?xml version='1.0' encoding='utf-8'?>"); + ps.println("<!--"); + ps.print( " Code Generated Tomcat Users and Roles from AT&T LUR on "); + ps.println(new Date()); + ps.println( "-->"); + ps.println("<tomcat-users>"); - // We loop through Users, but want to write Groups first... therefore, save off print - StringBuilder sb = new StringBuilder(); - - // Obtain all unique role names - HashSet<String> groups = new HashSet<>(); - for(AbsUserCache<?>.DumpInfo di : lur.dumpInfo()) { - sb.append("\n <user username=\""); - sb.append(di.user); - sb.append("\" roles=\""); - boolean first = true; - for(String role : di.perms) { - groups.add(role); - if(first)first = false; - else sb.append(','); - sb.append(role); - } - sb.append("\"/>"); + // We loop through Users, but want to write Groups first... therefore, save off print + StringBuilder sb = new StringBuilder(); + + // Obtain all unique role names + HashSet<String> groups = new HashSet<>(); + for(AbsUserCache<?>.DumpInfo di : lur.dumpInfo()) { + sb.append("\n <user username=\""); + sb.append(di.user); + sb.append("\" roles=\""); + boolean first = true; + for(String role : di.perms) { + groups.add(role); + if(first)first = false; + else sb.append(','); + sb.append(role); + } + sb.append("\"/>"); - } + } - // Print roles - for(String group : groups) { - ps.print(" <role rolename=\""); - ps.print(group); - ps.println("\"/>"); - } - - ps.println(sb); + // Print roles + for(String group : groups) { + ps.print(" <role rolename=\""); + ps.print(group); + ps.println("\"/>"); + } + + ps.println(sb); - ps.println("</tomcat-users>"); - ps.flush(); - } catch (Exception t) { - t.printStackTrace(ps); - return false; - } - return true; - } - - /** - * - * Note: This method returns a String if there's an error, or null if ok. - * This unusual style is necessitated by the fact that any Exceptions thrown are likely to - * be unlogged and hidden from view, making debugging almost impossible. - * - * @param writeto - * @param up - * @return - */ - public static String updateUsers(String writeto, LocalLur up) { - // Dump a Tomcat-user.xml lookalike (anywhere) - if(writeto!=null) { - // First read content - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - if(UsersDump.write(baos, up)) { - byte[] postulate = baos.toByteArray(); - // now get contents of file - File file = new File(writeto); - boolean writeIt; - if(file.exists()) { - try { - FileInputStream fis = new FileInputStream(file); - byte[] orig = new byte[(int)file.length()]; - int read; - try { - read = fis.read(orig); - } finally { - fis.close(); - } - if(read<=0) { - writeIt = false; - } else { - // Starting at third "<" (<tomcat-users> line) - int startA=0, startB=0; - for(int i=0;startA<orig.length && i<3;++startA) if(orig[startA]=='<')++i; - for(int i=0;startB<orig.length && i<3;++startB) if(postulate[startB]=='<')++i; - - writeIt=orig.length-startA!=postulate.length-startB; // first, check if remaining length is the same - while(!writeIt && startA<orig.length && startB<postulate.length) { - if(orig[startA++]!=postulate[startB++])writeIt = true; - } - } - } catch (Exception e) { - writeIt = true; - } - } else { - writeIt = true; - } - - if(writeIt) { - try { - FileOutputStream fos = new FileOutputStream(file); - try { - fos.write(postulate); - } finally { - fos.close(); - } - } catch (IOException e) { - return e.getMessage(); - } - } - } - } - return null; // no message means ok. - } + ps.println("</tomcat-users>"); + ps.flush(); + } catch (Exception t) { + t.printStackTrace(ps); + return false; + } + return true; + } + + /** + * + * Note: This method returns a String if there's an error, or null if ok. + * This unusual style is necessitated by the fact that any Exceptions thrown are likely to + * be unlogged and hidden from view, making debugging almost impossible. + * + * @param writeto + * @param up + * @return + */ + public static String updateUsers(String writeto, LocalLur up) { + // Dump a Tomcat-user.xml lookalike (anywhere) + if(writeto!=null) { + // First read content + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if(UsersDump.write(baos, up)) { + byte[] postulate = baos.toByteArray(); + // now get contents of file + File file = new File(writeto); + boolean writeIt; + if(file.exists()) { + try { + FileInputStream fis = new FileInputStream(file); + byte[] orig = new byte[(int)file.length()]; + int read; + try { + read = fis.read(orig); + } finally { + fis.close(); + } + if(read<=0) { + writeIt = false; + } else { + // Starting at third "<" (<tomcat-users> line) + int startA=0, startB=0; + for(int i=0;startA<orig.length && i<3;++startA) if(orig[startA]=='<')++i; + for(int i=0;startB<orig.length && i<3;++startB) if(postulate[startB]=='<')++i; + + writeIt=orig.length-startA!=postulate.length-startB; // first, check if remaining length is the same + while(!writeIt && startA<orig.length && startB<postulate.length) { + if(orig[startA++]!=postulate[startB++])writeIt = true; + } + } + } catch (Exception e) { + writeIt = true; + } + } else { + writeIt = true; + } + + if(writeIt) { + try { + FileOutputStream fos = new FileOutputStream(file); + try { + fos.write(postulate); + } finally { + fos.close(); + } + } catch (IOException e) { + return e.getMessage(); + } + } + } + } + return null; // no message means ok. + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java index 7fd1e93c..5aa502d4 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java @@ -32,5 +32,5 @@ import javax.servlet.Servlet; @Target({TYPE}) @Retention(RUNTIME) public @interface AUTHZ { - Class<? extends Servlet> value(); + Class<? extends Servlet> value(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java index f72a99bf..0bd87d98 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java @@ -37,62 +37,62 @@ import javax.servlet.http.HttpServletResponse; * */ public class AUTHZServlet<S extends Servlet> implements Servlet { - private String[] roles; - private Servlet delegate; + private String[] roles; + private Servlet delegate; - protected AUTHZServlet(Class<S> cls) { - try { - delegate = cls.newInstance(); - } catch (Exception e) { - delegate = null; - } - RolesAllowed rolesAllowed = cls.getAnnotation(RolesAllowed.class); - if (rolesAllowed == null) { - roles = null; - } else { - roles = rolesAllowed.value(); - } - } - - public void init(ServletConfig sc) throws ServletException { - if (delegate == null) { - throw new ServletException("Invalid Servlet Delegate"); - } - delegate.init(sc); - } - - public ServletConfig getServletConfig() { - return delegate.getServletConfig(); - } + protected AUTHZServlet(Class<S> cls) { + try { + delegate = cls.newInstance(); + } catch (Exception e) { + delegate = null; + } + RolesAllowed rolesAllowed = cls.getAnnotation(RolesAllowed.class); + if (rolesAllowed == null) { + roles = null; + } else { + roles = rolesAllowed.value(); + } + } + + public void init(ServletConfig sc) throws ServletException { + if (delegate == null) { + throw new ServletException("Invalid Servlet Delegate"); + } + delegate.init(sc); + } + + public ServletConfig getServletConfig() { + return delegate.getServletConfig(); + } - public String getServletInfo() { - return delegate.getServletInfo(); - } + public String getServletInfo() { + return delegate.getServletInfo(); + } - public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { - if (roles == null) { - delegate.service(req, resp); - return; - } + public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { + if (roles == null) { + delegate.service(req, resp); + return; + } - // Validate - try { - HttpServletRequest hreq = (HttpServletRequest)req; - for (String role : roles) { - if (hreq.isUserInRole(role)) { - delegate.service(req, resp); - return; - } - } + // Validate + try { + HttpServletRequest hreq = (HttpServletRequest)req; + for (String role : roles) { + if (hreq.isUserInRole(role)) { + delegate.service(req, resp); + return; + } + } - ((HttpServletResponse)resp).sendError(403); // forbidden - } catch (ClassCastException e) { - throw new ServletException("JASPIServlet only supports HTTPServletRequest/HttpServletResponse"); - } - } + ((HttpServletResponse)resp).sendError(403); // forbidden + } catch (ClassCastException e) { + throw new ServletException("JASPIServlet only supports HTTPServletRequest/HttpServletResponse"); + } + } - public void destroy() { - delegate.destroy(); - } + public void destroy() { + delegate.destroy(); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java index ab34a0a4..ae4347d3 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java @@ -24,12 +24,12 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.config.Get; public class AccessGetter implements Get { - private final Access access; - public AccessGetter(Access access) { - this.access = access; - } - public String get(String name, String def, boolean print) { - return access.getProperty(name, def); - } + private final Access access; + public AccessGetter(Access access) { + this.access = access; + } + public String get(String name, String def, boolean print) { + return access.getProperty(name, def); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java index 29234ed7..affb8f96 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java @@ -66,286 +66,286 @@ import org.onap.aaf.cadi.util.Timing; * */ public class CadiFilter implements Filter { - private static CadiHTTPManip httpChecker; - private static String[] pathExceptions; - private static List<Pair> mapPairs; - private Access access; - private Object[] additionalTafLurs; - private Filter oauthFilter; - private static int count=0; - - public Lur getLur() { - return httpChecker.getLur(); - } - - /** - * Construct a viable Filter - * - * Due to the vagaries of many containers, there is a tendency to create Objects and call "Init" on - * them at a later time. Therefore, this object creates with an object that denies all access - * until appropriate Init happens, just in case the container lets something slip by in the meantime. - * - */ - public CadiFilter() { - additionalTafLurs = CadiHTTPManip.noAdditional; - } + private static CadiHTTPManip httpChecker; + private static String[] pathExceptions; + private static List<Pair> mapPairs; + private Access access; + private Object[] additionalTafLurs; + private Filter oauthFilter; + private static int count=0; + + public Lur getLur() { + return httpChecker.getLur(); + } + + /** + * Construct a viable Filter + * + * Due to the vagaries of many containers, there is a tendency to create Objects and call "Init" on + * them at a later time. Therefore, this object creates with an object that denies all access + * until appropriate Init happens, just in case the container lets something slip by in the meantime. + * + */ + public CadiFilter() { + additionalTafLurs = CadiHTTPManip.noAdditional; + } - /** - * This constructor to be used when directly constructing and placing in HTTP Engine - * - * @param access - * @param moreTafLurs - * @throws ServletException - */ - public CadiFilter(Access access, Object ... moreTafLurs) throws ServletException { - additionalTafLurs = moreTafLurs; - init(new AccessGetter(this.access = access)); - } + /** + * This constructor to be used when directly constructing and placing in HTTP Engine + * + * @param access + * @param moreTafLurs + * @throws ServletException + */ + public CadiFilter(Access access, Object ... moreTafLurs) throws ServletException { + additionalTafLurs = moreTafLurs; + init(new AccessGetter(this.access = access)); + } - /** - * Use this to pass in a PreContructed CADI Filter, but with initializing... let Servlet do it - * @param init - * @param access - * @param moreTafLurs - * @throws ServletException - */ - public CadiFilter(boolean init, PropAccess access, Object ... moreTafLurs) throws ServletException { - this.access = access; - additionalTafLurs = moreTafLurs; - if(init) { - init(new AccessGetter(access)); - } - } + /** + * Use this to pass in a PreContructed CADI Filter, but with initializing... let Servlet do it + * @param init + * @param access + * @param moreTafLurs + * @throws ServletException + */ + public CadiFilter(boolean init, PropAccess access, Object ... moreTafLurs) throws ServletException { + this.access = access; + additionalTafLurs = moreTafLurs; + if(init) { + init(new AccessGetter(access)); + } + } - /** - * Init - * - * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a - * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this - * mechanism already. - */ - //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM Init functions - public void init(FilterConfig filterConfig) throws ServletException { - // need the Context for Logging, instantiating ClassLoader, etc - ServletContextAccess sca=new ServletContextAccess(filterConfig); - if(access==null) { - access = sca; - } - - // Set Protected getter with base Access, for internal class instantiations - init(new FCGet(access, sca.context(), filterConfig)); - } - + /** + * Init + * + * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a + * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this + * mechanism already. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM Init functions + public void init(FilterConfig filterConfig) throws ServletException { + // need the Context for Logging, instantiating ClassLoader, etc + ServletContextAccess sca=new ServletContextAccess(filterConfig); + if(access==null) { + access = sca; + } + + // Set Protected getter with base Access, for internal class instantiations + init(new FCGet(access, sca.context(), filterConfig)); + } + - @SuppressWarnings("unchecked") - private void init(Get getter) throws ServletException { + @SuppressWarnings("unchecked") + private void init(Get getter) throws ServletException { // Start with the assumption of "Don't trust anyone". - TrustChecker tc = TrustChecker.NOTRUST; // default position - try { - Class<TrustChecker> ctc = (Class<TrustChecker>) Class.forName("org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker"); - if(ctc!=null) { - Constructor<TrustChecker> contc = ctc.getConstructor(Access.class); - if(contc!=null) { - tc = contc.newInstance(access); - } - } - } catch (Exception e) { - access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage()); - } - - try { - Class<Filter> cf=null; - try { - cf= (Class<Filter>) Class.forName("org.onap.aaf.cadi.oauth.OAuthFilter"); - oauthFilter = cf.newInstance(); - } catch (ClassNotFoundException e) { - oauthFilter = new Filter() { // Null Filter - @Override - public void destroy() { - } - - @Override - public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException { - chain.doFilter(req, resp); - } - - @Override - public void init(FilterConfig arg0) throws ServletException { - } - }; - } - } catch (Exception e) { - access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage()); - } + TrustChecker tc = TrustChecker.NOTRUST; // default position + try { + Class<TrustChecker> ctc = (Class<TrustChecker>) Class.forName("org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker"); + if(ctc!=null) { + Constructor<TrustChecker> contc = ctc.getConstructor(Access.class); + if(contc!=null) { + tc = contc.newInstance(access); + } + } + } catch (Exception e) { + access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage()); + } + + try { + Class<Filter> cf=null; + try { + cf= (Class<Filter>) Class.forName("org.onap.aaf.cadi.oauth.OAuthFilter"); + oauthFilter = cf.newInstance(); + } catch (ClassNotFoundException e) { + oauthFilter = new Filter() { // Null Filter + @Override + public void destroy() { + } + + @Override + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException { + chain.doFilter(req, resp); + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + } + }; + } + } catch (Exception e) { + access.log(Level.INIT, "AAFTrustChecker cannot be loaded",e.getMessage()); + } // Synchronize, because some instantiations call init several times on the same object // In this case, the epiTaf will be changed to a non-NullTaf, and thus not instantiate twice. - synchronized(CadiHTTPManip.noAdditional /*will always remain same Object*/) { - ++count; - if(httpChecker == null) { - if(access==null) { - access = new PropAccess(); - } - try { - httpChecker = new CadiHTTPManip(access,null /*reuseable Con*/,tc, additionalTafLurs); - } catch (CadiException | LocatorException e1) { - throw new ServletException(e1); - } - } else if(access==null) { - access= httpChecker.getAccess(); - } + synchronized(CadiHTTPManip.noAdditional /*will always remain same Object*/) { + ++count; + if(httpChecker == null) { + if(access==null) { + access = new PropAccess(); + } + try { + httpChecker = new CadiHTTPManip(access,null /*reuseable Con*/,tc, additionalTafLurs); + } catch (CadiException | LocatorException e1) { + throw new ServletException(e1); + } + } else if(access==null) { + access= httpChecker.getAccess(); + } - /* - * Setup Authn Path Exceptions - */ - if(pathExceptions==null) { - String str = getter.get(Config.CADI_NOAUTHN, null, true); - if(str!=null) { - pathExceptions = str.split("\\s*:\\s*"); - } - } - - /* - * SETUP Permission Converters... those that can take Strings from a Vendor Product, and convert to appropriate AAF Permissions - */ - if(mapPairs==null) { - String str = getter.get(Config.AAF_PERM_MAP, null, true); - if(str!=null) { - String mstr = getter.get(Config.AAF_PERM_MAP, null, true); - if(mstr!=null) { - String map[] = mstr.split("\\s*:\\s*"); - if(map.length>0) { - MapPermConverter mpc=null; - int idx; - mapPairs = new ArrayList<>(); - for(String entry : map) { - if((idx=entry.indexOf('='))<0) { // it's a Path, so create a new converter - access.log(Level.INIT,"Loading Perm Conversions for:",entry); - mapPairs.add(new Pair(entry,mpc=new MapPermConverter())); - } else { - if(mpc!=null) { - mpc.map().put(entry.substring(0,idx),entry.substring(idx+1)); - } else { - access.log(Level.ERROR,"cadi_perm_map is malformed; ",entry, "is skipped"); - } - } - } - } - } - } - } - } + /* + * Setup Authn Path Exceptions + */ + if(pathExceptions==null) { + String str = getter.get(Config.CADI_NOAUTHN, null, true); + if(str!=null) { + pathExceptions = str.split("\\s*:\\s*"); + } + } + + /* + * SETUP Permission Converters... those that can take Strings from a Vendor Product, and convert to appropriate AAF Permissions + */ + if(mapPairs==null) { + String str = getter.get(Config.AAF_PERM_MAP, null, true); + if(str!=null) { + String mstr = getter.get(Config.AAF_PERM_MAP, null, true); + if(mstr!=null) { + String map[] = mstr.split("\\s*:\\s*"); + if(map.length>0) { + MapPermConverter mpc=null; + int idx; + mapPairs = new ArrayList<>(); + for(String entry : map) { + if((idx=entry.indexOf('='))<0) { // it's a Path, so create a new converter + access.log(Level.INIT,"Loading Perm Conversions for:",entry); + mapPairs.add(new Pair(entry,mpc=new MapPermConverter())); + } else { + if(mpc!=null) { + mpc.map().put(entry.substring(0,idx),entry.substring(idx+1)); + } else { + access.log(Level.ERROR,"cadi_perm_map is malformed; ",entry, "is skipped"); + } + } + } + } + } + } + } + } - // Remove Getter + // Remove Getter getter = Get.NULL; - } + } - /** - * Containers call "destroy" when time to cleanup - */ - public void destroy() { - // Synchronize, in case multiCadiFilters are used. - synchronized(CadiHTTPManip.noAdditional) { - if(--count<=0 && httpChecker!=null) { - httpChecker.destroy(); - httpChecker=null; - access=null; - pathExceptions=null; - } - } - } + /** + * Containers call "destroy" when time to cleanup + */ + public void destroy() { + // Synchronize, in case multiCadiFilters are used. + synchronized(CadiHTTPManip.noAdditional) { + if(--count<=0 && httpChecker!=null) { + httpChecker.destroy(); + httpChecker=null; + access=null; + pathExceptions=null; + } + } + } - /** - * doFilter - * - * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and - * only call the next item in the filterChain if request is suitably Authenticated. - */ - //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - final long startAll = System.nanoTime(); - long startCode, startValidate; - float code=0f, validate=0f; - String user = "n/a"; - String tag = ""; - try { - HttpServletRequest hreq = (HttpServletRequest)request; - if(noAuthn(hreq)) { - startCode=System.nanoTime(); - chain.doFilter(request, response); - code = Timing.millis(startCode); - } else { - HttpServletResponse hresp = (HttpServletResponse)response; - startValidate=System.nanoTime(); - TafResp tresp = httpChecker.validate(hreq, hresp, hreq); - validate = Timing.millis(startValidate); - if(tresp.isAuthenticated()==RESP.IS_AUTHENTICATED) { - user = tresp.getPrincipal().personalName(); - tag = tresp.getPrincipal().tag(); - CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq)); - if(httpChecker.notCadi(cw, hresp)) { - startCode=System.nanoTime(); - oauthFilter.doFilter(cw,response,chain); - code = Timing.millis(startCode); - } - } - } - } catch (ClassCastException e) { - throw new ServletException("CadiFilter expects Servlet to be an HTTP Servlet",e); - } finally { - access.printf(Level.WARN, "Trans: user=%s[%s],ip=%s,ms=%f,validate=%f,code=%f", - user,tag,request.getRemoteAddr(), - Timing.millis(startAll),validate,code); - } - } + /** + * doFilter + * + * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and + * only call the next item in the filterChain if request is suitably Authenticated. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + final long startAll = System.nanoTime(); + long startCode, startValidate; + float code=0f, validate=0f; + String user = "n/a"; + String tag = ""; + try { + HttpServletRequest hreq = (HttpServletRequest)request; + if(noAuthn(hreq)) { + startCode=System.nanoTime(); + chain.doFilter(request, response); + code = Timing.millis(startCode); + } else { + HttpServletResponse hresp = (HttpServletResponse)response; + startValidate=System.nanoTime(); + TafResp tresp = httpChecker.validate(hreq, hresp, hreq); + validate = Timing.millis(startValidate); + if(tresp.isAuthenticated()==RESP.IS_AUTHENTICATED) { + user = tresp.getPrincipal().personalName(); + tag = tresp.getPrincipal().tag(); + CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq)); + if(httpChecker.notCadi(cw, hresp)) { + startCode=System.nanoTime(); + oauthFilter.doFilter(cw,response,chain); + code = Timing.millis(startCode); + } + } + } + } catch (ClassCastException e) { + throw new ServletException("CadiFilter expects Servlet to be an HTTP Servlet",e); + } finally { + access.printf(Level.WARN, "Trans: user=%s[%s],ip=%s,ms=%f,validate=%f,code=%f", + user,tag,request.getRemoteAddr(), + Timing.millis(startAll),validate,code); + } + } - /** - * If PathExceptions exist, report if these should not have Authn applied. - * @param hreq - * @return - */ - private boolean noAuthn(HttpServletRequest hreq) { - if(pathExceptions!=null) { - String pi = hreq.getPathInfo(); - if(pi==null) return false; // JBoss sometimes leaves null - for(String pe : pathExceptions) { - if(pi.startsWith(pe))return true; - } - } - return false; - } - - /** - * Get Converter by Path - */ - private PermConverter getConverter(HttpServletRequest hreq) { - if(mapPairs!=null) { - String pi = hreq.getPathInfo(); - if(pi !=null) { - for(Pair p: mapPairs) { - if(pi.startsWith(p.name))return p.pc; - } - } - } - return NullPermConverter.singleton(); - } - - /** - * store PermConverters by Path prefix - * @author Jonathan - * - */ - private class Pair { - public Pair(String key, PermConverter pc) { - name = key; - this.pc = pc; - } - public String name; - public PermConverter pc; - } + /** + * If PathExceptions exist, report if these should not have Authn applied. + * @param hreq + * @return + */ + private boolean noAuthn(HttpServletRequest hreq) { + if(pathExceptions!=null) { + String pi = hreq.getPathInfo(); + if(pi==null) return false; // JBoss sometimes leaves null + for(String pe : pathExceptions) { + if(pi.startsWith(pe))return true; + } + } + return false; + } + + /** + * Get Converter by Path + */ + private PermConverter getConverter(HttpServletRequest hreq) { + if(mapPairs!=null) { + String pi = hreq.getPathInfo(); + if(pi !=null) { + for(Pair p: mapPairs) { + if(pi.startsWith(p.name))return p.pc; + } + } + } + return NullPermConverter.singleton(); + } + + /** + * store PermConverters by Path prefix + * @author Jonathan + * + */ + private class Pair { + public Pair(String key, PermConverter pc) { + name = key; + this.pc = pc; + } + public String name; + public PermConverter pc; + } } 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 9d1653fa..3c0f139b 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,159 +55,159 @@ import org.onap.aaf.cadi.util.UserChainManip; * */ public class CadiHTTPManip { - 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"; - private static final String CADI_CACHE_CLEAR = "/cadi/cache/clear"; - private static final String CADI_LOG_SET = "/cadi/log/set/"; - private static final Object LOCK = new Object(); - private Access access; - private HttpTaf taf; - private CredVal up; - private Lur lur; - private String thisPerm,companyPerm,aaf_id; - - public static final Object[] noAdditional = new Object[0]; // CadiFilter can be created each call in some systems + 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"; + private static final String CADI_CACHE_CLEAR = "/cadi/cache/clear"; + private static final String CADI_LOG_SET = "/cadi/log/set/"; + private static final Object LOCK = new Object(); + private Access access; + private HttpTaf taf; + private CredVal up; + private Lur lur; + private String thisPerm,companyPerm,aaf_id; + + public static final Object[] noAdditional = new Object[0]; // CadiFilter can be created each call in some systems - public CadiHTTPManip(Access access, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException, LocatorException { - synchronized(LOCK) { - this.access = access; -// Get getter = new AccessGetter(access); - Config.setDefaultRealm(access); - - aaf_id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_APPID, null)); - if(aaf_id==null) { - access.printf(Level.INIT, "%s is not set. %s can be used instead",Config.AAF_APPID,Config.CADI_ALIAS); - } else { - access.printf(Level.INIT, "%s is set to %s",Config.AAF_APPID,aaf_id); - } - String ns = aaf_id==null?null:UserChainManip.idToNS(aaf_id); - if(ns!=null) { - thisPerm = ns+ACCESS_CADI_CONTROL; - int dot = ns.indexOf('.'); - if(dot>=0) { - int dot2=ns.indexOf('.',dot+1); - if(dot2<0) { - dot2=dot; - } - companyPerm = ns.substring(0, dot2)+ACCESS_CADI_CONTROL; - } else { - companyPerm = "com"+ACCESS_CADI_CONTROL; - } - } else { - thisPerm = companyPerm = "com"+ACCESS_CADI_CONTROL; - } - SecurityInfoC<HttpURLConnection> si; - si = SecurityInfoC.instance(access, HttpURLConnection.class); - - lur = Config.configLur(si, con, additionalTafLurs); - - tc.setLur(lur); - if(lur instanceof EpiLur) { - up = ((EpiLur)lur).getUserPassImpl(); - } else if(lur instanceof CredVal) { - up = (CredVal)lur; - } else { - up = null; - } - taf = Config.configHttpTaf(con,si, tc, up, lur, additionalTafLurs); - } - } + public CadiHTTPManip(Access access, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException, LocatorException { + synchronized(LOCK) { + this.access = access; +// Get getter = new AccessGetter(access); + Config.setDefaultRealm(access); + + aaf_id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_APPID, null)); + if(aaf_id==null) { + access.printf(Level.INIT, "%s is not set. %s can be used instead",Config.AAF_APPID,Config.CADI_ALIAS); + } else { + access.printf(Level.INIT, "%s is set to %s",Config.AAF_APPID,aaf_id); + } + String ns = aaf_id==null?null:UserChainManip.idToNS(aaf_id); + if(ns!=null) { + thisPerm = ns+ACCESS_CADI_CONTROL; + int dot = ns.indexOf('.'); + if(dot>=0) { + int dot2=ns.indexOf('.',dot+1); + if(dot2<0) { + dot2=dot; + } + companyPerm = ns.substring(0, dot2)+ACCESS_CADI_CONTROL; + } else { + companyPerm = "com"+ACCESS_CADI_CONTROL; + } + } else { + thisPerm = companyPerm = "com"+ACCESS_CADI_CONTROL; + } + SecurityInfoC<HttpURLConnection> si; + si = SecurityInfoC.instance(access, HttpURLConnection.class); + + lur = Config.configLur(si, con, additionalTafLurs); + + tc.setLur(lur); + if(lur instanceof EpiLur) { + up = ((EpiLur)lur).getUserPassImpl(); + } else if(lur instanceof CredVal) { + up = (CredVal)lur; + } else { + up = null; + } + taf = Config.configHttpTaf(con,si, tc, up, lur, additionalTafLurs); + } + } - public TafResp validate(HttpServletRequest hreq, HttpServletResponse hresp, Object state) throws IOException { - 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()); - 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()); - break; - case HTTP_REDIRECT_INVOKED: - access.log(Level.INFO,"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()); - hresp.sendError(403, tresp.desc()); // Forbidden - break; + public TafResp validate(HttpServletRequest hreq, HttpServletResponse hresp, Object state) throws IOException { + 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()); + 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()); + break; + case HTTP_REDIRECT_INVOKED: + access.log(Level.INFO,"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()); + 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()); - 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 - 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 - } - return tresp; - } - - public boolean notCadi(CadiWrap req, HttpServletResponse resp) { - - String pathInfo = req.getPathInfo(); - if(METH.equalsIgnoreCase(req.getMethod()) && pathInfo!=null && pathInfo.contains(CADI)) { - if(req.getUser().equals(aaf_id) || req.isUserInRole(thisPerm) || req.isUserInRole(companyPerm)) { - try { - if(pathInfo.contains(CADI_CACHE_PRINT)) { - resp.getOutputStream().println(lur.toString()); - resp.setStatus(200); - return false; - } else if(pathInfo.contains(CADI_CACHE_CLEAR)) { - StringBuilder report = new StringBuilder(); - lur.clear(req.getUserPrincipal(), report); - resp.getOutputStream().println(report.toString()); - resp.setStatus(200); - return false; - } else if(pathInfo.contains(CADI_LOG_SET)) { - Level l; - int slash = pathInfo.lastIndexOf('/'); - String level = pathInfo.substring(slash+1); - try { - l = Level.valueOf(level); - access.printf(Level.AUDIT, "%s has set CADI Log Level to '%s'",req.getUser(),l.name()); - access.setLogLevel(l); - } catch (IllegalArgumentException e) { - access.printf(Level.AUDIT, "'%s' is not a valid CADI Log Level",level); - } - return false; - } - } catch (IOException e) { - access.log(e); - } - } - } - return true; - } + default: + access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d" + , hreq.getRemoteAddr(), hreq.getRemotePort()); + 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 + 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 + } + return tresp; + } + + public boolean notCadi(CadiWrap req, HttpServletResponse resp) { + + String pathInfo = req.getPathInfo(); + if(METH.equalsIgnoreCase(req.getMethod()) && pathInfo!=null && pathInfo.contains(CADI)) { + if(req.getUser().equals(aaf_id) || req.isUserInRole(thisPerm) || req.isUserInRole(companyPerm)) { + try { + if(pathInfo.contains(CADI_CACHE_PRINT)) { + resp.getOutputStream().println(lur.toString()); + resp.setStatus(200); + return false; + } else if(pathInfo.contains(CADI_CACHE_CLEAR)) { + StringBuilder report = new StringBuilder(); + lur.clear(req.getUserPrincipal(), report); + resp.getOutputStream().println(report.toString()); + resp.setStatus(200); + return false; + } else if(pathInfo.contains(CADI_LOG_SET)) { + Level l; + int slash = pathInfo.lastIndexOf('/'); + String level = pathInfo.substring(slash+1); + try { + l = Level.valueOf(level); + access.printf(Level.AUDIT, "%s has set CADI Log Level to '%s'",req.getUser(),l.name()); + access.setLogLevel(l); + } catch (IllegalArgumentException e) { + access.printf(Level.AUDIT, "'%s' is not a valid CADI Log Level",level); + } + return false; + } + } catch (IOException e) { + access.log(e); + } + } + } + return true; + } - public Lur getLur() { - return lur; - } - - public void destroy() { - access.log(Level.INFO,"CadiHttpChecker destroyed."); - if(lur!=null) { - lur.destroy(); - lur=null; - } - } + public Lur getLur() { + return lur; + } + + public void destroy() { + access.log(Level.INFO,"CadiHttpChecker destroyed."); + if(lur!=null) { + lur.destroy(); + lur=null; + } + } - public Access getAccess() { - return access; - } + public Access getAccess() { + return access; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java index 9c4cca10..f56cbf27 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java @@ -33,44 +33,44 @@ import org.onap.aaf.cadi.config.Get; * cleans up the initialization code. */ class FCGet implements Get { - /** - * - */ - private final Access access; - private FilterConfig filterConfig; - private ServletContext context; + /** + * + */ + private final Access access; + private FilterConfig filterConfig; + private ServletContext context; - public FCGet(Access access, ServletContext context, FilterConfig filterConfig) { - this.access = access; - this.context = context; - this.filterConfig = filterConfig; - } + public FCGet(Access access, ServletContext context, FilterConfig filterConfig) { + this.access = access; + this.context = context; + this.filterConfig = filterConfig; + } - public String get(String name, String def, boolean print) { - String str = null; - // Try Server Context First - if(context!=null) { - str = context.getInitParameter(name); - } - - // Try Filter Context next - if(str==null && filterConfig != null) { - str = filterConfig.getInitParameter(name); - } - - if(str==null) { - str = access.getProperty(name, def); - } - // Take def if nothing else - if(str==null) { - str = def; - // don't log defaults - } else { - str = str.trim(); // this is vital in Property File based values, as spaces can hide easily - if(print) { - access.log(Level.INFO,"Setting", name, "to", str); - } - } - return str; - } + public String get(String name, String def, boolean print) { + String str = null; + // Try Server Context First + if(context!=null) { + str = context.getInitParameter(name); + } + + // Try Filter Context next + if(str==null && filterConfig != null) { + str = filterConfig.getInitParameter(name); + } + + if(str==null) { + str = access.getProperty(name, def); + } + // Take def if nothing else + if(str==null) { + str = def; + // don't log defaults + } else { + str = str.trim(); // this is vital in Property File based values, as spaces can hide easily + if(print) { + access.log(Level.INFO,"Setting", name, "to", str); + } + } + return str; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java index f0786b12..7953e076 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java @@ -25,30 +25,30 @@ import java.util.HashMap; import java.util.Map; public class MapPermConverter implements PermConverter { - private HashMap<String,String> map; + private HashMap<String,String> map; - /** - * Create with colon separated name value pairs - * i.e. teAdmin=com.att.myNS.myPerm|*|*:teUser=... - * - * @param value - */ - public MapPermConverter() { - map = new HashMap<>(); - } + /** + * Create with colon separated name value pairs + * i.e. teAdmin=com.att.myNS.myPerm|*|*:teUser=... + * + * @param value + */ + public MapPermConverter() { + map = new HashMap<>(); + } - /** - * use to instantiate entries - * - * @return - */ - public Map<String,String> map() { - return map; - } + /** + * use to instantiate entries + * + * @return + */ + public Map<String,String> map() { + return map; + } - public String convert(String minimal) { - String rv = map.get(minimal); - return (rv == null) ? minimal : rv; - } + public String convert(String minimal) { + String rv = map.get(minimal); + return (rv == null) ? minimal : rv; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java index 8b70d95d..bb63d097 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java @@ -32,14 +32,14 @@ package org.onap.aaf.cadi.filter; */ public class NullPermConverter implements PermConverter { - private static final NullPermConverter singleton = new NullPermConverter(); + private static final NullPermConverter singleton = new NullPermConverter(); - private NullPermConverter() {} + private NullPermConverter() {} - public static NullPermConverter singleton() { return singleton; } + public static NullPermConverter singleton() { return singleton; } - public String convert(String minimal) { - return minimal; - } + public String convert(String minimal) { + return minimal; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java index cf87c840..f0de0481 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java @@ -48,133 +48,133 @@ import org.onap.aaf.cadi.config.Config; * */ public class PathFilter implements Filter { - private final Log log; - - private ServletContext context; - private String aafType; - private String notAuthorizedMsg; - - /** - * Construct a viable Filter for installing in Container WEB.XML, etc. - * - */ - public PathFilter() { - log = new Log() { - public void info(String ... msg) { - context.log(build("INFO:", msg)); - } - public void audit(String ... msg) { - context.log(build("AUDIT:", msg)); - } - private String build(String type, String []msg) { - StringBuilder sb = new StringBuilder(type); - for (String s : msg) { - sb.append(' '); - sb.append(s); - } - return sb.toString(); - } - }; - } - - /** - * Filter that can be constructed within Java - * @param access - */ - public PathFilter(final Access access) { - log = new Log() { - public void info(String ... msg) { - access.log(Level.INFO, (Object[])msg); - } - public void audit(String ... msg) { - access.log(Level.AUDIT, (Object[])msg); - } - }; - } - - /** - * Init - * - * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a - * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this - * mechanism already. - */ - public void init(FilterConfig filterConfig) throws ServletException { - // need the Context for Logging, instantiating ClassLoader, etc - context = filterConfig.getServletContext(); - StringBuilder sb = new StringBuilder(); - StringBuilder err = new StringBuilder(); - Object attr = context.getAttribute(Config.PATHFILTER_NS); - if (attr == null) { - err.append("PathFilter - pathfilter_ns is not set"); - } else { - sb.append(attr.toString()); - } - - attr = context.getAttribute(Config.PATHFILTER_STACK); - if (attr == null) { - log.info("PathFilter - No pathfilter_stack set, ignoring"); - } else { - sb.append('.'); - sb.append(attr.toString()); - } - - attr = context.getAttribute(Config.PATHFILTER_URLPATTERN); - if (attr == null) { - log.info("PathFilter - No pathfilter_urlpattern set, defaulting to 'urlpattern'"); - sb.append(".urlpattern"); - } else { - sb.append('.'); - sb.append(attr.toString()); - } - - log.info("PathFilter - AAF Permission Type is", sb.toString()); - - sb.append('|'); - - aafType = sb.toString(); - - attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG); - if (attr == null) { - notAuthorizedMsg = "Forbidden - Not Authorized to access this Path"; - } else { - notAuthorizedMsg = attr.toString(); - } - - if (err.length() > 0) { - throw new ServletException(err.toString()); - } - } - - private interface Log { - public void info(String ... msg); - public void audit(String ... msg); - } - - /** - * doFilter - * - * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and - * only call the next item in the filterChain if request is suitably Authenticated. - */ - //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest hreq = (HttpServletRequest)request; - HttpServletResponse hresp = (HttpServletResponse)response; - String perm = aafType + hreq.getPathInfo() + '|' + hreq.getMethod(); - if (hreq.isUserInRole(perm)) { - chain.doFilter(request, response); - } else { - log.audit("PathFilter has denied", hreq.getUserPrincipal().getName(), "access to", perm); - hresp.sendError(403, notAuthorizedMsg); - } - } - - /** - * Containers call "destroy" when time to cleanup - */ - public void destroy() { - log.info("PathFilter destroyed."); - } + private final Log log; + + private ServletContext context; + private String aafType; + private String notAuthorizedMsg; + + /** + * Construct a viable Filter for installing in Container WEB.XML, etc. + * + */ + public PathFilter() { + log = new Log() { + public void info(String ... msg) { + context.log(build("INFO:", msg)); + } + public void audit(String ... msg) { + context.log(build("AUDIT:", msg)); + } + private String build(String type, String []msg) { + StringBuilder sb = new StringBuilder(type); + for (String s : msg) { + sb.append(' '); + sb.append(s); + } + return sb.toString(); + } + }; + } + + /** + * Filter that can be constructed within Java + * @param access + */ + public PathFilter(final Access access) { + log = new Log() { + public void info(String ... msg) { + access.log(Level.INFO, (Object[])msg); + } + public void audit(String ... msg) { + access.log(Level.AUDIT, (Object[])msg); + } + }; + } + + /** + * Init + * + * Standard Filter "init" call with FilterConfig to obtain properties. POJOs can construct a + * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this + * mechanism already. + */ + public void init(FilterConfig filterConfig) throws ServletException { + // need the Context for Logging, instantiating ClassLoader, etc + context = filterConfig.getServletContext(); + StringBuilder sb = new StringBuilder(); + StringBuilder err = new StringBuilder(); + Object attr = context.getAttribute(Config.PATHFILTER_NS); + if (attr == null) { + err.append("PathFilter - pathfilter_ns is not set"); + } else { + sb.append(attr.toString()); + } + + attr = context.getAttribute(Config.PATHFILTER_STACK); + if (attr == null) { + log.info("PathFilter - No pathfilter_stack set, ignoring"); + } else { + sb.append('.'); + sb.append(attr.toString()); + } + + attr = context.getAttribute(Config.PATHFILTER_URLPATTERN); + if (attr == null) { + log.info("PathFilter - No pathfilter_urlpattern set, defaulting to 'urlpattern'"); + sb.append(".urlpattern"); + } else { + sb.append('.'); + sb.append(attr.toString()); + } + + log.info("PathFilter - AAF Permission Type is", sb.toString()); + + sb.append('|'); + + aafType = sb.toString(); + + attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG); + if (attr == null) { + notAuthorizedMsg = "Forbidden - Not Authorized to access this Path"; + } else { + notAuthorizedMsg = attr.toString(); + } + + if (err.length() > 0) { + throw new ServletException(err.toString()); + } + } + + private interface Log { + public void info(String ... msg); + public void audit(String ... msg); + } + + /** + * doFilter + * + * This is the standard J2EE invocation. Analyze the request, modify response as necessary, and + * only call the next item in the filterChain if request is suitably Authenticated. + */ + //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest hreq = (HttpServletRequest)request; + HttpServletResponse hresp = (HttpServletResponse)response; + String perm = aafType + hreq.getPathInfo() + '|' + hreq.getMethod(); + if (hreq.isUserInRole(perm)) { + chain.doFilter(request, response); + } else { + log.audit("PathFilter has denied", hreq.getUserPrincipal().getName(), "access to", perm); + hresp.sendError(403, notAuthorizedMsg); + } + } + + /** + * Containers call "destroy" when time to cleanup + */ + public void destroy() { + log.info("PathFilter destroyed."); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java index bb97894b..dfd0f64b 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java @@ -28,5 +28,5 @@ package org.onap.aaf.cadi.filter; * */ public interface PermConverter { - public String convert(String minimal); + public String convert(String minimal); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java index 5f709f12..ac61a5c6 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java @@ -47,10 +47,10 @@ import java.lang.annotation.Target; @Target({TYPE}) @Retention(RUNTIME) public @interface RolesAllowed { - /** - * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a - * Handler - * @return - */ - String[] value(); + /** + * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a + * Handler + * @return + */ + String[] value(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java index 02c2600f..5386eb2d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java @@ -47,10 +47,10 @@ import javax.servlet.Servlet; @Target({TYPE}) @Retention(RUNTIME) public @interface ServletImpl { - /** - * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a - * Handler - * @return - */ - Class<? extends Servlet> value(); + /** + * Security role of the implementation, which doesn't have to be an EJB or CORBA like object. Can be just a + * Handler + * @return + */ + Class<? extends Servlet> value(); } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java index 43dd1018..c1b477b1 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java @@ -28,42 +28,42 @@ import org.onap.aaf.cadi.GetCred; import org.onap.aaf.cadi.Symm; public class ConfigPrincipal implements Principal, GetCred { - private String name; - private byte[] cred; - private String content; + private String name; + private byte[] cred; + private String content; - public ConfigPrincipal(String name, String passwd) { - this.name = name; - this.cred = passwd.getBytes(); - content = null; - } + public ConfigPrincipal(String name, String passwd) { + this.name = name; + this.cred = passwd.getBytes(); + content = null; + } - public ConfigPrincipal(String name, byte[] cred) { - this.name = name; - this.cred = cred; - content = null; - } + public ConfigPrincipal(String name, byte[] cred) { + this.name = name; + this.cred = cred; + content = null; + } - public String getName() { - return name; - } - - public byte[] getCred() { - return cred; - } + public String getName() { + return name; + } + + public byte[] getCred() { + return cred; + } - public String toString() { - return name; - } - - public String getAsBasicAuthHeader() throws IOException { - if(content ==null) { - String s = name + ':' + new String(cred); - content = "Basic " + Symm.base64.encode(s); - } else if(!content.startsWith("Basic ")) { // content is the saved password from construction - String s = name + ':' + content; - content = "Basic " + Symm.base64.encode(s); - } - return content; - } + public String toString() { + return name; + } + + public String getAsBasicAuthHeader() throws IOException { + if(content ==null) { + String s = name + ':' + new String(cred); + content = "Basic " + Symm.base64.encode(s); + } else if(!content.startsWith("Basic ")) { // content is the saved password from construction + String s = name + ':' + content; + content = "Basic " + Symm.base64.encode(s); + } + return content; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java index b442c7d9..2c5e1957 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java @@ -46,124 +46,124 @@ import org.onap.aaf.cadi.Permission; * */ public final class EpiLur implements Lur { - private final Lur[] lurs; - - /** - * EpiLur constructor - * - * Construct the EpiLur from variable TAF parameters - * @param lurs - * @throws CadiException - */ - public EpiLur(Lur ... lurs) throws CadiException{ - this.lurs = lurs; - if(lurs.length==0) throw new CadiException("Need at least one Lur implementation in constructor"); - } + private final Lur[] lurs; + + /** + * EpiLur constructor + * + * Construct the EpiLur from variable TAF parameters + * @param lurs + * @throws CadiException + */ + public EpiLur(Lur ... lurs) throws CadiException{ + this.lurs = lurs; + if(lurs.length==0) throw new CadiException("Need at least one Lur implementation in constructor"); + } - public boolean fish(Principal bait, Permission ... pond) { - if(pond==null) { - return false; - } - boolean rv = false; - Lur lur; - for(int i=0;!rv && i<lurs.length;++i) { - rv = (lur = lurs[i]).fish(bait, pond); - if(!rv && lur.handlesExclusively(pond)) break; - } - return rv; - } + public boolean fish(Principal bait, Permission ... pond) { + if(pond==null) { + return false; + } + boolean rv = false; + Lur lur; + for(int i=0;!rv && i<lurs.length;++i) { + rv = (lur = lurs[i]).fish(bait, pond); + if(!rv && lur.handlesExclusively(pond)) break; + } + return rv; + } - public void fishAll(Principal bait, List<Permission> permissions) { - for(Lur lur : lurs) { - lur.fishAll(bait, permissions); - } - } + public void fishAll(Principal bait, List<Permission> permissions) { + for(Lur lur : lurs) { + lur.fishAll(bait, permissions); + } + } - public void destroy() { - for(Lur lur : lurs) { - lur.destroy(); - } - } + public void destroy() { + for(Lur lur : lurs) { + lur.destroy(); + } + } - /** - * Return the first Lur (if any) which also implements UserPass - * @return - */ - public CredVal getUserPassImpl() { - for(Lur lur : lurs) { - if(lur instanceof CredVal) { - return (CredVal)lur; - } - } - return null; - } + /** + * Return the first Lur (if any) which also implements UserPass + * @return + */ + public CredVal getUserPassImpl() { + for(Lur lur : lurs) { + if(lur instanceof CredVal) { + return (CredVal)lur; + } + } + return null; + } - // Never needed... Only EpiLur uses... - public boolean handlesExclusively(Permission ... pond) { - return false; - } - - /** - * Get Lur for index. Returns null if out of range - * @param idx - * @return - */ - public Lur get(int idx) { - if(idx>=0 && idx<lurs.length) { - return lurs[idx]; - } - return null; - } + // Never needed... Only EpiLur uses... + public boolean handlesExclusively(Permission ... pond) { + return false; + } + + /** + * Get Lur for index. Returns null if out of range + * @param idx + * @return + */ + public Lur get(int idx) { + if(idx>=0 && idx<lurs.length) { + return lurs[idx]; + } + return null; + } - public boolean handles(Principal p) { - for(Lur l : lurs) { - if(l.handles(p)) { - return true; - } - } - return false; - } + public boolean handles(Principal p) { + for(Lur l : lurs) { + if(l.handles(p)) { + return true; + } + } + return false; + } - public void remove(String id) { - for(Lur l : lurs) { - if(l instanceof CachingLur) { - ((CachingLur<?>)l).remove(id); - } - } - } - - public Lur subLur(Class<? extends Lur> cls ) { - for(Lur l : lurs) { - if(l.getClass().isAssignableFrom(cls)) { - return l; - } - } - return null; - } + public void remove(String id) { + for(Lur l : lurs) { + if(l instanceof CachingLur) { + ((CachingLur<?>)l).remove(id); + } + } + } + + public Lur subLur(Class<? extends Lur> cls ) { + for(Lur l : lurs) { + if(l.getClass().isAssignableFrom(cls)) { + return l; + } + } + return null; + } - @Override - public Permission createPerm(String p) { - return new LocalPermission(p); - } + @Override + public Permission createPerm(String p) { + return new LocalPermission(p); + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Lur#clear(java.security.Principal, java.lang.StringBuilder) - */ - @Override - public void clear(Principal p, StringBuilder report) { - for(Lur lur : lurs) { - lur.clear(p, report); - } - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - for(Lur lur : lurs) { - sb.append(lur.getClass().getSimpleName()); - sb.append(": Report\n"); - sb.append(lur.toString()); - sb.append('\n'); - } - return sb.toString(); - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Lur#clear(java.security.Principal, java.lang.StringBuilder) + */ + @Override + public void clear(Principal p, StringBuilder report) { + for(Lur lur : lurs) { + lur.clear(p, report); + } + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + for(Lur lur : lurs) { + sb.append(lur.getClass().getSimpleName()); + sb.append(": Report\n"); + sb.append(lur.toString()); + sb.append('\n'); + } + return sb.toString(); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java index e177a22f..d2b6f1aa 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java @@ -45,177 +45,177 @@ import org.onap.aaf.cadi.config.Config; * */ public final class LocalLur extends AbsUserCache<LocalPermission> implements Lur, CredVal { - public static final String SEMI = "\\s*;\\s*"; - public static final String COLON = "\\s*:\\s*"; - public static final String COMMA = "\\s*,\\s*"; - public static final String PERCENT = "\\s*%\\s*"; - - // Use to quickly determine whether any given group is supported by this LUR - private final Set<String> supportingGroups; - private String supportedRealm; - - /** - * Construct by building structure, see "build" - * - * Reconstruct with "build" - * - * @param userProperties - * @param groupProperties - * @param decryptor - * @throws IOException - */ - public LocalLur(Access access, String userProperties, String groupProperties) throws IOException { - super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire - supportedRealm = access.getProperty(Config.BASIC_REALM, "localized"); - supportingGroups = new TreeSet<>(); - - if (userProperties != null) { - parseUserProperties(userProperties); - } - - if (groupProperties != null) { - parseGroupProperties(groupProperties); - } - } - - public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) { - if (cred == null) { - return false; - } - User<LocalPermission> usr = getUser(user, cred); - if (usr == null) { - return false; - } - // covers null as well as bad pass - if ((type == Type.PASSWORD) && (usr.principal instanceof ConfigPrincipal)) {; - return Hash.isEqual(cred, ((ConfigPrincipal)usr.principal).getCred()); - } - return false; - } - - // @Override - public boolean fish(Principal bait, Permission ... pond) { - if (pond == null) { - return false; - } - for(Permission p : pond) { - if (handles(bait) && p instanceof LocalPermission) { // local Users only have LocalPermissions - User<LocalPermission> user = getUser(bait); - if (user != null) { - return user.contains((LocalPermission)p); - } - } - } - return false; - } - - // We do not want to expose the actual Group, so make a copy. - public void fishAll(Principal bait, List<Permission> perms) { - if (handles(bait)) { - User<LocalPermission> user = getUser(bait); - if (user != null) { - user.copyPermsTo(perms); - } - } - } - - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal) - */ - @Override - public boolean handles(Principal principal) { - if (principal == null) { - return false; - } - return principal.getName().endsWith(supportedRealm); - } - - @Override - public boolean handlesExclusively(Permission ... pond) { - boolean rv = false; - for (Permission p : pond) { - if(rv=supportingGroups.contains(p.getKey())) { - break; - } - } - return rv; - } - - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String) - */ - @Override - public Permission createPerm(String p) { - return new LocalPermission(p); - } - - private void parseUserProperties(String userProperties) throws IOException { - // For each User name... - for (String userProperty : userProperties.trim().split(SEMI)) { - String[] userInfo = userProperty.split(COLON, 2); - String[] userPass = userInfo[0].split(PERCENT, 2); - String userName = userPass[0]; - - byte[] password = null; - if (userPass.length > 1) { - password = access.decrypt(userPass[1], true).getBytes(); - if (userName.indexOf('@') < 0) { - userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); - } - } - User<LocalPermission> usr; - usr = new User<>(new ConfigPrincipal(userName, password)); - addUser(usr); - access.log(Level.INIT, "Local User:", usr.principal); - - if (userInfo.length > 1) { - Map<String, Permission> newMap = usr.newMap(); - for (String group : userInfo[1].split(COMMA)) { - supportingGroups.add(group); - usr.add(newMap, new LocalPermission(group)); - } - usr.setMap(newMap); - } - } - } - - - private void parseGroupProperties(String groupProperties) throws IOException { - // For each Group name... - for (String group : groupProperties.trim().split(SEMI)) { - String[] groups = group.split(COLON, 2); - if (groups.length <= 1) { - continue; - } - supportingGroups.add(groups[0]); - LocalPermission p = new LocalPermission(groups[0]); - - // Add all users (known by comma separators) - for (String groupMember : groups[1].split(COMMA)) { - // look for password, if so, put in passMap - String[] userPass = groupMember.split(PERCENT, 2); - String userName = userPass[0]; - if (userName.indexOf('@') < 0) { - userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); - } - - User<LocalPermission> usr = null; - byte[] password = null; - if (userPass.length > 1) { - password = access.decrypt(userPass[1], true).getBytes(); - } - usr = getUser(userName, password); - if (usr == null) { - usr = new User<>(new ConfigPrincipal(userName, password)); - addUser(usr); - } - else { - usr.principal = new ConfigPrincipal(userName, password); - } - usr.add(p); - access.log(Level.INIT, "Local User:", usr.principal); - } - } - } + public static final String SEMI = "\\s*;\\s*"; + public static final String COLON = "\\s*:\\s*"; + public static final String COMMA = "\\s*,\\s*"; + public static final String PERCENT = "\\s*%\\s*"; + + // Use to quickly determine whether any given group is supported by this LUR + private final Set<String> supportingGroups; + private String supportedRealm; + + /** + * Construct by building structure, see "build" + * + * Reconstruct with "build" + * + * @param userProperties + * @param groupProperties + * @param decryptor + * @throws IOException + */ + public LocalLur(Access access, String userProperties, String groupProperties) throws IOException { + super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire + supportedRealm = access.getProperty(Config.BASIC_REALM, "localized"); + supportingGroups = new TreeSet<>(); + + if (userProperties != null) { + parseUserProperties(userProperties); + } + + if (groupProperties != null) { + parseGroupProperties(groupProperties); + } + } + + public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) { + if (cred == null) { + return false; + } + User<LocalPermission> usr = getUser(user, cred); + if (usr == null) { + return false; + } + // covers null as well as bad pass + if ((type == Type.PASSWORD) && (usr.principal instanceof ConfigPrincipal)) {; + return Hash.isEqual(cred, ((ConfigPrincipal)usr.principal).getCred()); + } + return false; + } + + // @Override + public boolean fish(Principal bait, Permission ... pond) { + if (pond == null) { + return false; + } + for(Permission p : pond) { + if (handles(bait) && p instanceof LocalPermission) { // local Users only have LocalPermissions + User<LocalPermission> user = getUser(bait); + if (user != null) { + return user.contains((LocalPermission)p); + } + } + } + return false; + } + + // We do not want to expose the actual Group, so make a copy. + public void fishAll(Principal bait, List<Permission> perms) { + if (handles(bait)) { + User<LocalPermission> user = getUser(bait); + if (user != null) { + user.copyPermsTo(perms); + } + } + } + + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal) + */ + @Override + public boolean handles(Principal principal) { + if (principal == null) { + return false; + } + return principal.getName().endsWith(supportedRealm); + } + + @Override + public boolean handlesExclusively(Permission ... pond) { + boolean rv = false; + for (Permission p : pond) { + if(rv=supportingGroups.contains(p.getKey())) { + break; + } + } + return rv; + } + + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String) + */ + @Override + public Permission createPerm(String p) { + return new LocalPermission(p); + } + + private void parseUserProperties(String userProperties) throws IOException { + // For each User name... + for (String userProperty : userProperties.trim().split(SEMI)) { + String[] userInfo = userProperty.split(COLON, 2); + String[] userPass = userInfo[0].split(PERCENT, 2); + String userName = userPass[0]; + + byte[] password = null; + if (userPass.length > 1) { + password = access.decrypt(userPass[1], true).getBytes(); + if (userName.indexOf('@') < 0) { + userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); + } + } + User<LocalPermission> usr; + usr = new User<>(new ConfigPrincipal(userName, password)); + addUser(usr); + access.log(Level.INIT, "Local User:", usr.principal); + + if (userInfo.length > 1) { + Map<String, Permission> newMap = usr.newMap(); + for (String group : userInfo[1].split(COMMA)) { + supportingGroups.add(group); + usr.add(newMap, new LocalPermission(group)); + } + usr.setMap(newMap); + } + } + } + + + private void parseGroupProperties(String groupProperties) throws IOException { + // For each Group name... + for (String group : groupProperties.trim().split(SEMI)) { + String[] groups = group.split(COLON, 2); + if (groups.length <= 1) { + continue; + } + supportingGroups.add(groups[0]); + LocalPermission p = new LocalPermission(groups[0]); + + // Add all users (known by comma separators) + for (String groupMember : groups[1].split(COMMA)) { + // look for password, if so, put in passMap + String[] userPass = groupMember.split(PERCENT, 2); + String userName = userPass[0]; + if (userName.indexOf('@') < 0) { + userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); + } + + User<LocalPermission> usr = null; + byte[] password = null; + if (userPass.length > 1) { + password = access.decrypt(userPass[1], true).getBytes(); + } + usr = getUser(userName, password); + if (usr == null) { + usr = new User<>(new ConfigPrincipal(userName, password)); + addUser(usr); + } + else { + usr.principal = new ConfigPrincipal(userName, password); + } + usr.add(p); + access.log(Level.INIT, "Local User:", usr.principal); + } + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java index 8d6f9698..ee7bab9c 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java @@ -24,27 +24,27 @@ package org.onap.aaf.cadi.lur; import org.onap.aaf.cadi.Permission; public class LocalPermission implements Permission { - private String key; - - public LocalPermission(String role) { - this.key = role; - } - - public String getKey() { - return key; - } + private String key; + + public LocalPermission(String role) { + this.key = role; + } + + public String getKey() { + return key; + } - public String toString() { - return key; - } + public String toString() { + return key; + } - public boolean match(Permission p) { - return key.equals(p.getKey()); - } + public boolean match(Permission p) { + return key.equals(p.getKey()); + } - public String permType() { - return "LOCAL"; - } - - + public String permType() { + return "LOCAL"; + } + + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java index b314f20e..fe9bbd30 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java @@ -28,60 +28,60 @@ import org.onap.aaf.cadi.Lur; import org.onap.aaf.cadi.Permission; public class NullLur implements Lur { - private static final Permission NULL = new Permission() { - @Override - public String permType() { - return ""; - } + private static final Permission NULL = new Permission() { + @Override + public String permType() { + return ""; + } - @Override - public String getKey() { - return ""; - } + @Override + public String getKey() { + return ""; + } - @Override - public boolean match(Permission p) { - return false; - }}; + @Override + public boolean match(Permission p) { + return false; + }}; - public boolean fish(Principal bait, Permission ... pond) { - // Well, for Jenkins, this is ok... It finds out it can't do J2EE Security, and then looks at it's own -// System.err.println("CADI's LUR has not been configured, but is still being called. Access is being denied"); - return false; - } + public boolean fish(Principal bait, Permission ... pond) { + // Well, for Jenkins, this is ok... It finds out it can't do J2EE Security, and then looks at it's own +// System.err.println("CADI's LUR has not been configured, but is still being called. Access is being denied"); + return false; + } - public void fishAll(Principal bait, List<Permission> permissions) { - } + public void fishAll(Principal bait, List<Permission> permissions) { + } - public void destroy() { - } + public void destroy() { + } - public boolean handlesExclusively(Permission ... pond) { - return false; - } + public boolean handlesExclusively(Permission ... pond) { + return false; + } - public boolean handles(Principal p) { - return false; - } + public boolean handles(Principal p) { + return false; + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String) - */ - @Override - public Permission createPerm(String p) { - return NULL; - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String) + */ + @Override + public Permission createPerm(String p) { + return NULL; + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.Lur#clear(java.security.Principal, java.lang.StringBuilder) - */ - @Override - public void clear(Principal p, StringBuilder report) { - report.append(NullLur.class.getSimpleName()); - report.append('\n'); - } - - public String toString() { - return NullLur.class.getSimpleName() + '\n'; - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.Lur#clear(java.security.Principal, java.lang.StringBuilder) + */ + @Override + public void clear(Principal p, StringBuilder report) { + report.append(NullLur.class.getSimpleName()); + report.append('\n'); + } + + public String toString() { + return NullLur.class.getSimpleName() + '\n'; + } }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java index a235f1d4..d3c1e236 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java @@ -32,102 +32,102 @@ import org.onap.aaf.cadi.GetCred; import org.onap.aaf.cadi.Symm; public class BasicPrincipal extends BearerPrincipal implements GetCred { - private static byte[] basic = "Basic ".getBytes(); + private static byte[] basic = "Basic ".getBytes(); - private String name = null; - private String shortName = null; - private String domain; - private byte[] cred = null; - private long created; + private String name = null; + private String shortName = null; + private String domain; + private byte[] cred = null; + private long created; - public BasicPrincipal(String content,String defaultDomain) throws IOException { - created = System.currentTimeMillis(); - ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes()); - // Read past "Basic ", ensuring it starts with it. - for(int i=0;i<basic.length;++i) { - if(bis.read()!=basic[i]) { - name=content; - cred = null; - return; - } - } - BasicOS bos = new BasicOS(content.length()); - Symm.base64.decode(bis,bos); // note: writes directly to name until ':' - if(name==null) throw new IOException("Invalid Coding"); - else cred = bos.toCred(); - int at; - if((at=name.indexOf('@'))>0) { - domain=name.substring(at+1); - shortName=name.substring(0, at); - } else { - shortName = name; - domain=defaultDomain; - name = name + '@' + defaultDomain; - } - } - - public BasicPrincipal(BasicCred bc, String domain) { - name = bc.getUser(); - cred = bc.getCred(); - this.domain = domain; - } + public BasicPrincipal(String content,String defaultDomain) throws IOException { + created = System.currentTimeMillis(); + ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes()); + // Read past "Basic ", ensuring it starts with it. + for(int i=0;i<basic.length;++i) { + if(bis.read()!=basic[i]) { + name=content; + cred = null; + return; + } + } + BasicOS bos = new BasicOS(content.length()); + Symm.base64.decode(bis,bos); // note: writes directly to name until ':' + if(name==null) throw new IOException("Invalid Coding"); + else cred = bos.toCred(); + int at; + if((at=name.indexOf('@'))>0) { + domain=name.substring(at+1); + shortName=name.substring(0, at); + } else { + shortName = name; + domain=defaultDomain; + name = name + '@' + defaultDomain; + } + } + + public BasicPrincipal(BasicCred bc, String domain) { + name = bc.getUser(); + cred = bc.getCred(); + this.domain = domain; + } - private class BasicOS extends OutputStream { - private boolean first = true; - private ByteArrayOutputStream baos; - - public BasicOS(int size) { - baos = new ByteArrayOutputStream(size); - } + private class BasicOS extends OutputStream { + private boolean first = true; + private ByteArrayOutputStream baos; + + public BasicOS(int size) { + baos = new ByteArrayOutputStream(size); + } - @Override - public void write(int b) throws IOException { - if(b==':' && first) { - first = false; - name = new String(baos.toByteArray()); - baos.reset(); // - } else { - baos.write(b); - } - } - - private byte[] toCred() { - return baos.toByteArray(); - } - } - - public String getName() { - return name; - } - - public String getShortName() { - return shortName; - } - - public String getDomain() { - return domain; - } - - public byte[] getCred() { - return cred; - } - - public long created() { - return created; - } + @Override + public void write(int b) throws IOException { + if(b==':' && first) { + first = false; + name = new String(baos.toByteArray()); + baos.reset(); // + } else { + baos.write(b); + } + } + + private byte[] toCred() { + return baos.toByteArray(); + } + } + + public String getName() { + return name; + } + + public String getShortName() { + return shortName; + } + + public String getDomain() { + return domain; + } + + public byte[] getCred() { + return cred; + } + + public long created() { + return created; + } - public String toString() { - return "Basic Authorization for " + name + " evaluated on " + new Date(created).toString(); - } + public String toString() { + return "Basic Authorization for " + name + " evaluated on " + new Date(created).toString(); + } - @Override - public String tag() { - return "BAth"; - } + @Override + public String tag() { + return "BAth"; + } - @Override - public String personalName() { - return name; // personalName not available with Basic Auth - } + @Override + public String personalName() { + return name; // personalName not available with Basic Auth + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java index ea0ff2fe..6fdcdc0d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java @@ -22,12 +22,12 @@ package org.onap.aaf.cadi.principal; public abstract class BearerPrincipal extends TaggedPrincipal { - private String bearer = null; - public BearerPrincipal setBearer(String bearer) { - this.bearer = bearer; - return this; - } - public String getBearer() { - return bearer; - } + private String bearer = null; + public BearerPrincipal setBearer(String bearer) { + this.bearer = bearer; + return this; + } + public String getBearer() { + return bearer; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java index 68229d3d..f81e160d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java @@ -34,32 +34,32 @@ import org.onap.aaf.cadi.taf.HttpTaf; * */ public class CachedBasicPrincipal extends BasicPrincipal implements CachedPrincipal { - private final HttpTaf creator; - private long timeToLive; - private long expires; + private final HttpTaf creator; + private long timeToLive; + private long expires; - public CachedBasicPrincipal(HttpTaf creator, BasicCred bc, String domain, long timeToLive) { - super(bc, domain); - this.creator = creator; - this.timeToLive = timeToLive; - expires = System.currentTimeMillis()+timeToLive; - } - - public CachedBasicPrincipal(HttpTaf creator, String content, String domain, long timeToLive) throws IOException { - super(content, domain); - this.creator = creator; - this.timeToLive = timeToLive; - expires = System.currentTimeMillis()+timeToLive; - } + public CachedBasicPrincipal(HttpTaf creator, BasicCred bc, String domain, long timeToLive) { + super(bc, domain); + this.creator = creator; + this.timeToLive = timeToLive; + expires = System.currentTimeMillis()+timeToLive; + } + + public CachedBasicPrincipal(HttpTaf creator, String content, String domain, long timeToLive) throws IOException { + super(content, domain); + this.creator = creator; + this.timeToLive = timeToLive; + expires = System.currentTimeMillis()+timeToLive; + } - public CachedPrincipal.Resp revalidate(Object state) { - Resp resp = creator.revalidate(this, state); - if(resp.equals(Resp.REVALIDATED))expires = System.currentTimeMillis()+timeToLive; - return resp; - } + public CachedPrincipal.Resp revalidate(Object state) { + Resp resp = creator.revalidate(this, state); + if(resp.equals(Resp.REVALIDATED))expires = System.currentTimeMillis()+timeToLive; + return resp; + } - public long expires() { - return expires; - } + public long expires() { + return expires; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/Kind.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/Kind.java index bb6dc673..8c75701f 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/Kind.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/Kind.java @@ -24,30 +24,30 @@ package org.onap.aaf.cadi.principal; import java.security.Principal; public class Kind { - public static final char X509 = 'X'; - public static final char OAUTH = 'O'; - public static final char AAF_OAUTH='A'; - public static final char BASIC_AUTH = 'B'; - public static final char UNKNOWN = 'U'; - - - public static char getKind(final Principal principal) { - Principal check; - if(principal instanceof TrustPrincipal) { - check = ((TrustPrincipal)principal).original(); - } else { - check = principal; - } - if(check instanceof X509Principal) { - return X509; - } - if(check instanceof OAuth2FormPrincipal) { - // Note: if AAF, will turn into 'A' - return OAUTH; - } - if(check instanceof BasicPrincipal) { - return BASIC_AUTH; - } - return UNKNOWN; - } + public static final char X509 = 'X'; + public static final char OAUTH = 'O'; + public static final char AAF_OAUTH='A'; + public static final char BASIC_AUTH = 'B'; + public static final char UNKNOWN = 'U'; + + + public static char getKind(final Principal principal) { + Principal check; + if(principal instanceof TrustPrincipal) { + check = ((TrustPrincipal)principal).original(); + } else { + check = principal; + } + if(check instanceof X509Principal) { + return X509; + } + if(check instanceof OAuth2FormPrincipal) { + // Note: if AAF, will turn into 'A' + return OAUTH; + } + if(check instanceof BasicPrincipal) { + return BASIC_AUTH; + } + return UNKNOWN; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/OAuth2FormPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/OAuth2FormPrincipal.java index 1df2bd3e..4d13de87 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/OAuth2FormPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/OAuth2FormPrincipal.java @@ -22,40 +22,40 @@ package org.onap.aaf.cadi.principal; public class OAuth2FormPrincipal extends TaggedPrincipal { - private final String username; - private final String client_id; - - /* - * Note: client_id and username might be the same, if only authenticating the Client_ID - */ - public OAuth2FormPrincipal(final String client_id, final String username) { - this.username = username; - this.client_id = client_id; - } - - @Override - public String getName() { - return username; - } - - public String client_id() { - return client_id; - } + private final String username; + private final String client_id; + + /* + * Note: client_id and username might be the same, if only authenticating the Client_ID + */ + public OAuth2FormPrincipal(final String client_id, final String username) { + this.username = username; + this.client_id = client_id; + } + + @Override + public String getName() { + return username; + } + + public String client_id() { + return client_id; + } - @Override - public String tag() { - return "OAuth"; - } + @Override + public String tag() { + return "OAuth"; + } - @Override - public String personalName() { - if(username!=null && username!=client_id) { - StringBuilder sb = new StringBuilder(); - sb.append(username); - sb.append('|'); - sb.append(client_id); - return sb.toString(); - } - return client_id; - } + @Override + public String personalName() { + if(username!=null && username!=client_id) { + StringBuilder sb = new StringBuilder(); + sb.append(username); + sb.append('|'); + sb.append(client_id); + return sb.toString(); + } + return client_id; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/StringTagLookup.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/StringTagLookup.java index a3927168..04bcf59a 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/StringTagLookup.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/StringTagLookup.java @@ -24,12 +24,12 @@ import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.principal.TaggedPrincipal.TagLookup; public class StringTagLookup implements TagLookup { - private String tag; - public StringTagLookup(final String tag) { - this.tag = tag; - } - @Override - public String lookup() throws CadiException { - return tag; - } + private String tag; + public StringTagLookup(final String tag) { + this.tag = tag; + } + @Override + public String lookup() throws CadiException { + return tag; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TaggedPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TaggedPrincipal.java index a3b07c6c..9dddcd63 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TaggedPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TaggedPrincipal.java @@ -26,35 +26,35 @@ import org.onap.aaf.cadi.CadiException; public abstract class TaggedPrincipal implements Principal { - public TaggedPrincipal() { - tagLookup = null; - } - - public TaggedPrincipal(final TagLookup tl) { - tagLookup = tl; - } - - public abstract String tag(); // String representing what kind of Authentication occurred. - - public interface TagLookup { - public String lookup() throws CadiException; - } - - private TagLookup tagLookup; - - public void setTagLookup(TagLookup tl) { - tagLookup = tl; - } - - public String personalName() { - if(tagLookup == null) { - return getName(); - } - try { - return tagLookup.lookup(); - } catch (CadiException e) { - return getName(); - } - } + public TaggedPrincipal() { + tagLookup = null; + } + + public TaggedPrincipal(final TagLookup tl) { + tagLookup = tl; + } + + public abstract String tag(); // String representing what kind of Authentication occurred. + + public interface TagLookup { + public String lookup() throws CadiException; + } + + private TagLookup tagLookup; + + public void setTagLookup(TagLookup tl) { + tagLookup = tl; + } + + public String personalName() { + if(tagLookup == null) { + return getName(); + } + try { + return tagLookup.lookup(); + } catch (CadiException e) { + return getName(); + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java index 09083316..5d4a0586 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java @@ -26,45 +26,45 @@ import java.security.Principal; import org.onap.aaf.cadi.UserChain; public class TrustPrincipal extends BearerPrincipal implements UserChain { - private final String name; - private final Principal original; - private String userChain; - - public TrustPrincipal(final Principal actual, final String asName) { - this.original = actual; - name = asName.trim(); - if(actual instanceof UserChain) { - UserChain uc = (UserChain)actual; - userChain = uc.userChain(); - } else if(actual instanceof TaggedPrincipal) { - userChain=((TaggedPrincipal)actual).tag(); - } else { - userChain = actual.getClass().getSimpleName(); - } - } - - @Override - public String getName() { - return name; - } - - @Override - public String userChain() { - return userChain; - } - - public Principal original() { - return original; - } + private final String name; + private final Principal original; + private String userChain; + + public TrustPrincipal(final Principal actual, final String asName) { + this.original = actual; + name = asName.trim(); + if(actual instanceof UserChain) { + UserChain uc = (UserChain)actual; + userChain = uc.userChain(); + } else if(actual instanceof TaggedPrincipal) { + userChain=((TaggedPrincipal)actual).tag(); + } else { + userChain = actual.getClass().getSimpleName(); + } + } + + @Override + public String getName() { + return name; + } + + @Override + public String userChain() { + return userChain; + } + + public Principal original() { + return original; + } - @Override - public String tag() { - return userChain; - } + @Override + public String tag() { + return userChain; + } - @Override - public String personalName() { - return original.getName() + '[' + userChain + ']'; - } - + @Override + public String personalName() { + return original.getName() + '[' + userChain + ']'; + } + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/UnAuthPrincipal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/UnAuthPrincipal.java index 52f78e80..f0cacd8d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/UnAuthPrincipal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/UnAuthPrincipal.java @@ -24,14 +24,14 @@ package org.onap.aaf.cadi.principal; import java.security.Principal; public class UnAuthPrincipal implements Principal { - private String name; - - public UnAuthPrincipal(final String name) { - this.name = name; - } - @Override - public String getName() { - return name; - } + private String name; + + public UnAuthPrincipal(final String name) { + this.name = name; + } + @Override + public String getName() { + return name; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java index 200b8174..1cd114a0 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java @@ -30,83 +30,83 @@ import org.onap.aaf.cadi.GetCred; import org.onap.aaf.cadi.taf.basic.BasicHttpTaf; public class X509Principal extends BearerPrincipal implements GetCred { - private static final Pattern pattern = Pattern.compile("[a-zA-Z0-9]*\\@[a-zA-Z0-9.]*"); - private final X509Certificate cert; - private final String name; - private byte[] content; - private BasicHttpTaf bht; + private static final Pattern pattern = Pattern.compile("[a-zA-Z0-9]*\\@[a-zA-Z0-9.]*"); + private final X509Certificate cert; + private final String name; + private byte[] content; + private BasicHttpTaf bht; - public X509Principal(String identity, X509Certificate cert) { - name = identity; - content = null; - this.cert = cert; - } + public X509Principal(String identity, X509Certificate cert) { + name = identity; + content = null; + this.cert = cert; + } - public X509Principal(String identity, X509Certificate cert, byte[] content, BasicHttpTaf bht) { - name = identity; - this.content = content; - this.cert = cert; - this.bht = bht; - } + public X509Principal(String identity, X509Certificate cert, byte[] content, BasicHttpTaf bht) { + name = identity; + this.content = content; + this.cert = cert; + this.bht = bht; + } - public X509Principal(X509Certificate cert, byte[] content, BasicHttpTaf bht) throws IOException { - this.content=content; - this.cert = cert; - String _name = null; - String subj = cert.getSubjectDN().getName(); - int cn = subj.indexOf("OU="); - if(cn>=0) { - cn+=3; - int space = subj.indexOf(',',cn); - if(space>=0) { - String id = subj.substring(cn, space); - if(pattern.matcher(id).matches()) { - _name = id; - } - } - } - if(_name==null) { - throw new IOException("X509 does not have Identity as CN"); - } - name = _name; - this.bht = bht; - } - - public String getAsHeader() throws IOException { - try { - if(content==null) { - content=cert.getEncoded(); - } - } catch (CertificateEncodingException e) { - throw new IOException(e); - } - return "X509 " + content; - } - - public String toString() { - return "X509 Authentication for " + name; - } + public X509Principal(X509Certificate cert, byte[] content, BasicHttpTaf bht) throws IOException { + this.content=content; + this.cert = cert; + String _name = null; + String subj = cert.getSubjectDN().getName(); + int cn = subj.indexOf("OU="); + if(cn>=0) { + cn+=3; + int space = subj.indexOf(',',cn); + if(space>=0) { + String id = subj.substring(cn, space); + if(pattern.matcher(id).matches()) { + _name = id; + } + } + } + if(_name==null) { + throw new IOException("X509 does not have Identity as CN"); + } + name = _name; + this.bht = bht; + } + + public String getAsHeader() throws IOException { + try { + if(content==null) { + content=cert.getEncoded(); + } + } catch (CertificateEncodingException e) { + throw new IOException(e); + } + return "X509 " + content; + } + + public String toString() { + return "X509 Authentication for " + name; + } - public byte[] getCred() { - try { - return content==null?(content=cert.getEncoded()):content; - } catch (CertificateEncodingException e) { - return null; - } - } + public byte[] getCred() { + try { + return content==null?(content=cert.getEncoded()):content; + } catch (CertificateEncodingException e) { + return null; + } + } - public String getName() { - return name; - } + public String getName() { + return name; + } - @Override - public String tag() { - return "x509"; - } + @Override + public String tag() { + return "x509"; + } - public BasicHttpTaf getBasicHttpTaf() { - return bht; - } + public BasicHttpTaf getBasicHttpTaf() { + return bht; + } } 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 fb54abdb..b3ac0945 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 @@ -35,102 +35,102 @@ import org.onap.aaf.cadi.util.Timing; */ public abstract class AbsTafResp implements TafResp { - protected final Access access; - protected final String tafName; - protected final TaggedPrincipal principal; - protected final String desc; - private float timing; + protected final Access access; + protected final String tafName; + protected final TaggedPrincipal principal; + protected final String desc; + private float timing; - /** - * 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, TaggedPrincipal principal, String description) { - this.access = access; - this.tafName = tafname; - this.principal = principal; - 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, TaggedPrincipal principal, String description) { + this.access = access; + this.tafName = tafname; + this.principal = principal; + this.desc = description; + } - /** - * isValid() - * - * Respond in the affirmative if the TAF was able to Authenticate - */ - public boolean isValid() { - return principal != null; - } + /** + * isValid() + * + * Respond in the affirmative if the TAF was able to Authenticate + */ + public boolean isValid() { + return principal != null; + } - /** - * desc() - * - * Respond with description of response as given by the TAF - */ - public String desc() { - return desc; - } + /** + * desc() + * + * Respond with description of response as given by the TAF + */ + public String desc() { + return desc; + } - /** - * isAuthenticated() - * - * Respond with the TAF's code of whether Authenticated, or suggested next steps - * default is either IS_AUTHENTICATED, or TRY_ANOTHER_TAF. The TAF can overload - * and suggest others, such as "NO_FURTHER_PROCESSING", if it can detect that this - * is some sort of security breach (i.e. Denial of Service) - */ - public RESP isAuthenticated() { - return principal==null?RESP.TRY_ANOTHER_TAF:RESP.IS_AUTHENTICATED; - } + /** + * isAuthenticated() + * + * Respond with the TAF's code of whether Authenticated, or suggested next steps + * default is either IS_AUTHENTICATED, or TRY_ANOTHER_TAF. The TAF can overload + * and suggest others, such as "NO_FURTHER_PROCESSING", if it can detect that this + * is some sort of security breach (i.e. Denial of Service) + */ + public RESP isAuthenticated() { + return principal==null?RESP.TRY_ANOTHER_TAF:RESP.IS_AUTHENTICATED; + } - /** - * getPrincipal() - * - * Return the principal created by the TAF based on Authentication. - * - * Returns "null" if Authentication failed (no principal) - */ - public TaggedPrincipal getPrincipal() { - return principal; - } + /** + * getPrincipal() + * + * Return the principal created by the TAF based on Authentication. + * + * Returns "null" if Authentication failed (no principal) + */ + public TaggedPrincipal getPrincipal() { + return principal; + } - /** - * getAccess() - * - * Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated. - */ - public Access getAccess() { - return access; - } + /** + * getAccess() + * + * Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated. + */ + public Access getAccess() { + return access; + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.taf.TafResp#isFailedAttempt() - */ - public boolean isFailedAttempt() { - return false; - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#isFailedAttempt() + */ + public boolean isFailedAttempt() { + return false; + } - @Override - public float timing() { - return timing; - } - - @Override - public void timing(final long start) { - timing = Timing.millis(start); - } + @Override + public float timing() { + return timing; + } + + @Override + public void timing(final long start) { + timing = Timing.millis(start); + } - @Override - public String taf() { - return tafName; - } + @Override + public String taf() { + return tafName; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java index d772d493..b248e553 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java @@ -36,49 +36,49 @@ import org.onap.aaf.cadi.Taf; * */ public class EpiTaf implements Taf { - private Taf[] tafs; - - /** - * EpiTaf constructor - * - * Construct the EpiTaf from variable TAF parameters - * @param tafs - * @throws CadiException - */ - public EpiTaf(Taf ... tafs) throws CadiException{ - this.tafs = tafs; - if(tafs.length==0) throw new CadiException("Need at least one Taf implementation in constructor"); - } + private Taf[] tafs; + + /** + * EpiTaf constructor + * + * Construct the EpiTaf from variable TAF parameters + * @param tafs + * @throws CadiException + */ + public EpiTaf(Taf ... tafs) throws CadiException{ + this.tafs = tafs; + if(tafs.length==0) throw new CadiException("Need at least one Taf implementation in constructor"); + } - /** - * validate - * - * Respond with the first TAF to authenticate user based on variable info and "LifeForm" (is it - * a human behind an interface, or a server behind a protocol). - * - * If there is no TAF that can authenticate, respond with the first TAF that suggests it can - * establish an Authentication conversation (TRY_AUTHENTICATING). - * - * If no TAF declares either, respond with NullTafResp (which denies all questions) - */ - public TafResp validate(LifeForm reading, String... info) { - TafResp tresp,firstTryAuth=null; - for(Taf taf : tafs) { - tresp = taf.validate(reading, info); - switch(tresp.isAuthenticated()) { - case TRY_ANOTHER_TAF: - break; - case TRY_AUTHENTICATING: - if(firstTryAuth==null)firstTryAuth=tresp; - break; - default: - return tresp; - } - } + /** + * validate + * + * Respond with the first TAF to authenticate user based on variable info and "LifeForm" (is it + * a human behind an interface, or a server behind a protocol). + * + * If there is no TAF that can authenticate, respond with the first TAF that suggests it can + * establish an Authentication conversation (TRY_AUTHENTICATING). + * + * If no TAF declares either, respond with NullTafResp (which denies all questions) + */ + public TafResp validate(LifeForm reading, String... info) { + TafResp tresp,firstTryAuth=null; + for(Taf taf : tafs) { + tresp = taf.validate(reading, info); + switch(tresp.isAuthenticated()) { + case TRY_ANOTHER_TAF: + break; + case TRY_AUTHENTICATING: + if(firstTryAuth==null)firstTryAuth=tresp; + break; + default: + return tresp; + } + } - // No TAFs configured, at this point. It is safer at this point to be "not validated", - // rather than "let it go" - return firstTryAuth == null?NullTafResp.singleton():firstTryAuth; - } + // No TAFs configured, at this point. It is safer at this point to be "not validated", + // rather than "let it go" + return firstTryAuth == null?NullTafResp.singleton():firstTryAuth; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java index 1d7967e3..b0f56603 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java @@ -47,168 +47,168 @@ import org.onap.aaf.cadi.TrustChecker; * */ public class HttpEpiTaf implements HttpTaf { - private HttpTaf[] tafs; - private Access access; - private Locator<URI> locator; - private TrustChecker trustChecker; - - /** - * HttpEpiTaf constructor - * - * Construct the HttpEpiTaf from variable Http specific TAF parameters - - * @param tafs - * @throws CadiException - */ - public HttpEpiTaf(Access access, Locator<URI> locator, TrustChecker tc, HttpTaf ... tafs) throws CadiException{ - this.tafs = tafs; - this.access = access; - this.locator = locator; - this.trustChecker = tc; - // Establish what Header Property to look for UserChain/Trust Props - - if (tafs.length == 0) { - throw new CadiException("Need at least one HttpTaf implementation in constructor"); - } - } - - /** - * validate - * - * Respond with the first Http specific TAF to authenticate user based on variable info - * and "LifeForm" (is it a human behind a browser, or a server utilizing HTTP Protocol). - * - * If there is no HttpTAF that can authenticate, respond with the first TAF that suggests it can - * establish an Authentication conversation (TRY_AUTHENTICATING) (Examples include a redirect to CSP - * Servers for CSP Cookie, or BasicAuth 401 response, suggesting User/Password for given Realm - * submission - * - * If no TAF declares either, respond with NullTafResp (which denies all questions) - */ - public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { - // Given a LifeForm Neutral, for HTTP, we need to discover true Life-Form Readings - if (reading == LifeForm.LFN) { - reading = tricorderScan(req); - } - TafResp tresp = null; - TafResp firstTry = null; - List<Redirectable> redirectables = null; - List<TafResp> log; - if(access.willLog(Level.DEBUG)) { - log = new ArrayList<>(); - } else { - log = null; - } - try { - for (HttpTaf taf : tafs) { - final long start = System.nanoTime(); - tresp = taf.validate(reading, req, resp); - addToLog(log, tresp, start); - switch(tresp.isAuthenticated()) { - case TRY_ANOTHER_TAF: - break; // and loop - case TRY_AUTHENTICATING: - if (tresp instanceof Redirectable) { - if (redirectables == null) { - redirectables = new ArrayList<>(); - } - redirectables.add((Redirectable)tresp); - } else if (firstTry == null) { - firstTry = tresp; - } - break; - case IS_AUTHENTICATED: - tresp = trustChecker.mayTrust(tresp, req); - return tresp; - default: - return tresp; - } - } - } finally { - printLog(log); - } - - // If No TAFs configured, at this point. It is safer at this point to be "not validated", - // rather than "let it go" - // Note: if exists, there will always be more than 0 entries, according to above code - if (redirectables == null) { - return (firstTry != null) ? firstTry : NullTafResp.singleton(); - } - - // If there is one Tryable entry then return it - if (redirectables.size() > 1) { - return LoginPageTafResp.create(access, locator, resp, redirectables); - } else { - return redirectables.get(0); - } - } - - public boolean revalidate(Principal prin) throws Exception { - return false; - } - - /* - * Since this is internal, we use a little Star Trek humor to indicate looking in the HTTP Request to see if we can determine what kind - * of "LifeForm" reading we can determine, i.e. is there a Human (CarbonBasedLifeForm) behind a browser, or is it mechanical - * id (SiliconBasedLifeForm)? This makes a difference in some Authentication, i.e CSP, which doesn't work well for SBLFs - */ - private LifeForm tricorderScan(HttpServletRequest req) { - // For simplicity's sake, we'll say Humans use FQDNs, not IPs. - - // Current guess that only Browsers bother to set "Agent" codes that identify the kind of browser they are. - // If mechanical frameworks are found that populate this, then more advanced analysis may be required - // Jonathan 1/22/2013 - String agent = req.getHeader("User-Agent"); - if (agent != null && agent.startsWith("Mozilla")) { // covers I.E./Firefox/Safari/probably any other "advanced" Browser see http://en.wikipedia.org/wiki/User_agent - return LifeForm.CBLF; - } - return LifeForm.SBLF; // notably skips "curl","wget", (which is desired behavior. We don't want to try CSP, etc on these) - } - - public Resp revalidate(CachedPrincipal prin, Object state) { - Resp resp; - for (HttpTaf taf : tafs) { - resp = taf.revalidate(prin, state); - if (resp != Resp.NOT_MINE) { - return resp; - } -// switch(resp) { -// case NOT_MINE: -// break; -// default: -// return resp; -// } - } - return Resp.NOT_MINE; - } - - private void addToLog(List<TafResp> log, final TafResp tresp, final long start) { - if (log == null) { - return; - } - tresp.timing(start); - log.add(tresp); - } - - private void printLog(List<TafResp> log) { - if (log == null) { - return; - } - for (TafResp tresp : log) { - access.printf(Level.DEBUG, "%s: %s, ms=%f", tresp.taf(), tresp.desc(), tresp.timing()); - } - } - - /** - * List HttpTafs with their "toString" representations... primarily useful for Debugging in an IDE - * like Eclipse. - */ - public String toString() { - StringBuilder sb = new StringBuilder(); - for (HttpTaf ht : tafs) { - sb.append(ht.toString()); - sb.append(". "); - } - return sb.toString(); - } + private HttpTaf[] tafs; + private Access access; + private Locator<URI> locator; + private TrustChecker trustChecker; + + /** + * HttpEpiTaf constructor + * + * Construct the HttpEpiTaf from variable Http specific TAF parameters + + * @param tafs + * @throws CadiException + */ + public HttpEpiTaf(Access access, Locator<URI> locator, TrustChecker tc, HttpTaf ... tafs) throws CadiException{ + this.tafs = tafs; + this.access = access; + this.locator = locator; + this.trustChecker = tc; + // Establish what Header Property to look for UserChain/Trust Props + + if (tafs.length == 0) { + throw new CadiException("Need at least one HttpTaf implementation in constructor"); + } + } + + /** + * validate + * + * Respond with the first Http specific TAF to authenticate user based on variable info + * and "LifeForm" (is it a human behind a browser, or a server utilizing HTTP Protocol). + * + * If there is no HttpTAF that can authenticate, respond with the first TAF that suggests it can + * establish an Authentication conversation (TRY_AUTHENTICATING) (Examples include a redirect to CSP + * Servers for CSP Cookie, or BasicAuth 401 response, suggesting User/Password for given Realm + * submission + * + * If no TAF declares either, respond with NullTafResp (which denies all questions) + */ + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + // Given a LifeForm Neutral, for HTTP, we need to discover true Life-Form Readings + if (reading == LifeForm.LFN) { + reading = tricorderScan(req); + } + TafResp tresp = null; + TafResp firstTry = null; + List<Redirectable> redirectables = null; + List<TafResp> log; + if(access.willLog(Level.DEBUG)) { + log = new ArrayList<>(); + } else { + log = null; + } + try { + for (HttpTaf taf : tafs) { + final long start = System.nanoTime(); + tresp = taf.validate(reading, req, resp); + addToLog(log, tresp, start); + switch(tresp.isAuthenticated()) { + case TRY_ANOTHER_TAF: + break; // and loop + case TRY_AUTHENTICATING: + if (tresp instanceof Redirectable) { + if (redirectables == null) { + redirectables = new ArrayList<>(); + } + redirectables.add((Redirectable)tresp); + } else if (firstTry == null) { + firstTry = tresp; + } + break; + case IS_AUTHENTICATED: + tresp = trustChecker.mayTrust(tresp, req); + return tresp; + default: + return tresp; + } + } + } finally { + printLog(log); + } + + // If No TAFs configured, at this point. It is safer at this point to be "not validated", + // rather than "let it go" + // Note: if exists, there will always be more than 0 entries, according to above code + if (redirectables == null) { + return (firstTry != null) ? firstTry : NullTafResp.singleton(); + } + + // If there is one Tryable entry then return it + if (redirectables.size() > 1) { + return LoginPageTafResp.create(access, locator, resp, redirectables); + } else { + return redirectables.get(0); + } + } + + public boolean revalidate(Principal prin) throws Exception { + return false; + } + + /* + * Since this is internal, we use a little Star Trek humor to indicate looking in the HTTP Request to see if we can determine what kind + * of "LifeForm" reading we can determine, i.e. is there a Human (CarbonBasedLifeForm) behind a browser, or is it mechanical + * id (SiliconBasedLifeForm)? This makes a difference in some Authentication, i.e CSP, which doesn't work well for SBLFs + */ + private LifeForm tricorderScan(HttpServletRequest req) { + // For simplicity's sake, we'll say Humans use FQDNs, not IPs. + + // Current guess that only Browsers bother to set "Agent" codes that identify the kind of browser they are. + // If mechanical frameworks are found that populate this, then more advanced analysis may be required + // Jonathan 1/22/2013 + String agent = req.getHeader("User-Agent"); + if (agent != null && agent.startsWith("Mozilla")) { // covers I.E./Firefox/Safari/probably any other "advanced" Browser see http://en.wikipedia.org/wiki/User_agent + return LifeForm.CBLF; + } + return LifeForm.SBLF; // notably skips "curl","wget", (which is desired behavior. We don't want to try CSP, etc on these) + } + + public Resp revalidate(CachedPrincipal prin, Object state) { + Resp resp; + for (HttpTaf taf : tafs) { + resp = taf.revalidate(prin, state); + if (resp != Resp.NOT_MINE) { + return resp; + } +// switch(resp) { +// case NOT_MINE: +// break; +// default: +// return resp; +// } + } + return Resp.NOT_MINE; + } + + private void addToLog(List<TafResp> log, final TafResp tresp, final long start) { + if (log == null) { + return; + } + tresp.timing(start); + log.add(tresp); + } + + private void printLog(List<TafResp> log) { + if (log == null) { + return; + } + for (TafResp tresp : log) { + access.printf(Level.DEBUG, "%s: %s, ms=%f", tresp.taf(), tresp.desc(), tresp.timing()); + } + } + + /** + * List HttpTafs with their "toString" representations... primarily useful for Debugging in an IDE + * like Eclipse. + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + for (HttpTaf ht : tafs) { + sb.append(ht.toString()); + sb.append(". "); + } + return sb.toString(); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java index 9484458c..77976ce2 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java @@ -38,23 +38,23 @@ import org.onap.aaf.cadi.Taf.LifeForm; * */ public interface HttpTaf { - /** - * validate - * - * Validate the Request, and respond with created TafResp object. - * - * @param reading - * @param req - * @param resp - * @return - */ - public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp); - - /** - * Re-Validate Credential - * - * @param prin - * @return - */ - public CachedPrincipal.Resp revalidate(CachedPrincipal prin,Object state); + /** + * validate + * + * Validate the Request, and respond with created TafResp object. + * + * @param reading + * @param req + * @param resp + * @return + */ + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp); + + /** + * Re-Validate Credential + * + * @param prin + * @return + */ + public CachedPrincipal.Resp revalidate(CachedPrincipal prin,Object state); } 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 c8abec0a..a5ce45b7 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 @@ -33,68 +33,68 @@ import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.Locator.Item; public class LoginPageTafResp extends AbsTafResp { - private final HttpServletResponse httpResp; - private final String loginPageURL; + private final HttpServletResponse httpResp; + 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"); - httpResp = resp; - this.loginPageURL = loginPageURL; - } + private LoginPageTafResp(Access access, final HttpServletResponse resp, String loginPageURL) { + super(access, "LoginPage", null, "Multiple Possible HTTP Logins available. Redirecting to Login Choice Page"); + httpResp = resp; + this.loginPageURL = loginPageURL; + } - @Override - public RESP authenticate() throws IOException { - httpResp.sendRedirect(loginPageURL); - return RESP.HTTP_REDIRECT_INVOKED; - } - - @Override - public RESP isAuthenticated() { - return RESP.TRY_AUTHENTICATING; - } - - public static TafResp create(Access access, Locator<URI> locator, final HttpServletResponse resp, List<Redirectable> redirectables) { - if (locator == null) { - if (!redirectables.isEmpty()) { - access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf"); - return redirectables.get(0); - } - return NullTafResp.singleton(); - } + @Override + public RESP authenticate() throws IOException { + httpResp.sendRedirect(loginPageURL); + return RESP.HTTP_REDIRECT_INVOKED; + } + + @Override + public RESP isAuthenticated() { + return RESP.TRY_AUTHENTICATING; + } + + public static TafResp create(Access access, Locator<URI> locator, final HttpServletResponse resp, List<Redirectable> redirectables) { + if (locator == null) { + if (!redirectables.isEmpty()) { + access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf"); + return redirectables.get(0); + } + return NullTafResp.singleton(); + } - try { - Item item = locator.best(); - URI uri = locator.get(item); - if (uri == null) { - return NullTafResp.singleton(); - } + try { + Item item = locator.best(); + URI uri = locator.get(item); + if (uri == null) { + return NullTafResp.singleton(); + } - StringBuilder sb = new StringBuilder(uri.toString()); - String query = uri.getQuery(); - boolean first = ((query == null) || (query.length() == 0)); - for (Redirectable redir : redirectables) { - if (first) { - sb.append('?'); - first = false; - } - else { - sb.append('&'); - } - sb.append(redir.get()); - } - if (!redirectables.isEmpty()) { - return new LoginPageTafResp(access, resp, sb.toString()); - } - } catch (Exception e) { - access.log(e, "Error deriving Login Page location"); - } + StringBuilder sb = new StringBuilder(uri.toString()); + String query = uri.getQuery(); + boolean first = ((query == null) || (query.length() == 0)); + for (Redirectable redir : redirectables) { + if (first) { + sb.append('?'); + first = false; + } + else { + sb.append('&'); + } + sb.append(redir.get()); + } + if (!redirectables.isEmpty()) { + return new LoginPageTafResp(access, resp, sb.toString()); + } + } catch (Exception e) { + access.log(e, "Error deriving Login Page location"); + } - return NullTafResp.singleton(); - } - - @Override - public String taf() { - return "LoginPage"; - } + return NullTafResp.singleton(); + } + + @Override + public String taf() { + return "LoginPage"; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java index e8293faa..7e834794 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java @@ -37,28 +37,28 @@ import org.onap.aaf.cadi.CachedPrincipal.Resp; * */ public class NullTaf implements Taf, HttpTaf { - // Singleton Pattern - public NullTaf() {} + // Singleton Pattern + public NullTaf() {} - /** - * validate - * - * Always Respond with a NullTafResp, which declares it is unauthenticated, and unauthorized - */ - public TafResp validate(LifeForm reading, String... info) { - return NullTafResp.singleton(); - } + /** + * validate + * + * Always Respond with a NullTafResp, which declares it is unauthenticated, and unauthorized + */ + public TafResp validate(LifeForm reading, String... info) { + return NullTafResp.singleton(); + } - /** - * validate - * - * Always Respond with a NullTafResp, which declares it is unauthenticated, and unauthorized - */ - public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { - return NullTafResp.singleton(); - } + /** + * validate + * + * Always Respond with a NullTafResp, which declares it is unauthenticated, and unauthorized + */ + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + return NullTafResp.singleton(); + } - public Resp revalidate(CachedPrincipal prin, Object state) { - return Resp.NOT_MINE; - } + public Resp revalidate(CachedPrincipal prin, Object state) { + return Resp.NOT_MINE; + } } 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 af6ef9cc..a3c8f5bb 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 @@ -32,57 +32,57 @@ import org.onap.aaf.cadi.principal.TaggedPrincipal; * */ class NullTafResp implements TafResp { - private NullTafResp(){} - - private static TafResp singleton = new NullTafResp(); - - public static TafResp singleton() { - return singleton; - } - - public boolean isValid() { - return false; - } - - public RESP isAuthenticated() { - return RESP.NO_FURTHER_PROCESSING; - } - - public String desc() { - return "All Authentication denied"; - } - - public RESP authenticate() throws IOException { - return RESP.NO_FURTHER_PROCESSING; - } + private NullTafResp(){} + + private static TafResp singleton = new NullTafResp(); + + public static TafResp singleton() { + return singleton; + } + + public boolean isValid() { + return false; + } + + public RESP isAuthenticated() { + return RESP.NO_FURTHER_PROCESSING; + } + + public String desc() { + return "All Authentication denied"; + } + + public RESP authenticate() throws IOException { + return RESP.NO_FURTHER_PROCESSING; + } - public TaggedPrincipal getPrincipal() { - return null; - } + public TaggedPrincipal getPrincipal() { + return null; + } - public Access getAccess() { - return Access.NULL; - } + public Access getAccess() { + return Access.NULL; + } - /* (non-Javadoc) - * @see org.onap.aaf.cadi.taf.TafResp#isFailedAttempt() - */ - public boolean isFailedAttempt() { - return true; - } + /* (non-Javadoc) + * @see org.onap.aaf.cadi.taf.TafResp#isFailedAttempt() + */ + public boolean isFailedAttempt() { + return true; + } - @Override - public float timing() { - return 0; - } + @Override + public float timing() { + return 0; + } - @Override - public void timing(long start) { - } - - @Override - public String taf() { - return "NULL"; - } + @Override + public void timing(long start) { + } + + @Override + public String taf() { + return "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 a38c8532..e6555051 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 @@ -34,56 +34,56 @@ import org.onap.aaf.cadi.util.Timing; * */ public class PuntTafResp implements TafResp { - private final String name; - private final String desc; - private float timing; + private final String name; + private final String desc; + private float timing; - public PuntTafResp(String name, String explanation) { - this.name = name; - desc = "Not processing this transaction: " + explanation; - } - - public boolean isValid() { - return false; - } - - public RESP isAuthenticated() { - return RESP.TRY_ANOTHER_TAF; - } - - public String desc() { - return desc; - } - - public RESP authenticate() throws IOException { - return RESP.TRY_ANOTHER_TAF; - } + public PuntTafResp(String name, String explanation) { + this.name = name; + desc = "Not processing this transaction: " + explanation; + } + + public boolean isValid() { + return false; + } + + public RESP isAuthenticated() { + return RESP.TRY_ANOTHER_TAF; + } + + public String desc() { + return desc; + } + + public RESP authenticate() throws IOException { + return RESP.TRY_ANOTHER_TAF; + } - public TaggedPrincipal getPrincipal() { - return null; - } + public TaggedPrincipal getPrincipal() { + return null; + } - public Access getAccess() { - return NullTafResp.singleton().getAccess(); - } + public Access getAccess() { + return NullTafResp.singleton().getAccess(); + } - public boolean isFailedAttempt() { - return false; - } + public boolean isFailedAttempt() { + return false; + } - @Override - public float timing() { - return timing; - } + @Override + public float timing() { + return timing; + } - @Override - public void timing(long start) { - timing = Timing.millis(start); - } - - @Override - public String taf() { - return name; - } + @Override + public void timing(long start) { + timing = Timing.millis(start); + } + + @Override + public String taf() { + return name; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java index 8dc5c118..47c262b0 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java @@ -22,10 +22,10 @@ package org.onap.aaf.cadi.taf; public interface Redirectable extends TafResp { - /** - * Create a Redirectable URL entry prefaced by a URLEncoder.String for a Menu - * example: - * "Global Login=https://xxxx....." - */ - public String get(); + /** + * Create a Redirectable URL entry prefaced by a URLEncoder.String for a Menu + * example: + * "Global Login=https://xxxx....." + */ + public String get(); } 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 acade37a..f3afde72 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 @@ -34,78 +34,78 @@ import org.onap.aaf.cadi.principal.TaggedPrincipal; * */ public interface TafResp { - public static enum RESP { - IS_AUTHENTICATED, - NO_FURTHER_PROCESSING, - TRY_AUTHENTICATING, - TRY_ANOTHER_TAF, - FAIL, - // A note was made to avoid the response REDIRECT. However, I have deemed that it is - // unavoidable when the underlying TAF did do a REDIRECT, because it requires a HTTP - // Service code to exit without modifying the Response any further. - // Therefore, I have changed this to indicate what HAS happened, with should accommodate - // both positions. Jonathan 10/18/2012 -// public static final int HTTP_REDIRECT_INVOKED = 11; - HTTP_REDIRECT_INVOKED, - HAS_PROCESSED}; - - /** - * Basic success check - * @return - */ - public boolean isValid(); - - /** - * String description of what has occurred (for logging/exceptions) - * @return - */ - public String desc(); - - /** - * Check Response - * @return - */ - public RESP isAuthenticated(); + public static enum RESP { + IS_AUTHENTICATED, + NO_FURTHER_PROCESSING, + TRY_AUTHENTICATING, + TRY_ANOTHER_TAF, + FAIL, + // A note was made to avoid the response REDIRECT. However, I have deemed that it is + // unavoidable when the underlying TAF did do a REDIRECT, because it requires a HTTP + // Service code to exit without modifying the Response any further. + // Therefore, I have changed this to indicate what HAS happened, with should accommodate + // both positions. Jonathan 10/18/2012 +// public static final int HTTP_REDIRECT_INVOKED = 11; + HTTP_REDIRECT_INVOKED, + HAS_PROCESSED}; + + /** + * Basic success check + * @return + */ + public boolean isValid(); + + /** + * String description of what has occurred (for logging/exceptions) + * @return + */ + public String desc(); + + /** + * Check Response + * @return + */ + public RESP isAuthenticated(); - /** - * Authenticate, returning FAIL or Other Valid indication - * - * HTTP implementations should watch for "HTTP_REDIRECT_INVOKED", and end the HTTP call appropriately. - * @return - * @throws CadiException - */ - public RESP authenticate() throws IOException; + /** + * Authenticate, returning FAIL or Other Valid indication + * + * HTTP implementations should watch for "HTTP_REDIRECT_INVOKED", and end the HTTP call appropriately. + * @return + * @throws CadiException + */ + public RESP authenticate() throws IOException; - /** - * Once authenticated, this object should hold a Principal created from the authorization - * @return - */ - public TaggedPrincipal getPrincipal(); + /** + * Once authenticated, this object should hold a Principal created from the authorization + * @return + */ + public TaggedPrincipal getPrincipal(); - /** - * get the Access object which created this object, allowing the responder to appropriate Log, etc - */ - public Access getAccess(); - - /** - * Be able to check if part of a Failed attempt - */ - public boolean isFailedAttempt(); - - /** - * report how long this took - * @return - */ - public float timing(); + /** + * get the Access object which created this object, allowing the responder to appropriate Log, etc + */ + public Access getAccess(); + + /** + * Be able to check if part of a Failed attempt + */ + public boolean isFailedAttempt(); + + /** + * report how long this took + * @return + */ + public float timing(); - /** - * Set end of timing in Millis, given Nanos - * @param start - */ - void timing(long start); - - /** - * Support Taf Name - */ - String taf(); + /** + * Set end of timing in Millis, given Nanos + * @param start + */ + void timing(long start); + + /** + * Support Taf Name + */ + String taf(); } 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 98ead3ca..6b8adeb8 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 @@ -28,67 +28,67 @@ import org.onap.aaf.cadi.principal.TaggedPrincipal; import org.onap.aaf.cadi.util.Timing; public class TrustNotTafResp implements TafResp { - private final TafResp delegate; - private final String desc; - private float timing; - - public TrustNotTafResp(final TafResp delegate, final String desc) { - this.delegate = delegate; - this.desc = desc; - } - - @Override - public boolean isValid() { - return false; - } + private final TafResp delegate; + private final String desc; + private float timing; + + public TrustNotTafResp(final TafResp delegate, final String desc) { + this.delegate = delegate; + this.desc = desc; + } + + @Override + public boolean isValid() { + return false; + } - @Override - public String desc() { - return desc; - } + @Override + public String desc() { + return desc; + } - @Override - public RESP isAuthenticated() { - return RESP.NO_FURTHER_PROCESSING; - } + @Override + public RESP isAuthenticated() { + return RESP.NO_FURTHER_PROCESSING; + } - @Override - public RESP authenticate() throws IOException { - return RESP.NO_FURTHER_PROCESSING; - } + @Override + public RESP authenticate() throws IOException { + return RESP.NO_FURTHER_PROCESSING; + } - @Override - public TaggedPrincipal getPrincipal() { - return delegate.getPrincipal(); - } + @Override + public TaggedPrincipal getPrincipal() { + return delegate.getPrincipal(); + } - @Override - public Access getAccess() { - return delegate.getAccess(); - } + @Override + public Access getAccess() { + return delegate.getAccess(); + } - @Override - public boolean isFailedAttempt() { - return true; - } - @Override - public float timing() { - return timing; - } + @Override + public boolean isFailedAttempt() { + return true; + } + @Override + public float timing() { + return timing; + } - @Override - public void timing(long start) { - timing = Timing.millis(start); - } - - @Override - public String toString() { - return desc(); - } - - @Override - public String taf() { - return "TrustNot"; - } + @Override + public void timing(long start) { + timing = Timing.millis(start); + } + + @Override + public String toString() { + return desc(); + } + + @Override + public String taf() { + return "TrustNot"; + } } 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 9d3b28ca..91f9f8c4 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 @@ -28,68 +28,68 @@ import org.onap.aaf.cadi.principal.TaggedPrincipal; import org.onap.aaf.cadi.util.Timing; public class TrustTafResp implements TafResp { - private final TafResp delegate; - private final TaggedPrincipal principal; - private final String desc; - private float timing; - - public TrustTafResp(final TafResp delegate, final TaggedPrincipal principal, final String desc) { - this.delegate = delegate; - this.principal = principal; - this.desc = desc + ' ' + delegate.desc(); - } - - @Override - public boolean isValid() { - return delegate.isValid(); - } + private final TafResp delegate; + private final TaggedPrincipal principal; + private final String desc; + private float timing; + + public TrustTafResp(final TafResp delegate, final TaggedPrincipal principal, final String desc) { + this.delegate = delegate; + this.principal = principal; + this.desc = desc + ' ' + delegate.desc(); + } + + @Override + public boolean isValid() { + return delegate.isValid(); + } - @Override - public String desc() { - return desc; - } + @Override + public String desc() { + return desc; + } - @Override - public RESP isAuthenticated() { - return delegate.isAuthenticated(); - } + @Override + public RESP isAuthenticated() { + return delegate.isAuthenticated(); + } - @Override - public RESP authenticate() throws IOException { - return delegate.authenticate(); - } + @Override + public RESP authenticate() throws IOException { + return delegate.authenticate(); + } - @Override - public TaggedPrincipal getPrincipal() { - return principal; - } + @Override + public TaggedPrincipal getPrincipal() { + return principal; + } - @Override - public Access getAccess() { - return delegate.getAccess(); - } + @Override + public Access getAccess() { + return delegate.getAccess(); + } - @Override - public boolean isFailedAttempt() { - return delegate.isFailedAttempt(); - } - @Override - public float timing() { - return timing; - } + @Override + public boolean isFailedAttempt() { + return delegate.isFailedAttempt(); + } + @Override + public float timing() { + return timing; + } - @Override - public void timing(long start) { - timing = Timing.millis(start); - } - - public String toString() { - return principal.getName() + " by trust of " + desc(); - } - - @Override - public String taf() { - return "Trust"; - } + @Override + public void timing(long start) { + timing = Timing.millis(start); + } + + public String toString() { + return principal.getName() + " by trust of " + desc(); + } + + @Override + public String taf() { + return "Trust"; + } } 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 8fc985cf..21830b01 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 @@ -60,139 +60,139 @@ import org.onap.aaf.cadi.taf.dos.DenialOfServiceTaf; * */ public class BasicHttpTaf implements HttpTaf { - private Access access; - private String realm; - private CredVal rbac; - private Map<String,CredVal> rbacs = new TreeMap<>(); - private boolean warn; - private long timeToLive; - - public BasicHttpTaf(Access access, CredVal rbac, String realm, long timeToLive, boolean turnOnWarning) { - this.access = access; - this.realm = realm; - this.rbac = rbac; - this.warn = turnOnWarning; - this.timeToLive = timeToLive; - } + private Access access; + private String realm; + private CredVal rbac; + private Map<String,CredVal> rbacs = new TreeMap<>(); + private boolean warn; + private long timeToLive; + + public BasicHttpTaf(Access access, CredVal rbac, String realm, long timeToLive, boolean turnOnWarning) { + this.access = access; + this.realm = realm; + this.rbac = rbac; + this.warn = turnOnWarning; + this.timeToLive = timeToLive; + } - public void add(final CredValDomain cvd) { - rbacs.put(cvd.domain(), cvd); - } - - /** - * Note: BasicHttp works for either Carbon Based (Humans) or Silicon Based (machine) Lifeforms. - * @see Taf - */ - 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 - if(req instanceof BasicCred) { - BasicCred bc = (BasicCred)req; - if(bc.getUser()!=null) { // CadiWrap, if set, makes sure User & Password are both valid, or both null - if(DenialOfServiceTaf.isDeniedID(bc.getUser())!=null) { - return DenialOfServiceTaf.respDenyID(access,bc.getUser()); - } - CachedBasicPrincipal bp = new CachedBasicPrincipal(this,bc,realm,timeToLive); - - // Be able to do Organizational specific lookups by Domain - CredVal cv = rbacs.get(bp.getDomain()); - if(cv==null) { - cv = rbac; - } - - // ONLY FOR Last Ditch DEBUGGING... - // access.log(Level.WARN,bp.getName() + ":" + new String(bp.getCred())); - if(cv.validate(bp.getName(),Type.PASSWORD,bp.getCred(),req)) { - 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()), - RESP.TRY_AUTHENTICATING,resp,realm,true); - } - } - } - // Get User/Password from Authorization Header value - String authz = req.getHeader("Authorization"); - if(authz != null && authz.startsWith("Basic ")) { - if(warn&&!req.isSecure()) { - access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); - } - try { - CachedBasicPrincipal ba = new CachedBasicPrincipal(this,authz,realm,timeToLive); - if(DenialOfServiceTaf.isDeniedID(ba.getName())!=null) { - return DenialOfServiceTaf.respDenyID(access,ba.getName()); - } - - final int at = ba.getName().indexOf('@'); - CredVal cv = rbacs.get(ba.getName().substring(at+1)); - if(cv==null) { - cv = rbac; // default - } + public void add(final CredValDomain cvd) { + rbacs.put(cvd.domain(), cvd); + } + + /** + * Note: BasicHttp works for either Carbon Based (Humans) or Silicon Based (machine) Lifeforms. + * @see Taf + */ + 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 + if(req instanceof BasicCred) { + BasicCred bc = (BasicCred)req; + if(bc.getUser()!=null) { // CadiWrap, if set, makes sure User & Password are both valid, or both null + if(DenialOfServiceTaf.isDeniedID(bc.getUser())!=null) { + return DenialOfServiceTaf.respDenyID(access,bc.getUser()); + } + CachedBasicPrincipal bp = new CachedBasicPrincipal(this,bc,realm,timeToLive); + + // Be able to do Organizational specific lookups by Domain + CredVal cv = rbacs.get(bp.getDomain()); + if(cv==null) { + cv = rbac; + } + + // ONLY FOR Last Ditch DEBUGGING... + // access.log(Level.WARN,bp.getName() + ":" + new String(bp.getCred())); + if(cv.validate(bp.getName(),Type.PASSWORD,bp.getCred(),req)) { + 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()), + RESP.TRY_AUTHENTICATING,resp,realm,true); + } + } + } + // Get User/Password from Authorization Header value + String authz = req.getHeader("Authorization"); + if(authz != null && authz.startsWith("Basic ")) { + if(warn&&!req.isSecure()) { + access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); + } + try { + CachedBasicPrincipal ba = new CachedBasicPrincipal(this,authz,realm,timeToLive); + if(DenialOfServiceTaf.isDeniedID(ba.getName())!=null) { + return DenialOfServiceTaf.respDenyID(access,ba.getName()); + } + + final int at = ba.getName().indexOf('@'); + CredVal cv = rbacs.get(ba.getName().substring(at+1)); + if(cv==null) { + cv = rbac; // default + } - // ONLY FOR Last Ditch DEBUGGING... - // access.log(Level.WARN,ba.getName() + ":" + new String(ba.getCred())); - if(cv.validate(ba.getName(), Type.PASSWORD, ba.getCred(), req)) { - 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"), - 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,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false); - } - - protected String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) { - StringBuilder sb = new StringBuilder(); - if(pr!=null) { - sb.append("user="); - sb.append(pr.getName()); - sb.append(','); - } - sb.append("ip="); - sb.append(req.getRemoteAddr()); - sb.append(",port="); - sb.append(req.getRemotePort()); - if(msg.length>0) { - sb.append(",msg=\""); - for(Object s : msg) { - sb.append(s.toString()); - } - sb.append('"'); - } - return sb.toString(); - } - - public void addCredVal(final String realm, final CredVal cv) { - rbacs.put(realm, cv); - } + // ONLY FOR Last Ditch DEBUGGING... + // access.log(Level.WARN,ba.getName() + ":" + new String(ba.getCred())); + if(cv.validate(ba.getName(), Type.PASSWORD, ba.getCred(), req)) { + 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"), + 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,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false); + } + + protected String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) { + StringBuilder sb = new StringBuilder(); + if(pr!=null) { + sb.append("user="); + sb.append(pr.getName()); + sb.append(','); + } + sb.append("ip="); + sb.append(req.getRemoteAddr()); + sb.append(",port="); + sb.append(req.getRemotePort()); + if(msg.length>0) { + sb.append(",msg=\""); + for(Object s : msg) { + sb.append(s.toString()); + } + sb.append('"'); + } + return sb.toString(); + } + + public void addCredVal(final String realm, final CredVal cv) { + rbacs.put(realm, cv); + } - public CredVal getCredVal(String key) { - CredVal cv = rbacs.get(key); - if(cv==null) { - cv = rbac; - } - return cv; - } - - @Override - public Resp revalidate(CachedPrincipal prin, Object state) { - if(prin instanceof BasicPrincipal) { - BasicPrincipal ba = (BasicPrincipal)prin; - if(DenialOfServiceTaf.isDeniedID(ba.getName())!=null) { - return Resp.UNVALIDATED; - } - return rbac.validate(ba.getName(), Type.PASSWORD, ba.getCred(), state)?Resp.REVALIDATED:Resp.UNVALIDATED; - } - return Resp.NOT_MINE; - } - - public String toString() { - return "Basic Auth enabled on realm: " + realm; - } + public CredVal getCredVal(String key) { + CredVal cv = rbacs.get(key); + if(cv==null) { + cv = rbac; + } + return cv; + } + + @Override + public Resp revalidate(CachedPrincipal prin, Object state) { + if(prin instanceof BasicPrincipal) { + BasicPrincipal ba = (BasicPrincipal)prin; + if(DenialOfServiceTaf.isDeniedID(ba.getName())!=null) { + return Resp.UNVALIDATED; + } + return rbac.validate(ba.getName(), Type.PASSWORD, ba.getCred(), state)?Resp.REVALIDATED:Resp.UNVALIDATED; + } + return Resp.NOT_MINE; + } + + public String toString() { + return "Basic Auth enabled on realm: " + realm; + } } 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 643cf29e..d1acf5fe 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 @@ -31,31 +31,31 @@ import org.onap.aaf.cadi.taf.AbsTafResp; import org.onap.aaf.cadi.taf.TafResp; public class BasicHttpTafResp extends AbsTafResp implements TafResp { - private static final String tafName = BasicHttpTaf.class.getSimpleName(); - private HttpServletResponse httpResp; - private String realm; - private RESP status; - private final boolean wasFailed; - - public BasicHttpTafResp(Access access, TaggedPrincipal principal, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) { - super(access, tafName, principal, 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+'"'); - return RESP.HTTP_REDIRECT_INVOKED; - } - - public RESP isAuthenticated() { - return status; - } - - public boolean isFailedAttempt() { - return wasFailed; - } + private static final String tafName = BasicHttpTaf.class.getSimpleName(); + private HttpServletResponse httpResp; + private String realm; + private RESP status; + private final boolean wasFailed; + + public BasicHttpTafResp(Access access, TaggedPrincipal principal, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) { + super(access, tafName, principal, 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+'"'); + return RESP.HTTP_REDIRECT_INVOKED; + } + + public RESP isAuthenticated() { + return status; + } + + public boolean isFailedAttempt() { + return wasFailed; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java index 0da41b81..f597159e 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java @@ -29,18 +29,18 @@ import javax.servlet.http.HttpServletRequest; import org.onap.aaf.cadi.principal.TaggedPrincipal; public interface CertIdentity { - /** - * identity from X509Certificate Object and/or certBytes - * - * If you have both, include them. If you only have one, leave the other null, and it will be generated if needed - * - * The Request is there to obtain Header or Attribute info of ultimate user - * - * @param req - * @param cert - * @param certBytes - * @return - * @throws CertificateException - */ - public TaggedPrincipal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException; + /** + * identity from X509Certificate Object and/or certBytes + * + * If you have both, include them. If you only have one, leave the other null, and it will be generated if needed + * + * The Request is there to obtain Header or Attribute info of ultimate user + * + * @param req + * @param cert + * @param certBytes + * @return + * @throws CertificateException + */ + public TaggedPrincipal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java index c18f9036..d51cc86a 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java @@ -29,25 +29,25 @@ import org.onap.aaf.cadi.taf.AbsTafResp; import org.onap.aaf.cadi.taf.TafResp; public class X509HttpTafResp extends AbsTafResp implements TafResp { - private static final String tafName = X509Taf.class.getSimpleName(); - - private RESP status; - - public X509HttpTafResp(Access access, TaggedPrincipal principal, String description, RESP status) { - super(access, tafName, principal, description); - this.status = status; - } - - public RESP authenticate() throws IOException { - return RESP.TRY_ANOTHER_TAF; - } - - public RESP isAuthenticated() { - return status; - } - - public String toString() { - return status.name(); - } + private static final String tafName = X509Taf.class.getSimpleName(); + + private RESP status; + + public X509HttpTafResp(Access access, TaggedPrincipal principal, String description, RESP status) { + super(access, tafName, principal, description); + this.status = status; + } + + public RESP authenticate() throws IOException { + return RESP.TRY_ANOTHER_TAF; + } + + public RESP isAuthenticated() { + return status; + } + + public String toString() { + return status.name(); + } } 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 77efa956..d0034c76 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 @@ -56,221 +56,221 @@ import org.onap.aaf.cadi.taf.basic.BasicHttpTaf; import org.onap.aaf.cadi.util.Split; public class X509Taf implements HttpTaf { - private static final String CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION = "Certificate NOT valid for Authentication"; - public static final CertificateFactory certFactory; - public static final MessageDigest messageDigest; - public static final TrustManagerFactory tmf; - private Access access; - private CertIdentity[] certIdents; -// private Lur lur; - private ArrayList<String> cadiIssuers; - private String env; - private SecurityInfo si; - private BasicHttpTaf bht; + private static final String CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION = "Certificate NOT valid for Authentication"; + public static final CertificateFactory certFactory; + public static final MessageDigest messageDigest; + public static final TrustManagerFactory tmf; + private Access access; + private CertIdentity[] certIdents; +// private Lur lur; + private ArrayList<String> cadiIssuers; + private String env; + private SecurityInfo si; + private BasicHttpTaf bht; - static { - try { - certFactory = CertificateFactory.getInstance("X.509"); - messageDigest = MessageDigest.getInstance("SHA-256"); // use this to clone - tmf = TrustManagerFactory.getInstance(SecurityInfoC.SSL_KEY_MANAGER_FACTORY_ALGORITHM); - } catch (Exception e) { - throw new RuntimeException("X.509 and SHA-256 are required for X509Taf",e); - } - } - - public X509Taf(Access access, Lur lur, CertIdentity ... cis) throws CertificateException, NoSuchAlgorithmException, CadiException { - this.access = access; - env = access.getProperty(Config.AAF_ENV,null); - if(env==null) { - throw new CadiException("X509Taf requires Environment ("+Config.AAF_ENV+") to be set."); - } -// this.lur = lur; - this.cadiIssuers = new ArrayList<>(); - for(String ci : access.getProperty(Config.CADI_X509_ISSUERS, "").split(":")) { - access.printf(Level.INIT, "Trusting Identity for Certificates signed by \"%s\"",ci); - cadiIssuers.add(ci); - } - try { - Class<?> dci = access.classLoader().loadClass("org.onap.aaf.auth.direct.DirectCertIdentity"); - if(dci==null) { - certIdents = cis; - } else { - CertIdentity temp[] = new CertIdentity[cis.length+1]; - System.arraycopy(cis, 0, temp, 1, cis.length); - temp[0] = (CertIdentity) dci.newInstance(); - certIdents=temp; - } - } catch (Exception e) { - certIdents = cis; - } - - si = new SecurityInfo(access); - } + static { + try { + certFactory = CertificateFactory.getInstance("X.509"); + messageDigest = MessageDigest.getInstance("SHA-256"); // use this to clone + tmf = TrustManagerFactory.getInstance(SecurityInfoC.SSL_KEY_MANAGER_FACTORY_ALGORITHM); + } catch (Exception e) { + throw new RuntimeException("X.509 and SHA-256 are required for X509Taf",e); + } + } + + public X509Taf(Access access, Lur lur, CertIdentity ... cis) throws CertificateException, NoSuchAlgorithmException, CadiException { + this.access = access; + env = access.getProperty(Config.AAF_ENV,null); + if(env==null) { + throw new CadiException("X509Taf requires Environment ("+Config.AAF_ENV+") to be set."); + } +// this.lur = lur; + this.cadiIssuers = new ArrayList<>(); + for(String ci : access.getProperty(Config.CADI_X509_ISSUERS, "").split(":")) { + access.printf(Level.INIT, "Trusting Identity for Certificates signed by \"%s\"",ci); + cadiIssuers.add(ci); + } + try { + Class<?> dci = access.classLoader().loadClass("org.onap.aaf.auth.direct.DirectCertIdentity"); + if(dci==null) { + certIdents = cis; + } else { + CertIdentity temp[] = new CertIdentity[cis.length+1]; + System.arraycopy(cis, 0, temp, 1, cis.length); + temp[0] = (CertIdentity) dci.newInstance(); + certIdents=temp; + } + } catch (Exception e) { + certIdents = cis; + } + + si = new SecurityInfo(access); + } - public static final X509Certificate getCert(byte[] certBytes) throws CertificateException { - ByteArrayInputStream bais = new ByteArrayInputStream(certBytes); - return (X509Certificate)certFactory.generateCertificate(bais); - } + public static final X509Certificate getCert(byte[] certBytes) throws CertificateException { + ByteArrayInputStream bais = new ByteArrayInputStream(certBytes); + return (X509Certificate)certFactory.generateCertificate(bais); + } - public static final byte[] getFingerPrint(byte[] ba) { - MessageDigest md; - try { - md = (MessageDigest)messageDigest.clone(); - } catch (CloneNotSupportedException e) { - // should never get here - return new byte[0]; - } - md.update(ba); - return md.digest(); - } + public static final byte[] getFingerPrint(byte[] ba) { + MessageDigest md; + try { + md = (MessageDigest)messageDigest.clone(); + } catch (CloneNotSupportedException e) { + // should never get here + return new byte[0]; + } + md.update(ba); + return md.digest(); + } - @Override - public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { - // Check for Mutual SSL - try { - X509Certificate[] certarr = (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate"); - if(certarr!=null && certarr.length>0) { - si.checkClientTrusted(certarr); - // Note: If the Issuer is not in the TrustStore, it's not added to the Cert list - String issuer = certarr[0].getIssuerDN().toString(); - if(cadiIssuers.contains(issuer)) { - String subject = certarr[0].getSubjectDN().getName(); - // avoiding extra object creation, since this is validated EVERY transaction with a Cert - int at = subject.indexOf('@'); - if(at>=0) { - int start = subject.lastIndexOf(',', at); - if(start<0) { - start = 0; - } - int end = subject.indexOf(',', at); - if(end<0) { - end=subject.length(); - } - int temp; - if(((temp=subject.indexOf("OU=",start))>=0 && temp<end) || - ((temp=subject.indexOf("CN=",start))>=0 && temp<end)) { - String[] sa = Split.splitTrim(':', subject, temp+3,end); - if(sa.length==1 || (sa.length>1 && env!=null && env.equals(sa[1]))) { // Check Environment - return new X509HttpTafResp(access, - new X509Principal(sa[0], certarr[0],(byte[])null,bht), - "X509Taf validated " + sa[0] + (sa.length<2?"":" for aaf_env " + env ), RESP.IS_AUTHENTICATED); - } - } - - } - } - } - + @Override + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + // Check for Mutual SSL + try { + X509Certificate[] certarr = (X509Certificate[])req.getAttribute("javax.servlet.request.X509Certificate"); + if(certarr!=null && certarr.length>0) { + si.checkClientTrusted(certarr); + // Note: If the Issuer is not in the TrustStore, it's not added to the Cert list + String issuer = certarr[0].getIssuerDN().toString(); + if(cadiIssuers.contains(issuer)) { + String subject = certarr[0].getSubjectDN().getName(); + // avoiding extra object creation, since this is validated EVERY transaction with a Cert + int at = subject.indexOf('@'); + if(at>=0) { + int start = subject.lastIndexOf(',', at); + if(start<0) { + start = 0; + } + int end = subject.indexOf(',', at); + if(end<0) { + end=subject.length(); + } + int temp; + if(((temp=subject.indexOf("OU=",start))>=0 && temp<end) || + ((temp=subject.indexOf("CN=",start))>=0 && temp<end)) { + String[] sa = Split.splitTrim(':', subject, temp+3,end); + if(sa.length==1 || (sa.length>1 && env!=null && env.equals(sa[1]))) { // Check Environment + return new X509HttpTafResp(access, + new X509Principal(sa[0], certarr[0],(byte[])null,bht), + "X509Taf validated " + sa[0] + (sa.length<2?"":" for aaf_env " + env ), RESP.IS_AUTHENTICATED); + } + } + + } + } + } + - byte[] array = null; - byte[] certBytes = null; - X509Certificate cert=null; - String responseText=null; - String authHeader = req.getHeader("Authorization"); + byte[] array = null; + byte[] certBytes = null; + X509Certificate cert=null; + String responseText=null; + String authHeader = req.getHeader("Authorization"); - if(certarr!=null) { // If cert !=null, Cert is Tested by Mutual Protocol. - if(authHeader!=null) { // This is only intended to be a Secure Connection, not an Identity - for(String auth : Split.split(',',authHeader)) { - if(auth.startsWith("Bearer ")) { // Bearer = OAuth... Don't use as Authenication - return new X509HttpTafResp(access, null, "Certificate verified, but Bearer Token is presented", RESP.TRY_ANOTHER_TAF); - } - } - } - cert = certarr[0]; - responseText = ", validated by Mutual SSL Protocol"; - } else { // If cert == null, Get Declared Cert (in header), but validate by having them sign something - if(authHeader != null) { - for(String auth : Split.splitTrim(',',authHeader)) { - if(auth.startsWith("x509 ")) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(auth.length()); - try { - array = auth.getBytes(); - ByteArrayInputStream bais = new ByteArrayInputStream(array); - Symm.base64noSplit.decode(bais, baos, 5); - certBytes = baos.toByteArray(); - cert = getCert(certBytes); - - /** - * Identity from CERT if well know CA and specific encoded information - */ - // If found Identity doesn't work, try SignedStuff Protocol - // cert.checkValidity(); - // cert.--- GET FINGERPRINT? - String stuff = req.getHeader("Signature"); - if(stuff==null) - return new X509HttpTafResp(access, null, "Header entry 'Signature' required to validate One way X509 Certificate", RESP.TRY_ANOTHER_TAF); - String data = req.getHeader("Data"); - // if(data==null) - // return new X509HttpTafResp(access, null, "No signed Data to validate with X509 Certificate", RESP.TRY_ANOTHER_TAF); - - // Note: Data Pos shows is "<signatureType> <data>" - // int dataPos = (stuff.indexOf(' ')); // determine what is Algorithm - // Get Signature - bais = new ByteArrayInputStream(stuff.getBytes()); - baos = new ByteArrayOutputStream(stuff.length()); - Symm.base64noSplit.decode(bais, baos); - array = baos.toByteArray(); - // Signature sig = Signature.getInstance(stuff.substring(0, dataPos)); // get Algorithm from first part of Signature - - Signature sig = Signature.getInstance(cert.getSigAlgName()); - sig.initVerify(cert.getPublicKey()); - sig.update(data.getBytes()); - if(!sig.verify(array)) { - access.log(Level.ERROR, "Signature doesn't Match"); - return new X509HttpTafResp(access, null, CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION, RESP.TRY_ANOTHER_TAF); - } - responseText = ", validated by Signed Data"; - } catch (Exception e) { - access.log(e, "Exception while validating Cert"); - return new X509HttpTafResp(access, null, CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION, RESP.TRY_ANOTHER_TAF); - } - } - } - } - if(cert==null) { - return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF); - } - - // A cert has been found, match Identify - TaggedPrincipal prin=null; - - for(int i=0;prin==null && i<certIdents.length;++i) { - if((prin=certIdents[i].identity(req, cert, certBytes))!=null) { - responseText = prin.getName() + " matches Certificate " + cert.getSubjectX500Principal().getName() + responseText; - } - } - - // if Principal is found, check for "AS_USER" and whether this entity is trusted to declare - if(prin!=null) { - return new X509HttpTafResp( - access, - prin, - responseText, - RESP.IS_AUTHENTICATED); - } - } - } catch(Exception e) { - return new X509HttpTafResp(access, null, e.getMessage(), RESP.TRY_ANOTHER_TAF); - } - - return new X509HttpTafResp(access, null, "Certificate cannot be used for authentication", RESP.TRY_ANOTHER_TAF); - } + if(certarr!=null) { // If cert !=null, Cert is Tested by Mutual Protocol. + if(authHeader!=null) { // This is only intended to be a Secure Connection, not an Identity + for(String auth : Split.split(',',authHeader)) { + if(auth.startsWith("Bearer ")) { // Bearer = OAuth... Don't use as Authenication + return new X509HttpTafResp(access, null, "Certificate verified, but Bearer Token is presented", RESP.TRY_ANOTHER_TAF); + } + } + } + cert = certarr[0]; + responseText = ", validated by Mutual SSL Protocol"; + } else { // If cert == null, Get Declared Cert (in header), but validate by having them sign something + if(authHeader != null) { + for(String auth : Split.splitTrim(',',authHeader)) { + if(auth.startsWith("x509 ")) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(auth.length()); + try { + array = auth.getBytes(); + ByteArrayInputStream bais = new ByteArrayInputStream(array); + Symm.base64noSplit.decode(bais, baos, 5); + certBytes = baos.toByteArray(); + cert = getCert(certBytes); + + /** + * Identity from CERT if well know CA and specific encoded information + */ + // If found Identity doesn't work, try SignedStuff Protocol + // cert.checkValidity(); + // cert.--- GET FINGERPRINT? + String stuff = req.getHeader("Signature"); + if(stuff==null) + return new X509HttpTafResp(access, null, "Header entry 'Signature' required to validate One way X509 Certificate", RESP.TRY_ANOTHER_TAF); + String data = req.getHeader("Data"); + // if(data==null) + // return new X509HttpTafResp(access, null, "No signed Data to validate with X509 Certificate", RESP.TRY_ANOTHER_TAF); + + // Note: Data Pos shows is "<signatureType> <data>" + // int dataPos = (stuff.indexOf(' ')); // determine what is Algorithm + // Get Signature + bais = new ByteArrayInputStream(stuff.getBytes()); + baos = new ByteArrayOutputStream(stuff.length()); + Symm.base64noSplit.decode(bais, baos); + array = baos.toByteArray(); + // Signature sig = Signature.getInstance(stuff.substring(0, dataPos)); // get Algorithm from first part of Signature + + Signature sig = Signature.getInstance(cert.getSigAlgName()); + sig.initVerify(cert.getPublicKey()); + sig.update(data.getBytes()); + if(!sig.verify(array)) { + access.log(Level.ERROR, "Signature doesn't Match"); + return new X509HttpTafResp(access, null, CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION, RESP.TRY_ANOTHER_TAF); + } + responseText = ", validated by Signed Data"; + } catch (Exception e) { + access.log(e, "Exception while validating Cert"); + return new X509HttpTafResp(access, null, CERTIFICATE_NOT_VALID_FOR_AUTHENTICATION, RESP.TRY_ANOTHER_TAF); + } + } + } + } + if(cert==null) { + return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF); + } + + // A cert has been found, match Identify + TaggedPrincipal prin=null; + + for(int i=0;prin==null && i<certIdents.length;++i) { + if((prin=certIdents[i].identity(req, cert, certBytes))!=null) { + responseText = prin.getName() + " matches Certificate " + cert.getSubjectX500Principal().getName() + responseText; + } + } + + // if Principal is found, check for "AS_USER" and whether this entity is trusted to declare + if(prin!=null) { + return new X509HttpTafResp( + access, + prin, + responseText, + RESP.IS_AUTHENTICATED); + } + } + } catch(Exception e) { + return new X509HttpTafResp(access, null, e.getMessage(), RESP.TRY_ANOTHER_TAF); + } + + return new X509HttpTafResp(access, null, "Certificate cannot be used for authentication", RESP.TRY_ANOTHER_TAF); + } - @Override - public Resp revalidate(CachedPrincipal prin, Object state) { - return null; - } + @Override + public Resp revalidate(CachedPrincipal prin, Object state) { + return null; + } - public void add(BasicHttpTaf bht) { - this.bht = bht; - } - - public CredVal getCredVal(final String key) { - if(bht==null) { - return null; - } else { - return bht.getCredVal(key); - } - } - + public void add(BasicHttpTaf bht) { + this.bht = bht; + } + + public CredVal getCredVal(final String key) { + if(bht==null) { + return null; + } else { + return bht.getCredVal(key); + } + } + } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java index a0d56f67..4154e50e 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java @@ -48,328 +48,328 @@ import org.onap.aaf.cadi.taf.TafResp; import org.onap.aaf.cadi.taf.TafResp.RESP; public class DenialOfServiceTaf implements HttpTaf { - private static Map<String, Counter> deniedIP=null, deniedID=null; - private Access access; - private final TafResp puntNotDenied; - private static File dosIP, dosID; - - /** - * - * @param hostname - * @param prod - * @throws CadiException - */ - public DenialOfServiceTaf(Access access) throws CadiException { - puntNotDenied = new PuntTafResp("DenialOfServiceTaf", "This Transaction is not denied"); - this.access = access; - if(dosIP==null || dosID == null) { - String dirStr; - if((dirStr = access.getProperty(Config.AAF_DATA_DIR, null))!=null) { - dosIP = new File(dirStr+"/dosIP"); - readIP(); - dosID = new File(dirStr+"/dosID"); - readID(); - } - } - } + private static Map<String, Counter> deniedIP=null, deniedID=null; + private Access access; + private final TafResp puntNotDenied; + private static File dosIP, dosID; + + /** + * + * @param hostname + * @param prod + * @throws CadiException + */ + public DenialOfServiceTaf(Access access) throws CadiException { + puntNotDenied = new PuntTafResp("DenialOfServiceTaf", "This Transaction is not denied"); + this.access = access; + if(dosIP==null || dosID == null) { + String dirStr; + if((dirStr = access.getProperty(Config.AAF_DATA_DIR, null))!=null) { + dosIP = new File(dirStr+"/dosIP"); + readIP(); + dosID = new File(dirStr+"/dosID"); + readID(); + } + } + } - @Override - public TafResp validate(LifeForm reading, HttpServletRequest req, final HttpServletResponse resp) { - // Performance, when not needed - if(deniedIP != null) { - String ip; - Counter c = deniedIP.get(ip=req.getRemoteAddr()); - if(c!=null) { - c.inc(); - return respDenyIP(access,ip); - } - } - - // Note: Can't process Principal, because this is the first TAF, and no Principal is created. - // Other TAFs use "isDenied()" on this Object to validate. - return puntNotDenied; - } + @Override + public TafResp validate(LifeForm reading, HttpServletRequest req, final HttpServletResponse resp) { + // Performance, when not needed + if(deniedIP != null) { + String ip; + Counter c = deniedIP.get(ip=req.getRemoteAddr()); + if(c!=null) { + c.inc(); + return respDenyIP(access,ip); + } + } + + // Note: Can't process Principal, because this is the first TAF, and no Principal is created. + // Other TAFs use "isDenied()" on this Object to validate. + return puntNotDenied; + } - @Override - public Resp revalidate(CachedPrincipal prin, Object state) { - // We always return NOT MINE, because DOS Taf does not ever validate - return Resp.NOT_MINE; - } + @Override + public Resp revalidate(CachedPrincipal prin, Object state) { + // We always return NOT MINE, because DOS Taf does not ever validate + return Resp.NOT_MINE; + } - /* - * for use in Other TAFs, before they attempt backend validation of - */ - public static Counter isDeniedID(String identity) { - if(deniedID!=null) { - return deniedID.get(identity); - } - return null; - } - - /** - * - */ - public static Counter isDeniedIP(String ipvX) { - if(deniedIP!=null) { - return deniedIP.get(ipvX); - } - return null; - } + /* + * for use in Other TAFs, before they attempt backend validation of + */ + public static Counter isDeniedID(String identity) { + if(deniedID!=null) { + return deniedID.get(identity); + } + return null; + } + + /** + * + */ + public static Counter isDeniedIP(String ipvX) { + if(deniedIP!=null) { + return deniedIP.get(ipvX); + } + return null; + } - /** - * Return of "True" means IP has been added. - * Return of "False" means IP already added. - * - * @param ip - * @return - */ - public static synchronized boolean denyIP(String ip) { - boolean rv = false; - if(deniedIP==null) { - deniedIP = new HashMap<>(); - deniedIP.put(ip, new Counter(ip)); // Noted duplicated for minimum time spent - rv= true; - } else if(deniedIP.get(ip)==null) { - deniedIP.put(ip, new Counter(ip)); - rv = true; - } - if(rv) { - writeIP(); - } - return rv; - } - - private static void writeIP() { - if(dosIP!=null && deniedIP!=null) { - if(deniedIP.isEmpty()) { - if(dosIP.exists()) { - dosIP.delete(); - } - } else { - PrintStream fos; - try { - fos = new PrintStream(new FileOutputStream(dosIP,false)); - try { - for(String ip: deniedIP.keySet()) { - fos.println(ip); - } - } finally { - fos.close(); - } - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } - } - - private static void readIP() { - if(dosIP!=null && dosIP.exists()) { - BufferedReader br; - try { - br = new BufferedReader(new FileReader(dosIP)); - try { - if(deniedIP==null) { - deniedIP=new HashMap<>(); - } + /** + * Return of "True" means IP has been added. + * Return of "False" means IP already added. + * + * @param ip + * @return + */ + public static synchronized boolean denyIP(String ip) { + boolean rv = false; + if(deniedIP==null) { + deniedIP = new HashMap<>(); + deniedIP.put(ip, new Counter(ip)); // Noted duplicated for minimum time spent + rv= true; + } else if(deniedIP.get(ip)==null) { + deniedIP.put(ip, new Counter(ip)); + rv = true; + } + if(rv) { + writeIP(); + } + return rv; + } + + private static void writeIP() { + if(dosIP!=null && deniedIP!=null) { + if(deniedIP.isEmpty()) { + if(dosIP.exists()) { + dosIP.delete(); + } + } else { + PrintStream fos; + try { + fos = new PrintStream(new FileOutputStream(dosIP,false)); + try { + for(String ip: deniedIP.keySet()) { + fos.println(ip); + } + } finally { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } + } + + private static void readIP() { + if(dosIP!=null && dosIP.exists()) { + BufferedReader br; + try { + br = new BufferedReader(new FileReader(dosIP)); + try { + if(deniedIP==null) { + deniedIP=new HashMap<>(); + } - String line; - while((line=br.readLine())!=null) { - deniedIP.put(line, new Counter(line)); - } - } finally { - br.close(); - } - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } + String line; + while((line=br.readLine())!=null) { + deniedIP.put(line, new Counter(line)); + } + } finally { + br.close(); + } + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } - /** - * Return of "True" means IP has was removed. - * Return of "False" means IP wasn't being denied. - * - * @param ip - * @return - */ - public static synchronized boolean removeDenyIP(String ip) { - if(deniedIP!=null && deniedIP.remove(ip)!=null) { - writeIP(); - if(deniedIP.isEmpty()) { - deniedIP=null; - } - return true; - } - return false; - } + /** + * Return of "True" means IP has was removed. + * Return of "False" means IP wasn't being denied. + * + * @param ip + * @return + */ + public static synchronized boolean removeDenyIP(String ip) { + if(deniedIP!=null && deniedIP.remove(ip)!=null) { + writeIP(); + if(deniedIP.isEmpty()) { + deniedIP=null; + } + return true; + } + return false; + } - /** - * Return of "True" means ID has been added. - * Return of "False" means ID already added. - * - * @param ip - * @return - */ - public static synchronized boolean denyID(String id) { - boolean rv = false; - if(deniedID==null) { - deniedID = new HashMap<>(); - deniedID.put(id, new Counter(id)); // Noted duplicated for minimum time spent - rv = true; - } else if(deniedID.get(id)==null) { - deniedID.put(id, new Counter(id)); - rv = true; - } - if(rv) { - writeID(); - } - return rv; + /** + * Return of "True" means ID has been added. + * Return of "False" means ID already added. + * + * @param ip + * @return + */ + public static synchronized boolean denyID(String id) { + boolean rv = false; + if(deniedID==null) { + deniedID = new HashMap<>(); + deniedID.put(id, new Counter(id)); // Noted duplicated for minimum time spent + rv = true; + } else if(deniedID.get(id)==null) { + deniedID.put(id, new Counter(id)); + rv = true; + } + if(rv) { + writeID(); + } + return rv; - } + } - private static void writeID() { - if(dosID!=null && deniedID!=null) { - if(deniedID.isEmpty()) { - if(dosID.exists()) { - dosID.delete(); - } - } else { - PrintStream fos; - try { - fos = new PrintStream(new FileOutputStream(dosID,false)); - try { - for(String ip: deniedID.keySet()) { - fos.println(ip); - } - } finally { - fos.close(); - } - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } - } + private static void writeID() { + if(dosID!=null && deniedID!=null) { + if(deniedID.isEmpty()) { + if(dosID.exists()) { + dosID.delete(); + } + } else { + PrintStream fos; + try { + fos = new PrintStream(new FileOutputStream(dosID,false)); + try { + for(String ip: deniedID.keySet()) { + fos.println(ip); + } + } finally { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } + } - private static void readID() { - if(dosID!=null && dosID.exists()) { - BufferedReader br; - try { - br = new BufferedReader(new FileReader(dosID)); - try { - if(deniedID==null) { - deniedID=new HashMap<>(); - } - - String line; - while((line=br.readLine())!=null) { - deniedID.put(line, new Counter(line)); - } - } finally { - br.close(); - } - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } + private static void readID() { + if(dosID!=null && dosID.exists()) { + BufferedReader br; + try { + br = new BufferedReader(new FileReader(dosID)); + try { + if(deniedID==null) { + deniedID=new HashMap<>(); + } + + String line; + while((line=br.readLine())!=null) { + deniedID.put(line, new Counter(line)); + } + } finally { + br.close(); + } + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } - /** - * Return of "True" means ID has was removed. - * Return of "False" means ID wasn't being denied. - * - * @param ip - * @return - */ - public static synchronized boolean removeDenyID(String id) { - if(deniedID!=null && deniedID.remove(id)!=null) { - writeID(); - if(deniedID.isEmpty()) { - deniedID=null; - } + /** + * Return of "True" means ID has was removed. + * Return of "False" means ID wasn't being denied. + * + * @param ip + * @return + */ + public static synchronized boolean removeDenyID(String id) { + if(deniedID!=null && deniedID.remove(id)!=null) { + writeID(); + if(deniedID.isEmpty()) { + deniedID=null; + } - return true; - } - return false; - } - - public List<String> report() { - int initSize = 0; - if(deniedIP!=null)initSize+=deniedIP.size(); - if(deniedID!=null)initSize+=deniedID.size(); - ArrayList<String> al = new ArrayList<>(initSize); - if(deniedID!=null) { - for(Counter c : deniedID.values()) { - al.add(c.toString()); - } - } - if(deniedIP!=null) { - for(Counter c : deniedIP.values()) { - al.add(c.toString()); - } - } - return al; - } - - public static class Counter { - private final String name; - private int count = 0; - private Date first; - private long last; // note, we use "last" as long, to avoid popping useless dates on Heap. - - public Counter(String name) { - this.name = name; - first = null; - last = 0L; - count = 0; - } - - public String getName() { - return name; - } - - public int getCount() { - return count; - } + return true; + } + return false; + } + + public List<String> report() { + int initSize = 0; + if(deniedIP!=null)initSize+=deniedIP.size(); + if(deniedID!=null)initSize+=deniedID.size(); + ArrayList<String> al = new ArrayList<>(initSize); + if(deniedID!=null) { + for(Counter c : deniedID.values()) { + al.add(c.toString()); + } + } + if(deniedIP!=null) { + for(Counter c : deniedIP.values()) { + al.add(c.toString()); + } + } + return al; + } + + public static class Counter { + private final String name; + private int count = 0; + private Date first; + private long last; // note, we use "last" as long, to avoid popping useless dates on Heap. + + public Counter(String name) { + this.name = name; + first = null; + last = 0L; + count = 0; + } + + public String getName() { + return name; + } + + public int getCount() { + return count; + } - public long getLast() { - return last; - } - - /* - * Only allow Denial of ServiceTaf to increment - */ - private synchronized void inc() { - ++count; - last = System.currentTimeMillis(); - if(first==null) { - first = new Date(last); - } - } - - public String toString() { - if(count==0) - return name + " is on the denied list, but has not attempted Access"; - else - return - name + - " has been denied " + - count + - " times since " + - first + - ". Last denial was " + - new Date(last); - } - } + public long getLast() { + return last; + } + + /* + * Only allow Denial of ServiceTaf to increment + */ + private synchronized void inc() { + ++count; + last = System.currentTimeMillis(); + if(first==null) { + first = new Date(last); + } + } + + public String toString() { + if(count==0) + return name + " is on the denied list, but has not attempted Access"; + else + return + name + + " has been denied " + + count + + " times since " + + first + + ". Last denial was " + + new Date(last); + } + } - public static TafResp respDenyID(Access access, String identity) { - return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, identity + " is on the Identity Denial list"); - } - - public static TafResp respDenyIP(Access access, String ip) { - return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, ip + " is on the IP Denial list"); - } + public static TafResp respDenyID(Access access, String identity) { + return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, identity + " is on the Identity Denial list"); + } + + public static TafResp respDenyIP(Access access, String ip) { + return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, ip + " is on the IP Denial list"); + } } 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 e5a336f7..2fcd1553 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 @@ -27,29 +27,29 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.taf.AbsTafResp; public class DenialOfServiceTafResp extends AbsTafResp { - private static final String tafName = DenialOfServiceTaf.class.getSimpleName(); - - private RESP ect; // Homage to Arethra Franklin - - public DenialOfServiceTafResp(Access access, RESP resp, String description ) { - super(access, tafName, null, description); - ect = resp; - } - - // Override base behavior of checking Principal and trying another TAF - @Override - public RESP isAuthenticated() { - return ect; - } - - - public RESP authenticate() throws IOException { - return ect; - } - - @Override - public String taf() { - return "DOS"; - } + private static final String tafName = DenialOfServiceTaf.class.getSimpleName(); + + private RESP ect; // Homage to Arethra Franklin + + public DenialOfServiceTafResp(Access access, RESP resp, String description ) { + super(access, tafName, null, description); + ect = resp; + } + + // Override base behavior of checking Principal and trying another TAF + @Override + public RESP isAuthenticated() { + return ect; + } + + + public RESP authenticate() throws IOException { + return ect; + } + + @Override + public String taf() { + return "DOS"; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java index 74bf805d..70fabd82 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java @@ -25,38 +25,38 @@ import java.io.File; import java.io.IOException; public interface Chmod { - public void chmod(File f) throws IOException; - - public static final Chmod to755 = new Chmod() { - public void chmod(File f) throws IOException { - f.setExecutable(true, false); - f.setExecutable(true, true); - f.setReadable(true, false); - f.setReadable(true, true); - f.setWritable(false, false); - f.setWritable(true, true); - } - }; + public void chmod(File f) throws IOException; + + public static final Chmod to755 = new Chmod() { + public void chmod(File f) throws IOException { + f.setExecutable(true, false); + f.setExecutable(true, true); + f.setReadable(true, false); + f.setReadable(true, true); + f.setWritable(false, false); + f.setWritable(true, true); + } + }; - public static final Chmod to644 = new Chmod() { - public void chmod(File f) throws IOException { - f.setExecutable(false, false); - f.setExecutable(false, true); - f.setReadable(true, false); - f.setReadable(true, true); - f.setWritable(false, false); - f.setWritable(true, true); - } - }; + public static final Chmod to644 = new Chmod() { + public void chmod(File f) throws IOException { + f.setExecutable(false, false); + f.setExecutable(false, true); + f.setReadable(true, false); + f.setReadable(true, true); + f.setWritable(false, false); + f.setWritable(true, true); + } + }; - public static final Chmod to400 = new Chmod() { - public void chmod(File f) throws IOException { - f.setExecutable(false, false); - f.setExecutable(false, true); - f.setReadable(false, false); - f.setReadable(true, true); - f.setWritable(false, false); - f.setWritable(false, true); - } - }; + public static final Chmod to400 = new Chmod() { + public void chmod(File f) throws IOException { + f.setExecutable(false, false); + f.setExecutable(false, true); + f.setReadable(false, false); + f.setReadable(true, true); + f.setWritable(false, false); + f.setWritable(false, true); + } + }; }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/FQI.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/FQI.java index 4ea50a10..f0b8d38d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/FQI.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/FQI.java @@ -22,30 +22,30 @@ package org.onap.aaf.cadi.util; public class FQI { - /** - * Take a Fully Qualified User, and get a Namespace from it. - * @param fqi - * @return - */ - public final static String reverseDomain(final String fqi) { - StringBuilder sb = null; - String[] split = Split.split('.',fqi); - int at; - for(int i=split.length-1;i>=0;--i) { - if(sb == null) { - sb = new StringBuilder(); - } else { - sb.append('.'); - } + /** + * Take a Fully Qualified User, and get a Namespace from it. + * @param fqi + * @return + */ + public final static String reverseDomain(final String fqi) { + StringBuilder sb = null; + String[] split = Split.split('.',fqi); + int at; + for(int i=split.length-1;i>=0;--i) { + if(sb == null) { + sb = new StringBuilder(); + } else { + sb.append('.'); + } - if((at = split[i].indexOf('@'))>0) { - sb.append(split[i].subSequence(at+1, split[i].length())); - } else { - sb.append(split[i]); - } - } - - return sb==null?"":sb.toString(); - } + if((at = split[i].indexOf('@'))>0) { + sb.append(split[i].subSequence(at+1, split[i].length())); + } else { + sb.append(split[i]); + } + } + + return sb==null?"":sb.toString(); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java index 7b04942f..7c3ac30d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java @@ -25,65 +25,65 @@ import java.io.IOException; import java.io.OutputStream; public class JsonOutputStream extends OutputStream { - private static final byte[] TWO_SPACE = " ".getBytes(); - private OutputStream os; - private boolean closeable; - private int indent = 0; - private int prev,ret=0; + private static final byte[] TWO_SPACE = " ".getBytes(); + private OutputStream os; + private boolean closeable; + private int indent = 0; + private int prev,ret=0; - public JsonOutputStream(OutputStream os) { - // Don't close these, or dire consequences. - closeable = !os.equals(System.out) && !os.equals(System.err); - this.os = os; - } + public JsonOutputStream(OutputStream os) { + // Don't close these, or dire consequences. + closeable = !os.equals(System.out) && !os.equals(System.err); + this.os = os; + } - @Override - public void write(int b) throws IOException { - if(ret=='\n') { - ret = 0; - if(prev!=',' || (b!='{' && b!='[')) { - os.write('\n'); - for(int i=0;i<indent;++i) { - os.write(TWO_SPACE); - } - } - } - switch(b) { - case '{': - case '[': - ret = '\n'; - ++indent; - break; - case '}': - case ']': - --indent; - os.write('\n'); - for(int i=0;i<indent;++i) { - os.write(TWO_SPACE); - } - break; - case ',': - ret = '\n'; - break; - - } - os.write(b); - prev = b; - } - public void resetIndent() { - indent = 1; - } + @Override + public void write(int b) throws IOException { + if(ret=='\n') { + ret = 0; + if(prev!=',' || (b!='{' && b!='[')) { + os.write('\n'); + for(int i=0;i<indent;++i) { + os.write(TWO_SPACE); + } + } + } + switch(b) { + case '{': + case '[': + ret = '\n'; + ++indent; + break; + case '}': + case ']': + --indent; + os.write('\n'); + for(int i=0;i<indent;++i) { + os.write(TWO_SPACE); + } + break; + case ',': + ret = '\n'; + break; + + } + os.write(b); + prev = b; + } + public void resetIndent() { + indent = 1; + } - @Override - public void flush() throws IOException { - os.flush(); - } + @Override + public void flush() throws IOException { + os.flush(); + } - @Override - public void close() throws IOException { - if(closeable) { - os.close(); - } - } + @Override + public void close() throws IOException { + if(closeable) { + os.close(); + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/MaskFormatException.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/MaskFormatException.java index 7dd51c0a..15390285 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/MaskFormatException.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/MaskFormatException.java @@ -24,8 +24,8 @@ package org.onap.aaf.cadi.util; @SuppressWarnings("serial") public class MaskFormatException extends Exception { - public MaskFormatException(String string) { - super(string); - } + public MaskFormatException(String string) { + super(string); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/MyConsole.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/MyConsole.java index 2312d00b..b930bc28 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/MyConsole.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/MyConsole.java @@ -22,7 +22,7 @@ package org.onap.aaf.cadi.util; public interface MyConsole { - public String readLine(String fmt, Object ... args); - public char[] readPassword(String fmt, Object ... args); - public void printf(String fmt, Object ...args); + public String readLine(String fmt, Object ... args); + public char[] readPassword(String fmt, Object ... args); + public void printf(String fmt, Object ...args); }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/NetMask.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/NetMask.java index fccb04fc..2a3d75ff 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/NetMask.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/NetMask.java @@ -27,73 +27,73 @@ package org.onap.aaf.cadi.util; * Needs the IPV6 Mask Builder. */ public class NetMask { - private long mask; + private long mask; - public NetMask(byte[] inBytes) { - mask = derive(inBytes); - } - - public NetMask(String string) throws MaskFormatException { - mask = derive(string,true); - } - - public boolean isInNet(byte[] inBytes) { - long addr = derive(inBytes); - return (mask & addr) == addr; - } - - public boolean isInNet(String str) { - long addr; - try { - addr = derive(str,false); - return (mask & addr) == addr; - } catch (MaskFormatException e) { - // will not hit this code; - return false; - } - } + public NetMask(byte[] inBytes) { + mask = derive(inBytes); + } + + public NetMask(String string) throws MaskFormatException { + mask = derive(string,true); + } + + public boolean isInNet(byte[] inBytes) { + long addr = derive(inBytes); + return (mask & addr) == addr; + } + + public boolean isInNet(String str) { + long addr; + try { + addr = derive(str,false); + return (mask & addr) == addr; + } catch (MaskFormatException e) { + // will not hit this code; + return false; + } + } - public static long derive(byte[] inBytes) { - long addr = 0L; - int offset = inBytes.length*8; - for(int i=0;i<inBytes.length;++i) { - addr&=(inBytes[i]<<offset); - offset-=8; - } - return addr; - } + public static long derive(byte[] inBytes) { + long addr = 0L; + int offset = inBytes.length*8; + for(int i=0;i<inBytes.length;++i) { + addr&=(inBytes[i]<<offset); + offset-=8; + } + return addr; + } - public static long derive(String str, boolean check) throws MaskFormatException { - long rv=0L; - int idx=str.indexOf(':'); - int slash = str.indexOf('/'); + public static long derive(String str, boolean check) throws MaskFormatException { + long rv=0L; + int idx=str.indexOf(':'); + int slash = str.indexOf('/'); - if(idx<0) { // Not IPV6, so it's IPV4... Is there a mask of 123/254? - idx=str.indexOf('.'); - int offset = 24; - int end = slash>=0?slash:str.length(); - int bits = slash>=0?Integer.parseInt(str.substring(slash+1)):32; - if(check && bits>32) { - throw new MaskFormatException("Invalid Mask Offset in IPV4 Address"); - } - int prev = 0; - long lbyte; - while(prev<end) { - if(idx<0) { - idx = end; - } - lbyte = Long.parseLong(str.substring(prev, idx)); - if(check && (lbyte>255 || lbyte<0)) { - throw new MaskFormatException("Invalid Byte in IPV4 Address"); - } - rv|=lbyte<<offset; - prev = ++idx; - idx=str.indexOf('.',prev); - offset-=8; - } - rv|=0x00000000FFFFFFFFL>>bits; - } - return rv; - } + if(idx<0) { // Not IPV6, so it's IPV4... Is there a mask of 123/254? + idx=str.indexOf('.'); + int offset = 24; + int end = slash>=0?slash:str.length(); + int bits = slash>=0?Integer.parseInt(str.substring(slash+1)):32; + if(check && bits>32) { + throw new MaskFormatException("Invalid Mask Offset in IPV4 Address"); + } + int prev = 0; + long lbyte; + while(prev<end) { + if(idx<0) { + idx = end; + } + lbyte = Long.parseLong(str.substring(prev, idx)); + if(check && (lbyte>255 || lbyte<0)) { + throw new MaskFormatException("Invalid Byte in IPV4 Address"); + } + rv|=lbyte<<offset; + prev = ++idx; + idx=str.indexOf('.',prev); + offset-=8; + } + rv|=0x00000000FFFFFFFFL>>bits; + } + return rv; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java index 7cd7a633..156397b6 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Pool.java @@ -61,322 +61,322 @@ import org.onap.aaf.cadi.CadiException; * @param <T> */ public class Pool<T> { - /** - * This is a constant which specified the default maximum number of unused - * objects to be held at any given time. - */ - private static final int MAX_RANGE = 6; // safety + /** + * This is a constant which specified the default maximum number of unused + * objects to be held at any given time. + */ + private static final int MAX_RANGE = 6; // safety - /** - * only Simple List needed. - * - * NOTE TO MAINTAINERS: THIS OBJECT DOES IT'S OWN SYNCHRONIZATION. All - * changes that touch list must account for correctly synchronizing list. - */ - private LinkedList<Pooled<T>> list; + /** + * only Simple List needed. + * + * NOTE TO MAINTAINERS: THIS OBJECT DOES IT'S OWN SYNCHRONIZATION. All + * changes that touch list must account for correctly synchronizing list. + */ + private LinkedList<Pooled<T>> list; - /** - * keep track of how many elements exist, to avoid asking list. - */ - private int count; + /** + * keep track of how many elements exist, to avoid asking list. + */ + private int count; - /** - * Spares are those Object that are primed and ready to go. - */ - private int spares; + /** + * Spares are those Object that are primed and ready to go. + */ + private int spares; - /** - * Actual MAX number of spares allowed to hang around. Can be set to - * something besides the default MAX_RANGE. - */ - private int max_range = MAX_RANGE; + /** + * Actual MAX number of spares allowed to hang around. Can be set to + * something besides the default MAX_RANGE. + */ + private int max_range = MAX_RANGE; - /** - * The Creator for this particular pool. It must work for type T. - */ - private Creator<T> creator; + /** + * The Creator for this particular pool. It must work for type T. + */ + private Creator<T> creator; - private Log logger; + private Log logger; - /** - * Create a new Pool, given the implementation of Creator<T>, which must be - * able to create/destroy T objects at will. - * - * @param creator - */ - public Pool(Creator<T> creator) { - count = spares = 0; - this.creator = creator; - list = new LinkedList<>(); - logger = Log.NULL; - } - - /** - * Attach Pool Logging activities to any other Logging Mechanism. - * @param logger - */ - public void setLogger(Log logger) { - this.logger = logger; - } - - public void log(Object ...objects) { - logger.log(objects); - } + /** + * Create a new Pool, given the implementation of Creator<T>, which must be + * able to create/destroy T objects at will. + * + * @param creator + */ + public Pool(Creator<T> creator) { + count = spares = 0; + this.creator = creator; + list = new LinkedList<>(); + logger = Log.NULL; + } + + /** + * Attach Pool Logging activities to any other Logging Mechanism. + * @param logger + */ + public void setLogger(Log logger) { + this.logger = logger; + } + + public void log(Object ...objects) { + logger.log(objects); + } - /** - * Preallocate a certain number of T Objects. Useful for services so that - * the first transactions don't get hit with all the Object creation costs - * - * @param lt - * @param prime - * @throws CadiException - */ - public void prime(int prime) throws CadiException { - for (int i = 0; i < prime; ++i) { - Pooled<T> pt = new Pooled<T>(creator.create(), this); - synchronized (list) { - list.addFirst(pt); - ++count; - } - } + /** + * Preallocate a certain number of T Objects. Useful for services so that + * the first transactions don't get hit with all the Object creation costs + * + * @param lt + * @param prime + * @throws CadiException + */ + public void prime(int prime) throws CadiException { + for (int i = 0; i < prime; ++i) { + Pooled<T> pt = new Pooled<T>(creator.create(), this); + synchronized (list) { + list.addFirst(pt); + ++count; + } + } - } + } - /** - * Destroy and remove all remaining objects. This is valuable for closing - * down all Allocated objects cleanly for exiting. It is also a good method - * for removing objects when, for instance, all Objects are invalid because - * of broken connections, etc. - */ - public void drain() { - synchronized (list) { - for (int i = 0; i < list.size(); ++i) { - Pooled<T> pt = list.remove(); - creator.destroy(pt.content); - logger.log("Pool drained ", creator.toString()); - } - count = spares = 0; - } + /** + * Destroy and remove all remaining objects. This is valuable for closing + * down all Allocated objects cleanly for exiting. It is also a good method + * for removing objects when, for instance, all Objects are invalid because + * of broken connections, etc. + */ + public void drain() { + synchronized (list) { + for (int i = 0; i < list.size(); ++i) { + Pooled<T> pt = list.remove(); + creator.destroy(pt.content); + logger.log("Pool drained ", creator.toString()); + } + count = spares = 0; + } - } + } - /** - * This is the essential function for Pool. Get an Object "T" inside a - * "Pooled<T>" object. If there is a spare Object, then use it. If not, then - * create and pass back. - * - * This one uses a Null LogTarget - * - * IMPORTANT: When the use of this object is done (and the object is still - * in a valid state), then "done()" should be called immediately to allow - * the object to be reused. That is the point of the Pool... - * - * If the Object is in an invalid state, then "toss()" should be used so the - * Pool doesn't pass on invalid objects to others. - * - * @param lt - * @return - * @throws CadiException - */ - public Pooled<T> get() throws CadiException { - Pooled<T> pt; - synchronized (list) { - if (list.isEmpty()) { - pt = null; - } else { - pt = list.removeLast(); - --count; - creator.reuse(pt.content); - } - } - if (pt == null) { - if (spares < max_range) - ++spares; - pt = new Pooled<T>(creator.create(), this); - } else { - if (spares > 1) - --spares; - } - return pt; - } + /** + * This is the essential function for Pool. Get an Object "T" inside a + * "Pooled<T>" object. If there is a spare Object, then use it. If not, then + * create and pass back. + * + * This one uses a Null LogTarget + * + * IMPORTANT: When the use of this object is done (and the object is still + * in a valid state), then "done()" should be called immediately to allow + * the object to be reused. That is the point of the Pool... + * + * If the Object is in an invalid state, then "toss()" should be used so the + * Pool doesn't pass on invalid objects to others. + * + * @param lt + * @return + * @throws CadiException + */ + public Pooled<T> get() throws CadiException { + Pooled<T> pt; + synchronized (list) { + if (list.isEmpty()) { + pt = null; + } else { + pt = list.removeLast(); + --count; + creator.reuse(pt.content); + } + } + if (pt == null) { + if (spares < max_range) + ++spares; + pt = new Pooled<T>(creator.create(), this); + } else { + if (spares > 1) + --spares; + } + return pt; + } - /** - * This function will validate whether the Objects are still in a usable - * state. If not, they are tossed from the Pool. This is valuable to have - * when Remote Connections go down, and there is a question on whether the - * Pooled Objects are still functional. - * - * @return - */ - public boolean validate() { - boolean rv = true; - synchronized (list) { - for (Iterator<Pooled<T>> iter = list.iterator(); iter.hasNext();) { - Pooled<T> t = iter.next(); - if (!creator.isValid(t.content)) { - rv = false; - t.toss(); - iter.remove(); - } - } - } - return rv; - } + /** + * This function will validate whether the Objects are still in a usable + * state. If not, they are tossed from the Pool. This is valuable to have + * when Remote Connections go down, and there is a question on whether the + * Pooled Objects are still functional. + * + * @return + */ + public boolean validate() { + boolean rv = true; + synchronized (list) { + for (Iterator<Pooled<T>> iter = list.iterator(); iter.hasNext();) { + Pooled<T> t = iter.next(); + if (!creator.isValid(t.content)) { + rv = false; + t.toss(); + iter.remove(); + } + } + } + return rv; + } - /** - * This is an internal method, used only by the Internal Pooled<T> class. - * - * The Pooled<T> class "offers" it's Object back after use. It is an - * "offer", because Pool will simply destroy and remove the object if it has - * more than enough spares. - * - * @param lt - * @param used - * @return - */ - // Used only by Pooled<T> - private boolean offer(Pooled<T> used) { - if (count < spares) { - synchronized (list) { - list.addFirst(used); - ++count; - } - logger.log("Pool recovered ", creator); - } else { - logger.log("Pool destroyed ", creator); - creator.destroy(used.content); - } - return false; - } + /** + * This is an internal method, used only by the Internal Pooled<T> class. + * + * The Pooled<T> class "offers" it's Object back after use. It is an + * "offer", because Pool will simply destroy and remove the object if it has + * more than enough spares. + * + * @param lt + * @param used + * @return + */ + // Used only by Pooled<T> + private boolean offer(Pooled<T> used) { + if (count < spares) { + synchronized (list) { + list.addFirst(used); + ++count; + } + logger.log("Pool recovered ", creator); + } else { + logger.log("Pool destroyed ", creator); + creator.destroy(used.content); + } + return false; + } - /** - * The Creator Interface give the Pool the ability to Create, Destroy and - * Validate the Objects it is maintaining. Thus, it is a specially written - * Implementation for each type. - * - * @author Jonathan - * - * @param <T> - */ - public interface Creator<T> { - public T create() throws CadiException; + /** + * The Creator Interface give the Pool the ability to Create, Destroy and + * Validate the Objects it is maintaining. Thus, it is a specially written + * Implementation for each type. + * + * @author Jonathan + * + * @param <T> + */ + public interface Creator<T> { + public T create() throws CadiException; - public void destroy(T t); + public void destroy(T t); - public boolean isValid(T t); + public boolean isValid(T t); - public void reuse(T t); - } + public void reuse(T t); + } - public interface Log { - public void log(Object ... o); - - public final static Log NULL = new Log() { - @Override - public void log(Object ... o) { - } - }; - } - /** - * The "Pooled<T>" class is the transient class that wraps the actual Object - * T for API use/ It gives the ability to return ("done()", or "toss()") the - * Object to the Pool when processing is finished. - * - * For Safety, i.e. to avoid memory leaks and invalid Object States, there - * is a "finalize" method. It is strictly for when coder forgets to return - * the object, or perhaps hasn't covered the case during Exceptions or - * Runtime Exceptions with finally (preferred). This should not be - * considered normal procedure, as finalize() is called at an undetermined - * time during garbage collection, and is thus rather useless for a Pool. - * However, we don't want Coding Mistakes to put the whole program in an - * invalid state, so if something happened such that "done()" or "toss()" - * were not called, the resource is still cleaned up as well as possible. - * - * @author Jonathan - * - * @param <T> - */ - public static class Pooled<T> { - public final T content; - private Pool<T> pool; + public interface Log { + public void log(Object ... o); + + public final static Log NULL = new Log() { + @Override + public void log(Object ... o) { + } + }; + } + /** + * The "Pooled<T>" class is the transient class that wraps the actual Object + * T for API use/ It gives the ability to return ("done()", or "toss()") the + * Object to the Pool when processing is finished. + * + * For Safety, i.e. to avoid memory leaks and invalid Object States, there + * is a "finalize" method. It is strictly for when coder forgets to return + * the object, or perhaps hasn't covered the case during Exceptions or + * Runtime Exceptions with finally (preferred). This should not be + * considered normal procedure, as finalize() is called at an undetermined + * time during garbage collection, and is thus rather useless for a Pool. + * However, we don't want Coding Mistakes to put the whole program in an + * invalid state, so if something happened such that "done()" or "toss()" + * were not called, the resource is still cleaned up as well as possible. + * + * @author Jonathan + * + * @param <T> + */ + public static class Pooled<T> { + public final T content; + private Pool<T> pool; - /** - * Create the Wrapping Object Pooled<T>. - * - * @param t - * @param pool - * @param logTarget - */ - public Pooled(T t, Pool<T> pool) { - content = t; - this.pool = pool; + /** + * Create the Wrapping Object Pooled<T>. + * + * @param t + * @param pool + * @param logTarget + */ + public Pooled(T t, Pool<T> pool) { + content = t; + this.pool = pool; - } + } - /** - * This is the key API for the Pool, as calling "done()" offers this - * object back to the Pool for reuse. - * - * Do not use the Pooled<T> object again after calling "done()". - */ - public void done() { - if (pool != null) { - pool.offer(this); - } - } + /** + * This is the key API for the Pool, as calling "done()" offers this + * object back to the Pool for reuse. + * + * Do not use the Pooled<T> object again after calling "done()". + */ + public void done() { + if (pool != null) { + pool.offer(this); + } + } - /** - * The user of the Object may discover that the Object t is no longer in - * a valid state. Don't put Garbage back in the Refrigerator... Toss it, - * if it's no longer valid. - * - * toss() is also used for draining the Pool, etc. - * - * toss() will attempt to destroy the Object by using the Creator - * Interface. - * - */ - public void toss() { - if (pool != null) { - pool.creator.destroy(content); - } - // Don't allow finalize to put it back in. - pool = null; - } + /** + * The user of the Object may discover that the Object t is no longer in + * a valid state. Don't put Garbage back in the Refrigerator... Toss it, + * if it's no longer valid. + * + * toss() is also used for draining the Pool, etc. + * + * toss() will attempt to destroy the Object by using the Creator + * Interface. + * + */ + public void toss() { + if (pool != null) { + pool.creator.destroy(content); + } + // Don't allow finalize to put it back in. + pool = null; + } - /** - * Just in case someone neglected to offer back object... Do not rely on - * this, as there is no specific time when finalize is called, which - * rather defeats the purpose of a Pool. - */ - @Override - protected void finalize() throws Throwable { - if (pool != null) { - done(); - pool = null; - } - } - } + /** + * Just in case someone neglected to offer back object... Do not rely on + * this, as there is no specific time when finalize is called, which + * rather defeats the purpose of a Pool. + */ + @Override + protected void finalize() throws Throwable { + if (pool != null) { + done(); + pool = null; + } + } + } - /** - * Get the maximum number of spare objects allowed at any moment - * - * @return - */ - public int getMaxRange() { - return max_range; - } + /** + * Get the maximum number of spare objects allowed at any moment + * + * @return + */ + public int getMaxRange() { + return max_range; + } - /** - * Set a Max Range for numbers of spare objects waiting to be used. - * - * No negative numbers are allowed - * - * @return - */ - public void setMaxRange(int max_range) { - // Do not allow negative numbers - this.max_range = Math.max(0, max_range); - } + /** + * Set a Max Range for numbers of spare objects waiting to be used. + * + * No negative numbers are allowed + * + * @return + */ + public void setMaxRange(int max_range) { + // Do not allow negative numbers + this.max_range = Math.max(0, max_range); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Split.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Split.java index 3fa9a3f1..a2c76967 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Split.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Split.java @@ -31,84 +31,84 @@ package org.onap.aaf.cadi.util; */ public class Split { - public static String[] split(char c, String value) { - return split(c,value,0,value.length()); - } + public static String[] split(char c, String value) { + return split(c,value,0,value.length()); + } - public static String[] split(char c, String value, int start, int end) { - if(value==null) { - return new String[0]; - } + public static String[] split(char c, String value, int start, int end) { + if(value==null) { + return new String[0]; + } - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count,idx; - for(count=1,idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,++idx),++count); - String[] rv = new String[count]; - if(count==1) { - rv[0]=value.substring(start,end); - } else { - int last=0; - count=-1; - for(idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,idx)) { - rv[++count]=value.substring(last,idx); - last = ++idx; - } - rv[++count]=value.substring(last,end); - } - return rv; - } + // Count items to preallocate Array (memory alloc is more expensive than counting twice) + int count,idx; + for(count=1,idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,++idx),++count); + String[] rv = new String[count]; + if(count==1) { + rv[0]=value.substring(start,end); + } else { + int last=0; + count=-1; + for(idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,idx)) { + rv[++count]=value.substring(last,idx); + last = ++idx; + } + rv[++count]=value.substring(last,end); + } + return rv; + } - public static String[] splitTrim(char c, String value, int start, int end) { - if(value==null) { - return new String[0]; - } + public static String[] splitTrim(char c, String value, int start, int end) { + if(value==null) { + return new String[0]; + } - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count,idx; - for(count=1,idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,++idx),++count); - String[] rv = new String[count]; - if(count==1) { - rv[0]=value.substring(start,end).trim(); - } else { - int last=0; - count=-1; - for(idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,idx)) { - rv[++count]=value.substring(last,idx).trim(); - last = ++idx; - } - rv[++count]=value.substring(last,end).trim(); - } - return rv; - } + // Count items to preallocate Array (memory alloc is more expensive than counting twice) + int count,idx; + for(count=1,idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,++idx),++count); + String[] rv = new String[count]; + if(count==1) { + rv[0]=value.substring(start,end).trim(); + } else { + int last=0; + count=-1; + for(idx=value.indexOf(c,start);idx>=0 && idx<end;idx=value.indexOf(c,idx)) { + rv[++count]=value.substring(last,idx).trim(); + last = ++idx; + } + rv[++count]=value.substring(last,end).trim(); + } + return rv; + } - public static String[] splitTrim(char c, String value) { - return splitTrim(c,value,0,value.length()); - } + public static String[] splitTrim(char c, String value) { + return splitTrim(c,value,0,value.length()); + } - public static String[] splitTrim(char c, String value, int size) { - if(value==null) { - return new String[0]; - } + public static String[] splitTrim(char c, String value, int size) { + if(value==null) { + return new String[0]; + } - int idx; - String[] rv = new String[size]; - if(size==1) { - rv[0]=value.trim(); - } else { - int last=0; - int count=-1; - size-=2; - for(idx=value.indexOf(c);idx>=0 && count<size;idx=value.indexOf(c,idx)) { - rv[++count]=value.substring(last,idx).trim(); - last = ++idx; - } - if(idx>0) { - rv[++count]=value.substring(last,idx).trim(); - } else { - rv[++count]=value.substring(last).trim(); - } - } - return rv; - } + int idx; + String[] rv = new String[size]; + if(size==1) { + rv[0]=value.trim(); + } else { + int last=0; + int count=-1; + size-=2; + for(idx=value.indexOf(c);idx>=0 && count<size;idx=value.indexOf(c,idx)) { + rv[++count]=value.substring(last,idx).trim(); + last = ++idx; + } + if(idx>0) { + rv[++count]=value.substring(last,idx).trim(); + } else { + rv[++count]=value.substring(last).trim(); + } + } + return rv; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/SubStandardConsole.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/SubStandardConsole.java index b7dd0148..5cab15f6 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/SubStandardConsole.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/SubStandardConsole.java @@ -27,44 +27,44 @@ import java.io.InputStreamReader; // Substandard, because System.in doesn't do Passwords.. public class SubStandardConsole implements MyConsole { - private final static char[] BLANK = new char[0]; - private final BufferedReader br; + private final static char[] BLANK = new char[0]; + private final BufferedReader br; - public SubStandardConsole() { - br = new BufferedReader(new InputStreamReader(System.in)); - } - - @Override - public String readLine(String fmt, Object... args) { - String rv; - try { - System.out.printf(fmt,args); - rv = br.readLine(); - if(args.length==1 && rv.length()==0) { - rv = args[0].toString(); - } - } catch (IOException e) { - System.err.println("uh oh..."); - rv = ""; - } - return rv; - } + public SubStandardConsole() { + br = new BufferedReader(new InputStreamReader(System.in)); + } + + @Override + public String readLine(String fmt, Object... args) { + String rv; + try { + System.out.printf(fmt,args); + rv = br.readLine(); + if(args.length==1 && rv.length()==0) { + rv = args[0].toString(); + } + } catch (IOException e) { + System.err.println("uh oh..."); + rv = ""; + } + return rv; + } - @Override - public char[] readPassword(String fmt, Object... args) { - try { - System.out.printf(fmt,args); - String response = br.readLine(); - return response==null?BLANK:response.toCharArray(); + @Override + public char[] readPassword(String fmt, Object... args) { + try { + System.out.printf(fmt,args); + String response = br.readLine(); + return response==null?BLANK:response.toCharArray(); - } catch (IOException e) { - System.err.println("uh oh..."); - return BLANK; - } - } + } catch (IOException e) { + System.err.println("uh oh..."); + return BLANK; + } + } - @Override - public void printf(String fmt, Object... args) { - System.out.printf(fmt, args); - } + @Override + public void printf(String fmt, Object... args) { + System.out.printf(fmt, args); + } }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/TheConsole.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/TheConsole.java index 4c5d35b7..9ddd0626 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/TheConsole.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/TheConsole.java @@ -22,26 +22,26 @@ package org.onap.aaf.cadi.util; public class TheConsole implements MyConsole { - @Override - public String readLine(String fmt, Object... args) { - String rv = System.console().readLine(fmt, args); - if(args.length>0 && args[0]!=null && rv.length()==0) { - rv = args[0].toString(); - } - return rv; - } + @Override + public String readLine(String fmt, Object... args) { + String rv = System.console().readLine(fmt, args); + if(args.length>0 && args[0]!=null && rv.length()==0) { + rv = args[0].toString(); + } + return rv; + } - @Override - public char[] readPassword(String fmt, Object... args) { - return System.console().readPassword(fmt, args); - } - - public static boolean implemented() { - return System.console()!=null; - } + @Override + public char[] readPassword(String fmt, Object... args) { + return System.console().readPassword(fmt, args); + } + + public static boolean implemented() { + return System.console()!=null; + } - @Override - public void printf(String fmt, Object... args) { - System.console().printf(fmt, args); - } + @Override + public void printf(String fmt, Object... args) { + System.console().printf(fmt, args); + } }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Timing.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Timing.java index 82bd389a..529849de 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Timing.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Timing.java @@ -21,7 +21,7 @@ package org.onap.aaf.cadi.util; public class Timing { - public static float millis(final long start) { - return (System.nanoTime() - start) / 1000000f; - } + public static float millis(final long start) { + return (System.nanoTime() - start) / 1000000f; + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java index a8c0690f..ff74f39c 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java @@ -24,54 +24,54 @@ package org.onap.aaf.cadi.util; import org.onap.aaf.cadi.UserChain; public class UserChainManip { - /** - Build an element in the correct format for UserChain. - Format:<APP>:<ID>:<protocol>[:AS][,<APP>:<ID>:<protocol>]* - @see UserChain - */ - public static StringBuilder build(StringBuilder sb, String app, String id, UserChain.Protocol proto, boolean as) { - boolean mayAs; - if(!(mayAs=sb.length()==0)) { - sb.append(','); - } - sb.append(app); - sb.append(':'); - sb.append(id); - sb.append(':'); - sb.append(proto.name()); - if(as && mayAs) { - sb.append(":AS"); - } - return sb; - } - - public static String idToNS(String id) { - if(id==null) { - return ""; - } else { - StringBuilder sb = new StringBuilder(); - char c; - int end; - boolean first = true; - for(int idx = end = id.length()-1;idx>=0;--idx) { - if((c = id.charAt(idx))=='@' || c=='.') { - if(idx<end) { - if(first) { - first = false; - } else { - sb.append('.'); - } - for(int i=idx+1;i<=end;++i) { - sb.append(id.charAt(i)); - } - } - end=idx-1; - if(c=='@') { - break; - } - } - } - return sb.toString(); - } - } + /** + Build an element in the correct format for UserChain. + Format:<APP>:<ID>:<protocol>[:AS][,<APP>:<ID>:<protocol>]* + @see UserChain + */ + public static StringBuilder build(StringBuilder sb, String app, String id, UserChain.Protocol proto, boolean as) { + boolean mayAs; + if(!(mayAs=sb.length()==0)) { + sb.append(','); + } + sb.append(app); + sb.append(':'); + sb.append(id); + sb.append(':'); + sb.append(proto.name()); + if(as && mayAs) { + sb.append(":AS"); + } + return sb; + } + + public static String idToNS(String id) { + if(id==null) { + return ""; + } else { + StringBuilder sb = new StringBuilder(); + char c; + int end; + boolean first = true; + for(int idx = end = id.length()-1;idx>=0;--idx) { + if((c = id.charAt(idx))=='@' || c=='.') { + if(idx<end) { + if(first) { + first = false; + } else { + sb.append('.'); + } + for(int i=idx+1;i<=end;++i) { + sb.append(id.charAt(i)); + } + } + end=idx-1; + if(c=='@') { + break; + } + } + } + return sb.toString(); + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Vars.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Vars.java index 55470f99..b8468129 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/Vars.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/Vars.java @@ -24,97 +24,97 @@ package org.onap.aaf.cadi.util; import java.util.List; public class Vars { - /** - * Simplified Conversion based on typical use of getting AT&T style RESTful Error Messages - * @param text - * @param vars - * @return - */ - public static String convert(final String text, final List<String> vars) { - String[] array = new String[vars.size()]; - StringBuilder sb = new StringBuilder(); - convert(sb,text,vars.toArray(array)); - return sb.toString(); - } - /** - * Convert a format string with "%s" into AT&T RESTful Error %1 %2 (number) format - * If "holder" is passed in, it is built with full Message extracted (typically for Logging) - * @param holder - * @param text - * @param vars - * @return - */ - public static String convert(final StringBuilder holder, final String text, final String ... vars) { - StringBuilder sb = null; - int idx,index=0,prev = 0; - - if(text.contains("%s")) { - sb = new StringBuilder(); - } - - StringBuilder[] sbs = new StringBuilder[] {sb,holder}; - boolean replace, clearIndex = false; - int c; - while((idx=text.indexOf('%',prev))>=0) { - replace = false; - if(clearIndex) { - index=0; - } - if(sb!=null) { - sb.append(text,prev,idx); - } - if(holder!=null) { - holder.append(text,prev,idx); - } - - boolean go = true; - while(go) { - if(text.length()>++idx) { - switch(c=text.charAt(idx)) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - index *=10; - index +=(c-'0'); - clearIndex=replace=true; - continue; - case 's': - ++index; - replace = true; - continue; - default: - break; - } - } - prev = idx; - go=false; - if(replace) { - if(sb!=null) { - sb.append('%'); - sb.append(index); - } - if(index<=vars.length) { - if(holder!=null) { - holder.append(vars[index-1]); - } - } - } else { - for(StringBuilder s : sbs) { - if(s!=null) { - s.append("%"); - } - } - } - } - } - - if(sb!=null) { - sb.append(text,prev,text.length()); - } - if(holder!=null) { - holder.append(text,prev,text.length()); - } + /** + * Simplified Conversion based on typical use of getting AT&T style RESTful Error Messages + * @param text + * @param vars + * @return + */ + public static String convert(final String text, final List<String> vars) { + String[] array = new String[vars.size()]; + StringBuilder sb = new StringBuilder(); + convert(sb,text,vars.toArray(array)); + return sb.toString(); + } + /** + * Convert a format string with "%s" into AT&T RESTful Error %1 %2 (number) format + * If "holder" is passed in, it is built with full Message extracted (typically for Logging) + * @param holder + * @param text + * @param vars + * @return + */ + public static String convert(final StringBuilder holder, final String text, final String ... vars) { + StringBuilder sb = null; + int idx,index=0,prev = 0; + + if(text.contains("%s")) { + sb = new StringBuilder(); + } + + StringBuilder[] sbs = new StringBuilder[] {sb,holder}; + boolean replace, clearIndex = false; + int c; + while((idx=text.indexOf('%',prev))>=0) { + replace = false; + if(clearIndex) { + index=0; + } + if(sb!=null) { + sb.append(text,prev,idx); + } + if(holder!=null) { + holder.append(text,prev,idx); + } + + boolean go = true; + while(go) { + if(text.length()>++idx) { + switch(c=text.charAt(idx)) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + index *=10; + index +=(c-'0'); + clearIndex=replace=true; + continue; + case 's': + ++index; + replace = true; + continue; + default: + break; + } + } + prev = idx; + go=false; + if(replace) { + if(sb!=null) { + sb.append('%'); + sb.append(index); + } + if(index<=vars.length) { + if(holder!=null) { + holder.append(vars[index-1]); + } + } + } else { + for(StringBuilder s : sbs) { + if(s!=null) { + s.append("%"); + } + } + } + } + } + + if(sb!=null) { + sb.append(text,prev,text.length()); + } + if(holder!=null) { + holder.append(text,prev,text.length()); + } - return sb==null?text:sb.toString(); - } + return sb==null?text:sb.toString(); + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java index dff18acd..ebcfa9f7 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java @@ -33,5 +33,5 @@ package org.onap.aaf.cadi.wsse; * @param <OUTPUT> */ interface Action<OUTPUT> { - public boolean content(OUTPUT output, String text); + public boolean content(OUTPUT output, String text); }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java index 2582bc17..38322307 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java @@ -44,87 +44,87 @@ import javax.xml.stream.events.XMLEvent; */ //@SuppressWarnings("restriction") public class Match<OUTPUT> { - private QName qname; - private Match<OUTPUT>[] next; - private Match<OUTPUT> prev; - private Action<OUTPUT> action = null; - private boolean stopAfter; - private boolean exclusive; - + private QName qname; + private Match<OUTPUT>[] next; + private Match<OUTPUT> prev; + private Action<OUTPUT> action = null; + private boolean stopAfter; + private boolean exclusive; + - @SafeVarargs - public Match(String ns, String name, Match<OUTPUT> ... next) { - this.qname = new QName(ns,name); - this.next = next; - stopAfter = exclusive = false; - for(Match<OUTPUT> m : next) { // add the possible tags to look for - if(!m.stopAfter)m.prev = this; - } - } - - public Match<OUTPUT> onMatch(OUTPUT output, XReader reader) throws XMLStreamException { - while(reader.hasNext()) { - XEvent event = reader.nextEvent(); - switch(event.getEventType()) { - case XMLEvent.START_ELEMENT: - QName e_qname = event.asStartElement().getName(); - //System.out.println("Start - " + e_qname); - boolean match = false; - for(Match<OUTPUT> m : next) { - if(e_qname.equals(m.qname)) { - match=true; - if(m.onMatch(output, reader)==null) { - return null; // short circuit Parsing - } - break; - } - } - if(exclusive && !match) // When Tag MUST be present, i.e. the Root Tag, versus info we're not interested in - return null; - break; - case XMLEvent.CHARACTERS: - //System.out.println("Data - " +event.asCharacters().getData()); - if(action!=null) { - if(!action.content(output,event.asCharacters().getData())) { - return null; - } - } - break; - case XMLEvent.END_ELEMENT: - //System.out.println("End - " + event.asEndElement().getName()); - if(event.asEndElement().getName().equals(qname)) { - return prev; - } - break; - case XMLEvent.END_DOCUMENT: - return null; // Exit Chain - } - } - return this; - } + @SafeVarargs + public Match(String ns, String name, Match<OUTPUT> ... next) { + this.qname = new QName(ns,name); + this.next = next; + stopAfter = exclusive = false; + for(Match<OUTPUT> m : next) { // add the possible tags to look for + if(!m.stopAfter)m.prev = this; + } + } + + public Match<OUTPUT> onMatch(OUTPUT output, XReader reader) throws XMLStreamException { + while(reader.hasNext()) { + XEvent event = reader.nextEvent(); + switch(event.getEventType()) { + case XMLEvent.START_ELEMENT: + QName e_qname = event.asStartElement().getName(); + //System.out.println("Start - " + e_qname); + boolean match = false; + for(Match<OUTPUT> m : next) { + if(e_qname.equals(m.qname)) { + match=true; + if(m.onMatch(output, reader)==null) { + return null; // short circuit Parsing + } + break; + } + } + if(exclusive && !match) // When Tag MUST be present, i.e. the Root Tag, versus info we're not interested in + return null; + break; + case XMLEvent.CHARACTERS: + //System.out.println("Data - " +event.asCharacters().getData()); + if(action!=null) { + if(!action.content(output,event.asCharacters().getData())) { + return null; + } + } + break; + case XMLEvent.END_ELEMENT: + //System.out.println("End - " + event.asEndElement().getName()); + if(event.asEndElement().getName().equals(qname)) { + return prev; + } + break; + case XMLEvent.END_DOCUMENT: + return null; // Exit Chain + } + } + return this; + } - /** - * When this Matched Tag has completed, Stop parsing and end - * @return - */ - public Match<OUTPUT> stopAfter() { - stopAfter = true; - return this; - } - - /** - * Mark that this Object MUST be matched at this level or stop parsing and end - * - * @param action - * @return - */ - public Match<OUTPUT> exclusive() { - exclusive = true; - return this; - } + /** + * When this Matched Tag has completed, Stop parsing and end + * @return + */ + public Match<OUTPUT> stopAfter() { + stopAfter = true; + return this; + } + + /** + * Mark that this Object MUST be matched at this level or stop parsing and end + * + * @param action + * @return + */ + public Match<OUTPUT> exclusive() { + exclusive = true; + return this; + } - public Match<OUTPUT> set(Action<OUTPUT> action) { - this.action = action; - return this; - } + public Match<OUTPUT> set(Action<OUTPUT> action) { + this.action = action; + return this; + } }
\ No newline at end of file diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java index 017337b1..787f1b4b 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java @@ -42,42 +42,42 @@ import org.onap.aaf.cadi.BasicCred; * @author Jonathan */ public class WSSEParser { - private static final String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/"; - private static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; - private Match<BasicCred> parseTree; + private static final String SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/"; + private static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; + private Match<BasicCred> parseTree; - public WSSEParser() { - // soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/[wsse:Password&wsse:Username] - parseTree = new Match<BasicCred>(SOAP_NS,"root", // need a root level to start from... Doesn't matter what the tag is - new Match<BasicCred>(SOAP_NS,"Envelope", - new Match<BasicCred>(SOAP_NS,"Header", - new Match<BasicCred>(WSSE_NS,"Security", - new Match<BasicCred>(WSSE_NS,"UsernameToken", - new Match<BasicCred>(WSSE_NS,"Password").set(new Action<BasicCred>() { - public boolean content(BasicCred bc,String text) { - bc.setCred(text.getBytes()); - return true; - } - }), - new Match<BasicCred>(WSSE_NS,"Username").set(new Action<BasicCred>() { - public boolean content(BasicCred bc,String text) { - bc.setUser(text); - return true; - } - }) - ).stopAfter() // if found, end when UsernameToken ends (no further processing needed) - ) - ).stopAfter() // Stop Processing when Header Ends - ).exclusive()// Envelope must match Header, and no other. FYI, Body comes after Header short circuits (see above), so it's ok - ).exclusive(); // root must be Envelope - } - - public XMLStreamException parse(BasicCred bc, InputStream is) { - try { - parseTree.onMatch(bc, new XReader(is)); - return null; - } catch (XMLStreamException e) { - return e; - } - } + public WSSEParser() { + // soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/[wsse:Password&wsse:Username] + parseTree = new Match<BasicCred>(SOAP_NS,"root", // need a root level to start from... Doesn't matter what the tag is + new Match<BasicCred>(SOAP_NS,"Envelope", + new Match<BasicCred>(SOAP_NS,"Header", + new Match<BasicCred>(WSSE_NS,"Security", + new Match<BasicCred>(WSSE_NS,"UsernameToken", + new Match<BasicCred>(WSSE_NS,"Password").set(new Action<BasicCred>() { + public boolean content(BasicCred bc,String text) { + bc.setCred(text.getBytes()); + return true; + } + }), + new Match<BasicCred>(WSSE_NS,"Username").set(new Action<BasicCred>() { + public boolean content(BasicCred bc,String text) { + bc.setUser(text); + return true; + } + }) + ).stopAfter() // if found, end when UsernameToken ends (no further processing needed) + ) + ).stopAfter() // Stop Processing when Header Ends + ).exclusive()// Envelope must match Header, and no other. FYI, Body comes after Header short circuits (see above), so it's ok + ).exclusive(); // root must be Envelope + } + + public XMLStreamException parse(BasicCred bc, InputStream is) { + try { + parseTree.onMatch(bc, new XReader(is)); + return null; + } catch (XMLStreamException e) { + return e; + } + } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java index 12de366e..187d5b1e 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java @@ -38,98 +38,98 @@ import javax.xml.stream.events.XMLEvent; // @SuppressWarnings("restriction") public abstract class XEvent { - public abstract int getEventType(); + public abstract int getEventType(); - public StartElement asStartElement() { - return (StartElement)this; - } + public StartElement asStartElement() { + return (StartElement)this; + } - public Characters asCharacters() { - return (Characters)this; - } + public Characters asCharacters() { + return (Characters)this; + } - public EndElement asEndElement() { - return (EndElement)this; - } + public EndElement asEndElement() { + return (EndElement)this; + } public static abstract class NamedXEvent extends XEvent { - private QName qname; - - public NamedXEvent(QName qname) { - this.qname = qname; - } - - public QName getName() { - return qname; - } + private QName qname; + + public NamedXEvent(QName qname) { + this.qname = qname; + } + + public QName getName() { + return qname; + } + } + public static class StartElement extends NamedXEvent { + + public StartElement(String ns, String tag) { + super(new QName(ns,tag)); + } + + @Override + public int getEventType() { + return XMLEvent.START_ELEMENT; + } + } + + public static class EndElement extends NamedXEvent { + public EndElement(String ns, String tag) { + super(new QName(ns,tag)); + } + + @Override + public int getEventType() { + return XMLEvent.END_ELEMENT; + } + } + + public static class Characters extends XEvent { + private String data; + + public Characters(String data) { + this.data = data; + } + @Override + public int getEventType() { + return XMLEvent.CHARACTERS; + } + + public String getData() { + return data; + } + } + + public static class StartDocument extends XEvent { + + @Override + public int getEventType() { + return XMLEvent.START_DOCUMENT; + } + + } + + public static class EndDocument extends XEvent { + + @Override + public int getEventType() { + return XMLEvent.END_DOCUMENT; + } + + } + public static class Comment extends XEvent { + public final String value; + public Comment(String value) { + this.value = value; + } + + @Override + public int getEventType() { + return XMLEvent.COMMENT; + } + } - public static class StartElement extends NamedXEvent { - - public StartElement(String ns, String tag) { - super(new QName(ns,tag)); - } - - @Override - public int getEventType() { - return XMLEvent.START_ELEMENT; - } - } - - public static class EndElement extends NamedXEvent { - public EndElement(String ns, String tag) { - super(new QName(ns,tag)); - } - - @Override - public int getEventType() { - return XMLEvent.END_ELEMENT; - } - } - - public static class Characters extends XEvent { - private String data; - - public Characters(String data) { - this.data = data; - } - @Override - public int getEventType() { - return XMLEvent.CHARACTERS; - } - - public String getData() { - return data; - } - } - - public static class StartDocument extends XEvent { - - @Override - public int getEventType() { - return XMLEvent.START_DOCUMENT; - } - - } - - public static class EndDocument extends XEvent { - - @Override - public int getEventType() { - return XMLEvent.END_DOCUMENT; - } - - } - public static class Comment extends XEvent { - public final String value; - public Comment(String value) { - this.value = value; - } - - @Override - public int getEventType() { - return XMLEvent.COMMENT; - } - - } } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java index 78265e4b..b7cc40ad 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java @@ -49,379 +49,379 @@ import javax.xml.stream.XMLStreamException; */ // @SuppressWarnings("restriction") public class XReader { - private XEvent curr,another; - private InputStream is; - private ByteArrayOutputStream baos; - private int state, count, last; - - private Stack<Map<String,String>> nsses; - - public XReader(InputStream is) { - this.is = is; - curr = another = null; - baos = new ByteArrayOutputStream(); - state = BEGIN_DOC; - count = 0; - nsses = new Stack<Map<String,String>>(); - } - - public boolean hasNext() throws XMLStreamException { - if(curr==null) { - curr = parse(); - } - return curr!=null; - } + private XEvent curr,another; + private InputStream is; + private ByteArrayOutputStream baos; + private int state, count, last; + + private Stack<Map<String,String>> nsses; + + public XReader(InputStream is) { + this.is = is; + curr = another = null; + baos = new ByteArrayOutputStream(); + state = BEGIN_DOC; + count = 0; + nsses = new Stack<Map<String,String>>(); + } + + public boolean hasNext() throws XMLStreamException { + if(curr==null) { + curr = parse(); + } + return curr!=null; + } - public XEvent nextEvent() { - XEvent xe = curr; - curr = null; - return xe; - } + public XEvent nextEvent() { + XEvent xe = curr; + curr = null; + return xe; + } - // - // State Flags - // - // Note: The State of parsing XML can be complicated. There are too many to cleanly keep in "booleans". Additionally, - // there are certain checks that can be better made with Bitwise operations within switches - // Keeping track of state this way also helps us to accomplish logic without storing any back characters except one - private final static int BEGIN_DOC= 0x000001; - private final static int DOC_TYPE= 0x000002; - private final static int QUESTION_F= 0x000004; - private final static int QUESTION = 0x000008; - private final static int START_TAG = 0x000010; - private final static int END_TAG = 0x000020; - private final static int VALUE= 0x000040; - private final static int COMMENT = 0x001000; - private final static int COMMENT_E = 0x002000; - private final static int COMMENT_D1 =0x010000; - private final static int COMMENT_D2 =0x020000; - private final static int COMMENT_D3 =0x040000; - private final static int COMMENT_D4 =0x080000; - // useful combined Comment states - private final static int IN_COMMENT=COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2; - private final static int COMPLETE_COMMENT = COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2|COMMENT_D3|COMMENT_D4; - - - private XEvent parse() throws XMLStreamException { - Map<String,String> nss = nsses.isEmpty()?null:nsses.peek(); + // + // State Flags + // + // Note: The State of parsing XML can be complicated. There are too many to cleanly keep in "booleans". Additionally, + // there are certain checks that can be better made with Bitwise operations within switches + // Keeping track of state this way also helps us to accomplish logic without storing any back characters except one + private final static int BEGIN_DOC= 0x000001; + private final static int DOC_TYPE= 0x000002; + private final static int QUESTION_F= 0x000004; + private final static int QUESTION = 0x000008; + private final static int START_TAG = 0x000010; + private final static int END_TAG = 0x000020; + private final static int VALUE= 0x000040; + private final static int COMMENT = 0x001000; + private final static int COMMENT_E = 0x002000; + private final static int COMMENT_D1 =0x010000; + private final static int COMMENT_D2 =0x020000; + private final static int COMMENT_D3 =0x040000; + private final static int COMMENT_D4 =0x080000; + // useful combined Comment states + private final static int IN_COMMENT=COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2; + private final static int COMPLETE_COMMENT = COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2|COMMENT_D3|COMMENT_D4; + + + private XEvent parse() throws XMLStreamException { + Map<String,String> nss = nsses.isEmpty()?null:nsses.peek(); - XEvent rv; - if((rv=another)!=null) { // "another" is a tag that may have needed to be created, but not - // immediately returned. Save for next parse. If necessary, this could be turned into - // a FIFO storage, but a single reference is enough for now. - another = null; // "rv" is now set for the Event, and will be returned. Set to Null. - } else { - boolean go = true; - int c=0; - - try { - while(go && (c=is.read())>=0) { - ++count; - switch(c) { - case '<': // Tag is opening - state|=~BEGIN_DOC; // remove BEGIN_DOC flag, this is possibly an XML Doc - XEvent cxe = null; - if(baos.size()>0) { // If there are any characters between tags, we send as Character Event - String chars = baos.toString().trim(); // Trim out WhiteSpace before and after - if(chars.length()>0) { // don't send if Characters were only whitespace - cxe = new XEvent.Characters(chars); - baos.reset(); - go = false; - } - } - last = c; // make sure "last" character is set for use in "ParseTag" - Tag t = parseTag(); // call subroutine to process the tag as a unit - String ns; - switch(t.state&(START_TAG|END_TAG)) { - case START_TAG: - nss = getNss(nss,t); // Only Start Tags might have NS Attributes - // Get any NameSpace elements from tag. If there are, nss will become - // a new Map with all the previous NSs plus the new. This provides - // scoping behavior when used with the Stack - // drop through on purpose - case END_TAG: - ns = t.prefix==null||nss==null?"":nss.get(t.prefix); // Get the namespace from prefix (if exists) - break; - default: - ns = ""; - } - if(ns==null) - throw new XMLStreamException("Invalid Namespace Prefix at " + count); - go = false; - switch(t.state) { // based on - case DOC_TYPE: - rv = new XEvent.StartDocument(); - break; - case COMMENT: - rv = new XEvent.Comment(t.value); - break; - case START_TAG: - rv = new XEvent.StartElement(ns,t.name); - nsses.push(nss); // Change potential scope for Namespace - break; - case END_TAG: - rv = new XEvent.EndElement(ns,t.name); - nss = nsses.pop(); // End potential scope for Namespace - break; - case START_TAG|END_TAG: // This tag is both start/end aka <myTag/> - rv = new XEvent.StartElement(ns,t.name); - if(last=='/')another = new XEvent.EndElement(ns,t.name); - } - if(cxe!=null) { // if there is a Character Event, it actually should go first. ow. - another = rv; // Make current Event the "another" or next event, and - rv = cxe; // send Character Event now - } - break; - case ' ': - case '\t': - case '\n': - if((state&BEGIN_DOC)==BEGIN_DOC) { // if Whitespace before doc, just ignore - break; - } - // fallthrough on purpose - default: - if((state&BEGIN_DOC)==BEGIN_DOC) { // if there is any data at the start other than XML Tag, it's not XML - throw new XMLStreamException("Parse Error: This is not an XML Doc"); - } - baos.write(c); // save off Characters - } - last = c; // Some processing needs to know what the last character was, aka Escaped characters... ex \" - } - } catch (IOException e) { - throw new XMLStreamException(e); // all errors parsing will be treated as XMLStreamErrors (like StAX) - } - if(c==-1 && (state&BEGIN_DOC)==BEGIN_DOC) { // Normally, end of stream is ok, however, we need to know if the - throw new XMLStreamException("Premature End of File"); // document isn't an XML document, so we throw exception if it - } // hasn't yet been determined to be an XML Doc - } - return rv; - } - - /** - * parseTag - * - * Parsing a Tag is somewhat complicated, so it's helpful to separate this process from the - * higher level Parsing effort - * @return - * @throws IOException - * @throws XMLStreamException - */ - private Tag parseTag() throws IOException, XMLStreamException { - Tag tag = null; - boolean go = true; - state = 0; - int c, quote=0; // If "quote" is 0, then we're not in a quote. We set ' (in pretag) or " in attribs accordingly to denote quoted - String prefix=null,name=null,value=null; - baos.reset(); - - while(go && (c=is.read())>=0) { - ++count; - if(quote!=0) { // If we're in a quote, we only end if we hit another quote of the same time, not preceded by \ - if(c==quote && last!='\\') { - quote=0; - } else { - baos.write(c); - } - } else if((state&COMMENT)==COMMENT) { // similar to Quote is being in a comment - switch(c) { - case '-': - switch(state) { // XML has a complicated Quote set... <!-- --> ... we keep track if each has been met with flags. - case COMMENT|COMMENT_E: - state|=COMMENT_D1; - break; - case COMMENT|COMMENT_E|COMMENT_D1: - state|=COMMENT_D2; - baos.reset(); // clear out "!--", it's a Comment - break; - case COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2: - state|=COMMENT_D3; - baos.write(c); - break; - case COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2|COMMENT_D3: - state|=COMMENT_D4; - baos.write(c); - break; - } - break; - case '>': // Tag indicator has been found, do we have all the comment characters in line? - if((state&COMPLETE_COMMENT)==COMPLETE_COMMENT) { - byte ba[] = baos.toByteArray(); - tag = new Tag(null,null, new String(ba,0,ba.length-2)); - baos.reset(); - go = false; - break; - } - // fall through on purpose - default: - state&=~(COMMENT_D3|COMMENT_D4); - if((state&IN_COMMENT)!=IN_COMMENT) state&=~IN_COMMENT; // false alarm, it's not actually a comment - baos.write(c); - } - } else { // Normal Tag Processing loop - switch(c) { - case '?': - switch(state & (QUESTION_F|QUESTION)) { // Validate the state of Doc tag... <?xml ... ?> - case QUESTION_F: - state |= DOC_TYPE; - state &= ~QUESTION_F; - break; - case 0: - state |=QUESTION_F; - break; - default: - throw new IOException("Bad character [?] at " + count); - } - break; - case '!': - if(last=='<') { - state|=COMMENT|COMMENT_E; // likely a comment, continue processing in Comment Loop - } - baos.write(c); - break; - case '/': - state|=(last=='<'?END_TAG:(END_TAG|START_TAG)); // end tag indicator </xxx>, ,or both <xxx/> - break; - case ':': - prefix=baos.toString(); // prefix indicator - baos.reset(); - break; - case '=': // used in Attributes - name=baos.toString(); - baos.reset(); - state|=VALUE; - break; - case '>': // end the tag, which causes end of this subprocess as well as formulation of the found data - go = false; - // passthrough on purpose - case ' ': - case '\t': - case '\n': // white space indicates change in internal tag state, ex between name and between attributes - if((state&VALUE)==VALUE) { - value = baos.toString(); // we're in VALUE state, add characters to Value - } else if(name==null) { - name = baos.toString(); // we're in Name state (default) add characters to Name - } - baos.reset(); // we've assigned chars, reset buffer - if(name!=null) { // Name is not null, there's a tag in the offing here... - Tag t = new Tag(prefix,name,value); - if(tag==null) { // Set as the tag to return, if not exists - tag = t; - } else { // if we already have a Tag, then we'll treat this one as an attribute - tag.add(t); - } - } - prefix=name=value=null; // reset these values in case we loop for attributes. - break; - case '\'': // is the character one of two kinds of quote? - case '"': - if(last!='\\') { - quote=c; - break; - } - // Fallthrough ok - default: - baos.write(c); // write any unprocessed bytes into buffer - - } - } - last = c; - } - int type = state&(DOC_TYPE|COMMENT|END_TAG|START_TAG); // get just the Tag states and turn into Type for Tag - if(type==0) { - type=START_TAG; - } - if(tag!=null) { - tag.state|=type; // add the appropriate Tag States - } - return tag; - } + XEvent rv; + if((rv=another)!=null) { // "another" is a tag that may have needed to be created, but not + // immediately returned. Save for next parse. If necessary, this could be turned into + // a FIFO storage, but a single reference is enough for now. + another = null; // "rv" is now set for the Event, and will be returned. Set to Null. + } else { + boolean go = true; + int c=0; + + try { + while(go && (c=is.read())>=0) { + ++count; + switch(c) { + case '<': // Tag is opening + state|=~BEGIN_DOC; // remove BEGIN_DOC flag, this is possibly an XML Doc + XEvent cxe = null; + if(baos.size()>0) { // If there are any characters between tags, we send as Character Event + String chars = baos.toString().trim(); // Trim out WhiteSpace before and after + if(chars.length()>0) { // don't send if Characters were only whitespace + cxe = new XEvent.Characters(chars); + baos.reset(); + go = false; + } + } + last = c; // make sure "last" character is set for use in "ParseTag" + Tag t = parseTag(); // call subroutine to process the tag as a unit + String ns; + switch(t.state&(START_TAG|END_TAG)) { + case START_TAG: + nss = getNss(nss,t); // Only Start Tags might have NS Attributes + // Get any NameSpace elements from tag. If there are, nss will become + // a new Map with all the previous NSs plus the new. This provides + // scoping behavior when used with the Stack + // drop through on purpose + case END_TAG: + ns = t.prefix==null||nss==null?"":nss.get(t.prefix); // Get the namespace from prefix (if exists) + break; + default: + ns = ""; + } + if(ns==null) + throw new XMLStreamException("Invalid Namespace Prefix at " + count); + go = false; + switch(t.state) { // based on + case DOC_TYPE: + rv = new XEvent.StartDocument(); + break; + case COMMENT: + rv = new XEvent.Comment(t.value); + break; + case START_TAG: + rv = new XEvent.StartElement(ns,t.name); + nsses.push(nss); // Change potential scope for Namespace + break; + case END_TAG: + rv = new XEvent.EndElement(ns,t.name); + nss = nsses.pop(); // End potential scope for Namespace + break; + case START_TAG|END_TAG: // This tag is both start/end aka <myTag/> + rv = new XEvent.StartElement(ns,t.name); + if(last=='/')another = new XEvent.EndElement(ns,t.name); + } + if(cxe!=null) { // if there is a Character Event, it actually should go first. ow. + another = rv; // Make current Event the "another" or next event, and + rv = cxe; // send Character Event now + } + break; + case ' ': + case '\t': + case '\n': + if((state&BEGIN_DOC)==BEGIN_DOC) { // if Whitespace before doc, just ignore + break; + } + // fallthrough on purpose + default: + if((state&BEGIN_DOC)==BEGIN_DOC) { // if there is any data at the start other than XML Tag, it's not XML + throw new XMLStreamException("Parse Error: This is not an XML Doc"); + } + baos.write(c); // save off Characters + } + last = c; // Some processing needs to know what the last character was, aka Escaped characters... ex \" + } + } catch (IOException e) { + throw new XMLStreamException(e); // all errors parsing will be treated as XMLStreamErrors (like StAX) + } + if(c==-1 && (state&BEGIN_DOC)==BEGIN_DOC) { // Normally, end of stream is ok, however, we need to know if the + throw new XMLStreamException("Premature End of File"); // document isn't an XML document, so we throw exception if it + } // hasn't yet been determined to be an XML Doc + } + return rv; + } + + /** + * parseTag + * + * Parsing a Tag is somewhat complicated, so it's helpful to separate this process from the + * higher level Parsing effort + * @return + * @throws IOException + * @throws XMLStreamException + */ + private Tag parseTag() throws IOException, XMLStreamException { + Tag tag = null; + boolean go = true; + state = 0; + int c, quote=0; // If "quote" is 0, then we're not in a quote. We set ' (in pretag) or " in attribs accordingly to denote quoted + String prefix=null,name=null,value=null; + baos.reset(); + + while(go && (c=is.read())>=0) { + ++count; + if(quote!=0) { // If we're in a quote, we only end if we hit another quote of the same time, not preceded by \ + if(c==quote && last!='\\') { + quote=0; + } else { + baos.write(c); + } + } else if((state&COMMENT)==COMMENT) { // similar to Quote is being in a comment + switch(c) { + case '-': + switch(state) { // XML has a complicated Quote set... <!-- --> ... we keep track if each has been met with flags. + case COMMENT|COMMENT_E: + state|=COMMENT_D1; + break; + case COMMENT|COMMENT_E|COMMENT_D1: + state|=COMMENT_D2; + baos.reset(); // clear out "!--", it's a Comment + break; + case COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2: + state|=COMMENT_D3; + baos.write(c); + break; + case COMMENT|COMMENT_E|COMMENT_D1|COMMENT_D2|COMMENT_D3: + state|=COMMENT_D4; + baos.write(c); + break; + } + break; + case '>': // Tag indicator has been found, do we have all the comment characters in line? + if((state&COMPLETE_COMMENT)==COMPLETE_COMMENT) { + byte ba[] = baos.toByteArray(); + tag = new Tag(null,null, new String(ba,0,ba.length-2)); + baos.reset(); + go = false; + break; + } + // fall through on purpose + default: + state&=~(COMMENT_D3|COMMENT_D4); + if((state&IN_COMMENT)!=IN_COMMENT) state&=~IN_COMMENT; // false alarm, it's not actually a comment + baos.write(c); + } + } else { // Normal Tag Processing loop + switch(c) { + case '?': + switch(state & (QUESTION_F|QUESTION)) { // Validate the state of Doc tag... <?xml ... ?> + case QUESTION_F: + state |= DOC_TYPE; + state &= ~QUESTION_F; + break; + case 0: + state |=QUESTION_F; + break; + default: + throw new IOException("Bad character [?] at " + count); + } + break; + case '!': + if(last=='<') { + state|=COMMENT|COMMENT_E; // likely a comment, continue processing in Comment Loop + } + baos.write(c); + break; + case '/': + state|=(last=='<'?END_TAG:(END_TAG|START_TAG)); // end tag indicator </xxx>, ,or both <xxx/> + break; + case ':': + prefix=baos.toString(); // prefix indicator + baos.reset(); + break; + case '=': // used in Attributes + name=baos.toString(); + baos.reset(); + state|=VALUE; + break; + case '>': // end the tag, which causes end of this subprocess as well as formulation of the found data + go = false; + // passthrough on purpose + case ' ': + case '\t': + case '\n': // white space indicates change in internal tag state, ex between name and between attributes + if((state&VALUE)==VALUE) { + value = baos.toString(); // we're in VALUE state, add characters to Value + } else if(name==null) { + name = baos.toString(); // we're in Name state (default) add characters to Name + } + baos.reset(); // we've assigned chars, reset buffer + if(name!=null) { // Name is not null, there's a tag in the offing here... + Tag t = new Tag(prefix,name,value); + if(tag==null) { // Set as the tag to return, if not exists + tag = t; + } else { // if we already have a Tag, then we'll treat this one as an attribute + tag.add(t); + } + } + prefix=name=value=null; // reset these values in case we loop for attributes. + break; + case '\'': // is the character one of two kinds of quote? + case '"': + if(last!='\\') { + quote=c; + break; + } + // Fallthrough ok + default: + baos.write(c); // write any unprocessed bytes into buffer + + } + } + last = c; + } + int type = state&(DOC_TYPE|COMMENT|END_TAG|START_TAG); // get just the Tag states and turn into Type for Tag + if(type==0) { + type=START_TAG; + } + if(tag!=null) { + tag.state|=type; // add the appropriate Tag States + } + return tag; + } - /** - * getNSS - * - * If the tag contains some Namespace attributes, create a new nss from the passed in one, copy all into it, then add - * This provides Scoping behavior - * - * if Nss is null in the first place, create an new nss, so we don't have to deal with null Maps. - * - * @param nss - * @param t - * @return - */ - private Map<String, String> getNss(Map<String, String> nss, Tag t) { - Map<String,String> newnss = null; - if(t.attribs!=null) { - for(Tag tag : t.attribs) { - if("xmlns".equals(tag.prefix)) { - if(newnss==null) { - newnss = new HashMap<>(); - if(nss!=null)newnss.putAll(nss); - } - newnss.put(tag.name, tag.value); - } - } - } - //return newnss==null?(nss==null?new HashMap<String,String>():nss):newnss; - if(newnss==null) { - if(nss==null) { - newnss = new HashMap<>(); - } else { - newnss = nss; - } - } - return newnss; - } + /** + * getNSS + * + * If the tag contains some Namespace attributes, create a new nss from the passed in one, copy all into it, then add + * This provides Scoping behavior + * + * if Nss is null in the first place, create an new nss, so we don't have to deal with null Maps. + * + * @param nss + * @param t + * @return + */ + private Map<String, String> getNss(Map<String, String> nss, Tag t) { + Map<String,String> newnss = null; + if(t.attribs!=null) { + for(Tag tag : t.attribs) { + if("xmlns".equals(tag.prefix)) { + if(newnss==null) { + newnss = new HashMap<>(); + if(nss!=null)newnss.putAll(nss); + } + newnss.put(tag.name, tag.value); + } + } + } + //return newnss==null?(nss==null?new HashMap<String,String>():nss):newnss; + if(newnss==null) { + if(nss==null) { + newnss = new HashMap<>(); + } else { + newnss = nss; + } + } + return newnss; + } - /** - * The result of the parseTag method - * - * Data is split up into prefix, name and value portions. "Tags" with Values that are inside a Tag are known in XLM - * as Attributes. - * - * @author Jonathan - * - */ - public class Tag { - public int state; - public String prefix,name,value; - public List<Tag> attribs; + /** + * The result of the parseTag method + * + * Data is split up into prefix, name and value portions. "Tags" with Values that are inside a Tag are known in XLM + * as Attributes. + * + * @author Jonathan + * + */ + public class Tag { + public int state; + public String prefix,name,value; + public List<Tag> attribs; - public Tag(String prefix, String name, String value) { - this.prefix = prefix; - this.name = name; - this.value = value; - attribs = null; - } + public Tag(String prefix, String name, String value) { + this.prefix = prefix; + this.name = name; + this.value = value; + attribs = null; + } - /** - * add an attribute - * Not all tags need attributes... lazy instantiate to save time and memory - * @param tag - */ - public void add(Tag attrib) { - if(attribs == null) { - attribs = new ArrayList<>(); - } - attribs.add(attrib); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - if(prefix!=null) { - sb.append(prefix); - sb.append(':'); - } - sb.append(name==null?"!!ERROR!!":name); + /** + * add an attribute + * Not all tags need attributes... lazy instantiate to save time and memory + * @param tag + */ + public void add(Tag attrib) { + if(attribs == null) { + attribs = new ArrayList<>(); + } + attribs.add(attrib); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + if(prefix!=null) { + sb.append(prefix); + sb.append(':'); + } + sb.append(name==null?"!!ERROR!!":name); - char quote = ((state&DOC_TYPE)==DOC_TYPE)?'\'':'"'; - if(value!=null) { - sb.append('='); - sb.append(quote); - sb.append(value); - sb.append(quote); - } - return sb.toString(); - } - } + char quote = ((state&DOC_TYPE)==DOC_TYPE)?'\'':'"'; + if(value!=null) { + sb.append('='); + sb.append(quote); + sb.append(value); + sb.append(quote); + } + return sb.toString(); + } + } } |