X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=auth%2Fauth-certman%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Fcm%2Fservice%2FCMService.java;h=900df8a75c7268fcc8aa25eb3e4ebea482f73991;hb=be1edcb6830745015f5de72e820f40f36dd571ad;hp=aa145f1c74c05bf45076f38702239049d15e7059;hpb=8bdca3de7c784ed20fa6a097ca8eb8e37cbc18f2;p=aaf%2Fauthz.git diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java index aa145f1c..900df8a7 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java @@ -3,7 +3,7 @@ * org.onap.aaf * =========================================================================== * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2018 IBM. + * Modifications Copyright (C) 2019 IBM. * =========================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,7 +80,7 @@ public class CMService { // Limit total requests private static final int MAX_X509s = 200; // Need a "LIMIT Exception" DB. private static final String MAX_X509S_TAG = "cm_max_x509s"; // be able to adjust limit in future - + public static final String REQUEST = "request"; public static final String IGNORE_IPS = "ignoreIPs"; public static final String RENEW = "renew"; @@ -93,6 +93,8 @@ public class CMService { private static final String[] NO_NOTES = new String[0]; private final Permission root_read_permission; + private final String aaf_ns; + private final CertDAO certDAO; private final CredDAO credDAO; private final ArtiDAO artiDAO; @@ -114,8 +116,9 @@ public class CMService { this.certManager = certman; + aaf_ns = trans.getProperty(Config.AAF_ROOT_NS, Config.AAF_ROOT_NS_DEF); root_read_permission=new AAFPermission( - trans.getProperty(Config.AAF_ROOT_NS, Config.AAF_ROOT_NS_DEF), + aaf_ns, ACCESS, "*", "read" @@ -149,44 +152,32 @@ public class CMService { List notes = null; List fqdns; + boolean dynamic_sans = trans.fish(new AAFPermission(null, ca.getPermType(), ca.getName(),DYNAMIC_SANS)); + boolean ignoreIPs = trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), IGNORE_IPS)); boolean domain_based = false; - boolean dynamic_sans = false; + // Note: Many Cert Impls require FQDN in "CN=" to be in the SANS as well. Therefore, the "fqdn" variable + // includes main ID plus ADDITIONAL SANS at all times. if(req.value.fqdns.isEmpty()) { - fqdns = new ArrayList<>(); + fqdns = new ArrayList<>(); + fqdns.add(key); } else { - // Only Template or Dynamic permitted to pass in FQDNs - if (req.value.fqdns.get(0).startsWith("*")) { // Domain set + // Only Template or Dynamic permitted to pass in FQDNs + if (req.value.fqdns.get(0).startsWith("*")) { // Domain set if (trans.fish(new AAFPermission(null,ca.getPermType(), ca.getName(), DOMAIN))) { - domain_based = true; + domain_based = true; } else { return Result.err(Result.ERR_Denied, "Domain based Authorizations (" + req.value.fqdns.get(0) + ") requires Exception"); } - } else { - if(trans.fish(new AAFPermission(null, ca.getPermType(), ca.getName(),DYNAMIC_SANS))) { - dynamic_sans = true; - } else { - return Result.err(Result.ERR_Denied, - "Dynamic SANs for (" + req.value.mechid + ") requires Permission"); - } - } - fqdns = new ArrayList<>(req.value.fqdns); + } + fqdns = new ArrayList<>(req.value.fqdns); } String email = null; try { Organization org = trans.org(); - - boolean ignoreIPs; - if(allowIgnoreIPs) { - ignoreIPs = trans.fish(new AAFPermission(mechNS,CERTMAN, ca.getName(), IGNORE_IPS)); - } else { - ignoreIPs = false; - } - - InetAddress primary = null; // Organize incoming information to get to appropriate Artifact if (!fqdns.isEmpty()) { // Passed in FQDNS, validated above @@ -197,8 +188,8 @@ public class CMService { String domain = fqdns.get(0).substring(1); // starts with *, see above fqdns.remove(0); if (fqdns.isEmpty()) { - return Result.err(Result.ERR_Denied, - "Requests using domain require machine declaration"); + return Result.err(Result.ERR_Denied, + "Requests using domain require machine declaration"); } if (!ignoreIPs) { @@ -212,7 +203,7 @@ public class CMService { } } else { - // Passed in FQDNs, but not starting with * + // Passed in FQDNs, but not starting with * if (!ignoreIPs) { for (String cn : req.value.fqdns) { try { @@ -220,7 +211,8 @@ public class CMService { Set potentialSanNames = new HashSet<>(); for (InetAddress ia1 : ias) { InetAddress ia2 = InetAddress.getByAddress(ia1.getAddress()); - if (primary == null && ias.length == 1 && trans.ip().equals(ia1.getHostAddress())) { + String ip = trans.ip(); + if (primary == null && ip.equals(ia1.getHostAddress())) { primary = ia1; } else if (!cn.equals(ia1.getHostName()) && !ia2.getHostName().equals(ia2.getHostAddress())) { @@ -254,37 +246,37 @@ public class CMService { return Result.err(Result.ERR_Denied,"Authorization must not include SANS when doing Dynamic SANS (%s, %s)", req.value.mechid, key); } } else { - if(domain_based) { - ra = artiDAO.read(trans, req.value.mechid, key); - if (ra.isOKhasData()) { // is the Template available? - add = ra.value.get(0); - add.machine = host; - for (String s : fqdns) { - if (!s.equals(add.machine)) { - add.sans(true).add(s); - } - } - Result rc = artiDAO.create(trans, add); // Create new Artifact from Template - if (rc.notOK()) { - return Result.err(rc); - } - } else { - return Result.err(Result.ERR_Denied,"No Authorization Template for %s, %s", req.value.mechid, key); - } - } else { + if(domain_based) { + ra = artiDAO.read(trans, req.value.mechid, key); + if (ra.isOKhasData()) { // is the Template available? + add = ra.value.get(0); + add.machine = host; + for (String s : fqdns) { + if (!s.equals(add.machine)) { + add.sans(true).add(s); + } + } + Result rc = artiDAO.create(trans, add); // Create new Artifact from Template + if (rc.notOK()) { + return Result.err(rc); + } + } else { + return Result.err(Result.ERR_Denied,"No Authorization Template for %s, %s", req.value.mechid, key); + } + } else { return Result.err(Result.ERR_Denied,"No Authorization found for %s, %s", req.value.mechid, key); - } + } } // Add Artifact listed FQDNs if(!dynamic_sans) { - if (add.sans != null) { - for (String s : add.sans) { - if (!fqdns.contains(s)) { - fqdns.add(s); - } - } - } + if (add.sans != null) { + for (String s : add.sans) { + if (!fqdns.contains(s)) { + fqdns.add(s); + } + } + } } // Policy 2: If Config marked as Expired, do not create or renew @@ -296,16 +288,16 @@ public class CMService { // Policy 3: MechID must be current Identity muser = org.getIdentity(trans, add.mechid); - if (muser == null) { - return Result.err(Result.ERR_Policy, "MechID must exist in %s", org.getName()); + if (muser == null || !muser.isFound()) { + return Result.err(Result.ERR_Policy, "AppID '%s' must exist in %s",add.mechid,org.getName()); } // Policy 4: Sponsor must be current Identity ouser = muser.responsibleTo(); - if (ouser == null) { + if (ouser == null || !ouser.isFound()) { return Result.err(Result.ERR_Policy, "%s does not have a current sponsor at %s", add.mechid, org.getName()); - } else if (!ouser.isFound() || ouser.mayOwn() != null) { + } else if (ouser.mayOwn() != null) { return Result.err(Result.ERR_Policy, "%s reports that %s cannot be responsible for %s", org.getName(), trans.user()); } @@ -327,19 +319,28 @@ public class CMService { trans.user(), mechNS); } + // Policy 8: IP Addresses allowed in Certs only by Permission + if(!trans.fish(new AAFPermission(aaf_ns,CERTMAN, ca.getName(), "ip"))) { + for(String fqdn : fqdns) { + if(CA.IPV4_PATTERN.matcher(fqdn).matches() || CA.IPV6_PATTERN.matcher(fqdn).matches()) { + return Result.err(Status.ERR_Denied, + "Machines include a IP Address. IP Addresses are not allowed except by Permission"); + } + } + } + // Make sure Primary is the first in fqdns + if (fqdns.size() > 1) { for (int i = 0; i < fqdns.size(); ++i) { if (primary==null && !ignoreIPs) { trans.error().log("CMService var primary is null"); } else { String fg = fqdns.get(i); - if (fg!=null && primary!=null && fg.equals(primary.getHostName())) { - if (i != 0) { + if ((fg!=null && primary!=null && fg.equals(primary.getHostName()))&&(i != 0)) { String tmp = fqdns.get(0); fqdns.set(0, primary.getHostName()); fqdns.set(i, tmp); - } } } } @@ -354,7 +355,7 @@ public class CMService { try { csrMeta = BCFactory.createCSRMeta(ca, req.value.mechid, email, fqdns); csrMeta.environment(ca.getEnv()); - + // Before creating, make sure they don't have too many if(!trans.fish(limitOverridePerm)) { Result> existing = certDAO.readID(trans, req.value.mechid); @@ -366,11 +367,9 @@ public class CMService { Collection certs = Factory.toX509Certificate(cdd.x509); for(Iterator iter = certs.iterator(); iter.hasNext();) { X509Certificate x509 = (X509Certificate)iter.next(); - if(x509.getNotAfter().after(now) && x509.getSubjectDN().getName().contains(cn)) { - if(++count>max_509s) { + if((x509.getNotAfter().after(now) && x509.getSubjectDN().getName().contains(cn))&&(++count>max_509s)) { break; - } - } + } } } if(count>max_509s) { @@ -392,7 +391,7 @@ public class CMService { cdd.id = req.value.mechid; cdd.x500 = x509.getSubjectDN().getName(); cdd.x509 = Factory.toString(trans, x509); - + certDAO.create(trans, cdd); CredDAO.Data crdd = new CredDAO.Data();