From 62c4eb45e157d502463d797c1353802ca8e1e307 Mon Sep 17 00:00:00 2001 From: sg481n Date: Fri, 25 Aug 2017 01:57:24 -0400 Subject: Update project structure for aaf/cadi Update project structure from com.att to org.onap and add distribution management and staging plugin. Issue-id: AAF-22 Change-Id: Idf2b591139e38921ad28782a51486714a05dee92 Signed-off-by: sg481n --- aaf/pom.xml | 78 +- aaf/src/main/java/Examples.java | 41 -- .../main/java/com/att/cadi/aaf/AAFPermission.java | 105 --- .../main/java/com/att/cadi/aaf/AAFTransmutate.java | 87 --- .../java/com/att/cadi/aaf/ConnectivityTest.java | 458 ------------ aaf/src/main/java/com/att/cadi/aaf/PermEval.java | 149 ---- .../att/cadi/aaf/cert/AAFListedCertIdentity.java | 178 ----- .../java/com/att/cadi/aaf/client/ErrMessage.java | 97 --- .../java/com/att/cadi/aaf/client/Examples.java | 444 ----------- .../java/com/att/cadi/aaf/marshal/CertMarshal.java | 66 -- .../com/att/cadi/aaf/marshal/CertsMarshal.java | 45 -- .../main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java | 206 ------ .../main/java/com/att/cadi/aaf/v2_0/AAFCon.java | 395 ---------- .../java/com/att/cadi/aaf/v2_0/AAFConDME2.java | 223 ------ .../java/com/att/cadi/aaf/v2_0/AAFConHttp.java | 186 ----- .../java/com/att/cadi/aaf/v2_0/AAFLurPerm.java | 220 ------ .../main/java/com/att/cadi/aaf/v2_0/AAFTaf.java | 167 ----- .../com/att/cadi/aaf/v2_0/AAFTrustChecker.java | 115 --- .../main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java | 268 ------- aaf/src/main/java/com/att/cadi/cm/ArtifactDir.java | 287 -------- .../main/java/com/att/cadi/cm/CertException.java | 46 -- aaf/src/main/java/com/att/cadi/cm/CmAgent.java | 710 ------------------ aaf/src/main/java/com/att/cadi/cm/Factory.java | 448 ----------- .../main/java/com/att/cadi/cm/PlaceArtifact.java | 33 - .../java/com/att/cadi/cm/PlaceArtifactInFiles.java | 53 -- .../com/att/cadi/cm/PlaceArtifactInKeystore.java | 129 ---- .../com/att/cadi/cm/PlaceArtifactOnStream.java | 52 -- .../java/com/att/cadi/cm/PlaceArtifactScripts.java | 138 ---- aaf/src/main/java/com/att/cadi/sso/AAFSSO.java | 285 ------- .../java/org/onap/aaf/cadi/aaf/AAFPermission.java | 105 +++ .../java/org/onap/aaf/cadi/aaf/AAFTransmutate.java | 87 +++ .../org/onap/aaf/cadi/aaf/ConnectivityTest.java | 459 ++++++++++++ .../main/java/org/onap/aaf/cadi/aaf/PermEval.java | 149 ++++ .../aaf/cadi/aaf/cert/AAFListedCertIdentity.java | 179 +++++ .../org/onap/aaf/cadi/aaf/client/ErrMessage.java | 98 +++ .../org/onap/aaf/cadi/aaf/client/Examples.java | 444 +++++++++++ .../org/onap/aaf/cadi/aaf/marshal/CertMarshal.java | 66 ++ .../onap/aaf/cadi/aaf/marshal/CertsMarshal.java | 45 ++ .../java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java | 207 ++++++ .../java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java | 396 ++++++++++ .../org/onap/aaf/cadi/aaf/v2_0/AAFConDME2.java | 224 ++++++ .../org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java | 187 +++++ .../org/onap/aaf/cadi/aaf/v2_0/AAFLurPerm.java | 221 ++++++ .../java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java | 167 +++++ .../onap/aaf/cadi/aaf/v2_0/AAFTrustChecker.java | 116 +++ .../java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLur.java | 269 +++++++ .../java/org/onap/aaf/cadi/cm/ArtifactDir.java | 288 ++++++++ .../java/org/onap/aaf/cadi/cm/CertException.java | 46 ++ .../main/java/org/onap/aaf/cadi/cm/CmAgent.java | 712 ++++++++++++++++++ .../main/java/org/onap/aaf/cadi/cm/Factory.java | 449 ++++++++++++ .../java/org/onap/aaf/cadi/cm/PlaceArtifact.java | 34 + .../org/onap/aaf/cadi/cm/PlaceArtifactInFiles.java | 54 ++ .../onap/aaf/cadi/cm/PlaceArtifactInKeystore.java | 130 ++++ .../onap/aaf/cadi/cm/PlaceArtifactOnStream.java | 52 ++ .../org/onap/aaf/cadi/cm/PlaceArtifactScripts.java | 139 ++++ .../main/java/org/onap/aaf/cadi/sso/AAFSSO.java | 285 +++++++ .../test/java/com/att/aaf/content/JU_Content.java | 83 --- .../test/java/com/att/aaf/example/CadiTest.java | 58 -- .../java/com/att/aaf/example/ExampleAuthCheck.java | 57 -- .../java/com/att/aaf/example/ExamplePerm2_0.java | 113 --- .../com/att/aaf/example/ExamplePerm2_0_DME2.java | 113 --- .../test/java/com/att/aaf/example/X509Test.java | 89 --- .../java/com/att/cadi/lur/aaf/test/JU_JMeter.java | 145 ---- .../com/att/cadi/lur/aaf/test/JU_Lur2_0Call.java | 575 --------------- .../com/att/cadi/lur/aaf/test/JU_PermEval.java | 108 --- .../att/cadi/lur/aaf/test/MultiThreadPermHit.java | 145 ---- .../java/com/att/cadi/lur/aaf/test/TestAccess.java | 122 --- .../org/onap/aaf/cadi/lur/aaf/test/JU_JMeter.java | 144 ++++ .../onap/aaf/cadi/lur/aaf/test/JU_Lur2_0Call.java | 574 +++++++++++++++ .../onap/aaf/cadi/lur/aaf/test/JU_PermEval.java | 107 +++ .../aaf/cadi/lur/aaf/test/MultiThreadPermHit.java | 145 ++++ .../org/onap/aaf/cadi/lur/aaf/test/TestAccess.java | 122 +++ .../test/java/org/onap/aaf/content/JU_Content.java | 83 +++ .../test/java/org/onap/aaf/example/CadiTest.java | 58 ++ .../org/onap/aaf/example/ExampleAuthCheck.java | 57 ++ .../java/org/onap/aaf/example/ExamplePerm2_0.java | 113 +++ .../org/onap/aaf/example/ExamplePerm2_0_DME2.java | 113 +++ .../test/java/org/onap/aaf/example/X509Test.java | 89 +++ cass/pom.xml | 84 ++- .../att/cadi/aaf/cass/AAFAuthenticatedUser.java | 111 --- .../com/att/cadi/aaf/cass/AAFAuthenticator.java | 175 ----- .../java/com/att/cadi/aaf/cass/AAFAuthorizer.java | 227 ------ .../main/java/com/att/cadi/aaf/cass/AAFBase.java | 192 ----- .../aaf/cadi/aaf/cass/AAFAuthenticatedUser.java | 110 +++ .../onap/aaf/cadi/aaf/cass/AAFAuthenticator.java | 174 +++++ .../org/onap/aaf/cadi/aaf/cass/AAFAuthorizer.java | 226 ++++++ .../java/org/onap/aaf/cadi/aaf/cass/AAFBase.java | 191 +++++ cass/src/test/java/com/att/aaf/cass/JU_CASS.java | 107 --- .../java/com/att/cadi/aaf/cass/test/JU_CASS.java | 107 --- .../org/onap/aaf/cadi/aaf/cass/test/JU_CASS.java | 106 +++ cass/src/test/java/org/onap/aaf/cass/JU_CASS.java | 106 +++ client/pom.xml | 82 ++- .../main/java/com/att/cadi/client/AAFClient.java | 198 ----- .../java/com/att/cadi/client/AbsBasicAuth.java | 93 --- .../java/com/att/cadi/client/AbsTransferSS.java | 73 -- .../src/main/java/com/att/cadi/client/Delete.java | 70 -- .../src/main/java/com/att/cadi/client/EClient.java | 52 -- .../main/java/com/att/cadi/client/EnvAccess.java | 167 ----- .../src/main/java/com/att/cadi/client/Future.java | 34 - client/src/main/java/com/att/cadi/client/Get.java | 48 -- .../src/main/java/com/att/cadi/client/Holder.java | 44 -- client/src/main/java/com/att/cadi/client/Post.java | 49 -- .../java/com/att/cadi/client/PropertyLocator.java | 143 ---- client/src/main/java/com/att/cadi/client/Put.java | 64 -- .../main/java/com/att/cadi/client/RawClient.java | 158 ---- client/src/main/java/com/att/cadi/client/Rcli.java | 696 ------------------ .../src/main/java/com/att/cadi/client/Result.java | 57 -- .../main/java/com/att/cadi/client/Retryable.java | 71 -- .../src/main/java/com/att/cadi/dme2/DEClient.java | 222 ------ .../main/java/com/att/cadi/dme2/DME2BasicAuth.java | 63 -- .../main/java/com/att/cadi/dme2/DME2ClientSS.java | 64 -- .../main/java/com/att/cadi/dme2/DME2Locator.java | 348 --------- .../java/com/att/cadi/dme2/DME2TransferSS.java | 55 -- .../main/java/com/att/cadi/dme2/DME2x509SS.java | 67 -- client/src/main/java/com/att/cadi/dme2/DRcli.java | 141 ---- .../main/java/com/att/cadi/dnsloc/DNSLocator.java | 167 ----- .../main/java/com/att/cadi/http/HBasicAuthSS.java | 76 -- .../src/main/java/com/att/cadi/http/HClient.java | 433 ----------- client/src/main/java/com/att/cadi/http/HMangr.java | 235 ------ client/src/main/java/com/att/cadi/http/HRcli.java | 133 ---- .../main/java/com/att/cadi/http/HTransferSS.java | 65 -- .../src/main/java/com/att/cadi/http/HX509SS.java | 167 ----- .../java/com/att/cadi/locator/DME2Locator.java | 345 --------- .../main/java/com/att/cadi/locator/DNSLocator.java | 163 ----- .../att/cadi/locator/HClientHotPeerLocator.java | 61 -- .../java/com/att/cadi/locator/HotPeerLocator.java | 303 -------- .../java/com/att/cadi/locator/PropertyLocator.java | 281 ------- .../java/com/att/cadi/routing/GreatCircle.java | 189 ----- .../java/org/onap/aaf/cadi/client/AAFClient.java | 199 +++++ .../org/onap/aaf/cadi/client/AbsBasicAuth.java | 93 +++ .../org/onap/aaf/cadi/client/AbsTransferSS.java | 73 ++ .../main/java/org/onap/aaf/cadi/client/Delete.java | 71 ++ .../java/org/onap/aaf/cadi/client/EClient.java | 52 ++ .../java/org/onap/aaf/cadi/client/EnvAccess.java | 169 +++++ .../main/java/org/onap/aaf/cadi/client/Future.java | 34 + .../main/java/org/onap/aaf/cadi/client/Get.java | 49 ++ .../main/java/org/onap/aaf/cadi/client/Holder.java | 44 ++ .../main/java/org/onap/aaf/cadi/client/Post.java | 50 ++ .../org/onap/aaf/cadi/client/PropertyLocator.java | 143 ++++ .../main/java/org/onap/aaf/cadi/client/Put.java | 65 ++ .../java/org/onap/aaf/cadi/client/RawClient.java | 159 ++++ .../main/java/org/onap/aaf/cadi/client/Rcli.java | 697 ++++++++++++++++++ .../main/java/org/onap/aaf/cadi/client/Result.java | 57 ++ .../java/org/onap/aaf/cadi/client/Retryable.java | 72 ++ .../main/java/org/onap/aaf/cadi/dme2/DEClient.java | 223 ++++++ .../java/org/onap/aaf/cadi/dme2/DME2BasicAuth.java | 64 ++ .../java/org/onap/aaf/cadi/dme2/DME2ClientSS.java | 65 ++ .../java/org/onap/aaf/cadi/dme2/DME2Locator.java | 349 +++++++++ .../org/onap/aaf/cadi/dme2/DME2TransferSS.java | 56 ++ .../java/org/onap/aaf/cadi/dme2/DME2x509SS.java | 68 ++ .../main/java/org/onap/aaf/cadi/dme2/DRcli.java | 142 ++++ .../java/org/onap/aaf/cadi/dnsloc/DNSLocator.java | 167 +++++ .../java/org/onap/aaf/cadi/http/HBasicAuthSS.java | 76 ++ .../main/java/org/onap/aaf/cadi/http/HClient.java | 434 +++++++++++ .../main/java/org/onap/aaf/cadi/http/HMangr.java | 236 ++++++ .../main/java/org/onap/aaf/cadi/http/HRcli.java | 134 ++++ .../java/org/onap/aaf/cadi/http/HTransferSS.java | 65 ++ .../main/java/org/onap/aaf/cadi/http/HX509SS.java | 168 +++++ .../org/onap/aaf/cadi/locator/DME2Locator.java | 347 +++++++++ .../java/org/onap/aaf/cadi/locator/DNSLocator.java | 163 +++++ .../aaf/cadi/locator/HClientHotPeerLocator.java | 61 ++ .../org/onap/aaf/cadi/locator/HotPeerLocator.java | 304 ++++++++ .../org/onap/aaf/cadi/locator/PropertyLocator.java | 282 +++++++ .../org/onap/aaf/cadi/routing/GreatCircle.java | 189 +++++ .../test/java/com/client/test/BasicDME2Client.java | 61 -- .../test/java/com/client/test/JU_DNSLocator.java | 57 -- .../java/com/client/test/JU_PropertyLocator.java | 98 --- client/src/test/java/com/client/test/PaulUzee.java | 145 ---- .../src/test/java/com/client/test/TestAccess.java | 90 --- .../test/java/com/client/test/TestDME2Client.java | 97 --- .../java/com/client/test/TestDME2RcliClient.java | 78 -- .../src/test/java/com/client/test/TestHClient.java | 83 --- .../org/onap/aaf/client/test/BasicDME2Client.java | 61 ++ .../org/onap/aaf/client/test/JU_DNSLocator.java | 56 ++ .../onap/aaf/client/test/JU_PropertyLocator.java | 97 +++ .../java/org/onap/aaf/client/test/PaulUzee.java | 146 ++++ .../java/org/onap/aaf/client/test/TestAccess.java | 90 +++ .../org/onap/aaf/client/test/TestDME2Client.java | 98 +++ .../onap/aaf/client/test/TestDME2RcliClient.java | 79 ++ .../java/org/onap/aaf/client/test/TestHClient.java | 84 +++ core/pom.xml | 80 +- core/src/main/java/com/att/cadi/AES.java | 127 ---- .../main/java/com/att/cadi/AbsCachedPrincipal.java | 33 - core/src/main/java/com/att/cadi/AbsUserCache.java | 408 ----------- core/src/main/java/com/att/cadi/Access.java | 172 ----- core/src/main/java/com/att/cadi/BasicCred.java | 36 - .../main/java/com/att/cadi/BufferedCadiWrap.java | 80 -- .../com/att/cadi/BufferedServletInputStream.java | 214 ------ .../main/java/com/att/cadi/CachedPrincipal.java | 47 -- core/src/main/java/com/att/cadi/CachingLur.java | 35 - core/src/main/java/com/att/cadi/CadiException.java | 50 -- core/src/main/java/com/att/cadi/CadiWrap.java | 193 ----- core/src/main/java/com/att/cadi/Capacitor.java | 240 ------ core/src/main/java/com/att/cadi/CmdLine.java | 356 --------- core/src/main/java/com/att/cadi/Connector.java | 27 - core/src/main/java/com/att/cadi/CredVal.java | 42 -- core/src/main/java/com/att/cadi/GetCred.java | 27 - core/src/main/java/com/att/cadi/Hash.java | 202 ----- core/src/main/java/com/att/cadi/Locator.java | 36 - .../main/java/com/att/cadi/LocatorException.java | 47 -- core/src/main/java/com/att/cadi/Lur.java | 94 --- core/src/main/java/com/att/cadi/Permission.java | 29 - core/src/main/java/com/att/cadi/PropAccess.java | 320 -------- core/src/main/java/com/att/cadi/Revalidator.java | 35 - core/src/main/java/com/att/cadi/SLF4JAccess.java | 100 --- .../src/main/java/com/att/cadi/SecuritySetter.java | 44 -- .../java/com/att/cadi/ServletContextAccess.java | 69 -- core/src/main/java/com/att/cadi/StrLur.java | 56 -- core/src/main/java/com/att/cadi/Symm.java | 811 -------------------- core/src/main/java/com/att/cadi/Taf.java | 57 -- core/src/main/java/com/att/cadi/Transmutate.java | 45 -- core/src/main/java/com/att/cadi/TrustChecker.java | 53 -- core/src/main/java/com/att/cadi/User.java | 144 ---- core/src/main/java/com/att/cadi/UserChain.java | 43 -- core/src/main/java/com/att/cadi/config/Config.java | 814 -------------------- core/src/main/java/com/att/cadi/config/Get.java | 97 --- .../main/java/com/att/cadi/config/GetAccess.java | 63 -- .../main/java/com/att/cadi/config/MultiGet.java | 43 -- .../java/com/att/cadi/config/SecurityInfo.java | 243 ------ .../java/com/att/cadi/config/SecurityInfoC.java | 44 -- .../main/java/com/att/cadi/config/UsersDump.java | 158 ---- core/src/main/java/com/att/cadi/filter/AUTHZ.java | 37 - .../java/com/att/cadi/filter/AUTHZServlet.java | 100 --- .../java/com/att/cadi/filter/AccessGetter.java | 37 - .../main/java/com/att/cadi/filter/CadiAccess.java | 243 ------ .../main/java/com/att/cadi/filter/CadiFilter.java | 305 -------- .../java/com/att/cadi/filter/CadiHTTPManip.java | 227 ------ core/src/main/java/com/att/cadi/filter/FCGet.java | 77 -- .../java/com/att/cadi/filter/MapPermConverter.java | 55 -- .../com/att/cadi/filter/NullPermConverter.java | 43 -- .../main/java/com/att/cadi/filter/PathFilter.java | 183 ----- .../java/com/att/cadi/filter/PermConverter.java | 32 - .../java/com/att/cadi/filter/RolesAllowed.java | 55 -- .../main/java/com/att/cadi/filter/ServletImpl.java | 55 -- .../java/com/att/cadi/lur/ConfigPrincipal.java | 70 -- core/src/main/java/com/att/cadi/lur/EpiLur.java | 167 ----- core/src/main/java/com/att/cadi/lur/LocalLur.java | 201 ----- .../java/com/att/cadi/lur/LocalPermission.java | 51 -- core/src/main/java/com/att/cadi/lur/NullLur.java | 88 --- .../com/att/cadi/principal/BasicPrincipal.java | 117 --- .../com/att/cadi/principal/BearerPrincipal.java | 36 - .../com/att/cadi/principal/CSPPrincipal_T.java | 33 - .../att/cadi/principal/CachedBasicPrincipal.java | 65 -- .../com/att/cadi/principal/TGuardPrincipal.java | 80 -- .../com/att/cadi/principal/TGuardPrincipal_T.java | 33 - .../com/att/cadi/principal/TrustPrincipal.java | 67 -- .../java/com/att/cadi/principal/X509Principal.java | 92 --- .../src/main/java/com/att/cadi/taf/AbsTafResp.java | 116 --- core/src/main/java/com/att/cadi/taf/EpiTaf.java | 84 --- .../src/main/java/com/att/cadi/taf/HttpEpiTaf.java | 185 ----- core/src/main/java/com/att/cadi/taf/HttpTaf.java | 60 -- .../java/com/att/cadi/taf/LoginPageTafResp.java | 87 --- core/src/main/java/com/att/cadi/taf/NullTaf.java | 64 -- .../main/java/com/att/cadi/taf/NullTafResp.java | 73 -- .../main/java/com/att/cadi/taf/PuntTafResp.java | 71 -- .../main/java/com/att/cadi/taf/Redirectable.java | 32 - core/src/main/java/com/att/cadi/taf/TafResp.java | 94 --- .../java/com/att/cadi/taf/TrustNotTafResp.java | 77 -- .../main/java/com/att/cadi/taf/TrustTafResp.java | 79 -- .../java/com/att/cadi/taf/basic/BasicHttpTaf.java | 159 ---- .../com/att/cadi/taf/basic/BasicHttpTafResp.java | 63 -- .../java/com/att/cadi/taf/cert/CertIdentity.java | 46 -- .../com/att/cadi/taf/cert/X509HttpTafResp.java | 52 -- .../main/java/com/att/cadi/taf/cert/X509Taf.java | 257 ------- .../com/att/cadi/taf/dos/DenialOfServiceTaf.java | 370 ---------- .../att/cadi/taf/dos/DenialOfServiceTafResp.java | 48 -- .../com/att/cadi/taf/localhost/LocalhostTaf.java | 130 ---- .../att/cadi/taf/localhost/LocalhostTafResp.java | 81 -- core/src/main/java/com/att/cadi/util/Chmod.java | 63 -- .../java/com/att/cadi/util/JsonOutputStream.java | 90 --- .../com/att/cadi/util/MaskFormatException.java | 32 - .../src/main/java/com/att/cadi/util/MyConsole.java | 29 - core/src/main/java/com/att/cadi/util/NetMask.java | 100 --- core/src/main/java/com/att/cadi/util/Split.java | 91 --- .../java/com/att/cadi/util/SubStandardConsole.java | 63 -- .../main/java/com/att/cadi/util/TheConsole.java | 48 -- .../java/com/att/cadi/util/UserChainManip.java | 78 -- core/src/main/java/com/att/cadi/util/Vars.java | 121 --- core/src/main/java/com/att/cadi/wsse/Action.java | 37 - core/src/main/java/com/att/cadi/wsse/Match.java | 130 ---- .../main/java/com/att/cadi/wsse/WSSEParser.java | 86 --- core/src/main/java/com/att/cadi/wsse/XEvent.java | 135 ---- core/src/main/java/com/att/cadi/wsse/XReader.java | 416 ----------- core/src/main/java/org/onap/aaf/cadi/AES.java | 127 ++++ .../java/org/onap/aaf/cadi/AbsCachedPrincipal.java | 33 + .../main/java/org/onap/aaf/cadi/AbsUserCache.java | 408 +++++++++++ core/src/main/java/org/onap/aaf/cadi/Access.java | 172 +++++ .../src/main/java/org/onap/aaf/cadi/BasicCred.java | 36 + .../java/org/onap/aaf/cadi/BufferedCadiWrap.java | 80 ++ .../onap/aaf/cadi/BufferedServletInputStream.java | 214 ++++++ .../java/org/onap/aaf/cadi/CachedPrincipal.java | 47 ++ .../main/java/org/onap/aaf/cadi/CachingLur.java | 35 + .../main/java/org/onap/aaf/cadi/CadiException.java | 50 ++ core/src/main/java/org/onap/aaf/cadi/CadiWrap.java | 193 +++++ .../src/main/java/org/onap/aaf/cadi/Capacitor.java | 240 ++++++ core/src/main/java/org/onap/aaf/cadi/CmdLine.java | 356 +++++++++ .../src/main/java/org/onap/aaf/cadi/Connector.java | 27 + core/src/main/java/org/onap/aaf/cadi/CredVal.java | 42 ++ core/src/main/java/org/onap/aaf/cadi/GetCred.java | 27 + core/src/main/java/org/onap/aaf/cadi/Hash.java | 202 +++++ core/src/main/java/org/onap/aaf/cadi/Locator.java | 36 + .../java/org/onap/aaf/cadi/LocatorException.java | 47 ++ core/src/main/java/org/onap/aaf/cadi/Lur.java | 94 +++ .../main/java/org/onap/aaf/cadi/Permission.java | 29 + .../main/java/org/onap/aaf/cadi/PropAccess.java | 321 ++++++++ .../main/java/org/onap/aaf/cadi/Revalidator.java | 35 + .../main/java/org/onap/aaf/cadi/SLF4JAccess.java | 100 +++ .../java/org/onap/aaf/cadi/SecuritySetter.java | 44 ++ .../org/onap/aaf/cadi/ServletContextAccess.java | 69 ++ core/src/main/java/org/onap/aaf/cadi/StrLur.java | 56 ++ core/src/main/java/org/onap/aaf/cadi/Symm.java | 811 ++++++++++++++++++++ core/src/main/java/org/onap/aaf/cadi/Taf.java | 57 ++ .../main/java/org/onap/aaf/cadi/Transmutate.java | 45 ++ .../main/java/org/onap/aaf/cadi/TrustChecker.java | 53 ++ core/src/main/java/org/onap/aaf/cadi/User.java | 144 ++++ .../src/main/java/org/onap/aaf/cadi/UserChain.java | 43 ++ .../main/java/org/onap/aaf/cadi/config/Config.java | 815 +++++++++++++++++++++ .../main/java/org/onap/aaf/cadi/config/Get.java | 97 +++ .../java/org/onap/aaf/cadi/config/GetAccess.java | 63 ++ .../java/org/onap/aaf/cadi/config/MultiGet.java | 43 ++ .../org/onap/aaf/cadi/config/SecurityInfo.java | 243 ++++++ .../org/onap/aaf/cadi/config/SecurityInfoC.java | 44 ++ .../java/org/onap/aaf/cadi/config/UsersDump.java | 158 ++++ .../main/java/org/onap/aaf/cadi/filter/AUTHZ.java | 37 + .../org/onap/aaf/cadi/filter/AUTHZServlet.java | 100 +++ .../org/onap/aaf/cadi/filter/AccessGetter.java | 37 + .../java/org/onap/aaf/cadi/filter/CadiAccess.java | 243 ++++++ .../java/org/onap/aaf/cadi/filter/CadiFilter.java | 305 ++++++++ .../org/onap/aaf/cadi/filter/CadiHTTPManip.java | 227 ++++++ .../main/java/org/onap/aaf/cadi/filter/FCGet.java | 77 ++ .../org/onap/aaf/cadi/filter/MapPermConverter.java | 55 ++ .../onap/aaf/cadi/filter/NullPermConverter.java | 43 ++ .../java/org/onap/aaf/cadi/filter/PathFilter.java | 183 +++++ .../org/onap/aaf/cadi/filter/PermConverter.java | 32 + .../org/onap/aaf/cadi/filter/RolesAllowed.java | 55 ++ .../java/org/onap/aaf/cadi/filter/ServletImpl.java | 55 ++ .../org/onap/aaf/cadi/lur/ConfigPrincipal.java | 70 ++ .../main/java/org/onap/aaf/cadi/lur/EpiLur.java | 167 +++++ .../main/java/org/onap/aaf/cadi/lur/LocalLur.java | 201 +++++ .../org/onap/aaf/cadi/lur/LocalPermission.java | 51 ++ .../main/java/org/onap/aaf/cadi/lur/NullLur.java | 88 +++ .../onap/aaf/cadi/principal/BasicPrincipal.java | 117 +++ .../onap/aaf/cadi/principal/BearerPrincipal.java | 36 + .../onap/aaf/cadi/principal/CSPPrincipal_T.java | 33 + .../aaf/cadi/principal/CachedBasicPrincipal.java | 65 ++ .../onap/aaf/cadi/principal/TGuardPrincipal.java | 80 ++ .../onap/aaf/cadi/principal/TGuardPrincipal_T.java | 33 + .../onap/aaf/cadi/principal/TrustPrincipal.java | 67 ++ .../org/onap/aaf/cadi/principal/X509Principal.java | 92 +++ .../java/org/onap/aaf/cadi/taf/AbsTafResp.java | 116 +++ .../main/java/org/onap/aaf/cadi/taf/EpiTaf.java | 84 +++ .../java/org/onap/aaf/cadi/taf/HttpEpiTaf.java | 185 +++++ .../main/java/org/onap/aaf/cadi/taf/HttpTaf.java | 60 ++ .../org/onap/aaf/cadi/taf/LoginPageTafResp.java | 87 +++ .../main/java/org/onap/aaf/cadi/taf/NullTaf.java | 64 ++ .../java/org/onap/aaf/cadi/taf/NullTafResp.java | 73 ++ .../java/org/onap/aaf/cadi/taf/PuntTafResp.java | 71 ++ .../java/org/onap/aaf/cadi/taf/Redirectable.java | 32 + .../main/java/org/onap/aaf/cadi/taf/TafResp.java | 94 +++ .../org/onap/aaf/cadi/taf/TrustNotTafResp.java | 77 ++ .../java/org/onap/aaf/cadi/taf/TrustTafResp.java | 79 ++ .../org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java | 159 ++++ .../onap/aaf/cadi/taf/basic/BasicHttpTafResp.java | 63 ++ .../org/onap/aaf/cadi/taf/cert/CertIdentity.java | 46 ++ .../onap/aaf/cadi/taf/cert/X509HttpTafResp.java | 52 ++ .../java/org/onap/aaf/cadi/taf/cert/X509Taf.java | 257 +++++++ .../onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java | 370 ++++++++++ .../aaf/cadi/taf/dos/DenialOfServiceTafResp.java | 48 ++ .../onap/aaf/cadi/taf/localhost/LocalhostTaf.java | 130 ++++ .../aaf/cadi/taf/localhost/LocalhostTafResp.java | 81 ++ .../main/java/org/onap/aaf/cadi/util/Chmod.java | 63 ++ .../org/onap/aaf/cadi/util/JsonOutputStream.java | 90 +++ .../onap/aaf/cadi/util/MaskFormatException.java | 32 + .../java/org/onap/aaf/cadi/util/MyConsole.java | 29 + .../main/java/org/onap/aaf/cadi/util/NetMask.java | 100 +++ .../main/java/org/onap/aaf/cadi/util/Split.java | 91 +++ .../org/onap/aaf/cadi/util/SubStandardConsole.java | 63 ++ .../java/org/onap/aaf/cadi/util/TheConsole.java | 48 ++ .../org/onap/aaf/cadi/util/UserChainManip.java | 78 ++ .../src/main/java/org/onap/aaf/cadi/util/Vars.java | 121 +++ .../main/java/org/onap/aaf/cadi/wsse/Action.java | 37 + .../main/java/org/onap/aaf/cadi/wsse/Match.java | 130 ++++ .../java/org/onap/aaf/cadi/wsse/WSSEParser.java | 86 +++ .../main/java/org/onap/aaf/cadi/wsse/XEvent.java | 135 ++++ .../main/java/org/onap/aaf/cadi/wsse/XReader.java | 416 +++++++++++ core/src/test/java/com/att/cadi/JU_AES.java | 86 --- .../java/com/att/cadi/lur/test/JU_LocalLur.java | 101 --- .../java/com/att/cadi/lur/test/TestAccess.java | 91 --- .../src/test/java/com/att/cadi/test/JU_Base64.java | 157 ---- .../cadi/test/JU_BufferedServletInputStream.java | 191 ----- .../test/java/com/att/cadi/test/JU_Capacitor.java | 144 ---- core/src/test/java/com/att/cadi/test/JU_Hash.java | 61 -- .../test/java/com/att/cadi/test/JU_Passcode.java | 90 --- .../java/com/att/cadi/test/JU_UserChainManip.java | 48 -- core/src/test/java/com/att/cadi/test/JU_Vars.java | 126 ---- core/src/test/java/com/att/cadi/test/Test.java | 70 -- .../java/com/att/cadi/wsse/test/JU_WSSE_Read.java | 191 ----- .../java/com/att/cadi/wsse/test/JU_XReader.java | 66 -- core/src/test/java/org/onap/aaf/cadi/JU_AES.java | 88 +++ .../org/onap/aaf/cadi/lur/test/JU_LocalLur.java | 100 +++ .../org/onap/aaf/cadi/lur/test/TestAccess.java | 91 +++ .../java/org/onap/aaf/cadi/test/JU_Base64.java | 156 ++++ .../cadi/test/JU_BufferedServletInputStream.java | 190 +++++ .../java/org/onap/aaf/cadi/test/JU_Capacitor.java | 143 ++++ .../test/java/org/onap/aaf/cadi/test/JU_Hash.java | 60 ++ .../java/org/onap/aaf/cadi/test/JU_Passcode.java | 89 +++ .../org/onap/aaf/cadi/test/JU_UserChainManip.java | 47 ++ .../test/java/org/onap/aaf/cadi/test/JU_Vars.java | 125 ++++ .../src/test/java/org/onap/aaf/cadi/test/Test.java | 70 ++ .../org/onap/aaf/cadi/wsse/test/JU_WSSE_Read.java | 190 +++++ .../org/onap/aaf/cadi/wsse/test/JU_XReader.java | 65 ++ pom.xml | 132 ++-- 412 files changed, 28247 insertions(+), 28026 deletions(-) delete mode 100644 aaf/src/main/java/Examples.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/AAFPermission.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/AAFTransmutate.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/ConnectivityTest.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/PermEval.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/cert/AAFListedCertIdentity.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/client/ErrMessage.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/client/Examples.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/marshal/CertMarshal.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/marshal/CertsMarshal.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java delete mode 100644 aaf/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/ArtifactDir.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/CertException.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/CmAgent.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/Factory.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/PlaceArtifact.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInFiles.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInKeystore.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/PlaceArtifactOnStream.java delete mode 100644 aaf/src/main/java/com/att/cadi/cm/PlaceArtifactScripts.java delete mode 100644 aaf/src/main/java/com/att/cadi/sso/AAFSSO.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFTransmutate.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/ConnectivityTest.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/cert/AAFListedCertIdentity.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/client/Examples.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertMarshal.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertsMarshal.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConDME2.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFLurPerm.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTrustChecker.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLur.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/ArtifactDir.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/CertException.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/CmAgent.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/Factory.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifact.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInFiles.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInKeystore.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactOnStream.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactScripts.java create mode 100644 aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java delete mode 100644 aaf/src/test/java/com/att/aaf/content/JU_Content.java delete mode 100644 aaf/src/test/java/com/att/aaf/example/CadiTest.java delete mode 100644 aaf/src/test/java/com/att/aaf/example/ExampleAuthCheck.java delete mode 100644 aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0.java delete mode 100644 aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0_DME2.java delete mode 100644 aaf/src/test/java/com/att/aaf/example/X509Test.java delete mode 100644 aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_JMeter.java delete mode 100644 aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_Lur2_0Call.java delete mode 100644 aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_PermEval.java delete mode 100644 aaf/src/test/java/com/att/cadi/lur/aaf/test/MultiThreadPermHit.java delete mode 100644 aaf/src/test/java/com/att/cadi/lur/aaf/test/TestAccess.java create mode 100644 aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_JMeter.java create mode 100644 aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_Lur2_0Call.java create mode 100644 aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_PermEval.java create mode 100644 aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/MultiThreadPermHit.java create mode 100644 aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/TestAccess.java create mode 100644 aaf/src/test/java/org/onap/aaf/content/JU_Content.java create mode 100644 aaf/src/test/java/org/onap/aaf/example/CadiTest.java create mode 100644 aaf/src/test/java/org/onap/aaf/example/ExampleAuthCheck.java create mode 100644 aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0.java create mode 100644 aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0_DME2.java create mode 100644 aaf/src/test/java/org/onap/aaf/example/X509Test.java delete mode 100644 cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticatedUser.java delete mode 100644 cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticator.java delete mode 100644 cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthorizer.java delete mode 100644 cass/src/main/java/com/att/cadi/aaf/cass/AAFBase.java create mode 100644 cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticatedUser.java create mode 100644 cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticator.java create mode 100644 cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthorizer.java create mode 100644 cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFBase.java delete mode 100644 cass/src/test/java/com/att/aaf/cass/JU_CASS.java delete mode 100644 cass/src/test/java/com/att/cadi/aaf/cass/test/JU_CASS.java create mode 100644 cass/src/test/java/org/onap/aaf/cadi/aaf/cass/test/JU_CASS.java create mode 100644 cass/src/test/java/org/onap/aaf/cass/JU_CASS.java delete mode 100644 client/src/main/java/com/att/cadi/client/AAFClient.java delete mode 100644 client/src/main/java/com/att/cadi/client/AbsBasicAuth.java delete mode 100644 client/src/main/java/com/att/cadi/client/AbsTransferSS.java delete mode 100644 client/src/main/java/com/att/cadi/client/Delete.java delete mode 100644 client/src/main/java/com/att/cadi/client/EClient.java delete mode 100644 client/src/main/java/com/att/cadi/client/EnvAccess.java delete mode 100644 client/src/main/java/com/att/cadi/client/Future.java delete mode 100644 client/src/main/java/com/att/cadi/client/Get.java delete mode 100644 client/src/main/java/com/att/cadi/client/Holder.java delete mode 100644 client/src/main/java/com/att/cadi/client/Post.java delete mode 100644 client/src/main/java/com/att/cadi/client/PropertyLocator.java delete mode 100644 client/src/main/java/com/att/cadi/client/Put.java delete mode 100644 client/src/main/java/com/att/cadi/client/RawClient.java delete mode 100644 client/src/main/java/com/att/cadi/client/Rcli.java delete mode 100644 client/src/main/java/com/att/cadi/client/Result.java delete mode 100644 client/src/main/java/com/att/cadi/client/Retryable.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DEClient.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DME2BasicAuth.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DME2ClientSS.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DME2Locator.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DME2TransferSS.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DME2x509SS.java delete mode 100644 client/src/main/java/com/att/cadi/dme2/DRcli.java delete mode 100644 client/src/main/java/com/att/cadi/dnsloc/DNSLocator.java delete mode 100644 client/src/main/java/com/att/cadi/http/HBasicAuthSS.java delete mode 100644 client/src/main/java/com/att/cadi/http/HClient.java delete mode 100644 client/src/main/java/com/att/cadi/http/HMangr.java delete mode 100644 client/src/main/java/com/att/cadi/http/HRcli.java delete mode 100644 client/src/main/java/com/att/cadi/http/HTransferSS.java delete mode 100644 client/src/main/java/com/att/cadi/http/HX509SS.java delete mode 100644 client/src/main/java/com/att/cadi/locator/DME2Locator.java delete mode 100644 client/src/main/java/com/att/cadi/locator/DNSLocator.java delete mode 100644 client/src/main/java/com/att/cadi/locator/HClientHotPeerLocator.java delete mode 100644 client/src/main/java/com/att/cadi/locator/HotPeerLocator.java delete mode 100644 client/src/main/java/com/att/cadi/locator/PropertyLocator.java delete mode 100644 client/src/main/java/com/att/cadi/routing/GreatCircle.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/AAFClient.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/AbsBasicAuth.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/AbsTransferSS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Delete.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/EClient.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/EnvAccess.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Future.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Get.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Holder.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Post.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/PropertyLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Put.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/RawClient.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Rcli.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Result.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/client/Retryable.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DEClient.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DME2BasicAuth.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DME2ClientSS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DME2Locator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DME2TransferSS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DME2x509SS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dme2/DRcli.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/dnsloc/DNSLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HBasicAuthSS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HClient.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HMangr.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HRcli.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HTransferSS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/http/HX509SS.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/locator/DME2Locator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/locator/DNSLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/locator/HClientHotPeerLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/locator/HotPeerLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/locator/PropertyLocator.java create mode 100644 client/src/main/java/org/onap/aaf/cadi/routing/GreatCircle.java delete mode 100644 client/src/test/java/com/client/test/BasicDME2Client.java delete mode 100644 client/src/test/java/com/client/test/JU_DNSLocator.java delete mode 100644 client/src/test/java/com/client/test/JU_PropertyLocator.java delete mode 100644 client/src/test/java/com/client/test/PaulUzee.java delete mode 100644 client/src/test/java/com/client/test/TestAccess.java delete mode 100644 client/src/test/java/com/client/test/TestDME2Client.java delete mode 100644 client/src/test/java/com/client/test/TestDME2RcliClient.java delete mode 100644 client/src/test/java/com/client/test/TestHClient.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/BasicDME2Client.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/JU_DNSLocator.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/JU_PropertyLocator.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/PaulUzee.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/TestAccess.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/TestDME2Client.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/TestDME2RcliClient.java create mode 100644 client/src/test/java/org/onap/aaf/client/test/TestHClient.java delete mode 100644 core/src/main/java/com/att/cadi/AES.java delete mode 100644 core/src/main/java/com/att/cadi/AbsCachedPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/AbsUserCache.java delete mode 100644 core/src/main/java/com/att/cadi/Access.java delete mode 100644 core/src/main/java/com/att/cadi/BasicCred.java delete mode 100644 core/src/main/java/com/att/cadi/BufferedCadiWrap.java delete mode 100644 core/src/main/java/com/att/cadi/BufferedServletInputStream.java delete mode 100644 core/src/main/java/com/att/cadi/CachedPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/CachingLur.java delete mode 100644 core/src/main/java/com/att/cadi/CadiException.java delete mode 100644 core/src/main/java/com/att/cadi/CadiWrap.java delete mode 100644 core/src/main/java/com/att/cadi/Capacitor.java delete mode 100644 core/src/main/java/com/att/cadi/CmdLine.java delete mode 100644 core/src/main/java/com/att/cadi/Connector.java delete mode 100644 core/src/main/java/com/att/cadi/CredVal.java delete mode 100644 core/src/main/java/com/att/cadi/GetCred.java delete mode 100644 core/src/main/java/com/att/cadi/Hash.java delete mode 100644 core/src/main/java/com/att/cadi/Locator.java delete mode 100644 core/src/main/java/com/att/cadi/LocatorException.java delete mode 100644 core/src/main/java/com/att/cadi/Lur.java delete mode 100644 core/src/main/java/com/att/cadi/Permission.java delete mode 100644 core/src/main/java/com/att/cadi/PropAccess.java delete mode 100644 core/src/main/java/com/att/cadi/Revalidator.java delete mode 100644 core/src/main/java/com/att/cadi/SLF4JAccess.java delete mode 100644 core/src/main/java/com/att/cadi/SecuritySetter.java delete mode 100644 core/src/main/java/com/att/cadi/ServletContextAccess.java delete mode 100644 core/src/main/java/com/att/cadi/StrLur.java delete mode 100644 core/src/main/java/com/att/cadi/Symm.java delete mode 100644 core/src/main/java/com/att/cadi/Taf.java delete mode 100644 core/src/main/java/com/att/cadi/Transmutate.java delete mode 100644 core/src/main/java/com/att/cadi/TrustChecker.java delete mode 100644 core/src/main/java/com/att/cadi/User.java delete mode 100644 core/src/main/java/com/att/cadi/UserChain.java delete mode 100644 core/src/main/java/com/att/cadi/config/Config.java delete mode 100644 core/src/main/java/com/att/cadi/config/Get.java delete mode 100644 core/src/main/java/com/att/cadi/config/GetAccess.java delete mode 100644 core/src/main/java/com/att/cadi/config/MultiGet.java delete mode 100644 core/src/main/java/com/att/cadi/config/SecurityInfo.java delete mode 100644 core/src/main/java/com/att/cadi/config/SecurityInfoC.java delete mode 100644 core/src/main/java/com/att/cadi/config/UsersDump.java delete mode 100644 core/src/main/java/com/att/cadi/filter/AUTHZ.java delete mode 100644 core/src/main/java/com/att/cadi/filter/AUTHZServlet.java delete mode 100644 core/src/main/java/com/att/cadi/filter/AccessGetter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/CadiAccess.java delete mode 100644 core/src/main/java/com/att/cadi/filter/CadiFilter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/CadiHTTPManip.java delete mode 100644 core/src/main/java/com/att/cadi/filter/FCGet.java delete mode 100644 core/src/main/java/com/att/cadi/filter/MapPermConverter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/NullPermConverter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/PathFilter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/PermConverter.java delete mode 100644 core/src/main/java/com/att/cadi/filter/RolesAllowed.java delete mode 100644 core/src/main/java/com/att/cadi/filter/ServletImpl.java delete mode 100644 core/src/main/java/com/att/cadi/lur/ConfigPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/lur/EpiLur.java delete mode 100644 core/src/main/java/com/att/cadi/lur/LocalLur.java delete mode 100644 core/src/main/java/com/att/cadi/lur/LocalPermission.java delete mode 100644 core/src/main/java/com/att/cadi/lur/NullLur.java delete mode 100644 core/src/main/java/com/att/cadi/principal/BasicPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/principal/BearerPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/principal/CSPPrincipal_T.java delete mode 100644 core/src/main/java/com/att/cadi/principal/CachedBasicPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/principal/TGuardPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/principal/TGuardPrincipal_T.java delete mode 100644 core/src/main/java/com/att/cadi/principal/TrustPrincipal.java delete mode 100644 core/src/main/java/com/att/cadi/principal/X509Principal.java delete mode 100644 core/src/main/java/com/att/cadi/taf/AbsTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/EpiTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/HttpEpiTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/HttpTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/LoginPageTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/NullTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/NullTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/PuntTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/Redirectable.java delete mode 100644 core/src/main/java/com/att/cadi/taf/TafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/TrustNotTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/TrustTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/basic/BasicHttpTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/basic/BasicHttpTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/cert/CertIdentity.java delete mode 100644 core/src/main/java/com/att/cadi/taf/cert/X509HttpTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/cert/X509Taf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/dos/DenialOfServiceTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/dos/DenialOfServiceTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/taf/localhost/LocalhostTaf.java delete mode 100644 core/src/main/java/com/att/cadi/taf/localhost/LocalhostTafResp.java delete mode 100644 core/src/main/java/com/att/cadi/util/Chmod.java delete mode 100644 core/src/main/java/com/att/cadi/util/JsonOutputStream.java delete mode 100644 core/src/main/java/com/att/cadi/util/MaskFormatException.java delete mode 100644 core/src/main/java/com/att/cadi/util/MyConsole.java delete mode 100644 core/src/main/java/com/att/cadi/util/NetMask.java delete mode 100644 core/src/main/java/com/att/cadi/util/Split.java delete mode 100644 core/src/main/java/com/att/cadi/util/SubStandardConsole.java delete mode 100644 core/src/main/java/com/att/cadi/util/TheConsole.java delete mode 100644 core/src/main/java/com/att/cadi/util/UserChainManip.java delete mode 100644 core/src/main/java/com/att/cadi/util/Vars.java delete mode 100644 core/src/main/java/com/att/cadi/wsse/Action.java delete mode 100644 core/src/main/java/com/att/cadi/wsse/Match.java delete mode 100644 core/src/main/java/com/att/cadi/wsse/WSSEParser.java delete mode 100644 core/src/main/java/com/att/cadi/wsse/XEvent.java delete mode 100644 core/src/main/java/com/att/cadi/wsse/XReader.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/AES.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/AbsCachedPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Access.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/BasicCred.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/BufferedCadiWrap.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/BufferedServletInputStream.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CachedPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CachingLur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CadiException.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CadiWrap.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Capacitor.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CmdLine.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Connector.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/CredVal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/GetCred.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Hash.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Locator.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/LocatorException.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Lur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Permission.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/PropAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Revalidator.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/SLF4JAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/StrLur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Symm.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Taf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/Transmutate.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/TrustChecker.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/User.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/UserChain.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/Config.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/Get.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/MultiGet.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/SecurityInfoC.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AUTHZ.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/CSPPrincipal_T.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal_T.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTaf.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTafResp.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/Chmod.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/MaskFormatException.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/MyConsole.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/NetMask.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/Split.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/SubStandardConsole.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/TheConsole.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/util/Vars.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/wsse/Action.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/wsse/Match.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java create mode 100644 core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java delete mode 100644 core/src/test/java/com/att/cadi/JU_AES.java delete mode 100644 core/src/test/java/com/att/cadi/lur/test/JU_LocalLur.java delete mode 100644 core/src/test/java/com/att/cadi/lur/test/TestAccess.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_Base64.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_BufferedServletInputStream.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_Capacitor.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_Hash.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_Passcode.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_UserChainManip.java delete mode 100644 core/src/test/java/com/att/cadi/test/JU_Vars.java delete mode 100644 core/src/test/java/com/att/cadi/test/Test.java delete mode 100644 core/src/test/java/com/att/cadi/wsse/test/JU_WSSE_Read.java delete mode 100644 core/src/test/java/com/att/cadi/wsse/test/JU_XReader.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/JU_AES.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/lur/test/JU_LocalLur.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/lur/test/TestAccess.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_Base64.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_BufferedServletInputStream.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_Capacitor.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_Hash.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_Passcode.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_UserChainManip.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/JU_Vars.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/test/Test.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/wsse/test/JU_WSSE_Read.java create mode 100644 core/src/test/java/org/onap/aaf/cadi/wsse/test/JU_XReader.java diff --git a/aaf/pom.xml b/aaf/pom.xml index ca4f30a..4545082 100644 --- a/aaf/pom.xml +++ b/aaf/pom.xml @@ -22,7 +22,7 @@ --> - com.att.cadi + org.onap.aaf.cadi parent 1.0.0-SNAPSHOT .. @@ -34,19 +34,29 @@ https://github.com/att/AAF CADI cadi-aaf + + UTF-8 + 1.0.0-SNAPSHOT + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/${project.groupId}/${project.artifactId}/${project.version} + + - com.att.authz + org.onap.aaf.authz authz-client - + - com.att.cadi + org.onap.aaf.cadi cadi-client - com.att.cadi + org.onap.aaf.cadi cadi-client @@ -88,7 +98,7 @@ tests - com.att.cadi.cm.CmAgent + org.onap.aaf.cadi.cm.CmAgent @@ -182,7 +192,61 @@ - + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ${nexusproxy} + 176c31dfe190a + ecomp-staging + + + + + ecomp-releases + AAF Release Repository + ${nexusproxy}${releaseNexusPath} + + + ecomp-snapshots + AAF Snapshot Repository + ${nexusproxy}${snapshotNexusPath} + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + + + onap-plugin-snapshots + https://nexus.onap.org/content/repositories/snapshots/ + + + + + + central + Maven 2 repository 2 + http://repo2.maven.org/maven2/ + + + onap-jar-snapshots + https://nexus.onap.org/content/repositories/snapshots + + + spring-repo + Spring repo + https://artifacts.alfresco.com/nexus/content/repositories/public/ + + + repository.jboss.org-public + JBoss.org Maven repository + https://repository.jboss.org/nexus/content/groups/public + + diff --git a/aaf/src/main/java/Examples.java b/aaf/src/main/java/Examples.java deleted file mode 100644 index 7ea379b..0000000 --- a/aaf/src/main/java/Examples.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -import com.att.rosetta.env.RosettaEnv; - -public class Examples { - public static void main(String[] args) { - if(args.length<1) { - System.out.println("Usage: Examples [\"optional\" - will show optional fields]"); - } else { - boolean options = args.length>1&&"optional".equals(args[1]); - try { - RosettaEnv env = new RosettaEnv(); - System.out.println(com.att.cadi.aaf.client.Examples.print(env, args[0], options)); - } catch (Exception e) { - System.out.println(e.getMessage()); - } - } - } - - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/AAFPermission.java b/aaf/src/main/java/com/att/cadi/aaf/AAFPermission.java deleted file mode 100644 index 79dd9ee..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/AAFPermission.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf; - -import com.att.cadi.Permission; - -/** - * A Class that understands the AAF format of Permission (name/type/action) - * or String "name|type|action" - * - * - */ -public class AAFPermission implements Permission { - protected String type,instance,action,key; - - protected AAFPermission() {} - - public AAFPermission(String type, String instance, String action) { - this.type = type; - this.instance = instance; - this.action = action; - key = type + '|' + instance + '|' + action; - } - - /** - * Match a Permission - * if Permission is Fielded type "Permission", we use the fields - * otherwise, we split the Permission with '|' - * - * when the type or action starts with REGEX indicator character ( ! ), - * then it is evaluated as a regular expression. - * - * If you want a simple field comparison, it is faster without REGEX - */ - public boolean match(Permission p) { - if(p instanceof AAFPermission) { - AAFPermission ap = (AAFPermission)p; - // Note: In AAF > 1.0, Accepting "*" from name would violate multi-tenancy - // Current solution is only allow direct match on Type. - // 8/28/2014 - added REGEX ability - if(type.equals(ap.getName())) - if(PermEval.evalInstance(instance,ap.getInstance())) - if(PermEval.evalAction(action,ap.getAction())) - return true; - } else { - // Permission is concatenated together: separated by | - String[] aaf = p.getKey().split("[\\s]*\\|[\\s]*",3); - if(aaf.length>0 && type.equals(aaf[0])) - if(PermEval.evalInstance(instance,aaf.length>1?aaf[1]:"*")) - if(PermEval.evalAction(action,aaf.length>2?aaf[2]:"*")) - return true; - } - return false; - } - - public String getName() { - return type; - } - - public String getInstance() { - return instance; - } - - public String getAction() { - return action; - } - - public String getKey() { - return key; - } - - /* (non-Javadoc) - * @see com.att.cadi.Permission#permType() - */ - public String permType() { - return "AAF"; - } - - public String toString() { - return "AAFPermission:\n\tType: " + type + - "\n\tInstance: " + instance + - "\n\tAction: " + action + - "\n\tKey: " + key; - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/AAFTransmutate.java b/aaf/src/main/java/com/att/cadi/aaf/AAFTransmutate.java deleted file mode 100644 index c7f0e2c..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/AAFTransmutate.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf; - -import java.security.Principal; -import java.util.regex.Pattern; - -import com.att.cadi.Transmutate; -import com.att.cadi.lur.ConfigPrincipal; -import com.att.cadi.principal.BasicPrincipal; -import com.att.cadi.principal.CSPPrincipal_T; - -/** - * AAFTransmutate - * - * Each System determines the mechanisms for which one Principal is transmutated to another, such as whether it is created - * independently, etc. - * - * For AAF, the only important thing is that these are valid ATTUID/mechIDs, to avoid unnecessary user hits - * - * attUIDs look like ab1234 or AB1234 or AZ123a - * mechids look like m12345 - * - * - */ -public final class AAFTransmutate implements Transmutate { - private Pattern pattern = Pattern.compile("[a-zA-Z]\\w\\d\\d\\d\\w"); - - public Principal mutate(Principal p) { - // Accept these three internal kinds of Principals - if(p instanceof CSPPrincipal_T - || p instanceof BasicPrincipal - || p instanceof ConfigPrincipal) { - return p; - } else { - - final String name = p.getName(); - final int idx = name.indexOf('@'); - String shortName; - if(idx>0) { // strip off any domain - shortName = name.substring(0,idx); - } else { - shortName = name; - } - - // Check for ATTUID specs before creating CSP_T - return pattern.matcher(shortName).matches()? - new CSP_T(name): // Note: use REAL name, short name for CSP_T - null; - } - } - - /** - * Essential Principal reflecting CSP Principal - * - * - */ - private final class CSP_T implements CSPPrincipal_T { - private String name; - public CSP_T(String name) { - this.name = name; - } - public String getName() { - return name; - } - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/ConnectivityTest.java b/aaf/src/main/java/com/att/cadi/aaf/ConnectivityTest.java deleted file mode 100644 index 7508522..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/ConnectivityTest.java +++ /dev/null @@ -1,458 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf; - -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.Field; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.URI; -import java.net.UnknownHostException; -import java.util.Date; - -import com.att.aft.dme2.api.DME2Client; -import com.att.aft.dme2.api.DME2Manager; -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.cadi.Locator.Item; -import com.att.cadi.LocatorException; -import com.att.cadi.Lur; -import com.att.cadi.PropAccess; -import com.att.cadi.SecuritySetter; -import com.att.cadi.TrustChecker; -import com.att.cadi.aaf.v2_0.AAFCon; -import com.att.cadi.aaf.v2_0.AAFConDME2; -import com.att.cadi.client.Future; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.http.HBasicAuthSS; -import com.att.cadi.http.HClient; -import com.att.cadi.http.HX509SS; -import com.att.cadi.locator.DME2Locator; -import com.att.cadi.locator.PropertyLocator; -import com.att.inno.env.APIException; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -import aaf.v2_0.Perms; - -public class ConnectivityTest { - private static final String PROD = "PROD"; - private static final String SRV_RESOLVE = "https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=%s/routeOffer=%s"; - private static final String GW_RESOLVE = "https://DME2RESOLVE/service=com.att.authz.authz-gw/version=2.0/envContext=%s/routeOffer=%s"; - - public static void main(String[] args) { - if(args.length<2) { - System.out.println("Usage: ConnectivityTester "); - } else { - print(true,"START OF CONNECTIVITY TESTS",new Date().toString(),System.getProperty("user.name"), - "Note: All API Calls are /authz/perms/user/"); - - final String aaf_env = args[0]; - args[1]=Config.CADI_PROP_FILES+'='+args[1]; - - PropAccess pa = new PropAccess(args); - String user = pa.getProperty(Config.AAF_MECHID); - String pass = pa.getProperty(Config.AAF_MECHPASS); - String alias = pa.getProperty(Config.CADI_ALIAS); - if(user==null) { - user=alias; - } - RosettaEnv env = new RosettaEnv(pa.getProperties()); - - try { - RosettaDF permsDF = env.newDataFactory(Perms.class); - SecurityInfoC si = new SecurityInfoC(pa); - HBasicAuthSS hbass = new HBasicAuthSS(pa,si); - if(hbass.getID()==null) { - hbass=null; // not configured with ID. - } - HX509SS hxss=null; - AAFCon aafcon; - - try { - hxss = new HX509SS(user,si); - } catch(Exception e) { - e.printStackTrace(); - print(false,"Continuing"); - } - String aafurl; - if(user==null || (pass==null && alias==null)) { - System.out.printf("ERROR: DME2 Client cannot be tested with out %s and %s properties" - , Config.AAF_MECHID, Config.AAF_MECHPASS ); - } else { - if("TEST".equals(aaf_env) || "IST".equals(aaf_env) || "PROD".equals(aaf_env)) { - DME2Manager dm = null; - print(false,"Attempt DME2Manager Load"); - if(Class.forName("com.att.aft.dme2.api.DME2Manager")==null) { - print(true,"DME2 jar is not available: Skipping DME2 Tests"); - } else { // DME2 Client Tests - pass=pa.decrypt(pass,false); - // Out of the box DME2 - aafurl = String.format(SRV_RESOLVE, aaf_env, PROD.equals(aaf_env)?"DEFAULT":"BAU_SE"); - print(true,"TEST CADI Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - print(true,"Find and TEST Connections with DME2Locator",aafurl); - DME2Locator dl = new DME2Locator(pa,dm,aafurl); - connectTest(dl); - - dm = new DME2Manager("DME2Manager",pa.getProperties()); - - dme2RawTest(dm, aafurl,user,pass); - - // URL specific Variant - if((aafurl = specificDME2URL(dl, aafurl))!=null) { - print(true,"TEST Specific DME2 CADI Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - dme2RawTest(dm,aafurl,user,pass); - } - - print(true,"CADI Direct AAFConDME2 Object Usage",aafurl); - try { - pa.setProperty(Config.AAF_URL,aafurl); - aafcon = new AAFConDME2(pa); - test(aafcon,permsDF,user); - } catch(Throwable t) { - t.printStackTrace(); - } - - // find a direct client to code a Direct HTTP with - // - if(hbass!=null) { - print(true,"CADI Http DME2Locator Client Coding Methodology BasicAuth",aafurl); - hClientTest(dl,hbass,user); - } - if(hxss!=null) { - print(true,"CADI Http DME2Locator Client Coding Methodology X509",aafurl); - hClientTest(dl,hxss,user); - } - - // ##### PROXY CHECKS - aafurl = String.format(GW_RESOLVE, aaf_env, PROD.equals(aaf_env)?"DEFAULT":"BAU_SE"); - print(true,"TEST PROXY DME2 CADI Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - - dme2RawTest(dm, aafurl,user,pass); - - // URL specific Variant - dl = new DME2Locator(pa,dm,aafurl); - if((aafurl = specificDME2URL(dl, aafurl))!=null) { - print(true,"TEST PROXY Specific DME2 CADI Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - dme2RawTest(dm,aafurl,user,pass); - } - } - } - - // Prop Locator - PropertyLocator pl = servicePropLocator(aaf_env); - connectTest(pl); - URI uri = pl.get(pl.best()); - if(uri!=null) { - aafurl = uri.toString(); - print(true,"TEST Service PropertyLocator based Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - if(hbass!=null) { - print(true,"CADI Service Http PropLocator Client Coding Methodology Basic Auth",aafurl); - hClientTest(pl,hbass, user); - print(true,"CADI Service Http PropLocator Client Coding Methodology /authn/basicAuth",aafurl); - basicAuthTest(pl,hbass); - } - if(hxss!=null) { - print(true,"CADI Service Http PropLocator Client Coding Methodology X509",aafurl); - hClientTest(pl,hxss, user); - } - } - pl = proxyPropLocator(aaf_env); - connectTest(pl); - uri = pl.get(pl.best()); - if(uri!=null) { - aafurl = uri.toString(); - print(true,"TEST PROXY PropertyLocator based Config",aafurl); - aafcon = testConfig(pa,aafurl); - test(aafcon,permsDF,user); - - if(hbass!=null) { - print(true,"CADI PROXY Http PropLocator Client Coding Methodology Basic Auth",aafurl); - hClientTest(pl,hbass, user); - print(true,"CADI PROXY Http PropLocator Client Coding Methodology /proxy/authn/basicAuth",aafurl); - basicAuthTest(pl,hbass); - } - if(hxss!=null) { - print(true,"CADI PROXY Http PropLocator Client Coding Methodology X509",aafurl); - hClientTest(pl,hxss, user); - } - } - } - - } catch(Exception e) { - e.printStackTrace(System.err); - } finally { - print(true,"END OF TESTS"); - } - } - } - - private static void print(Boolean strong, String ... args) { - PrintStream out = System.out; - out.println(); - if(strong) { - for(int i=0;i<70;++i) { - out.print('='); - } - out.println(); - } - for(String s : args) { - out.print(strong?"== ":"------ "); - out.print(s); - if(!strong) { - out.print(" ------"); - } - out.println(); - } - if(strong) { - for(int i=0;i<70;++i) { - out.print('='); - } - } - out.println(); - } - - private static void test(AAFCon aafcon,RosettaDF permsDF,String user) { - if(aafcon==null) { - print(false,"AAFCon is null"); - } else { - try { - print(false,"Calling with AAFCon"); - Future fp = aafcon.client("2.0").read("/authz/perms/user/"+user, Perms.class, permsDF); - if(fp.get(4000)) { - System.out.printf("Found %d Permission(s)\n",fp.value.getPerm().size()); - } else { - System.out.printf("Error: %d %s\n",fp.code(),fp.body()); - } - } catch (Throwable t) { - t.printStackTrace(); - } - } - } - - private static AAFCon testConfig(PropAccess pa, String aafurl) { - try { - pa.setProperty(Config.AAF_URL, aafurl); - Lur lur = Config.configLur(pa); - Config.configHttpTaf(pa, TrustChecker.NOTRUST, null, lur); - if(lur != null) { - Field f = null; - try { - f = lur.getClass().getField("aaf"); - return (AAFCon)f.get(lur); - } catch (Exception nsfe) { - } - } - - } catch(Throwable t) { - t.printStackTrace(); - } - return null; - } - - private static String specificDME2URL(Locator loc, String aafurl) throws LocatorException { - Item item = loc.best(); - if(item!=null) { - URI uri = loc.get(item); - return aafurl.replace("DME2RESOLVE", String.format("%s:%d",uri.getHost(),uri.getPort())); - } - return null; - } - - private static void connectTest(Locator dl) throws LocatorException { - URI uri; - Socket socket; - print(false,"TCP/IP Connect test to all Located Services"); - for(Item li = dl.first();li!=null;li=dl.next(li)) { - if((uri = dl.get(li)) == null) { - System.out.println("Locator Item empty"); - } else { - try { - socket = new Socket(); - socket.connect(new InetSocketAddress(uri.getHost(), uri.getPort()),3000); - System.out.printf("Can Connect a Socket to %s %d\n",uri.getHost(),uri.getPort()); - try { - socket.close(); - } catch (IOException e1) { - System.out.printf("Could not close Socket Connection: %s\n",e1.getMessage()); - } - } catch (IOException e) { - System.out.printf("Cannot Connect a Socket to %s %d: %s\n",uri.getHost(),uri.getPort(),e.getMessage()); - } - } - } - } - - private static PropertyLocator servicePropLocator(String env) throws LocatorException { - String purls; - switch(env) { - case "LOCAL": - try { - purls="https://"+InetAddress.getLocalHost().getHostName()+":8100"; - } catch (UnknownHostException e) { - throw new LocatorException(e); - } - break; - case "DEV": - purls="https://aaf.dev.att.com:8100,https://aaf.dev.att.com:8101"; - break; - case "TEST": - purls="https://aaftest.test.att.com:8100,https://aaftest.test.att.com:8101"; - break; - case "IST": - purls="https://aafist.test.att.com:8100,https://aafist.test.att.com:8101"; - break; - case PROD: - purls="https://aaf.it.att.com:8100,https://aaf.it.att.com:8101"; - break; - default: - if(env.contains(".")) { - purls="https://"+env+":8100"; - } else { - throw new LocatorException(ConnectivityTest.class.getSimpleName() + ": unknown Env"); - } - } - System.out.printf("Creating a PropertyLocator for %s\n",purls); - return new PropertyLocator(purls); - } - - private static PropertyLocator proxyPropLocator(String env) throws LocatorException { - String purls; - switch(env) { - case "LOCAL": - try { - purls="https://"+InetAddress.getLocalHost().getHostAddress()+":8100"; - } catch (UnknownHostException e) { - throw new LocatorException(e); - } - break; - case "DEV": - purls="https://aaf.dev.att.com:8095/proxy"; - break; - case "TEST": - purls="https://aaftest.test.att.com:8095/proxy"; - break; - case "IST": - purls="https://aafist.test.att.com:8095/proxy"; - break; - case PROD: - purls="https://aaf.it.att.com:8095/proxy"; - break; - default: - if(env.contains(".")) { - purls="https://"+env+":8095/proxy"; - } else { - throw new LocatorException(ConnectivityTest.class.getSimpleName() + ": unknown Env"); - } - - } - System.out.printf("Creating a PropertyLocator for %s\n",purls); - return new PropertyLocator(purls); - } - - - - - private static void hClientTest(Locator dl, SecuritySetter ss, String user) { - try { - URI uri = dl.get(dl.best()); - System.out.println("Resolved to: " + uri); - HClient client = new HClient(ss, uri, 3000); - client.setMethod("GET"); - client.setPathInfo("/authz/perms/user/"+user); - client.send(); - Future future = client.futureReadString(); - if(future.get(7000)) { - System.out.println(future.body()); - } else { - System.out.println(future.code() + ":" + future.body()); - } - } catch (CadiException | LocatorException | APIException e) { - e.printStackTrace(); - } - } - - - private static void basicAuthTest(PropertyLocator dl, SecuritySetter ss) { - try { - URI uri = dl.get(dl.best()); - System.out.println("Resolved to: " + uri); - HClient client = new HClient(ss, uri, 3000); - client.setMethod("GET"); - client.setPathInfo("/authn/basicAuth"); - client.addHeader("Accept", "text/plain"); - client.send(); - - - Future future = client.futureReadString(); - if(future.get(7000)) { - System.out.println("BasicAuth Validated"); - } else { - System.out.println("Failure " + future.code() + ":" + future.body()); - } - } catch (CadiException | LocatorException | APIException e) { - e.printStackTrace(); - } - } - - // Regular DME2Client Coding Style - private static void dme2RawTest(DME2Manager dm, String aafurl, String user, String pass) { - try { - if(dm==null) { - return; - } - URI uri = new URI(aafurl); - print(true,"DME2 Direct Client Coding Methodology",uri.toString()); - DME2Client client = dm.newClient( uri, 3000); - client.setMethod("GET"); // FYI, DME2 defaults to "POST" - client.setContext("/authz/perms/user/"+user); // DME2 direct requires separate setting of Context from URI - if(pass!=null) { // rely on Cert if no pass - client.setCredentials(user, pass); - } - client.setPayload(""); // DME2 will not send without something - String resp = client.sendAndWait(7000); - System.out.println(resp); - } catch(Throwable e) { - e.printStackTrace(); - } - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/PermEval.java b/aaf/src/main/java/com/att/cadi/aaf/PermEval.java deleted file mode 100644 index 448f60a..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/PermEval.java +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf; - -import com.att.inno.env.util.Split; - - -public class PermEval { - public static final char START_REGEX_CHAR = '!'; - public static final char START_INST_KEY_CHAR=':'; - public static final char ALT_START_INST_KEY_CHAR='/'; - - public static final char LIST_SEP = ','; - public static final String INST_KEY_REGEX = new StringBuilder().append(START_INST_KEY_CHAR).toString(); - public static final String ASTERIX = "*"; - - /** - * Evaluate Instance - * - * Instance can be more complex. It can be a string, a Regular Expression, or a ":" separated Key - * who's parts can also be a String, Regular Expression. - * - * sInst = Server's Instance - * In order to prevent false matches, keys must be the same length to count as equal - * Changing this will break existing users, like Cassandra. 9-4-2015 - */ - public static boolean evalInstance(String sInst, String pInst) { - if(sInst==null || pInst == null) { - return false; - } - if(ASTERIX.equals(sInst)) { - return true; // If Server's String is "*", then it accepts every Instance - } - char firstChar = pInst.charAt(0); - char startChar = firstChar==ALT_START_INST_KEY_CHAR?ALT_START_INST_KEY_CHAR:START_INST_KEY_CHAR; - switch(pInst.charAt(0)) { // First char - case START_REGEX_CHAR: // Evaluate as Regular Expression - String pItem = pInst.substring(1); - for(String sItem : Split.split(LIST_SEP,sInst)) { // allow for "," definition in Action - return sItem.matches(pItem); - } - - case START_INST_KEY_CHAR: // Evaluate a special Key field, i.e.:xyz:*:!df.* - case ALT_START_INST_KEY_CHAR: // Also allow '/' as special Key Field, i.e. /xyz/*/!.* - if(sInst.charAt(0)==startChar) { // To compare key-to-key, both strings must be keys - String[] skeys=Split.split(startChar,sInst); - String[] pkeys=Split.split(startChar,pInst); - if(skeys.length!=pkeys.length) return false; - - boolean pass = true; - for(int i=1;pass && i certs = null; - - // Did this to add other Trust Mechanisms - // Trust mechanism set by Property: - private static final String[] authMechanisms = new String[] {"tguard","basicAuth","csp"}; - private static String[] certIDs; - - private static Map> trusted =null; - - public AAFListedCertIdentity(Access access, AAFCon aafcon) throws APIException { - synchronized(AAFListedCertIdentity.class) { - if(certIDs==null) { - String cip = access.getProperty(Config.AAF_CERT_IDS, null); - if(cip!=null) { - certIDs = Split.split(',',cip); - } - } - if(certIDs!=null && certs==null) { - TimerTask cu = new CertUpdate(aafcon); - cu.run(); // want this to run in this thread first... - new Timer("AAF Identity Refresh Timer",true).scheduleAtFixedRate(cu, EIGHT_HOURS,EIGHT_HOURS); - } - } - } - - public static Set trusted(String authMech) { - return trusted.get(authMech); - } - - public Principal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException { - if(cert==null && certBytes==null)return null; - if(certBytes==null)certBytes = cert.getEncoded(); - byte[] fingerprint = X509Taf.getFingerPrint(certBytes); - String id = certs.get(new ByteArrayHolder(fingerprint)); - if(id!=null) { // Caller is Validated - return new X509Principal(id,cert,certBytes); - } - return null; - } - - private static class ByteArrayHolder implements Comparable { - private byte[] ba; - public ByteArrayHolder(byte[] ba) { - this.ba = ba; - } - public int compareTo(ByteArrayHolder b) { - return Hash.compareTo(ba, b.ba); - } - } - - private class CertUpdate extends TimerTask { - - private AAFCon aafcon; - public CertUpdate(AAFCon con) { - aafcon = con; - } - - @Override - public void run() { - try { - TreeMap newCertsMap = new TreeMap(); - Map> newTrustMap = new TreeMap>(); - Set userLookup = new HashSet(); - for(String s : certIDs) { - userLookup.add(s); - } - for(String authMech : authMechanisms) { - Future fusr = aafcon.client(AAF_VERSION).read("/authz/users/perm/com.att.aaf.trust/"+authMech+"/authenticate", Users.class, aafcon.usersDF); - if(fusr.get(5000)) { - List users = fusr.value.getUser(); - if(users.isEmpty()) { - aafcon.access.log(Level.WARN, "AAF Lookup-No IDs in Role com.att.aaf.trustForID <> "+authMech); - } else { - aafcon.access.log(Level.INFO,"Loading Trust Authentication Info for",authMech); - Set hsUser = new HashSet(); - for(User u : users) { - userLookup.add(u.getId()); - hsUser.add(u.getId()); - } - newTrustMap.put(authMech,hsUser); - } - } else { - aafcon.access.log(Level.WARN, "Could not get Users in Perm com.att.trust|tguard|authenticate",fusr.code(),fusr.body()); - } - - } - - for(String u : userLookup) { - Future fc = aafcon.client(AAF_VERSION).read("/authn/cert/id/"+u, Certs.class, aafcon.certsDF); - XMLGregorianCalendar now = Chrono.timeStamp(); - if(fc.get(5000)) { - List certs = fc.value.getCert(); - if(certs.isEmpty()) { - aafcon.access.log(Level.WARN, "No Cert Associations for",u); - } else { - for(Cert c : fc.value.getCert()) { - XMLGregorianCalendar then =c.getExpires(); - if(then !=null && then.compare(now)>0) { - newCertsMap.put(new ByteArrayHolder(c.getFingerprint()), c.getId()); - aafcon.access.log(Level.INIT,"Associating "+ c.getId() + " expiring " + Chrono.dateOnlyStamp(c.getExpires()) + " with " + c.getX500()); - } - } - } - } else { - aafcon.access.log(Level.WARN, "Could not get Certificates for",u); - } - } - - certs = newCertsMap; - trusted = newTrustMap; - } catch(Exception e) { - aafcon.access.log(e, "Failure to update Certificate Identities from AAF"); - } - } - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/client/ErrMessage.java b/aaf/src/main/java/com/att/cadi/aaf/client/ErrMessage.java deleted file mode 100644 index 4b619c6..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/client/ErrMessage.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.client; - -import java.io.PrintStream; - -import aaf.v2_0.Error; - -import com.att.cadi.client.Future; -import com.att.cadi.util.Vars; -import com.att.inno.env.APIException; -import com.att.inno.env.Data.TYPE; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -public class ErrMessage { - private RosettaDF errDF; - - public ErrMessage(RosettaEnv env) throws APIException { - errDF = env.newDataFactory(Error.class); - } - - /** - * AT&T Requires a specific Error Format for RESTful Services, which AAF complies with. - * - * This code will create a meaningful string from this format. - * - * @param ps - * @param df - * @param r - * @throws APIException - */ - public void printErr(PrintStream ps, String attErrJson) throws APIException { - StringBuilder sb = new StringBuilder(); - Error err = errDF.newData().in(TYPE.JSON).load(attErrJson).asObject(); - ps.println(toMsg(sb,err)); - } - - /** - * AT&T Requires a specific Error Format for RESTful Services, which AAF complies with. - * - * This code will create a meaningful string from this format. - * - * @param sb - * @param df - * @param r - * @throws APIException - */ - public StringBuilder toMsg(StringBuilder sb, String attErrJson) throws APIException { - return toMsg(sb,errDF.newData().in(TYPE.JSON).load(attErrJson).asObject()); - } - - public StringBuilder toMsg(Future future) { - return toMsg(new StringBuilder(),future); - } - - public StringBuilder toMsg(StringBuilder sb, Future future) { - try { - toMsg(sb,errDF.newData().in(TYPE.JSON).load(future.body()).asObject()); - } catch(Exception e) { - //just print what we can - sb.append(future.code()); - sb.append(": "); - sb.append(future.body()); - } - return sb; - } - - public StringBuilder toMsg(StringBuilder sb, Error err) { - sb.append(err.getMessageId()); - sb.append(' '); - String[] vars = new String[err.getVariables().size()]; - err.getVariables().toArray(vars); - Vars.convert(sb, err.getText(),vars); - return sb; - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/client/Examples.java b/aaf/src/main/java/com/att/cadi/aaf/client/Examples.java deleted file mode 100644 index d469805..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/client/Examples.java +++ /dev/null @@ -1,444 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.client; - - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.GregorianCalendar; - -import aaf.v2_0.Approval; -import aaf.v2_0.Approvals; -import aaf.v2_0.CredRequest; -import aaf.v2_0.Keys; -import aaf.v2_0.NsRequest; -import aaf.v2_0.Nss; -import aaf.v2_0.Nss.Ns; -import aaf.v2_0.Perm; -import aaf.v2_0.PermKey; -import aaf.v2_0.PermRequest; -import aaf.v2_0.Perms; -import aaf.v2_0.Pkey; -import aaf.v2_0.Request; -import aaf.v2_0.Role; -import aaf.v2_0.RoleKey; -import aaf.v2_0.RolePermRequest; -import aaf.v2_0.RoleRequest; -import aaf.v2_0.Roles; -import aaf.v2_0.UserRole; -import aaf.v2_0.UserRoleRequest; -import aaf.v2_0.UserRoles; -import aaf.v2_0.Users; -import aaf.v2_0.Users.User; - -import com.att.inno.env.APIException; -import com.att.inno.env.Data; -import com.att.inno.env.Data.TYPE; -import com.att.inno.env.util.Chrono; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -public class Examples { - public static String print(RosettaEnv env, String nameOrContentType, boolean optional) throws APIException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { - // Discover ClassName - String className = null; - String version = null; - TYPE type = TYPE.JSON; // default - if(nameOrContentType.startsWith("application/")) { - for(String ct : nameOrContentType.split("\\s*,\\s*")) { - for(String elem : ct.split("\\s*;\\s*")) { - if(elem.endsWith("+json")) { - type = TYPE.JSON; - className = elem.substring(elem.indexOf('/')+1, elem.length()-5); - } else if(elem.endsWith("+xml")) { - type = TYPE.XML; - className = elem.substring(elem.indexOf('/')+1, elem.length()-4); - } else if(elem.startsWith("version=")) { - version = elem.substring(8); - } - } - if(className!=null && version!=null)break; - } - if(className==null) { - throw new APIException(nameOrContentType + " does not contain Class Information"); - } - } else { - className = nameOrContentType; - } - - // No Void.class in aaf.v2_0 package causing errors when trying to use a newVoidv2_0 - // method similar to others in this class. This makes it work, but is it right? - if ("Void".equals(className)) return ""; - - if("1.1".equals(version)) { - version = "v1_0"; - } else if(version!=null) { - version = "v" + version.replace('.', '_'); - } else { - version = "v2_0"; - } - - Class cls; - try { - cls = Examples.class.getClassLoader().loadClass("aaf."+version+'.'+className); - } catch (ClassNotFoundException e) { - throw new APIException(e); - } - - Method meth; - try { - meth = Examples.class.getDeclaredMethod("new"+cls.getSimpleName()+version,boolean.class); - } catch (Exception e) { - throw new APIException("ERROR: " + cls.getName() + " does not have an Example in Code. Request from AAF Developers"); - } - - RosettaDF df = env.newDataFactory(cls); - df.option(Data.PRETTY); - - Object data = meth.invoke(null,optional); - - @SuppressWarnings("unchecked") - String rv = df.newData().load((C)data).out(type).asString(); -// Object obj = df.newData().in(type).load(rv).asObject(); - return rv; - } - - /* - * Set Base Class Request (easier than coding over and over) - */ - private static void setOptional(Request req) { - GregorianCalendar gc = new GregorianCalendar(); - req.setStart(Chrono.timeStamp(gc)); - gc.add(GregorianCalendar.MONTH, 6); - req.setEnd(Chrono.timeStamp(gc)); -// req.setForce("false"); - - } - - @SuppressWarnings("unused") - private static Request newRequestv2_0(boolean optional) { - Request r = new Request(); - setOptional(r); - return r; - } - @SuppressWarnings("unused") - private static RolePermRequest newRolePermRequestv2_0(boolean optional) { - RolePermRequest rpr = new RolePermRequest(); - Pkey pkey = new Pkey(); - pkey.setType("com.att.myns.mytype"); - pkey.setInstance("myInstance"); - pkey.setAction("myAction"); - rpr.setPerm(pkey); - rpr.setRole("com.att.myns.myrole"); - if(optional)setOptional(rpr); - return rpr; - } - - @SuppressWarnings("unused") - private static Roles newRolesv2_0(boolean optional) { - Role r; - Pkey p; - Roles rs = new Roles(); - rs.getRole().add(r = new Role()); - r.setName("com.att.myns.myRole"); - r.getPerms().add(p = new Pkey()); - p.setType("com.att.myns.myType"); - p.setInstance("myInstance"); - p.setAction("myAction"); - - r.getPerms().add(p = new Pkey()); - p.setType("com.att.myns.myType"); - p.setInstance("myInstance"); - p.setAction("myOtherAction"); - - rs.getRole().add(r = new Role()); - r.setName("com.att.myns.myOtherRole"); - r.getPerms().add(p = new Pkey()); - p.setType("com.att.myns.myOtherType"); - p.setInstance("myInstance"); - p.setAction("myAction"); - - r.getPerms().add(p = new Pkey()); - p.setType("com.att.myns.myOthertype"); - p.setInstance("myInstance"); - p.setAction("myOtherAction"); - - return rs; - } - - - @SuppressWarnings("unused") - private static PermRequest newPermRequestv2_0(boolean optional) { - PermRequest pr = new PermRequest(); - pr.setType("com.att.myns.myType"); - pr.setInstance("myInstance"); - pr.setAction("myAction"); - if(optional) { - pr.setDescription("Short and meaningful verbiage about the Permission"); - - setOptional(pr); - } - return pr; - } - - @SuppressWarnings("unused") - private static Perm newPermv2_0(boolean optional) { - Perm pr = new Perm(); - pr.setType("com.att.myns.myType"); - pr.setInstance("myInstance"); - pr.setAction("myAction"); - pr.getRoles().add("com.att.myns.myRole"); - pr.getRoles().add("com.att.myns.myRole2"); - pr.setDescription("This is my description, and I'm sticking with it"); - if(optional) { - pr.setDescription("Short and meaningful verbiage about the Permission"); - } - return pr; - } - - - @SuppressWarnings("unused") - private static PermKey newPermKeyv2_0(boolean optional) { - PermKey pr = new PermKey(); - pr.setType("com.att.myns.myType"); - pr.setInstance("myInstance"); - pr.setAction("myAction"); - return pr; - } - - @SuppressWarnings("unused") - private static Perms newPermsv2_0(boolean optional) { - Perms perms = new Perms(); - Perm p; - perms.getPerm().add(p=new Perm()); - p.setType("com.att.myns.myType"); - p.setInstance("myInstance"); - p.setAction("myAction"); - p.getRoles().add("com.att.myns.myRole"); - p.getRoles().add("com.att.myns.myRole2"); - - - perms.getPerm().add(p=new Perm()); - p.setType("com.att.myns.myOtherType"); - p.setInstance("myInstance"); - p.setAction("myOtherAction"); - p.getRoles().add("com.att.myns.myRole"); - p.getRoles().add("com.att.myns.myRole2"); - - return perms; - - } - - @SuppressWarnings("unused") - private static UserRoleRequest newUserRoleRequestv2_0(boolean optional) { - UserRoleRequest urr = new UserRoleRequest(); - urr.setRole("com.att.myns.myRole"); - urr.setUser("ab1234@csp.att.com"); - if(optional) setOptional(urr); - return urr; - } - - @SuppressWarnings("unused") - private static NsRequest newNsRequestv2_0(boolean optional) { - NsRequest nr = new NsRequest(); - nr.setName("com.att.myns"); - nr.getResponsible().add("ab1234@csp.att.com"); - nr.getResponsible().add("cd5678@csp.att.com"); - nr.getAdmin().add("zy9876@csp.att.com"); - nr.getAdmin().add("xw5432@csp.att.com"); - if(optional) { - nr.setDescription("This is my Namespace to set up"); - nr.setType("APP"); - setOptional(nr); - } - return nr; - } - - - @SuppressWarnings("unused") - private static Nss newNssv2_0(boolean optional) { - Ns ns; - - Nss nss = new Nss(); - nss.getNs().add(ns = new Nss.Ns()); - ns.setName("com.att.myns"); - ns.getResponsible().add("ab1234@csp.att.com"); - ns.getResponsible().add("cd5678@csp.att.com"); - ns.getAdmin().add("zy9876@csp.att.com"); - ns.getAdmin().add("xw5432@csp.att.com"); - ns.setDescription("This is my Namespace to set up"); - - nss.getNs().add(ns = new Nss.Ns()); - ns.setName("com.att.myOtherNs"); - ns.getResponsible().add("ab1234@csp.att.com"); - ns.getResponsible().add("cd5678@csp.att.com"); - ns.getAdmin().add("zy9876@csp.att.com"); - ns.getAdmin().add("xw5432@csp.att.com"); - - return nss; - } - @SuppressWarnings("unused") - private static RoleRequest newRoleRequestv2_0(boolean optional) { - RoleRequest rr = new RoleRequest(); - rr.setName("com.att.myns.myRole"); - if(optional) { - rr.setDescription("This is my Role"); - setOptional(rr); - } - return rr; - } - - @SuppressWarnings("unused") - private static CredRequest newCredRequestv2_0(boolean optional) { - CredRequest cr = new CredRequest(); - cr.setId("myID@fully.qualified.domain"); - if(optional) { - cr.setType(2); - cr.setEntry("0x125AB256344CE"); - } else { - cr.setPassword("This is my provisioned password"); - } - - return cr; - } - - @SuppressWarnings("unused") - private static Users newUsersv2_0(boolean optional) { - User user; - - Users users = new Users(); - users.getUser().add(user = new Users.User()); - user.setId("ab1234@csp.att.com"); - GregorianCalendar gc = new GregorianCalendar(); - user.setExpires(Chrono.timeStamp(gc)); - - users.getUser().add(user = new Users.User()); - user.setId("zy9876@csp.att.com"); - user.setExpires(Chrono.timeStamp(gc)); - - return users; - } - - @SuppressWarnings("unused") - private static Role newRolev2_0(boolean optional) { - Role r = new Role(); - Pkey p; - r.setName("com.att.myns.myRole"); - r.getPerms().add(p = new Pkey()); - p.setType("com.att.myns.myType"); - p.setInstance("myInstance"); - p.setAction("myAction"); - - return r; - } - - @SuppressWarnings("unused") - private static RoleKey newRoleKeyv2_0(boolean optional) { - RoleKey r = new RoleKey(); - Pkey p; - r.setName("com.att.myns.myRole"); - return r; - } - - @SuppressWarnings("unused") - private static Keys newKeysv2_0(boolean optional) { - Keys ks = new Keys(); - ks.getKey().add("Reponse 1"); - ks.getKey().add("Response 2"); - return ks; - } - - @SuppressWarnings("unused") - private static UserRoles newUserRolesv2_0(boolean optional) { - UserRoles urs = new UserRoles(); - UserRole ur = new UserRole(); - ur.setUser("xy1234"); - ur.setRole("com.test.myapp.myRole"); - ur.setExpires(Chrono.timeStamp()); - urs.getUserRole().add(ur); - - ur = new UserRole(); - ur.setUser("yx4321"); - ur.setRole("com.test.yourapp.yourRole"); - ur.setExpires(Chrono.timeStamp()); - urs.getUserRole().add(ur); - return urs; - } - - - @SuppressWarnings("unused") - private static Approvals newApprovalsv2_0(boolean optional) { - Approvals as = new Approvals(); - Approval a = new Approval(); - a.setApprover("MyApprover"); - a.setId("MyID"); - a.setMemo("My memo (and then some)"); - a.setOperation("MyOperation"); - a.setStatus("MyStatus"); - a.setTicket("MyTicket"); - a.setType("MyType"); - a.setUpdated(Chrono.timeStamp()); - a.setUser("MyUser"); - as.getApprovals().add(a); - a = new Approval(); - a.setApprover("MyApprover2"); - a.setId("MyID2"); - a.setMemo("My memo (and then some)2"); - a.setOperation("MyOperation2"); - a.setStatus("MyStatus2"); - a.setTicket("MyTicket2"); - a.setType("MyType2"); - a.setUpdated(Chrono.timeStamp()); - a.setUser("MyUser2"); - as.getApprovals().add(a); - return as; - } - - @SuppressWarnings("unused") - private static Approval newApprovalv2_0(boolean optional) { - Approval a = new Approval(); - a.setApprover("MyApprover"); - a.setId("MyID"); - a.setMemo("My memo (and then some)"); - a.setOperation("MyOperation"); - a.setStatus("MyStatus"); - a.setTicket("MyTicket"); - a.setType("MyType"); - a.setUpdated(Chrono.timeStamp()); - a.setUser("MyUser"); - return a; - } - - - - @SuppressWarnings("unused") - private static aaf.v2_0.Error newErrorv2_0(boolean optional) { - aaf.v2_0.Error err = new aaf.v2_0.Error(); - err.setMessageId("SVC1403"); - err.setText("MyText %s, %s: The last three digits are usually the HTTP Code"); - err.getVariables().add("Variable 1"); - err.getVariables().add("Variable 2"); - return err; - } - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/marshal/CertMarshal.java b/aaf/src/main/java/com/att/cadi/aaf/marshal/CertMarshal.java deleted file mode 100644 index ad75dc5..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/marshal/CertMarshal.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.marshal; - -import javax.xml.datatype.XMLGregorianCalendar; - -import aaf.v2_0.Certs.Cert; - -import com.att.rosetta.marshal.FieldDateTime; -import com.att.rosetta.marshal.FieldHexBinary; -import com.att.rosetta.marshal.FieldString; -import com.att.rosetta.marshal.ObjMarshal; - -public class CertMarshal extends ObjMarshal { - public CertMarshal() { - add(new FieldHexBinary("fingerprint") { - @Override - protected byte[] data(Cert t) { - return t.getFingerprint(); - } - }); - - add(new FieldString("id") { - @Override - protected String data(Cert t) { - return t.getId(); - } - }); - - add(new FieldString("x500") { - @Override - protected String data(Cert t) { - return t.getX500(); - } - }); - - add(new FieldDateTime("expires") { - @Override - protected XMLGregorianCalendar data(Cert t) { - return t.getExpires(); - } - }); - - - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/marshal/CertsMarshal.java b/aaf/src/main/java/com/att/cadi/aaf/marshal/CertsMarshal.java deleted file mode 100644 index 3a27a9c..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/marshal/CertsMarshal.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.marshal; - -import java.util.List; - -import aaf.v2_0.Certs; -import aaf.v2_0.Certs.Cert; - -import com.att.rosetta.marshal.ObjArray; -import com.att.rosetta.marshal.ObjMarshal; - -public class CertsMarshal extends ObjMarshal { - - public CertsMarshal() { - add(new ObjArray("cert",new CertMarshal()) { - @Override - protected List data(Certs t) { - return t.getCert(); - } - }); - } - - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java deleted file mode 100644 index 33005a3..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.io.IOException; - -import com.att.aft.dme2.api.DME2Exception; -import com.att.cadi.AbsUserCache; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CadiException; -import com.att.cadi.GetCred; -import com.att.cadi.Hash; -import com.att.cadi.User; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.cadi.config.Config; -import com.att.cadi.lur.ConfigPrincipal; -import com.att.inno.env.APIException; - -public class AAFAuthn extends AbsUserCache { - private AAFCon con; - private String realm; - - /** - * Configure with Standard AAF properties, Stand alone - * @param con - * @throws Exception - */ - // Package on purpose - AAFAuthn(AAFCon con) throws Exception { - super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount); - this.con = con; - - try { - setRealm(); - } catch (APIException e) { - if(e.getCause() instanceof DME2Exception) { - // Can't contact AAF, assume default - realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); - } - } - } - - /** - * Configure with Standard AAF properties, but share the Cache (with AAF Lur) - * @param con - * @throws Exception - */ - // Package on purpose - AAFAuthn(AAFCon con, AbsUserCache cache) throws Exception { - super(cache); - this.con = con; - try { - setRealm(); - } catch (Exception e) { - if(e.getCause() instanceof DME2Exception) { - access.log(e); - // Can't contact AAF, assume default - realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); - } - } - } - - private void setRealm() throws Exception { - // Make a call without security set to get the 401 response, which - // includes the Realm of the server - // This also checks on Connectivity early on. - Future fp = con.client(AAFCon.AAF_LATEST_VERSION).read("/authn/basicAuth", "text/plain"); - if(fp.get(con.timeout)) { - throw new Exception("Do not preset Basic Auth Information for AAFAuthn"); - } else { - if(fp.code()==401) { - realm = fp.header("WWW-Authenticate"); - if(realm!=null && realm.startsWith("Basic realm=\"")) { - realm = realm.substring(13, realm.length()-1); - } else { - realm = "unknown.com"; - } - } - } - } - - /** - * Return Native Realm of AAF Instance. - * - * @return - */ - public String getRealm() { - return realm; - } - - /** - * Returns null if ok, or an Error String; - * - * @param user - * @param password - * @return - * @throws IOException - * @throws CadiException - * @throws Exception - */ - public String validate(String user, String password) throws IOException, CadiException { - User usr = getUser(user); - if(password.startsWith("enc:???")) { - password = access.decrypt(password, true); - } - - byte[] bytes = password.getBytes(); - if(usr != null && usr.principal != null && usr.principal.getName().equals(user) - && usr.principal instanceof GetCred) { - - if(Hash.isEqual(((GetCred)usr.principal).getCred(),bytes)) { - return null; - } else { - remove(usr); - usr = null; - } - } - - AAFCachedPrincipal cp = new AAFCachedPrincipal(this,con.app, user, bytes, con.cleanInterval); - // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch - // Statement - switch(cp.revalidate()) { - case REVALIDATED: - if(usr!=null) { - usr.principal = cp; - } else { - addUser(new User(cp,con.timeout)); - } - return null; - case INACCESSIBLE: - return "AAF Inaccessible"; - case UNVALIDATED: - return "User/Pass combo invalid for " + user; - case DENIED: - return "AAF denies API for " + user; - default: - return "AAFAuthn doesn't handle Principal " + user; - } - } - - private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal { - private long expires,timeToLive; - - public AAFCachedPrincipal(AAFAuthn aaf, String app, String name, byte[] pass, int timeToLive) { - super(name,pass); - this.timeToLive = timeToLive; - expires = timeToLive + System.currentTimeMillis(); - } - - public Resp revalidate() { - if(con.isDisabled()) { - return Resp.DENIED; - } - try { - Miss missed = missed(getName()); - if(missed==null || missed.mayContinue(getCred())) { - Rcli client = con.client(AAFCon.AAF_LATEST_VERSION).forUser(con.basicAuth(getName(), new String(getCred()))); - Future fp = client.read( - "/authn/basicAuth", - "text/plain" - ); - if(fp.get(con.timeout)) { - expires = System.currentTimeMillis() + timeToLive; - addUser(new User(this, expires)); - return Resp.REVALIDATED; - } else { - addMiss(getName(), getCred()); - return Resp.UNVALIDATED; - } - } else { - return Resp.UNVALIDATED; - } - } catch (Exception e) { - con.access.log(e); - return Resp.INACCESSIBLE; - } - } - - public long expires() { - return expires; - } - }; - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java deleted file mode 100644 index a9d53f3..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java +++ /dev/null @@ -1,395 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.net.URI; -import java.security.Principal; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; - -import com.att.cadi.AbsUserCache; -import com.att.cadi.CadiException; -import com.att.cadi.CadiWrap; -import com.att.cadi.Connector; -import com.att.cadi.LocatorException; -import com.att.cadi.Lur; -import com.att.cadi.PropAccess; -import com.att.cadi.SecuritySetter; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.marshal.CertsMarshal; -import com.att.cadi.client.AbsBasicAuth; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.lur.EpiLur; -import com.att.cadi.principal.BasicPrincipal; -import com.att.cadi.util.Vars; -import com.att.inno.env.APIException; -import com.att.inno.env.Data.TYPE; -import com.att.inno.env.util.Split; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -import aaf.v2_0.Certs; -import aaf.v2_0.Error; -import aaf.v2_0.Perms; -import aaf.v2_0.Users; - -public abstract class AAFCon implements Connector { - public static final String AAF_LATEST_VERSION = "2.0"; - - final public PropAccess access; - // Package access - final public int timeout, cleanInterval, connTimeout; - final public int highCount, userExpires, usageRefreshTriggerCount; - private Map> clients = new ConcurrentHashMap>(); - final public RosettaDF permsDF; - final public RosettaDF certsDF; - final public RosettaDF usersDF; - final public RosettaDF errDF; - private String realm; - public final String app; - protected SecuritySetter ss; - protected SecurityInfoC si; - - private DisableCheck disableCheck; - - private AAFLurPerm lur; - - private RosettaEnv env; - protected abstract URI initURI(); - protected abstract void setInitURI(String uriString) throws CadiException; - - /** - * Use this call to get the appropriate client based on configuration (DME2, HTTP, future) - * - * @param apiVersion - * @return - * @throws CadiException - */ - public Rcli client(String apiVersion) throws CadiException { - Rcli client = clients.get(apiVersion); - if(client==null) { - client = rclient(initURI(),ss); - client.apiVersion(apiVersion) - .readTimeout(connTimeout); - clients.put(apiVersion, client); - } - return client; - } - - /** - * Use this API when you have permission to have your call act as the end client's ID. - * - * Your calls will get 403 errors if you do not have this permission. it is a special setup, rarely given. - * - * @param apiVersion - * @param req - * @return - * @throws CadiException - */ - public Rcli clientAs(String apiVersion, ServletRequest req) throws CadiException { - Rcli cl = client(apiVersion); - return cl.forUser(transferSS(((HttpServletRequest)req).getUserPrincipal())); - } - - protected AAFCon(AAFCon copy) { - access = copy.access; - timeout = copy.timeout; - cleanInterval = copy.cleanInterval; - connTimeout = copy.connTimeout; - highCount = copy.highCount; - userExpires = copy.userExpires; - usageRefreshTriggerCount = copy.usageRefreshTriggerCount; - permsDF = copy.permsDF; - certsDF = copy.certsDF; - usersDF = copy.usersDF; - errDF = copy.errDF; - app = copy.app; - ss = copy.ss; - si = copy.si; - env = copy.env; - disableCheck = copy.disableCheck; - realm = copy.realm; - } - - protected AAFCon(PropAccess access, String tag, SecurityInfoC si) throws CadiException{ - if(tag==null) { - throw new CadiException("AAFCon cannot be constructed with a tag=null"); - } - try { - this.access = access; - this.si = si; - this.ss = si.defSS; - if(ss==null) { - String mechid = access.getProperty(Config.AAF_MECHID, null); - String encpass = access.getProperty(Config.AAF_MECHPASS, null); - if(encpass==null) { - String alias = access.getProperty(Config.CADI_ALIAS, mechid); - if(alias==null) { - throw new CadiException(Config.CADI_ALIAS + " or " + Config.AAF_MECHID + " required."); - } - set(si.defSS=x509Alias(alias)); - } else { - if(mechid!=null && encpass !=null) { - set(si.defSS=basicAuth(mechid, encpass)); - } else { - set(si.defSS=new SecuritySetter() { - - @Override - public String getID() { - return ""; - } - - @Override - public void setSecurity(CLIENT client) throws CadiException { - throw new CadiException("AAFCon has not been initialized with Credentials (SecuritySetter)"); - } - - @Override - public int setLastResponse(int respCode) { - return 0; - } - }); - } - } - } - - timeout = Integer.parseInt(access.getProperty(Config.AAF_READ_TIMEOUT, Config.AAF_READ_TIMEOUT_DEF)); - cleanInterval = Integer.parseInt(access.getProperty(Config.AAF_CLEAN_INTERVAL, Config.AAF_CLEAN_INTERVAL_DEF)); - highCount = Integer.parseInt(access.getProperty(Config.AAF_HIGH_COUNT, Config.AAF_HIGH_COUNT_DEF).trim()); - connTimeout = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF).trim()); - userExpires = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim()); - usageRefreshTriggerCount = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim())-1; // zero based - - String str = access.getProperty(tag,null); - if(str==null) { - throw new CadiException(tag + " property is required."); - } - setInitURI(str); - - app=reverseDomain(ss.getID()); - realm="openecomp.org"; - - env = new RosettaEnv(); - permsDF = env.newDataFactory(Perms.class); - usersDF = env.newDataFactory(Users.class); - certsDF = env.newDataFactory(Certs.class); - certsDF.rootMarshal(new CertsMarshal()); // Speedier Marshaling - errDF = env.newDataFactory(Error.class); - } catch (APIException e) { - throw new CadiException("AAFCon cannot be configured",e); - } - } - - public RosettaEnv env() { - return env; - } - - /** - * Return the backing AAFCon, if there is a Lur Setup that is AAF. - * - * If there is no AAFLur setup, it will return "null" - * @param servletRequest - * @return - */ - public static final AAFCon obtain(Object servletRequest) { - if(servletRequest instanceof CadiWrap) { - Lur lur = ((CadiWrap)servletRequest).getLur(); - if(lur != null) { - if(lur instanceof EpiLur) { - AbsAAFLur aal = (AbsAAFLur) ((EpiLur)lur).subLur(AbsAAFLur.class); - if(aal!=null) { - return aal.aaf; - } - } else { - if(lur instanceof AbsAAFLur) { - return ((AbsAAFLur)lur).aaf; - } - } - } - } - return null; - } - - public abstract AAFCon clone(String url) throws CadiException; - - public AAFAuthn newAuthn() throws APIException { - try { - return new AAFAuthn(this); - } catch (APIException e) { - throw e; - } catch (Exception e) { - throw new APIException(e); - } - } - - public AAFAuthn newAuthn(AbsUserCache c) throws APIException { - try { - return new AAFAuthn(this,c); - } catch (APIException e) { - throw e; - } catch (Exception e) { - throw new APIException(e); - } - } - - public AAFLurPerm newLur() throws CadiException { - try { - if(lur==null) { - return new AAFLurPerm(this); - } else { - return new AAFLurPerm(this,lur); - } - } catch (CadiException e) { - throw e; - } catch (Exception e) { - throw new CadiException(e); - } - } - - public AAFLurPerm newLur(AbsUserCache c) throws APIException { - try { - return new AAFLurPerm(this,c); - } catch (APIException e) { - throw e; - } catch (Exception e) { - throw new APIException(e); - } - } - - /** - * Take a Fully Qualified User, and get a Namespace from it. - * @param user - * @return - */ - public static String reverseDomain(String user) { - StringBuilder sb = null; - String[] split = Split.split('.',user); - 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(); - } - - protected abstract Rcli rclient(URI uri, SecuritySetter ss) throws CadiException; - - public abstract RET best(Retryable retryable) throws LocatorException, CadiException, APIException; - - - public abstract SecuritySetter basicAuth(String user, String password) throws CadiException; - - public abstract SecuritySetter transferSS(Principal principal) throws CadiException; - - public abstract SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException; - - public abstract SecuritySetter x509Alias(String alias) throws APIException, CadiException; - - - public String getRealm() { - return realm; - - } - - public SecuritySetter set(final SecuritySetter ss) { - this.ss = ss; - if(ss instanceof AbsBasicAuth) { - disableCheck = (ss instanceof AbsBasicAuth)? - new DisableCheck() { - AbsBasicAuth aba = (AbsBasicAuth)ss; - @Override - public boolean isDisabled() { - return aba.isDenied(); - } - }: - new DisableCheck() { - @Override - public boolean isDisabled() { - return this.isDisabled(); - } - }; - } - for(Rcli client : clients.values()) { - client.setSecuritySetter(ss); - } - return ss; - } - - public SecurityInfoC securityInfo() { - return si; - } - - public String defID() { - if(ss!=null) { - return ss.getID(); - } - return "unknown"; - } - - public void invalidate() throws CadiException { - for(Rcli client : clients.values()) { - client.invalidate(); - clients.remove(client); - } - } - - public String readableErrMsg(Future f) { - String text = f.body(); - if(text==null || text.length()==0) { - text = f.code() + ": **No Message**"; - } else if(text.contains("%")) { - try { - Error err = errDF.newData().in(TYPE.JSON).load(f.body()).asObject(); - return Vars.convert(err.getText(),err.getVariables()); - } catch (APIException e){ - // just return the body below - } - } - return text; - } - - private interface DisableCheck { - public boolean isDisabled(); - }; - - public boolean isDisabled() { - return disableCheck.isDisabled(); - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java deleted file mode 100644 index 6fce97a..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.io.IOException; -import java.net.ConnectException; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.GeneralSecurityException; -import java.security.Principal; -import java.util.Properties; - -import com.att.aft.dme2.api.DME2Client; -import com.att.aft.dme2.api.DME2Exception; -import com.att.aft.dme2.api.DME2Manager; -import com.att.cadi.CadiException; -import com.att.cadi.LocatorException; -import com.att.cadi.PropAccess; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.dme2.DME2BasicAuth; -import com.att.cadi.dme2.DME2TransferSS; -import com.att.cadi.dme2.DME2x509SS; -import com.att.cadi.dme2.DRcli; -import com.att.cadi.principal.BasicPrincipal; -import com.att.inno.env.APIException; - -public class AAFConDME2 extends AAFCon{ - private DME2Manager manager; - private boolean isProxy; - private URI initURI; - - public AAFConDME2(PropAccess access) throws CadiException, GeneralSecurityException, IOException{ - super(access,Config.AAF_URL,new SecurityInfoC (access)); - manager = newManager(access); - setIsProxy(); - } - - public AAFConDME2(PropAccess access, String url) throws CadiException, GeneralSecurityException, IOException{ - super(access,url,new SecurityInfoC (access)); - manager = newManager(access); - setIsProxy(); - } - - public AAFConDME2(PropAccess access, SecurityInfoC si) throws CadiException { - super(access,Config.AAF_URL,si); - manager = newManager(access); - setIsProxy(); - } - - public AAFConDME2(PropAccess access, String url, SecurityInfoC si) throws CadiException { - super(access,url,si); - manager = newManager(access); - setIsProxy(); - } - - /** - * Construct a Connector based on the AAF one. This is for remote access to OTHER than AAF, - * but using Credentials, etc - */ - private AAFConDME2(AAFCon aafcon, String url) throws CadiException { - super(aafcon); - try { - initURI = new URI(url); - } catch (URISyntaxException e) { - throw new CadiException(e); - } - manager = newManager(access); - } - - /** - * Create a Connector based on the AAF one. This is for remote access to OTHER than AAF, - * but using Credentials, etc - */ - public AAFCon clone(String url) throws CadiException { - return new AAFConDME2(this,url); - } - - private void setIsProxy() { - String str; - if((str=access.getProperty(Config.AAF_URL, null))!=null) { - isProxy = str.contains("service=com.att.authz.authz-gw/version="); - } - } - - private DME2Manager newManager(PropAccess access) throws CadiException { - Properties props = access.getDME2Properties(); - // Critical that TLS Settings not ignored - try { - return new DME2Manager("AAFCon",props); - } catch (DME2Exception e) { - throw new CadiException(e); - } - } - - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String) - */ - @Override - public SecuritySetter basicAuth(String user, String password) throws CadiException { - if(password.startsWith("enc:???")) { - try { - password = access.decrypt(password, true); - } catch (IOException e) { - throw new CadiException("Error Decrypting Password",e); - } - } - - try { - return set(new DME2BasicAuth(user,password,si)); - } catch (IOException e) { - throw new CadiException("Error setting up DME2BasicAuth",e); - } - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter) - */ - @Override - protected Rcli rclient(URI uri, SecuritySetter ss) { - DRcli dc = new DRcli(uri, ss); - dc.setProxy(isProxy); - dc.setManager(manager); - return dc; - } - - @Override - public SecuritySetter transferSS(Principal principal) throws CadiException { - try { - return principal==null?ss:new DME2TransferSS(principal, app, si); - } catch (IOException e) { - throw new CadiException("Error creating DME2TransferSS",e); - } - } - - @Override - public SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException { - try { - return new DME2BasicAuth(principal,si); - } catch (IOException e) { - throw new CadiException("Error creating DME2BasicAuth",e); - } - - } - - @Override - public SecuritySetter x509Alias(String alias) throws CadiException { - try { - presetProps(access, alias); - return new DME2x509SS(alias,si); - } catch (Exception e) { - throw new CadiException("Error creating DME2x509SS",e); - } - } - - @Override - public RET best(Retryable retryable) throws LocatorException, CadiException, APIException { - // NOTE: DME2 had Retry Logic embedded lower. - try { - return (retryable.code(rclient(initURI,ss))); - } catch (ConnectException e) { - // DME2 should catch - try { - manager.refresh(); - } catch (Exception e1) { - throw new CadiException(e1); - } - throw new CadiException(e); - } - } - - public static void presetProps(PropAccess access, String alias) throws IOException { - System.setProperty(Config.AFT_DME2_CLIENT_SSL_CERT_ALIAS, alias); - if(System.getProperty(Config.AFT_DME2_CLIENT_IGNORE_SSL_CONFIG)==null) { - access.getDME2Properties(); - } - - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#initURI() - */ - @Override - protected URI initURI() { - return initURI; - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#setInitURI(java.lang.String) - */ - @Override - protected void setInitURI(String uriString) throws CadiException { - try { - initURI = new URI(uriString); - } catch (URISyntaxException e) { - throw new CadiException(e); - } - } -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java deleted file mode 100644 index e126f08..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.security.GeneralSecurityException; -import java.security.Principal; - -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.cadi.Locator.Item; -import com.att.cadi.LocatorException; -import com.att.cadi.PropAccess; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.AbsTransferSS; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.http.HBasicAuthSS; -import com.att.cadi.http.HMangr; -import com.att.cadi.http.HRcli; -import com.att.cadi.http.HTransferSS; -import com.att.cadi.http.HX509SS; -import com.att.cadi.principal.BasicPrincipal; -import com.att.inno.env.APIException; - -public class AAFConHttp extends AAFCon { - private final HMangr hman; - - public AAFConHttp(PropAccess access) throws CadiException, GeneralSecurityException, IOException { - super(access,Config.AAF_URL,new SecurityInfoC(access)); - hman = new HMangr(access,Config.loadLocator(access, access.getProperty(Config.AAF_URL,null))); - } - - public AAFConHttp(PropAccess access, String tag) throws CadiException, GeneralSecurityException, IOException { - super(access,tag,new SecurityInfoC(access)); - hman = new HMangr(access,Config.loadLocator(access, access.getProperty(tag,null))); - } - - public AAFConHttp(PropAccess access, String urlTag, SecurityInfoC si) throws CadiException { - super(access,urlTag,si); - hman = new HMangr(access,Config.loadLocator(access, access.getProperty(urlTag,null))); - } - - public AAFConHttp(PropAccess access, Locator locator) throws CadiException, GeneralSecurityException, IOException { - super(access,Config.AAF_URL,new SecurityInfoC(access)); - hman = new HMangr(access,locator); - } - - public AAFConHttp(PropAccess access, Locator locator, SecurityInfoC si) throws CadiException { - super(access,Config.AAF_URL,si); - hman = new HMangr(access,locator); - } - - public AAFConHttp(PropAccess access, Locator locator, SecurityInfoC si, String tag) throws CadiException { - super(access,tag,si); - hman = new HMangr(access, locator); - } - - private AAFConHttp(AAFCon aafcon, String url) { - super(aafcon); - hman = new HMangr(aafcon.access,Config.loadLocator(access, url)); - } - - @Override - public AAFCon clone(String url) { - return new AAFConHttp(this,url); - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String) - */ - @Override - public SecuritySetter basicAuth(String user, String password) throws CadiException { - if(password.startsWith("enc:???")) { - try { - password = access.decrypt(password, true); - } catch (IOException e) { - throw new CadiException("Error decrypting password",e); - } - } - try { - return new HBasicAuthSS(user,password,si); - } catch (IOException e) { - throw new CadiException("Error creating HBasicAuthSS",e); - } - } - - public SecuritySetter x509Alias(String alias) throws APIException, CadiException { - try { - return set(new HX509SS(alias,si)); - } catch (Exception e) { - throw new CadiException("Error creating X509SS",e); - } - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter) - */ - @Override - protected Rcli rclient(URI ignoredURI, SecuritySetter ss) throws CadiException { - if(hman.loc==null) { - throw new CadiException("No Locator set in AAFConHttp"); - } - try { - return new HRcli(hman, hman.loc.best() ,ss); - } catch (Exception e) { - throw new CadiException(e); - } - } - - @Override - public AbsTransferSS transferSS(Principal principal) throws CadiException { - return new HTransferSS(principal, app,si); - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuthSS(java.security.Principal) - */ - @Override - public SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException { - try { - return new HBasicAuthSS(principal,si); - } catch (IOException e) { - throw new CadiException("Error creating HBasicAuthSS",e); - } - } - - public HMangr hman() { - return hman; - } - - @Override - public RET best(Retryable retryable) throws LocatorException, CadiException, APIException { - return hman.best(ss, (Retryable)retryable); - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#initURI() - */ - @Override - protected URI initURI() { - try { - Item item = hman.loc.best(); - if(item!=null) { - return hman.loc.get(item); - } - } catch (LocatorException e) { - access.log(e, "Error in AAFConHttp obtaining initial URI"); - } - return null; - } - - /* (non-Javadoc) - * @see com.att.cadi.aaf.v2_0.AAFCon#setInitURI(java.lang.String) - */ - @Override - protected void setInitURI(String uriString) throws CadiException { - // TODO Auto-generated method stub - - } - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java deleted file mode 100644 index 7188224..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java +++ /dev/null @@ -1,220 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.net.ConnectException; -import java.net.URISyntaxException; -import java.security.Principal; -import java.util.Map; - -import com.att.aft.dme2.api.DME2Exception; -import com.att.cadi.AbsUserCache; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.CadiException; -import com.att.cadi.Permission; -import com.att.cadi.User; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.cadi.lur.LocalPermission; -import com.att.inno.env.APIException; -import com.att.inno.env.util.Split; - -import aaf.v2_0.Perm; -import aaf.v2_0.Perms; - -/** - * Use AAF Service as Permission Service. - * - * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves. - * - * If you want a simple Role Lur, use AAFRoleLur - * - * - */ -public class AAFLurPerm extends AbsAAFLur { - /** - * Need to be able to transmutate a Principal into either ATTUID or MechID, which are the only ones accepted at this - * point by AAF. There is no "domain", aka, no "@att.com" in "ab1234@att.com". - * - * The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid. - * Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely - * @throws APIException - * @throws URISyntaxException - * @throws DME2Exception - */ - // Package on purpose - AAFLurPerm(AAFCon con) throws CadiException, DME2Exception, URISyntaxException, APIException { - super(con); - } - - // Package on purpose - AAFLurPerm(AAFCon con, AbsUserCache auc) throws DME2Exception, URISyntaxException, APIException { - super(con,auc); - } - - protected User loadUser(Principal p) { - // Note: The rules for AAF is that it only stores permissions for ATTUID and MechIDs, which don't - // have domains. We are going to make the Transitive Class (see this.transmutative) to convert - Principal principal = transmutate.mutate(p); - if(principal==null)return null; // if not a valid Transmutated credential, don't bother calling... - return loadUser(p, p.getName()); - } - - protected User loadUser(String name) { - return loadUser((Principal)null, name); - } - - private User loadUser(final Principal prin, final String name) { - - //TODO Create a dynamic way to declare domains supported. - final long start = System.nanoTime(); - final boolean[] success = new boolean[]{false}; - -// new Exception("loadUser").printStackTrace(); - try { - return aaf.best(new Retryable>() { - @Override - public User code(Rcli client) throws CadiException, ConnectException, APIException { - Future fp = client.read("/authz/perms/user/"+name,aaf.permsDF); - - // In the meantime, lookup User, create if necessary - User user = getUser(name); - Principal p; - if(prin == null) { - p = new Principal() {// Create a holder for lookups - private String n = name; - public String getName() { - return n; - } - }; - } else { - p = prin; - } - - if(user==null) { - addUser(user = new User(p,aaf.userExpires)); // no password - } - - // OK, done all we can, now get content - if(fp.get(aaf.timeout)) { - success[0]=true; - Map newMap = user.newMap(); - boolean willLog = aaf.access.willLog(Level.DEBUG); - for(Perm perm : fp.value.getPerm()) { - user.add(newMap,new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction())); - if(willLog) { - aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\''); - } - } - user.setMap(newMap); - user.renewPerm(); - } else { - int code; - switch(code=fp.code()) { - case 401: - aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls"); - break; - default: - aaf.access.log(Access.Level.ERROR, code, fp.body()); - } - } - - return user; - } - }); - } catch (Exception e) { - aaf.access.log(e,"Calling","/authz/perms/user/"+name); - success[0]=false; - return null; - } finally { - float time = (System.nanoTime()-start)/1000000f; - aaf.access.log(Level.INFO, success[0]?"Loaded":"Load Failure",name,"from AAF in",time,"ms"); - } - } - - public Resp reload(User user) { - final String name = user.principal.getName(); - long start = System.nanoTime(); - boolean success = false; - try { - Future fp = aaf.client(AAFCon.AAF_LATEST_VERSION).read( - "/authz/perms/user/"+name, - aaf.permsDF - ); - - // OK, done all we can, now get content - if(fp.get(aaf.timeout)) { - success = true; - Map newMap = user.newMap(); - boolean willLog = aaf.access.willLog(Level.DEBUG); - for(Perm perm : fp.value.getPerm()) { - user.add(newMap, new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction())); - if(willLog) { - aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction()); - } - } - user.renewPerm(); - return Resp.REVALIDATED; - } else { - int code; - switch(code=fp.code()) { - case 401: - aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls"); - break; - default: - aaf.access.log(Access.Level.ERROR, code, fp.body()); - } - return Resp.UNVALIDATED; - } - } catch (Exception e) { - aaf.access.log(e,"Calling","/authz/perms/user/"+name); - return Resp.INACCESSIBLE; - } finally { - float time = (System.nanoTime()-start)/1000000f; - aaf.access.log(Level.AUDIT, success?"Reloaded":"Reload Failure",name,"from AAF in",time,"ms"); - } - } - - @Override - protected boolean isCorrectPermType(Permission pond) { - return pond instanceof AAFPermission; - } - - /* (non-Javadoc) - * @see com.att.cadi.Lur#createPerm(java.lang.String) - */ - @Override - public Permission createPerm(String p) { - String[] params = Split.split('|', p); - if(params.length==3) { - return new AAFPermission(params[0],params[1],params[2]); - } else { - return new LocalPermission(p); - } - } - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java deleted file mode 100644 index 4e189ce..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.AbsUserCache; -import com.att.cadi.Access.Level; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.GetCred; -import com.att.cadi.Hash; -import com.att.cadi.Taf.LifeForm; -import com.att.cadi.User; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.cadi.principal.BasicPrincipal; -import com.att.cadi.principal.CachedBasicPrincipal; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TafResp.RESP; -import com.att.cadi.taf.basic.BasicHttpTafResp; - -public class AAFTaf extends AbsUserCache implements HttpTaf { -// private static final String INVALID_AUTH_TOKEN = "Invalid Auth Token"; -// private static final String AUTHENTICATING_SERVICE_UNAVAILABLE = "Authenticating Service unavailable"; - private AAFCon aaf; - private boolean warn; - - public AAFTaf(AAFCon con, boolean turnOnWarning) { - super(con.access,con.cleanInterval,con.highCount, con.usageRefreshTriggerCount); - aaf = con; - warn = turnOnWarning; - } - - public AAFTaf(AAFCon con, boolean turnOnWarning, AbsUserCache other) { - super(other); - aaf = con; - warn = turnOnWarning; - } - - public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { - //TODO Do we allow just anybody to validate? - - // Note: Either Carbon or Silicon based LifeForms ok - String authz = req.getHeader("Authorization"); - if(authz != null && authz.startsWith("Basic ")) { - if(warn&&!req.isSecure())aaf.access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); - try { - CachedBasicPrincipal bp; - if(req.getUserPrincipal() instanceof CachedBasicPrincipal) { - bp = (CachedBasicPrincipal)req.getUserPrincipal(); - } else { - bp = new CachedBasicPrincipal(this,authz,aaf.getRealm(),aaf.userExpires); - } - // First try Cache - User usr = getUser(bp); - if(usr != null && usr.principal != null) { - if(usr.principal instanceof GetCred) { - if(Hash.isEqual(bp.getCred(),((GetCred)usr.principal).getCred())) { - return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by cached AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false); - } - } - } - - Miss miss = missed(bp.getName()); - if(miss!=null && !miss.mayContinue(bp.getCred())) { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, - "User/Pass Retry limit exceeded"), - RESP.FAIL,resp,aaf.getRealm(),true); - } - - Rcli userAAF = aaf.client(AAFCon.AAF_LATEST_VERSION).forUser(aaf.basicAuthSS(bp)); - Future fp = userAAF.read("/authn/basicAuth", "text/plain"); - if(fp.get(aaf.timeout)) { - if(usr!=null) { - usr.principal = bp; - } else { - addUser(new User(bp,aaf.userExpires)); - } - return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false); - } else { - // Note: AddMiss checks for miss==null, and is part of logic - boolean rv= addMiss(bp.getName(),bp.getCred()); - if(rv) { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, - "User/Pass combo invalid via AAF"), - RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true); - } else { - return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, - "User/Pass combo invalid via AAF - Retry limit exceeded"), - RESP.FAIL,resp,aaf.getRealm(),true); - } - } - } catch (IOException e) { - String msg = buildMsg(null,req,"Invalid Auth Token"); - aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); - return new BasicHttpTafResp(aaf.access,null,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true); - } catch (Exception e) { - String msg = buildMsg(null,req,"Authenticating Service unavailable"); - aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); - return new BasicHttpTafResp(aaf.access,null,msg, RESP.FAIL, resp, aaf.getRealm(),false); - } - } - return new BasicHttpTafResp(aaf.access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false); - } - - private String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) { - StringBuilder sb = new StringBuilder(); - for(Object s : msg) { - sb.append(s.toString()); - } - if(pr!=null) { - sb.append(" for "); - sb.append(pr.getName()); - } - sb.append(" from "); - sb.append(req.getRemoteAddr()); - sb.append(':'); - sb.append(req.getRemotePort()); - return sb.toString(); - } - - - - public Resp revalidate(CachedPrincipal prin) { - // !!!! TEST THIS.. Things may not be revalidated, if not BasicPrincipal - if(prin instanceof BasicPrincipal) { - Future fp; - try { - Rcli userAAF = aaf.client(AAFCon.AAF_LATEST_VERSION).forUser(aaf.transferSS(prin)); - fp = userAAF.read("/authn/basicAuth", "text/plain"); - return fp.get(aaf.timeout)?Resp.REVALIDATED:Resp.UNVALIDATED; - } catch (Exception e) { - aaf.access.log(e, "Cannot Revalidate",prin.getName()); - return Resp.INACCESSIBLE; - } - } - return Resp.NOT_MINE; - } - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java deleted file mode 100644 index 5ee3199..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java +++ /dev/null @@ -1,115 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import javax.servlet.http.HttpServletRequest ; - -import com.att.cadi.Access; -import com.att.cadi.Lur; -import com.att.cadi.TrustChecker; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.config.Config; -import com.att.cadi.principal.TrustPrincipal; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TrustNotTafResp; -import com.att.cadi.taf.TrustTafResp; -import com.att.inno.env.Env; -import com.att.inno.env.util.Split; - -public class AAFTrustChecker implements TrustChecker { - private final String tag, id; - private final AAFPermission perm; - private Lur lur; - - /** - * - * Instance will be replaced by Identity - * @param lur - * - * @param tag - * @param perm - */ - public AAFTrustChecker(final Env env) { - tag = env.getProperty(Config.CADI_USER_CHAIN_TAG, Config.CADI_USER_CHAIN); - id = env.getProperty(Config.CADI_ALIAS,env.getProperty(Config.AAF_MECHID)); // share between components - String str = env.getProperty(Config.CADI_TRUST_PERM); - AAFPermission temp=null; - if(str!=null) { - String[] sp = Split.splitTrim('|', str); - if(sp.length==3) { - temp = new AAFPermission(sp[0],sp[1],sp[2]); - } - } - perm=temp; - } - - public AAFTrustChecker(final Access access) { - tag = access.getProperty(Config.CADI_USER_CHAIN_TAG, Config.CADI_USER_CHAIN); - id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_MECHID,null)); // share between components - String str = access.getProperty(Config.CADI_TRUST_PERM,null); - AAFPermission temp=null; - if(str!=null) { - String[] sp = Split.splitTrim('|', str); - if(sp.length==3) { - temp = new AAFPermission(sp[0],sp[1],sp[2]); - } - } - perm=temp; - } - - /* (non-Javadoc) - * @see com.att.cadi.TrustChecker#setLur(com.att.cadi.Lur) - */ - @Override - public void setLur(Lur lur) { - this.lur = lur; - } - - @Override - public TafResp mayTrust(TafResp tresp, HttpServletRequest req) { - String user_info = req.getHeader(tag); - if(user_info !=null ) { - String[] info = Split.split(',', user_info); - if(info.length>0) { - String[] flds = Split.splitTrim(':',info[0]); - if(flds.length>3 && "AS".equals(flds[3])) { // is it set for "AS" - String pn = tresp.getPrincipal().getName(); - if(pn.equals(id) // We do trust our own App Components: if a trust entry is made with self, always accept - || lur.fish(tresp.getPrincipal(), perm)) { // Have Perm set by Config.CADI_TRUST_PERM - return new TrustTafResp(tresp, - new TrustPrincipal(tresp.getPrincipal(), flds[0]), - " " + flds[0] + " validated using " + flds[2] + " by " + flds[1] + ',' - ); - } else if(pn.equals(flds[0])) { // Ignore if same identity - return tresp; - } else { - return new TrustNotTafResp(tresp, tresp.getPrincipal().getName() + " requested trust as " - + flds[0] + ", but does not have Authorization"); - } - } - } - } - return tresp; - } - -} diff --git a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java b/aaf/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java deleted file mode 100644 index 297ad8a..0000000 --- a/aaf/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java +++ /dev/null @@ -1,268 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.v2_0; - -import java.net.URISyntaxException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import com.att.aft.dme2.api.DME2Exception; -import com.att.cadi.AbsUserCache; -import com.att.cadi.Access.Level; -import com.att.cadi.CachingLur; -import com.att.cadi.Permission; -import com.att.cadi.StrLur; -import com.att.cadi.Transmutate; -import com.att.cadi.User; -import com.att.cadi.config.Config; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.AAFTransmutate; -import com.att.inno.env.APIException; -import com.att.inno.env.util.Split; - -public abstract class AbsAAFLur extends AbsUserCache implements StrLur, CachingLur { - protected static final byte[] BLANK_PASSWORD = new byte[0]; - protected static final Transmutate transmutate = new AAFTransmutate(); - private String[] debug = null; - public AAFCon aaf; - private String[] supports; - - public AbsAAFLur(AAFCon con) throws DME2Exception, URISyntaxException, APIException { - super(con.access, con.cleanInterval, con.highCount, con.usageRefreshTriggerCount); - aaf = con; - setLur(this); - supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*"); - } - - public AbsAAFLur(AAFCon con, AbsUserCache auc) throws DME2Exception, URISyntaxException, APIException { - super(auc); - aaf = con; - setLur(this); - supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*"); - } - - @Override - public void setDebug(String ids) { - this.debug = ids==null?null:Split.split(',', ids); - } - - protected abstract User loadUser(Principal bait); - protected abstract User loadUser(String name); - public final boolean supports(String userName) { - if(userName!=null) { - for(String s : supports) { - if(userName.endsWith(s)) - return true; - } - } - return false; - } - - protected abstract boolean isCorrectPermType(Permission pond); - - // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond" - public boolean fish(Principal bait, Permission pond) { - return fish(bait.getName(), pond); - } - - public void fishAll(Principal bait, List perms) { - fishAll(bait.getName(),perms); - } - - // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond" - public boolean fish(String bait, Permission pond) { - if(isDebug(bait)) { - boolean rv = false; - StringBuilder sb = new StringBuilder("Log for "); - sb.append(bait); - if(supports(bait)) { - User user = getUser(bait); - if(user==null) { - sb.append("\n\tUser is not in Cache"); - } else { - if(user.noPerms())sb.append("\n\tUser has no Perms"); - if(user.permExpired()) { - sb.append("\n\tUser's perm expired ["); - sb.append(new Date(user.permExpires())); - sb.append(']'); - } else { - sb.append("\n\tUser's perm expires ["); - sb.append(new Date(user.permExpires())); - sb.append(']'); - } - } - if(user==null || (user.noPerms() && user.permExpired())) { - user = loadUser(bait); - sb.append("\n\tloadUser called"); - } - if(user==null) { - sb.append("\n\tUser was not Loaded"); - } else if(user.contains(pond)) { - sb.append("\n\tUser contains "); - sb.append(pond.getKey()); - rv = true; - } else { - sb.append("\n\tUser does not contain "); - sb.append(pond.getKey()); - List perms = new ArrayList(); - user.copyPermsTo(perms); - for(Permission p : perms) { - sb.append("\n\t\t"); - sb.append(p.getKey()); - } - } - } else { - sb.append("AAF Lur does not support ["); - sb.append(bait); - sb.append("]"); - } - aaf.access.log(Level.INFO, sb); - return rv; - } else { - if(supports(bait)) { - User user = getUser(bait); - if(user==null || (user.noPerms() && user.permExpired())) { - user = loadUser(bait); - } - return user==null?false:user.contains(pond); - } - return false; - } - } - - public void fishAll(String bait, List perms) { - if(isDebug(bait)) { - StringBuilder sb = new StringBuilder("Log for "); - sb.append(bait); - if(supports(bait)) { - User user = getUser(bait); - if(user==null) { - sb.append("\n\tUser is not in Cache"); - } else { - if(user.noPerms())sb.append("\n\tUser has no Perms"); - if(user.permExpired()) { - sb.append("\n\tUser's perm expired ["); - sb.append(new Date(user.permExpires())); - sb.append(']'); - } else { - sb.append("\n\tUser's perm expires ["); - sb.append(new Date(user.permExpires())); - sb.append(']'); - } - } - if(user==null || (user.noPerms() && user.permExpired())) { - user = loadUser(bait); - sb.append("\n\tloadUser called"); - } - if(user==null) { - sb.append("\n\tUser was not Loaded"); - } else { - sb.append("\n\tCopying Perms "); - user.copyPermsTo(perms); - for(Permission p : perms) { - sb.append("\n\t\t"); - sb.append(p.getKey()); - } - } - } else { - sb.append("AAF Lur does not support ["); - sb.append(bait); - sb.append("]"); - } - aaf.access.log(Level.INFO, sb); - } else { - if(supports(bait)) { - User user = getUser(bait); - if(user==null || (user.noPerms() && user.permExpired())) user = loadUser(bait); - if(user!=null) { - user.copyPermsTo(perms); - } - } - } - } - - @Override - public void remove(String user) { - super.remove(user); - } - - private boolean isDebug(String bait) { - if(debug!=null) { - if(debug.length==1 && "all".equals(debug[0]))return true; - for(String s : debug) { - if(s.equals(bait))return true; - } - } - return false; - } - /** - * This special case minimizes loops, avoids multiple Set hits, and calls all the appropriate Actions found. - * - * @param bait - * @param obj - * @param type - * @param instance - * @param actions - */ - public void fishOneOf(String bait, A obj, String type, String instance, List> actions) { - User user = getUser(bait); - if(user==null || (user.noPerms() && user.permExpired()))user = loadUser(bait); -// return user==null?false:user.contains(pond); - if(user!=null) { - ReuseAAFPermission perm = new ReuseAAFPermission(type,instance); - for(Action action : actions) { - perm.setAction(action.getName()); - if(user.contains(perm)) { - if(action.exec(obj))return; - } - } - } - } - - public static interface Action { - public String getName(); - /** - * Return false to continue, True to end now - * @return - */ - public boolean exec(A a); - } - - private class ReuseAAFPermission extends AAFPermission { - public ReuseAAFPermission(String type, String instance) { - super(type,instance,null); - } - - public void setAction(String s) { - action = s; - } - - /** - * This function understands that AAF Keys are hierarchical, :A:B:C, - * Cassandra follows a similar method, so we'll short circuit and do it more efficiently when there isn't a first hit - * @return - */ - } -} diff --git a/aaf/src/main/java/com/att/cadi/cm/ArtifactDir.java b/aaf/src/main/java/com/att/cadi/cm/ArtifactDir.java deleted file mode 100644 index 512be78..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/ArtifactDir.java +++ /dev/null @@ -1,287 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.security.KeyStore; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.att.cadi.CadiException; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; -import com.att.cadi.util.Chmod; -import com.att.inno.env.Trans; -import com.att.inno.env.util.Chrono; - -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; - -public abstract class ArtifactDir implements PlaceArtifact { - - protected static final String C_R = "\n"; - protected File dir; - private List encodeds = new ArrayList(); - - private Symm symm; - // This checks for multiple passes of Dir on the same objects. Run clear after done. - protected static Map processed = new HashMap(); - - - /** - * Note: Derived Classes should ALWAYS call "super.place(cert,arti)" first, and - * then "placeProperties(arti)" just after they implement - */ - @Override - public final boolean place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { - validate(arti); - - try { - // Obtain/setup directory as required - dir = new File(arti.getDir()); - if(processed.get("dir")==null) { - if(!dir.exists()) { - Chmod.to755.chmod(dir); - if(!dir.mkdirs()) { - throw new CadiException("Could not create " + dir); - } - } - - // Also place cm_url and Host Name - addProperty(Config.CM_URL,trans.getProperty(Config.CM_URL)); - addProperty(Config.HOSTNAME,arti.getMachine()); - //addProperty(Config.AAF_ENV,certInfo.getEnv()); - // Obtain Issuers - boolean first = true; - StringBuilder issuers = new StringBuilder(); -// for(String dn : certInfo.getCaIssuerDNs()) { -// if(first) { -// first=false; -// } else { -// issuers.append(':'); -// } -// issuers.append(dn); -// } - addProperty(Config.CADI_X509_ISSUERS,issuers.toString()); - } - symm = (Symm)processed.get("symm"); - if(symm==null) { - // CADI Key Gen - File f = new File(dir,arti.getAppName() + ".keyfile"); - if(!f.exists()) { - write(f,Chmod.to400,Symm.baseCrypt().keygen()); - } - symm = Symm.obtain(f); - - addEncProperty("ChallengePassword", certInfo.getChallenge()); - - processed.put("symm",symm); - } - - _place(trans, certInfo,arti); - - placeProperties(arti); - - processed.put("dir",dir); - - } catch (Exception e) { - throw new CadiException(e); - } - return true; - } - - /** - * Derived Classes implement this instead, so Dir can process first, and write any Properties last - * @param cert - * @param arti - * @return - * @throws CadiException - */ - protected abstract boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException; - - protected void addProperty(String tag, String value) throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append(tag); - sb.append('='); - sb.append(value); - encodeds.add(sb.toString()); - } - - protected void addEncProperty(String tag, String value) throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append(tag); - sb.append('='); - sb.append("enc:???"); - sb.append(symm.enpass(value)); - encodeds.add(sb.toString()); - } - - protected void write(File f, Chmod c, String ... data) throws IOException { - f.setWritable(true,true); - - FileOutputStream fos = new FileOutputStream(f); - PrintStream ps = new PrintStream(fos); - try { - for(String s : data) { - ps.print(s); - } - } finally { - ps.close(); - c.chmod(f); - } - } - - protected void write(File f, Chmod c, byte[] bytes) throws IOException { - f.setWritable(true,true); - - FileOutputStream fos = new FileOutputStream(f); - try { - fos.write(bytes); - } finally { - fos.close(); - c.chmod(f); - } - } - - protected void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException { - f.setWritable(true,true); - - FileOutputStream fos = new FileOutputStream(f); - try { - ks.store(fos, pass); - } catch (Exception e) { - throw new CadiException(e); - } finally { - fos.close(); - c.chmod(f); - } - } - - - private void validate(Artifact a) throws CadiException { - StringBuilder sb = new StringBuilder(); - if(a.getDir()==null) { - sb.append("File Artifacts require a path"); - } - - if(a.getAppName()==null) { - if(sb.length()>0) { - sb.append('\n'); - } - sb.append("File Artifacts require an AAF Namespace"); - } - - if(sb.length()>0) { - throw new CadiException(sb.toString()); - } - } - - private boolean placeProperties(Artifact arti) throws CadiException { - if(encodeds.size()==0) { - return true; - } - boolean first=processed.get("dir")==null; - try { - File f = new File(dir,arti.getAppName()+".props"); - if(f.exists()) { - if(first) { - f.delete(); - } else { - f.setWritable(true); - } - } - // Append if not first - PrintWriter pw = new PrintWriter(new FileWriter(f,!first)); - - // Write a Header - if(first) { - for(int i=0;i<60;++i) { - pw.print('#'); - } - pw.println(); - pw.println("# Properties Generated by AT&T Certificate Manager"); - pw.print("# by "); - pw.println(System.getProperty("user.name")); - pw.print("# on "); - pw.println(Chrono.dateStamp()); - pw.println("# @copyright 2016, AT&T"); - for(int i=0;i<60;++i) { - pw.print('#'); - } - pw.println(); - for(String prop : encodeds) { - if( prop.startsWith("cm_") - || prop.startsWith(Config.HOSTNAME) - || prop.startsWith(Config.AAF_ENV)) { - pw.println(prop); - } - } - } - - try { - for(String prop : encodeds) { - if(prop.startsWith("cadi")) { - pw.println(prop); - } - } - } finally { - pw.close(); - } - Chmod.to644.chmod(f); - - if(first) { - // Challenge - f = new File(dir,arti.getAppName()+".chal"); - if(f.exists()) { - f.delete(); - } - pw = new PrintWriter(new FileWriter(f)); - try { - for(String prop : encodeds) { - if(prop.startsWith("Challenge")) { - pw.println(prop); - } - } - } finally { - pw.close(); - } - Chmod.to400.chmod(f); - } - } catch(Exception e) { - throw new CadiException(e); - } - return true; - } - - public static void clear() { - processed.clear(); - } - -} diff --git a/aaf/src/main/java/com/att/cadi/cm/CertException.java b/aaf/src/main/java/com/att/cadi/cm/CertException.java deleted file mode 100644 index ce38c21..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/CertException.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -public class CertException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1373028409048516401L; - - public CertException() { - } - - public CertException(String message) { - super(message); - } - - public CertException(Throwable cause) { - super(cause); - } - - public CertException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/aaf/src/main/java/com/att/cadi/cm/CmAgent.java b/aaf/src/main/java/com/att/cadi/cm/CmAgent.java deleted file mode 100644 index 0240962..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/CmAgent.java +++ /dev/null @@ -1,710 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.KeyStore; -import java.security.cert.X509Certificate; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import com.att.cadi.PropAccess; -import com.att.cadi.Symm; -import com.att.cadi.aaf.client.ErrMessage; -import com.att.cadi.aaf.v2_0.AAFCon; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.client.Future; -import com.att.cadi.config.Config; -import com.att.cadi.http.HBasicAuthSS; -import com.att.cadi.sso.AAFSSO; -import com.att.inno.env.Data.TYPE; -import com.att.inno.env.Env; -import com.att.inno.env.TimeTaken; -import com.att.inno.env.Trans; -import com.att.inno.env.util.Chrono; -import com.att.inno.env.util.Split; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -import certman.v1_0.Artifacts; -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; -import certman.v1_0.CertificateRequest; - -public class CmAgent { - private static final String PRINT = "print"; - private static final String FILE = "file"; - private static final String PKCS12 = "pkcs12"; - private static final String JKS = "jks"; - private static final String SCRIPT="script"; - - private static final String CM_VER = "1.0"; - public static final int PASS_SIZE = 24; - private static int TIMEOUT; - - private static RosettaDF reqDF; - private static RosettaDF certDF; - private static RosettaDF artifactsDF; - private static ErrMessage errMsg; - private static Map placeArtifact; - private static RosettaEnv env; - - public static void main(String[] args) { - int exitCode = 0; - try { - AAFSSO aafsso = new AAFSSO(args); - if(aafsso.loginOnly()) { - aafsso.setLogDefault(); - aafsso.writeFiles(); - System.out.println("AAF SSO information created in ~/.aaf"); - } else { - PropAccess access = aafsso.access(); - env = new RosettaEnv(access.getProperties()); - Deque cmds = new ArrayDeque(); - for(String p : args) { - if(p.indexOf('=')<0) { - cmds.add(p); - } - } - - if(cmds.size()==0) { - aafsso.setLogDefault(); - System.out.println("Usage: java -jar cmd []*"); - System.out.println(" create []"); - System.out.println(" read []"); - System.out.println(" update []"); - System.out.println(" delete []"); - System.out.println(" copy [,]*"); - System.out.println(" place []"); - System.out.println(" showpass []"); - System.out.println(" check []"); - System.exit(1); - } - - TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000")); - - reqDF = env.newDataFactory(CertificateRequest.class); - artifactsDF = env.newDataFactory(Artifacts.class); - certDF = env.newDataFactory(CertInfo.class); - errMsg = new ErrMessage(env); - - placeArtifact = new HashMap(); - placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS)); - placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12)); - placeArtifact.put(FILE, new PlaceArtifactInFiles()); - placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out)); - placeArtifact.put(SCRIPT, new PlaceArtifactScripts()); - - Trans trans = env.newTrans(); - try { - // show Std out again - aafsso.setLogDefault(); - aafsso.setStdErrDefault(); - - // if CM_URL can be obtained, add to sso.props, if written - String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": "); - if(cm_url!=null) { - aafsso.addProp(Config.CM_URL, cm_url); - } - aafsso.writeFiles(); - - AAFCon aafcon = new AAFConHttp(access,Config.CM_URL); - - String cmd = cmds.removeFirst(); - if("place".equals(cmd)) { - placeCerts(trans,aafcon,cmds); - } else if("create".equals(cmd)) { - createArtifact(trans, aafcon,cmds); - } else if("read".equals(cmd)) { - readArtifact(trans, aafcon, cmds); - } else if("copy".equals(cmd)) { - copyArtifact(trans, aafcon, cmds); - } else if("update".equals(cmd)) { - updateArtifact(trans, aafcon, cmds); - } else if("delete".equals(cmd)) { - deleteArtifact(trans, aafcon, cmds); - } else if("showpass".equals(cmd)) { - showPass(trans,aafcon,cmds); - } else if("check".equals(cmd)) { - try { - exitCode = check(trans,aafcon,cmds); - } catch (Exception e) { - exitCode = 1; - throw e; - } - } else { - AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd); - } - } finally { - StringBuilder sb = new StringBuilder(); - trans.auditTrail(4, sb, Trans.REMOTE); - if(sb.length()>0) { - trans.info().log("Trans Info\n",sb); - } - } - aafsso.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if(exitCode!=0) { - System.exit(exitCode); - } - } - - private static String getProperty(PropAccess pa, Env env, boolean secure, String tag, String prompt, Object ... def) { - String value; - if((value=pa.getProperty(tag))==null) { - if(secure) { - value = new String(AAFSSO.cons.readPassword(prompt, def)); - } else { - value = AAFSSO.cons.readLine(prompt,def).trim(); - } - if(value!=null) { - if(value.length()>0) { - pa.setProperty(tag,value); - env.setProperty(tag,value); - } else if(def.length==1) { - value=def[0].toString(); - pa.setProperty(tag,value); - env.setProperty(tag,value); - } - } - } - return value; - } - - private static String mechID(Deque cmds) { - if(cmds.size()<1) { - String alias = env.getProperty(Config.CADI_ALIAS); - return alias!=null?alias:AAFSSO.cons.readLine("MechID: "); - } - return cmds.removeFirst(); - } - - private static String machine(Deque cmds) throws UnknownHostException { - if(cmds.size()>0) { - return cmds.removeFirst(); - } else { - String mach = env.getProperty(Config.HOSTNAME); - return mach!=null?mach:InetAddress.getLocalHost().getHostName(); - } - } - - private static String[] machines(Deque cmds) { - String machines; - if(cmds.size()>0) { - machines = cmds.removeFirst(); - } else { - machines = AAFSSO.cons.readLine("Machines (sep by ','): "); - } - return Split.split(',', machines); - } - - private static void createArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechID = mechID(cmds); - String machine = machine(cmds); - - Artifacts artifacts = new Artifacts(); - Artifact arti = new Artifact(); - artifacts.getArtifact().add(arti); - arti.setMechid(mechID!=null?mechID:AAFSSO.cons.readLine("MechID: ")); - arti.setMachine(machine!=null?machine:AAFSSO.cons.readLine("Machine (%s): ",InetAddress.getLocalHost().getHostName())); - arti.setCa(AAFSSO.cons.readLine("CA: (%s): ","aaf")); - - String resp = AAFSSO.cons.readLine("Types [file,jks,script] (%s): ", "jks"); - for(String s : Split.splitTrim(',', resp)) { - arti.getType().add(s); - } - // Always do Script - if(!resp.contains(SCRIPT)) { - arti.getType().add(SCRIPT); - } - - // Note: Sponsor is set on Creation by CM - String configRootName = AAFCon.reverseDomain(arti.getMechid()); - arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",configRootName)); - arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", System.getProperty("user.dir"))); - arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", System.getProperty("user.name"))); - arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renewal Days (%s):", "30"))); - arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (mailto owner):", ""))); - - TimeTaken tt = trans.start("Create Artifact", Env.REMOTE); - try { - Future future = aafcon.client(CM_VER).create("/cert/artifacts", artifactsDF, artifacts); - if(future.get(TIMEOUT)) { - trans.info().printf("Call to AAF Certman successful %s, %s",arti.getMechid(), arti.getMachine()); - } else { - trans.error().printf("Call to AAF Certman failed, %s", - errMsg.toMsg(future)); - } - } finally { - tt.done(); - } - } - - private static String toNotification(String notification) { - if(notification==null) { - notification=""; - } else if(notification.length()>0) { - if(notification.indexOf(':')<0) { - notification = "mailto:" + notification; - } - } - return notification; - } - - - private static void readArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechID = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Read Artifact", Env.SUB); - try { - Future future = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - - if(future.get(TIMEOUT)) { - boolean printed = false; - for(Artifact a : future.value.getArtifact()) { - AAFSSO.cons.printf("MechID: %s\n",a.getMechid()); - AAFSSO.cons.printf(" Sponsor: %s\n",a.getSponsor()); - AAFSSO.cons.printf("Machine: %s\n",a.getMachine()); - AAFSSO.cons.printf("CA: %s\n",a.getCa()); - StringBuilder sb = new StringBuilder(); - boolean first = true; - for(String t : a.getType()) { - if(first) {first=false;} - else{sb.append(',');} - sb.append(t); - } - AAFSSO.cons.printf("Types: %s\n",sb); - AAFSSO.cons.printf("Namespace: %s\n",a.getAppName()); - AAFSSO.cons.printf("Directory: %s\n",a.getDir()); - AAFSSO.cons.printf("O/S User: %s\n",a.getOsUser()); - AAFSSO.cons.printf("Renew Days: %d\n",a.getRenewDays()); - AAFSSO.cons.printf("Notification %s\n",a.getNotification()); - printed = true; - } - if(!printed) { - AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); - } - } else { - trans.error().log(errMsg.toMsg(future)); - } - } finally { - tt.done(); - } - } - - private static void copyArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechID = mechID(cmds); - String machine = machine(cmds); - String[] newmachs = machines(cmds); - if(newmachs==null || newmachs == null) { - trans.error().log("No machines listed to copy to"); - } else { - TimeTaken tt = trans.start("Copy Artifact", Env.REMOTE); - try { - Future future = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - - if(future.get(TIMEOUT)) { - boolean printed = false; - for(Artifact a : future.value.getArtifact()) { - for(String m : newmachs) { - a.setMachine(m); - Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, future.value); - if(fup.get(TIMEOUT)) { - trans.info().printf("Copy of %s %s successful to %s",mechID,machine,m); - } else { - trans.error().printf("Call to AAF Certman failed, %s", - errMsg.toMsg(fup)); - } - - printed = true; - } - } - if(!printed) { - AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); - } - } else { - trans.error().log(errMsg.toMsg(future)); - } - } finally { - tt.done(); - } - } - } - - private static void updateArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechID = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Update Artifact", Env.REMOTE); - try { - Future fread = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - - if(fread.get(TIMEOUT)) { - Artifacts artifacts = new Artifacts(); - for(Artifact a : fread.value.getArtifact()) { - Artifact arti = new Artifact(); - artifacts.getArtifact().add(arti); - - AAFSSO.cons.printf("For %s on %s\n", a.getMechid(),a.getMachine()); - arti.setMechid(a.getMechid()); - arti.setMachine(a.getMachine()); - arti.setCa(AAFSSO.cons.readLine("CA: (%s): ",a.getCa())); - StringBuilder sb = new StringBuilder(); - boolean first = true; - for(String t : a.getType()) { - if(first) {first=false;} - else{sb.append(',');} - sb.append(t); - } - - String resp = AAFSSO.cons.readLine("Types [file,jks,pkcs12] (%s): ", sb); - for(String s : Split.splitTrim(',', resp)) { - arti.getType().add(s); - } - // Always do Script - if(!resp.contains(SCRIPT)) { - arti.getType().add(SCRIPT); - } - - // Note: Sponsor is set on Creation by CM - arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",a.getAppName())); - arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", a.getDir())); - arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", a.getOsUser())); - arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renew Days (%s):", a.getRenewDays()))); - arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (%s):", a.getNotification()))); - - } - if(artifacts.getArtifact().size()==0) { - AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); - } else { - Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, artifacts); - if(fup.get(TIMEOUT)) { - trans.info().printf("Call to AAF Certman successful %s, %s",mechID,machine); - } else { - trans.error().printf("Call to AAF Certman failed, %s", - errMsg.toMsg(fup)); - } - } - } else { - trans.error().printf("Call to AAF Certman failed, %s %s, %s", - errMsg.toMsg(fread),mechID,machine); - } - } finally { - tt.done(); - } - } - - private static void deleteArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechid = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Delete Artifact", Env.REMOTE); - try { - Future future = aafcon.client(CM_VER) - .delete("/cert/artifacts/"+mechid+"/"+machine,"application/json" ); - - if(future.get(TIMEOUT)) { - trans.info().printf("Call to AAF Certman successful %s, %s",mechid,machine); - } else { - trans.error().printf("Call to AAF Certman failed, %s %s, %s", - errMsg.toMsg(future),mechid,machine); - } - } finally { - tt.done(); - } - } - - - - private static boolean placeCerts(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - boolean rv = false; - String mechID = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Place Artifact", Env.REMOTE); - try { - Future acf = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - if(acf.get(TIMEOUT)) { - // Have to wait for JDK 1.7 source... - //switch(artifact.getType()) { - if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { - AAFSSO.cons.printf("===> There are no artifacts for %s %s", mechID, machine); - } else { - for(Artifact a : acf.value.getArtifact()) { - String osID = System.getProperty("user.name"); - if(a.getOsUser().equals(osID)) { - CertificateRequest cr = new CertificateRequest(); - cr.setMechid(a.getMechid()); - cr.setSponsor(a.getSponsor()); - cr.getFqdns().add(a.getMachine()); - Future f = aafcon.client(CM_VER) - .setQueryParams("withTrust") - .updateRespondString("/cert/" + a.getCa(),reqDF, cr); - if(f.get(TIMEOUT)) { - CertInfo capi = certDF.newData().in(TYPE.JSON).load(f.body()).asObject(); - for(String type : a.getType()) { - PlaceArtifact pa = placeArtifact.get(type); - if(pa!=null) { - if(rv = pa.place(trans, capi, a)) { - notifyPlaced(a,rv); - } - } - } - // Cover for the above multiple pass possibilities with some static Data, then clear per Artifact - } else { - trans.error().log(errMsg.toMsg(f)); - } - } else { - trans.error().log("You must be OS User \"" + a.getOsUser() +"\" to place Certificates on this box"); - } - } - } - } else { - trans.error().log(errMsg.toMsg(acf)); - } - } finally { - tt.done(); - } - return rv; - } - - private static void notifyPlaced(Artifact a, boolean rv) { - - - } - - private static void showPass(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - String mechID = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Show Password", Env.REMOTE); - try { - Future acf = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - if(acf.get(TIMEOUT)) { - // Have to wait for JDK 1.7 source... - //switch(artifact.getType()) { - if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { - AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine); - } else { - String id = aafcon.defID(); - boolean allowed; - for(Artifact a : acf.value.getArtifact()) { - allowed = id!=null && (id.equals(a.getSponsor()) || - (id.equals(a.getMechid()) - && aafcon.securityInfo().defSS.getClass().isAssignableFrom(HBasicAuthSS.class))); - if(!allowed) { - Future pf = aafcon.client(CM_VER).read("/cert/may/" + - a.getAppName() + ".certman|"+a.getCa()+"|showpass","*/*"); - if(pf.get(TIMEOUT)) { - allowed = true; - } else { - trans.error().log(errMsg.toMsg(pf)); - } - } - if(allowed) { - File dir = new File(a.getDir()); - Properties props = new Properties(); - FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); - try { - props.load(fis); - fis.close(); - fis = new FileInputStream(new File(dir,a.getAppName()+".chal")); - props.load(fis); - } finally { - fis.close(); - } - - File f = new File(dir,a.getAppName()+".keyfile"); - if(f.exists()) { - Symm symm = Symm.obtain(f); - - for(Iterator> iter = props.entrySet().iterator(); iter.hasNext();) { - Entry en = iter.next(); - if(en.getValue().toString().startsWith("enc:???")) { - System.out.printf("%s=%s\n", en.getKey(), symm.depass(en.getValue().toString())); - } - } - } else { - trans.error().printf("%s.keyfile must exist to read passwords for %s on %s", - f.getAbsolutePath(),a.getMechid(), a.getMachine()); - } - } - } - } - } else { - trans.error().log(errMsg.toMsg(acf)); - } - } finally { - tt.done(); - } - - } - - - /** - * Check returns Error Codes, so that Scripts can know what to do - * - * 0 - Check Complete, nothing to do - * 1 - General Error - * 2 - Error for specific Artifact - read check.msg - * 10 - Certificate Updated - check.msg is email content - * - * @param trans - * @param aafcon - * @param cmds - * @return - * @throws Exception - */ - private static int check(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { - int exitCode=1; - String mechID = mechID(cmds); - String machine = machine(cmds); - - TimeTaken tt = trans.start("Check Certificate", Env.REMOTE); - try { - - Future acf = aafcon.client(CM_VER) - .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); - if(acf.get(TIMEOUT)) { - // Have to wait for JDK 1.7 source... - //switch(artifact.getType()) { - if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { - AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine); - } else { - String id = aafcon.defID(); - GregorianCalendar now = new GregorianCalendar(); - for(Artifact a : acf.value.getArtifact()) { - if(id.equals(a.getMechid())) { - File dir = new File(a.getDir()); - Properties props = new Properties(); - FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); - try { - props.load(fis); - } finally { - fis.close(); - } - - String prop; - File f; - - if((prop=props.getProperty(Config.CADI_KEYFILE))==null || - !(f=new File(prop)).exists()) { - trans.error().printf("Keyfile must exist to check Certificates for %s on %s", - a.getMechid(), a.getMachine()); - } else { - String ksf = props.getProperty(Config.CADI_KEYSTORE); - String ksps = props.getProperty(Config.CADI_KEYSTORE_PASSWORD); - if(ksf==null || ksps == null) { - trans.error().printf("Properties %s and %s must exist to check Certificates for %s on %s", - Config.CADI_KEYSTORE, Config.CADI_KEYSTORE_PASSWORD,a.getMechid(), a.getMachine()); - } else { - KeyStore ks = KeyStore.getInstance("JKS"); - Symm symm = Symm.obtain(f); - - fis = new FileInputStream(ksf); - try { - ks.load(fis,symm.depass(ksps).toCharArray()); - } finally { - fis.close(); - } - X509Certificate cert = (X509Certificate)ks.getCertificate(mechID); - String msg = null; - - if(cert==null) { - msg = String.format("X509Certificate does not exist for %s on %s in %s", - a.getMechid(), a.getMachine(), ksf); - trans.error().log(msg); - exitCode = 2; - } else { - GregorianCalendar renew = new GregorianCalendar(); - renew.setTime(cert.getNotAfter()); - renew.add(GregorianCalendar.DAY_OF_MONTH,-1*a.getRenewDays()); - if(renew.after(now)) { - msg = String.format("X509Certificate for %s on %s has been checked on %s. It expires on %s; it will not be renewed until %s.\n", - a.getMechid(), a.getMachine(),Chrono.dateOnlyStamp(now),cert.getNotAfter(),Chrono.dateOnlyStamp(renew)); - trans.info().log(msg); - exitCode = 0; // OK - } else { - trans.info().printf("X509Certificate for %s on %s expiration, %s, needs Renewal.\n", - a.getMechid(), a.getMachine(),cert.getNotAfter()); - cmds.offerLast(mechID); - cmds.offerLast(machine); - if(placeCerts(trans,aafcon,cmds)) { - msg = String.format("X509Certificate for %s on %s has been renewed. Ensure services using are refreshed.\n", - a.getMechid(), a.getMachine()); - exitCode = 10; // Refreshed - } else { - msg = String.format("X509Certificate for %s on %s attempted renewal, but failed. Immediate Investigation is required!\n", - a.getMechid(), a.getMachine()); - exitCode = 1; // Error Renewing - } - } - } - if(msg!=null) { - FileOutputStream fos = new FileOutputStream(a.getDir()+'/'+a.getAppName()+".msg"); - try { - fos.write(msg.getBytes()); - } finally { - fos.close(); - } - } - } - - } - } - } - } - } else { - trans.error().log(errMsg.toMsg(acf)); - exitCode=1; - } - } finally { - tt.done(); - } - return exitCode; - } - -} - - - - diff --git a/aaf/src/main/java/com/att/cadi/cm/Factory.java b/aaf/src/main/java/com/att/cadi/cm/Factory.java deleted file mode 100644 index 85b5dfb..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/Factory.java +++ /dev/null @@ -1,448 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.Signature; -import java.security.SignatureException; -import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.Collection; -import java.util.List; - -import javax.crypto.Cipher; -import javax.crypto.NoSuchPaddingException; - -import com.att.cadi.Symm; -import com.att.inno.env.Env; -import com.att.inno.env.TimeTaken; -import com.att.inno.env.Trans; - -public class Factory { - private static final String PRIVATE_KEY_HEADER = "PRIVATE KEY"; - public static final String KEY_ALGO = "RSA"; - public static final String SIG_ALGO = "SHA256withRSA"; - - public static final int KEY_LENGTH = 2048; - private static final KeyPairGenerator keygen; - private static final KeyFactory keyFactory; - private static final CertificateFactory certificateFactory; - private static final SecureRandom random; - - - private static final Symm base64 = Symm.base64.copy(64); - - static { - random = new SecureRandom(); - KeyPairGenerator tempKeygen; - try { - tempKeygen = KeyPairGenerator.getInstance(KEY_ALGO);//,"BC"); - tempKeygen.initialize(KEY_LENGTH, random); - } catch (NoSuchAlgorithmException e) { - tempKeygen = null; - e.printStackTrace(System.err); - } - keygen = tempKeygen; - - KeyFactory tempKeyFactory; - try { - tempKeyFactory=KeyFactory.getInstance(KEY_ALGO);//,"BC" - } catch (NoSuchAlgorithmException e) { - tempKeyFactory = null; - e.printStackTrace(System.err); - }; - keyFactory = tempKeyFactory; - - CertificateFactory tempCertificateFactory; - try { - tempCertificateFactory = CertificateFactory.getInstance("X.509"); - } catch (CertificateException e) { - tempCertificateFactory = null; - e.printStackTrace(System.err); - } - certificateFactory = tempCertificateFactory; - - - } - - - public static KeyPair generateKeyPair(Trans trans) { - TimeTaken tt; - if(trans!=null) { - tt = trans.start("Generate KeyPair", Env.SUB); - } else { - tt = null; - } - try { - return keygen.generateKeyPair(); - } finally { - if(tt!=null) { - tt.done(); - } - } - } - - private static final String LINE_END = "-----\n"; - - protected static String textBuilder(String kind, byte[] bytes) throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append("-----BEGIN "); - sb.append(kind); - sb.append(LINE_END); - - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - base64.encode(bais, baos); - sb.append(new String(baos.toByteArray())); - - if(sb.charAt(sb.length()-1)!='\n') { - sb.append('\n'); - } - sb.append("-----END "); - sb.append(kind); - sb.append(LINE_END); - return sb.toString(); - } - - public static PrivateKey toPrivateKey(Trans trans, String pk) throws IOException, CertException { - byte[] bytes = decode(new StringReader(pk)); - return toPrivateKey(trans, bytes); - } - - public static PrivateKey toPrivateKey(Trans trans, byte[] bytes) throws IOException, CertException { - TimeTaken tt=trans.start("Reconstitute Private Key", Env.SUB); - try { - return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes)); - } catch (InvalidKeySpecException e) { - throw new CertException("Translating Private Key from PKCS8 KeySpec",e); - } finally { - tt.done(); - } - } - - public static PrivateKey toPrivateKey(Trans trans, File file) throws IOException, CertException { - TimeTaken tt = trans.start("Decode Private Key File", Env.SUB); - try { - return toPrivateKey(trans,decode(file)); - }finally { - tt.done(); - } - } - - public static String toString(Trans trans, PrivateKey pk) throws IOException { -// PKCS8EncodedKeySpec pemContents = new PKCS8EncodedKeySpec(pk.getEncoded()); - trans.debug().log("Private Key to String"); - return textBuilder(PRIVATE_KEY_HEADER,pk.getEncoded()); - } - - public static PublicKey toPublicKey(Trans trans, String pk) throws IOException { - TimeTaken tt = trans.start("Reconstitute Public Key", Env.SUB); - try { - ByteArrayInputStream bais = new ByteArrayInputStream(pk.getBytes()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Symm.base64noSplit.decode(bais, baos); - - return keyFactory.generatePublic(new X509EncodedKeySpec(baos.toByteArray())); - } catch (InvalidKeySpecException e) { - trans.error().log(e,"Translating Public Key from X509 KeySpec"); - return null; - } finally { - tt.done(); - } - } - - public static String toString(Trans trans, PublicKey pk) throws IOException { - trans.debug().log("Public Key to String"); - return textBuilder("PUBLIC KEY",pk.getEncoded()); - } - - public static Collection toX509Certificate(String x509) throws CertificateException { - return toX509Certificate(x509.getBytes()); - } - - public static Collection toX509Certificate(List x509s) throws CertificateException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - for(String x509 : x509s) { - baos.write(x509.getBytes()); - } - } catch (IOException e) { - throw new CertificateException(e); - } - return toX509Certificate(new ByteArrayInputStream(baos.toByteArray())); - } - - public static Collection toX509Certificate(byte[] x509) throws CertificateException { - return certificateFactory.generateCertificates(new ByteArrayInputStream(x509)); - } - - public static Collection toX509Certificate(Trans trans, File file) throws CertificateException, FileNotFoundException { - FileInputStream fis = new FileInputStream(file); - try { - return toX509Certificate(fis); - } finally { - try { - fis.close(); - } catch (IOException e) { - throw new CertificateException(e); - } - } - } - - public static Collection toX509Certificate(InputStream is) throws CertificateException { - return certificateFactory.generateCertificates(is); - } - - public static String toString(Trans trans, Certificate cert) throws IOException, CertException { - if(trans.debug().isLoggable()) { - StringBuilder sb = new StringBuilder("Certificate to String"); - if(cert instanceof X509Certificate) { - sb.append(" - "); - sb.append(((X509Certificate)cert).getSubjectDN()); - } - trans.debug().log(sb); - } - try { - if(cert==null) { - throw new CertException("Certificate not built"); - } - return textBuilder("CERTIFICATE",cert.getEncoded()); - } catch (CertificateEncodingException e) { - throw new CertException(e); - } - } - - public static Cipher pkCipher() throws NoSuchAlgorithmException, NoSuchPaddingException { - return Cipher.getInstance(KEY_ALGO); - } - - public static Cipher pkCipher(Key key, boolean encrypt) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { - Cipher cipher = Cipher.getInstance(KEY_ALGO); - cipher.init(encrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE,key); - return cipher; - } - - public static byte[] strip(Reader rdr) throws IOException { - BufferedReader br = new BufferedReader(rdr); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - String line; - while((line=br.readLine())!=null) { - if(line.length()>0 && - !line.startsWith("-----") && - line.indexOf(':')<0) { // Header elements - baos.write(line.getBytes()); - } - } - return baos.toByteArray(); - } - - public static class StripperInputStream extends InputStream { - private Reader created; - private BufferedReader br; - private int idx; - private String line; - - public StripperInputStream(Reader rdr) { - if(rdr instanceof BufferedReader) { - br = (BufferedReader)rdr; - } else { - br = new BufferedReader(rdr); - } - created = null; - } - - public StripperInputStream(File file) throws FileNotFoundException { - this(new FileReader(file)); - created = br; - } - - public StripperInputStream(InputStream is) throws FileNotFoundException { - this(new InputStreamReader(is)); - created = br; - } - - @Override - public int read() throws IOException { - if(line==null || idx>=line.length()) { - while((line=br.readLine())!=null) { - if(line.length()>0 && - !line.startsWith("-----") && - line.indexOf(':')<0) { // Header elements - break; - } - } - - if(line==null) { - return -1; - } - idx = 0; - } - return line.charAt(idx++); - } - - /* (non-Javadoc) - * @see java.io.InputStream#close() - */ - @Override - public void close() throws IOException { - if(created!=null) { - created.close(); - } - } - } - - public static class Base64InputStream extends InputStream { - private InputStream created; - private InputStream is; - private byte trio[]; - private byte duo[]; - private int idx; - - - public Base64InputStream(File file) throws FileNotFoundException { - this(new FileInputStream(file)); - created = is; - } - - public Base64InputStream(InputStream is) throws FileNotFoundException { - this.is = is; - trio = new byte[3]; - idx = 4; - } - - @Override - public int read() throws IOException { - if(duo==null || idx>=duo.length) { - int read = is.read(trio); - if(read==-1) { - return -1; - } - duo = Symm.base64.decode(trio); - if(duo==null || duo.length==0) { - return -1; - } - idx=0; - } - - return duo[idx++]; - } - - /* (non-Javadoc) - * @see java.io.InputStream#close() - */ - @Override - public void close() throws IOException { - if(created!=null) { - created.close(); - } - } - } - - public static byte[] decode(byte[] bytes) throws IOException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Symm.base64.decode(bais, baos); - return baos.toByteArray(); - } - - public static byte[] decode(File f) throws IOException { - FileReader fr = new FileReader(f); - try { - return Factory.decode(fr); - } finally { - fr.close(); - } - - } - public static byte[] decode(Reader rdr) throws IOException { - return decode(strip(rdr)); - } - - - public static byte[] binary(File file) throws IOException { - DataInputStream dis = new DataInputStream(new FileInputStream(file)); - try { - byte[] bytes = new byte[(int)file.length()]; - dis.readFully(bytes); - return bytes; - } finally { - dis.close(); - } - } - - - public static byte[] sign(Trans trans, byte[] bytes, PrivateKey pk) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { - TimeTaken tt = trans.start("Sign Data", Env.SUB); - try { - Signature sig = Signature.getInstance(SIG_ALGO); - sig.initSign(pk, random); - sig.update(bytes); - return sig.sign(); - } finally { - tt.done(); - } - } - - public static String toSignatureString(byte[] signed) throws IOException { - return textBuilder("SIGNATURE", signed); - } - - public static boolean verify(Trans trans, byte[] bytes, byte[] signature, PublicKey pk) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { - TimeTaken tt = trans.start("Verify Data", Env.SUB); - try { - Signature sig = Signature.getInstance(SIG_ALGO); - sig.initVerify(pk); - sig.update(bytes); - return sig.verify(signature); - } finally { - tt.done(); - } - } -} diff --git a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifact.java b/aaf/src/main/java/com/att/cadi/cm/PlaceArtifact.java deleted file mode 100644 index 60434c3..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifact.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; - -import com.att.cadi.CadiException; -import com.att.inno.env.Trans; - -public interface PlaceArtifact { - public boolean place(Trans trans, CertInfo cert, Artifact arti) throws CadiException; -} diff --git a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInFiles.java b/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInFiles.java deleted file mode 100644 index c9145ec..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInFiles.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.File; - -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; - -import com.att.cadi.CadiException; -import com.att.cadi.util.Chmod; -import com.att.inno.env.Trans; - -public class PlaceArtifactInFiles extends ArtifactDir { - @Override - public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { - try { - // Setup Public Cert - File f = new File(dir,arti.getAppName()+".crt"); - write(f,Chmod.to644,certInfo.getCerts().get(0),C_R); - - // Setup Private Key - f = new File(dir,arti.getAppName()+".key"); - write(f,Chmod.to400,certInfo.getPrivatekey(),C_R); - - } catch (Exception e) { - throw new CadiException(e); - } - return true; - } -} - - diff --git a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInKeystore.java b/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInKeystore.java deleted file mode 100644 index 61374e9..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactInKeystore.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.File; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.Collection; - -import com.att.cadi.CadiException; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; -import com.att.cadi.util.Chmod; -import com.att.inno.env.Trans; - -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; - -public class PlaceArtifactInKeystore extends ArtifactDir { - private String kst; - //TODO get ROOT DNs or Trusted DNs from Certificate Manager. -// private static String[] rootDNs = new String[]{ -// "CN=ATT CADI Root CA - Test, O=ATT, OU=CSO, C=US", // Lab. delete eventually -// "CN=ATT AAF CADI TEST CA, OU=CSO, O=ATT, C=US", -// "CN=ATT AAF CADI CA, OU=CSO, O=ATT, C=US" -// }; - - public PlaceArtifactInKeystore(String kst) { - this.kst = kst; - } - - @Override - public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { - File fks = new File(dir,arti.getAppName()+'.'+kst); - try { - KeyStore jks = KeyStore.getInstance(kst); - if(fks.exists()) { - fks.delete(); - } - - // Get the Cert(s)... Might include Trust store - Collection certColl = Factory.toX509Certificate(certInfo.getCerts()); - X509Certificate[] certs = new X509Certificate[certColl.size()]; - certColl.toArray(certs); - - - // Add CADI Keyfile Entry to Properties - addProperty(Config.CADI_KEYFILE,arti.getDir()+'/'+arti.getAppName() + ".keyfile"); - // Set Keystore Password - addProperty(Config.CADI_KEYSTORE,fks.getAbsolutePath()); - String keystorePass = Symm.randomGen(CmAgent.PASS_SIZE); - addEncProperty(Config.CADI_KEYSTORE_PASSWORD,keystorePass); - char[] keystorePassArray = keystorePass.toCharArray(); - jks.load(null,keystorePassArray); // load in - - // Add Private Key/Cert Entry for App - // Note: Java SSL security classes, while having a separate key from keystore, - // is documented to not actually work. - // java.security.UnrecoverableKeyException: Cannot recover key - // You can create a custom Key Manager to make it work, but Practicality - // dictates that you live with the default, meaning, they are the same - String keyPass = keystorePass; //Symm.randomGen(CmAgent.PASS_SIZE); - PrivateKey pk = Factory.toPrivateKey(trans, certInfo.getPrivatekey()); - addEncProperty(Config.CADI_KEY_PASSWORD, keyPass); - addProperty(Config.CADI_ALIAS, arti.getMechid()); -// Set attribs = new HashSet(); -// if(kst.equals("pkcs12")) { -// // Friendly Name -// attribs.add(new PKCS12Attribute("1.2.840.113549.1.9.20", arti.getAppName())); -// } -// - KeyStore.ProtectionParameter protParam = - new KeyStore.PasswordProtection(keyPass.toCharArray()); - - KeyStore.PrivateKeyEntry pkEntry = - new KeyStore.PrivateKeyEntry(pk, new Certificate[] {certs[0]}); - jks.setEntry(arti.getMechid(), - pkEntry, protParam); - - // Write out - write(fks,Chmod.to400,jks,keystorePassArray); - - // Change out to TrustStore - fks = new File(dir,arti.getAppName()+".trust."+kst); - jks = KeyStore.getInstance(kst); - - // Set Truststore Password - addProperty(Config.CADI_TRUSTSTORE,fks.getAbsolutePath()); - String trustStorePass = Symm.randomGen(CmAgent.PASS_SIZE); - addEncProperty(Config.CADI_TRUSTSTORE_PASSWORD,trustStorePass); - char[] truststorePassArray = trustStorePass.toCharArray(); - jks.load(null,truststorePassArray); // load in - - // Add Trusted Certificates - for(int i=1; i0) { - trans.info().printf("Warning: %s\n",capi.getNotes()); - } - out.printf("Challenge: %s\n",capi.getChallenge()); - out.printf("PrivateKey:\n%s\n",capi.getPrivatekey()); - out.println("Certificate Chain:"); - for(String c : capi.getCerts()) { - out.println(c); - } - return true; - } -} diff --git a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactScripts.java b/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactScripts.java deleted file mode 100644 index 714b233..0000000 --- a/aaf/src/main/java/com/att/cadi/cm/PlaceArtifactScripts.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.cm; - -import java.io.File; - -import com.att.cadi.CadiException; -import com.att.cadi.util.Chmod; -import com.att.inno.env.Trans; -import com.att.inno.env.util.Chrono; -import com.att.inno.env.util.Split; - -import certman.v1_0.Artifacts.Artifact; -import certman.v1_0.CertInfo; - -public class PlaceArtifactScripts extends ArtifactDir { - @Override - public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { - try { - // Setup check.sh script - String filename = arti.getAppName()+".check.sh"; - File f1 = new File(dir,filename); - String email = arti.getNotification() + '\n'; - if(email.startsWith("mailto:")) { - email=email.substring(7); - } else { - email=arti.getOsUser() + '\n'; - } - - StringBuilder classpath = new StringBuilder(); - boolean first = true; - for(String pth : Split.split(File.pathSeparatorChar, System.getProperty("java.class.path"))) { - if(first) { - first=false; - } else { - classpath.append(File.pathSeparatorChar); - } - File f = new File(pth); - classpath.append(f.getCanonicalPath().replaceAll("[0-9]+\\.[0-9]+\\.[0-9]+","*")); - } - - write(f1,Chmod.to644, - "#!/bin/bash " + f1.getCanonicalPath()+'\n', - "# Certificate Manager Check Script\n", - "# Check on Certificate, and renew if needed.\n", - "# Generated by Certificate Manager " + Chrono.timeStamp()+'\n', - "DIR="+arti.getDir()+'\n', - "APP="+arti.getAppName()+'\n', - "EMAIL="+email, - "CP=\""+classpath.toString()+"\"\n", - checkScript - ); - - // Setup check.sh script - File f2 = new File(dir,arti.getAppName()+".crontab.sh"); - write(f2,Chmod.to644, - "#!/bin/bash " + f1.getCanonicalPath()+'\n', - "# Certificate Manager Crontab Loading Script\n", - "# Add/Update a Crontab entry, that adds a check on Certificate Manager generated Certificate nightly.\n", - "# Generated by Certificate Manager " + Chrono.timeStamp()+'\n', - "TFILE=\"/tmp/cmcron$$.temp\"\n", - "DIR=\""+arti.getDir()+"\"\n", - "CF=\""+arti.getAppName()+" Certificate Check Script\"\n", - "SCRIPT=\""+f1.getCanonicalPath()+"\"\n", - cronScript - ); - - } catch (Exception e) { - throw new CadiException(e); - } - return true; - } - - private final static String checkScript = - "> $DIR/$APP.msg\n\n" + - "function mailit {\n" + - " printf \"$*\" | /bin/mail -s \"AAF Certman Notification for `uname -n`\" $EMAIL\n"+ - "}\n\n" + - System.getProperty("java.home") + "/bin/" +"java -cp $CP " + - CmAgent.class.getName() + - " cadi_prop_files=$DIR/$APP.props check 2> $DIR/$APP.STDERR > $DIR/$APP.STDOUT\n" + - "case \"$?\" in\n" + - " 0)\n" + - " # Note: Validation will be mailed only the first day after any modification\n" + - " if [ \"`find $DIR -mtime 0 -name $APP.check.sh`\" != \"\" ] ; then\n" + - " mailit `echo \"Certficate Validated:\\n\\n\" | cat - $DIR/$APP.msg`\n" + - " else\n" + - " cat $DIR/$APP.msg\n" + - " fi\n" + - " ;;\n" + - " 1) mailit \"Error with Certificate Check:\\\\n\\\\nCheck logs $DIR/$APP.STDOUT and $DIR/$APP.STDERR on `uname -n`\"\n" + - " ;;\n" + - " 2) mailit `echo \"Certificate Check Error\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + - " ;;\n" + - " 10) mailit `echo \"Certificate Replaced\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + - " if [ -e $DIR/$APP.restart.sh ]; then\n" + - " # Note: it is THIS SCRIPT'S RESPONSIBILITY to notify upon success or failure as necessary!!\n" + - " /bin/sh $DIR/$APP.restart.sh\n" + - " fi\n" + - " ;;\n" + - " *) mailit `echo \"Unknown Error code for CM Agent\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + - " ;;\n" + - " esac\n\n" + - " # Note: make sure to cover this sripts' exit Code\n"; - - private final static String cronScript = - "crontab -l | sed -n \"/#### BEGIN $CF/,/END $CF ####/!p\" > $TFILE\n" + - "# Note: Randomize Minutes (0-60) and hours (1-4)\n" + - "echo \"#### BEGIN $CF ####\" >> $TFILE\n" + - "echo \"$(( $RANDOM % 60)) $(( $(( $RANDOM % 3 )) + 1 )) * * * /bin/bash $SCRIPT " + - ">> $DIR/cronlog 2>&1 \" >> $TFILE\n" + - "echo \"#### END $CF ####\" >> $TFILE\n" + - "crontab $TFILE\n" + - "rm $TFILE\n"; -} - - - diff --git a/aaf/src/main/java/com/att/cadi/sso/AAFSSO.java b/aaf/src/main/java/com/att/cadi/sso/AAFSSO.java deleted file mode 100644 index 4f66dd2..0000000 --- a/aaf/src/main/java/com/att/cadi/sso/AAFSSO.java +++ /dev/null @@ -1,285 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.sso; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import com.att.cadi.Access.Level; -import com.att.cadi.CadiException; -import com.att.cadi.PropAccess; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; -import com.att.cadi.util.MyConsole; -import com.att.cadi.util.SubStandardConsole; -import com.att.cadi.util.TheConsole; - - -public class AAFSSO { - public static final MyConsole cons = TheConsole.implemented()?new TheConsole():new SubStandardConsole(); - - private Properties diskprops = null; // use for temp storing User/Password on disk - private File dot_aaf = null, sso=null; // instantiated, if ever, with diskprops - - boolean removeSSO=false; - boolean loginOnly = false; - private PropAccess access; - private StringBuilder err; - private String user,encrypted_pass; - private boolean use_X509; - - private PrintStream os, stdout=null,stderr=null; - - private Method close; - - public AAFSSO(String[] args) throws IOException, CadiException { - List larg = new ArrayList(args.length); - - // Cover for bash's need to escape *... (\\*) - // also, remove SSO if required - for (int i = 0; i < args.length; ++i) { - if ("\\*".equals(args[i])) { - args[i] = "*"; - } - - if("-logout".equalsIgnoreCase(args[i])) { - removeSSO=true; - } else if("-login".equalsIgnoreCase(args[i])) { - loginOnly = true; - } else { - larg.add(args[i]); - } - } - - String[] nargs = new String[larg.size()]; - larg.toArray(nargs); - - dot_aaf = new File(System.getProperty("user.home")+"/.aaf"); - if(!dot_aaf.exists()) { - dot_aaf.mkdirs(); - } - File f = new File(dot_aaf,"sso.out"); - os = new PrintStream(new FileOutputStream(f,true)); - stdout = System.out; - stderr = System.err; - System.setOut(os); - System.setErr(os); - - access = new PropAccess(os,nargs); - Config.setDefaultRealm(access); - - user = access.getProperty(Config.AAF_MECHID); - encrypted_pass = access.getProperty(Config.AAF_MECHPASS); - - File dot_aaf_kf = new File(dot_aaf,"keyfile"); - - sso = new File(dot_aaf,"sso.props"); - if(removeSSO) { - if(dot_aaf_kf.exists()) { - dot_aaf_kf.setWritable(true,true); - dot_aaf_kf.delete(); - } - if(sso.exists()) { - sso.delete(); - } - System.out.println("AAF SSO information removed"); - System.exit(0); - } - - if(!dot_aaf_kf.exists()) { - FileOutputStream fos = new FileOutputStream(dot_aaf_kf); - try { - fos.write(Symm.encrypt.keygen()); - dot_aaf_kf.setExecutable(false,false); - dot_aaf_kf.setWritable(false,false); - dot_aaf_kf.setReadable(false,false); - dot_aaf_kf.setReadable(true, true); - } finally { - fos.close(); - } - } - - String keyfile = access.getProperty(Config.CADI_KEYFILE); // in case it's CertificateMan props - if(keyfile==null) { - access.setProperty(Config.CADI_KEYFILE, dot_aaf_kf.getAbsolutePath()); - } - - String alias = access.getProperty(Config.CADI_ALIAS); - if(user==null && alias!=null && access.getProperty(Config.CADI_KEYSTORE_PASSWORD)!=null) { - user = alias; - access.setProperty(Config.AAF_MECHID, user); - use_X509 = true; - } else { - use_X509 = false; - Symm decryptor = Symm.obtain(dot_aaf_kf); - if (user==null) { - if(sso.exists() && sso.lastModified()>System.currentTimeMillis()-(8*60*60*1000 /* 8 hours */)) { - String cm_url = access.getProperty(Config.CM_URL); // SSO might overwrite... - FileInputStream fos = new FileInputStream(sso); - try { - access.load(fos); - user = access.getProperty(Config.AAF_MECHID); - encrypted_pass = access.getProperty(Config.AAF_MECHPASS); - // decrypt with .aaf, and re-encrypt with regular Keyfile - access.setProperty(Config.AAF_MECHPASS, - access.encrypt(decryptor.depass(encrypted_pass))); - if(cm_url!=null) { //Command line CM_URL Overwrites ssofile. - access.setProperty(Config.CM_URL, cm_url); - } - } finally { - fos.close(); - } - } else { - diskprops = new Properties(); - String realm = Config.getDefaultRealm(); - // Turn on Console Sysout - System.setOut(stdout); - user=cons.readLine("aaf_id(%s@%s): ",System.getProperty("user.name"),realm); - if(user==null) { - user = System.getProperty("user.name")+'@'+realm; - } else if(user.length()==0) { // - user = System.getProperty("user.name")+'@' + realm; - } else if(user.indexOf('@')<0 && realm!=null) { - user = user+'@'+realm; - } - access.setProperty(Config.AAF_MECHID,user); - diskprops.setProperty(Config.AAF_MECHID,user); - encrypted_pass = new String(cons.readPassword("aaf_password: ")); - System.setOut(os); - encrypted_pass = Symm.ENC+decryptor.enpass(encrypted_pass); - access.setProperty(Config.AAF_MECHPASS,encrypted_pass); - diskprops.setProperty(Config.AAF_MECHPASS,encrypted_pass); - diskprops.setProperty(Config.CADI_KEYFILE, access.getProperty(Config.CADI_KEYFILE)); - } - } - } - if (user == null) { - err = new StringBuilder("Add -D" + Config.AAF_MECHID + "= "); - } - - if (encrypted_pass == null && alias==null) { - if (err == null) { - err = new StringBuilder(); - } else { - err.append("and "); - } - err.append("-D" + Config.AAF_MECHPASS + "= "); - } - } - - public void setLogDefault() { - access.setLogLevel(PropAccess.DEFAULT); - if(stdout!=null) { - System.setOut(stdout); - } - } - - public void setStdErrDefault() { - access.setLogLevel(PropAccess.DEFAULT); - if(stderr!=null) { - System.setErr(stderr); - } - } - - public void setLogDefault(Level level) { - access.setLogLevel(level); - if(stdout!=null) { - System.setOut(stdout); - } - } - - public boolean loginOnly() { - return loginOnly; - } - - public void addProp(String key, String value) { - if(diskprops!=null) { - diskprops.setProperty(key, value); - } - } - - public void writeFiles() throws IOException { - // Store Creds, if they work - if(diskprops!=null) { - if(!dot_aaf.exists()) { - dot_aaf.mkdirs(); - } - FileOutputStream fos = new FileOutputStream(sso); - try { - diskprops.store(fos, "AAF Single Signon"); - } finally { - fos.close(); - sso.setWritable(false,false); - sso.setExecutable(false,false); - sso.setReadable(false,false); - sso.setReadable(true,true); - } - } - if(sso!=null) { - sso.setReadable(false,false); - sso.setWritable(false,false); - sso.setExecutable(false,false); - sso.setReadable(true,true); - sso.setWritable(true,true); - } - } - - public PropAccess access() { - return access; - } - - public StringBuilder err() { - return err; - } - - public String user() { - return user; - } - - public String enc_pass() { - return encrypted_pass; - } - - public boolean useX509() { - return use_X509; - } - - public void close() { - if(close!=null) { - try { - close.invoke(null); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - // nothing to do here. - } - close = null; - } - } -} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java new file mode 100644 index 0000000..7cefc26 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFPermission.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf; + +import org.onap.aaf.cadi.Permission; + +/** + * A Class that understands the AAF format of Permission (name/type/action) + * or String "name|type|action" + * + * + */ +public class AAFPermission implements Permission { + protected String type,instance,action,key; + + protected AAFPermission() {} + + public AAFPermission(String type, String instance, String action) { + this.type = type; + this.instance = instance; + this.action = action; + key = type + '|' + instance + '|' + action; + } + + /** + * Match a Permission + * if Permission is Fielded type "Permission", we use the fields + * otherwise, we split the Permission with '|' + * + * when the type or action starts with REGEX indicator character ( ! ), + * then it is evaluated as a regular expression. + * + * If you want a simple field comparison, it is faster without REGEX + */ + public boolean match(Permission p) { + if(p instanceof AAFPermission) { + AAFPermission ap = (AAFPermission)p; + // Note: In AAF > 1.0, Accepting "*" from name would violate multi-tenancy + // Current solution is only allow direct match on Type. + // 8/28/2014 - added REGEX ability + if(type.equals(ap.getName())) + if(PermEval.evalInstance(instance,ap.getInstance())) + if(PermEval.evalAction(action,ap.getAction())) + return true; + } else { + // Permission is concatenated together: separated by | + String[] aaf = p.getKey().split("[\\s]*\\|[\\s]*",3); + if(aaf.length>0 && type.equals(aaf[0])) + if(PermEval.evalInstance(instance,aaf.length>1?aaf[1]:"*")) + if(PermEval.evalAction(action,aaf.length>2?aaf[2]:"*")) + return true; + } + return false; + } + + public String getName() { + return type; + } + + public String getInstance() { + return instance; + } + + public String getAction() { + return action; + } + + public String getKey() { + return key; + } + + /* (non-Javadoc) + * @see com.att.cadi.Permission#permType() + */ + public String permType() { + return "AAF"; + } + + public String toString() { + return "AAFPermission:\n\tType: " + type + + "\n\tInstance: " + instance + + "\n\tAction: " + action + + "\n\tKey: " + key; + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFTransmutate.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFTransmutate.java new file mode 100644 index 0000000..2d1b88f --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/AAFTransmutate.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf; + +import java.security.Principal; +import java.util.regex.Pattern; + +import org.onap.aaf.cadi.Transmutate; +import org.onap.aaf.cadi.lur.ConfigPrincipal; +import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.principal.CSPPrincipal_T; + +/** + * AAFTransmutate + * + * Each System determines the mechanisms for which one Principal is transmutated to another, such as whether it is created + * independently, etc. + * + * For AAF, the only important thing is that these are valid ATTUID/mechIDs, to avoid unnecessary user hits + * + * attUIDs look like ab1234 or AB1234 or AZ123a + * mechids look like m12345 + * + * + */ +public final class AAFTransmutate implements Transmutate { + private Pattern pattern = Pattern.compile("[a-zA-Z]\\w\\d\\d\\d\\w"); + + public Principal mutate(Principal p) { + // Accept these three internal kinds of Principals + if(p instanceof CSPPrincipal_T + || p instanceof BasicPrincipal + || p instanceof ConfigPrincipal) { + return p; + } else { + + final String name = p.getName(); + final int idx = name.indexOf('@'); + String shortName; + if(idx>0) { // strip off any domain + shortName = name.substring(0,idx); + } else { + shortName = name; + } + + // Check for ATTUID specs before creating CSP_T + return pattern.matcher(shortName).matches()? + new CSP_T(name): // Note: use REAL name, short name for CSP_T + null; + } + } + + /** + * Essential Principal reflecting CSP Principal + * + * + */ + private final class CSP_T implements CSPPrincipal_T { + private String name; + public CSP_T(String name) { + this.name = name; + } + public String getName() { + return name; + } + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/ConnectivityTest.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/ConnectivityTest.java new file mode 100644 index 0000000..daac0c3 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/ConnectivityTest.java @@ -0,0 +1,459 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf; + +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.Field; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.UnknownHostException; +import java.util.Date; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.aaf.v2_0.AAFCon; +import org.onap.aaf.cadi.aaf.v2_0.AAFConDME2; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.http.HBasicAuthSS; +import org.onap.aaf.cadi.http.HClient; +import org.onap.aaf.cadi.http.HX509SS; +import org.onap.aaf.cadi.locator.DME2Locator; +import org.onap.aaf.cadi.locator.PropertyLocator; + +import com.att.aft.dme2.api.DME2Client; +import com.att.aft.dme2.api.DME2Manager; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.rosetta.env.RosettaDF; +import org.onap.aaf.rosetta.env.RosettaEnv; + +import aaf.v2_0.Perms; + +public class ConnectivityTest { + private static final String PROD = "PROD"; + private static final String SRV_RESOLVE = "https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=%s/routeOffer=%s"; + private static final String GW_RESOLVE = "https://DME2RESOLVE/service=com.att.authz.authz-gw/version=2.0/envContext=%s/routeOffer=%s"; + + public static void main(String[] args) { + if(args.length<2) { + System.out.println("Usage: ConnectivityTester "); + } else { + print(true,"START OF CONNECTIVITY TESTS",new Date().toString(),System.getProperty("user.name"), + "Note: All API Calls are /authz/perms/user/"); + + final String aaf_env = args[0]; + args[1]=Config.CADI_PROP_FILES+'='+args[1]; + + PropAccess pa = new PropAccess(args); + String user = pa.getProperty(Config.AAF_MECHID); + String pass = pa.getProperty(Config.AAF_MECHPASS); + String alias = pa.getProperty(Config.CADI_ALIAS); + if(user==null) { + user=alias; + } + RosettaEnv env = new RosettaEnv(pa.getProperties()); + + try { + RosettaDF permsDF = env.newDataFactory(Perms.class); + SecurityInfoC si = new SecurityInfoC(pa); + HBasicAuthSS hbass = new HBasicAuthSS(pa,si); + if(hbass.getID()==null) { + hbass=null; // not configured with ID. + } + HX509SS hxss=null; + AAFCon aafcon; + + try { + hxss = new HX509SS(user,si); + } catch(Exception e) { + e.printStackTrace(); + print(false,"Continuing"); + } + String aafurl; + if(user==null || (pass==null && alias==null)) { + System.out.printf("ERROR: DME2 Client cannot be tested with out %s and %s properties" + , Config.AAF_MECHID, Config.AAF_MECHPASS ); + } else { + if("TEST".equals(aaf_env) || "IST".equals(aaf_env) || "PROD".equals(aaf_env)) { + DME2Manager dm = null; + print(false,"Attempt DME2Manager Load"); + if(Class.forName("com.att.aft.dme2.api.DME2Manager")==null) { + print(true,"DME2 jar is not available: Skipping DME2 Tests"); + } else { // DME2 Client Tests + pass=pa.decrypt(pass,false); + // Out of the box DME2 + aafurl = String.format(SRV_RESOLVE, aaf_env, PROD.equals(aaf_env)?"DEFAULT":"BAU_SE"); + print(true,"TEST CADI Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + print(true,"Find and TEST Connections with DME2Locator",aafurl); + DME2Locator dl = new DME2Locator(pa,dm,aafurl); + connectTest(dl); + + dm = new DME2Manager("DME2Manager",pa.getProperties()); + + dme2RawTest(dm, aafurl,user,pass); + + // URL specific Variant + if((aafurl = specificDME2URL(dl, aafurl))!=null) { + print(true,"TEST Specific DME2 CADI Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + dme2RawTest(dm,aafurl,user,pass); + } + + print(true,"CADI Direct AAFConDME2 Object Usage",aafurl); + try { + pa.setProperty(Config.AAF_URL,aafurl); + aafcon = new AAFConDME2(pa); + test(aafcon,permsDF,user); + } catch(Throwable t) { + t.printStackTrace(); + } + + // find a direct client to code a Direct HTTP with + // + if(hbass!=null) { + print(true,"CADI Http DME2Locator Client Coding Methodology BasicAuth",aafurl); + hClientTest(dl,hbass,user); + } + if(hxss!=null) { + print(true,"CADI Http DME2Locator Client Coding Methodology X509",aafurl); + hClientTest(dl,hxss,user); + } + + // ##### PROXY CHECKS + aafurl = String.format(GW_RESOLVE, aaf_env, PROD.equals(aaf_env)?"DEFAULT":"BAU_SE"); + print(true,"TEST PROXY DME2 CADI Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + + dme2RawTest(dm, aafurl,user,pass); + + // URL specific Variant + dl = new DME2Locator(pa,dm,aafurl); + if((aafurl = specificDME2URL(dl, aafurl))!=null) { + print(true,"TEST PROXY Specific DME2 CADI Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + dme2RawTest(dm,aafurl,user,pass); + } + } + } + + // Prop Locator + PropertyLocator pl = servicePropLocator(aaf_env); + connectTest(pl); + URI uri = pl.get(pl.best()); + if(uri!=null) { + aafurl = uri.toString(); + print(true,"TEST Service PropertyLocator based Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + if(hbass!=null) { + print(true,"CADI Service Http PropLocator Client Coding Methodology Basic Auth",aafurl); + hClientTest(pl,hbass, user); + print(true,"CADI Service Http PropLocator Client Coding Methodology /authn/basicAuth",aafurl); + basicAuthTest(pl,hbass); + } + if(hxss!=null) { + print(true,"CADI Service Http PropLocator Client Coding Methodology X509",aafurl); + hClientTest(pl,hxss, user); + } + } + pl = proxyPropLocator(aaf_env); + connectTest(pl); + uri = pl.get(pl.best()); + if(uri!=null) { + aafurl = uri.toString(); + print(true,"TEST PROXY PropertyLocator based Config",aafurl); + aafcon = testConfig(pa,aafurl); + test(aafcon,permsDF,user); + + if(hbass!=null) { + print(true,"CADI PROXY Http PropLocator Client Coding Methodology Basic Auth",aafurl); + hClientTest(pl,hbass, user); + print(true,"CADI PROXY Http PropLocator Client Coding Methodology /proxy/authn/basicAuth",aafurl); + basicAuthTest(pl,hbass); + } + if(hxss!=null) { + print(true,"CADI PROXY Http PropLocator Client Coding Methodology X509",aafurl); + hClientTest(pl,hxss, user); + } + } + } + + } catch(Exception e) { + e.printStackTrace(System.err); + } finally { + print(true,"END OF TESTS"); + } + } + } + + private static void print(Boolean strong, String ... args) { + PrintStream out = System.out; + out.println(); + if(strong) { + for(int i=0;i<70;++i) { + out.print('='); + } + out.println(); + } + for(String s : args) { + out.print(strong?"== ":"------ "); + out.print(s); + if(!strong) { + out.print(" ------"); + } + out.println(); + } + if(strong) { + for(int i=0;i<70;++i) { + out.print('='); + } + } + out.println(); + } + + private static void test(AAFCon aafcon,RosettaDF permsDF,String user) { + if(aafcon==null) { + print(false,"AAFCon is null"); + } else { + try { + print(false,"Calling with AAFCon"); + Future fp = aafcon.client("2.0").read("/authz/perms/user/"+user, Perms.class, permsDF); + if(fp.get(4000)) { + System.out.printf("Found %d Permission(s)\n",fp.value.getPerm().size()); + } else { + System.out.printf("Error: %d %s\n",fp.code(),fp.body()); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + private static AAFCon testConfig(PropAccess pa, String aafurl) { + try { + pa.setProperty(Config.AAF_URL, aafurl); + Lur lur = Config.configLur(pa); + Config.configHttpTaf(pa, TrustChecker.NOTRUST, null, lur); + if(lur != null) { + Field f = null; + try { + f = lur.getClass().getField("aaf"); + return (AAFCon)f.get(lur); + } catch (Exception nsfe) { + } + } + + } catch(Throwable t) { + t.printStackTrace(); + } + return null; + } + + private static String specificDME2URL(Locator loc, String aafurl) throws LocatorException { + Item item = loc.best(); + if(item!=null) { + URI uri = loc.get(item); + return aafurl.replace("DME2RESOLVE", String.format("%s:%d",uri.getHost(),uri.getPort())); + } + return null; + } + + private static void connectTest(Locator dl) throws LocatorException { + URI uri; + Socket socket; + print(false,"TCP/IP Connect test to all Located Services"); + for(Item li = dl.first();li!=null;li=dl.next(li)) { + if((uri = dl.get(li)) == null) { + System.out.println("Locator Item empty"); + } else { + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(uri.getHost(), uri.getPort()),3000); + System.out.printf("Can Connect a Socket to %s %d\n",uri.getHost(),uri.getPort()); + try { + socket.close(); + } catch (IOException e1) { + System.out.printf("Could not close Socket Connection: %s\n",e1.getMessage()); + } + } catch (IOException e) { + System.out.printf("Cannot Connect a Socket to %s %d: %s\n",uri.getHost(),uri.getPort(),e.getMessage()); + } + } + } + } + + private static PropertyLocator servicePropLocator(String env) throws LocatorException { + String purls; + switch(env) { + case "LOCAL": + try { + purls="https://"+InetAddress.getLocalHost().getHostName()+":8100"; + } catch (UnknownHostException e) { + throw new LocatorException(e); + } + break; + case "DEV": + purls="https://aaf.dev.att.com:8100,https://aaf.dev.att.com:8101"; + break; + case "TEST": + purls="https://aaftest.test.att.com:8100,https://aaftest.test.att.com:8101"; + break; + case "IST": + purls="https://aafist.test.att.com:8100,https://aafist.test.att.com:8101"; + break; + case PROD: + purls="https://aaf.it.att.com:8100,https://aaf.it.att.com:8101"; + break; + default: + if(env.contains(".")) { + purls="https://"+env+":8100"; + } else { + throw new LocatorException(ConnectivityTest.class.getSimpleName() + ": unknown Env"); + } + } + System.out.printf("Creating a PropertyLocator for %s\n",purls); + return new PropertyLocator(purls); + } + + private static PropertyLocator proxyPropLocator(String env) throws LocatorException { + String purls; + switch(env) { + case "LOCAL": + try { + purls="https://"+InetAddress.getLocalHost().getHostAddress()+":8100"; + } catch (UnknownHostException e) { + throw new LocatorException(e); + } + break; + case "DEV": + purls="https://aaf.dev.att.com:8095/proxy"; + break; + case "TEST": + purls="https://aaftest.test.att.com:8095/proxy"; + break; + case "IST": + purls="https://aafist.test.att.com:8095/proxy"; + break; + case PROD: + purls="https://aaf.it.att.com:8095/proxy"; + break; + default: + if(env.contains(".")) { + purls="https://"+env+":8095/proxy"; + } else { + throw new LocatorException(ConnectivityTest.class.getSimpleName() + ": unknown Env"); + } + + } + System.out.printf("Creating a PropertyLocator for %s\n",purls); + return new PropertyLocator(purls); + } + + + + + private static void hClientTest(Locator dl, SecuritySetter ss, String user) { + try { + URI uri = dl.get(dl.best()); + System.out.println("Resolved to: " + uri); + HClient client = new HClient(ss, uri, 3000); + client.setMethod("GET"); + client.setPathInfo("/authz/perms/user/"+user); + client.send(); + Future future = client.futureReadString(); + if(future.get(7000)) { + System.out.println(future.body()); + } else { + System.out.println(future.code() + ":" + future.body()); + } + } catch (CadiException | LocatorException | APIException e) { + e.printStackTrace(); + } + } + + + private static void basicAuthTest(PropertyLocator dl, SecuritySetter ss) { + try { + URI uri = dl.get(dl.best()); + System.out.println("Resolved to: " + uri); + HClient client = new HClient(ss, uri, 3000); + client.setMethod("GET"); + client.setPathInfo("/authn/basicAuth"); + client.addHeader("Accept", "text/plain"); + client.send(); + + + Future future = client.futureReadString(); + if(future.get(7000)) { + System.out.println("BasicAuth Validated"); + } else { + System.out.println("Failure " + future.code() + ":" + future.body()); + } + } catch (CadiException | LocatorException | APIException e) { + e.printStackTrace(); + } + } + + // Regular DME2Client Coding Style + private static void dme2RawTest(DME2Manager dm, String aafurl, String user, String pass) { + try { + if(dm==null) { + return; + } + URI uri = new URI(aafurl); + print(true,"DME2 Direct Client Coding Methodology",uri.toString()); + DME2Client client = dm.newClient( uri, 3000); + client.setMethod("GET"); // FYI, DME2 defaults to "POST" + client.setContext("/authz/perms/user/"+user); // DME2 direct requires separate setting of Context from URI + if(pass!=null) { // rely on Cert if no pass + client.setCredentials(user, pass); + } + client.setPayload(""); // DME2 will not send without something + String resp = client.sendAndWait(7000); + System.out.println(resp); + } catch(Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java new file mode 100644 index 0000000..896d153 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/PermEval.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf; + +import org.onap.aaf.inno.env.util.Split; + + +public class PermEval { + public static final char START_REGEX_CHAR = '!'; + public static final char START_INST_KEY_CHAR=':'; + public static final char ALT_START_INST_KEY_CHAR='/'; + + public static final char LIST_SEP = ','; + public static final String INST_KEY_REGEX = new StringBuilder().append(START_INST_KEY_CHAR).toString(); + public static final String ASTERIX = "*"; + + /** + * Evaluate Instance + * + * Instance can be more complex. It can be a string, a Regular Expression, or a ":" separated Key + * who's parts can also be a String, Regular Expression. + * + * sInst = Server's Instance + * In order to prevent false matches, keys must be the same length to count as equal + * Changing this will break existing users, like Cassandra. 9-4-2015 + */ + public static boolean evalInstance(String sInst, String pInst) { + if(sInst==null || pInst == null) { + return false; + } + if(ASTERIX.equals(sInst)) { + return true; // If Server's String is "*", then it accepts every Instance + } + char firstChar = pInst.charAt(0); + char startChar = firstChar==ALT_START_INST_KEY_CHAR?ALT_START_INST_KEY_CHAR:START_INST_KEY_CHAR; + switch(pInst.charAt(0)) { // First char + case START_REGEX_CHAR: // Evaluate as Regular Expression + String pItem = pInst.substring(1); + for(String sItem : Split.split(LIST_SEP,sInst)) { // allow for "," definition in Action + return sItem.matches(pItem); + } + + case START_INST_KEY_CHAR: // Evaluate a special Key field, i.e.:xyz:*:!df.* + case ALT_START_INST_KEY_CHAR: // Also allow '/' as special Key Field, i.e. /xyz/*/!.* + if(sInst.charAt(0)==startChar) { // To compare key-to-key, both strings must be keys + String[] skeys=Split.split(startChar,sInst); + String[] pkeys=Split.split(startChar,pInst); + if(skeys.length!=pkeys.length) return false; + + boolean pass = true; + for(int i=1;pass && i certs = null; + + // Did this to add other Trust Mechanisms + // Trust mechanism set by Property: + private static final String[] authMechanisms = new String[] {"tguard","basicAuth","csp"}; + private static String[] certIDs; + + private static Map> trusted =null; + + public AAFListedCertIdentity(Access access, AAFCon aafcon) throws APIException { + synchronized(AAFListedCertIdentity.class) { + if(certIDs==null) { + String cip = access.getProperty(Config.AAF_CERT_IDS, null); + if(cip!=null) { + certIDs = Split.split(',',cip); + } + } + if(certIDs!=null && certs==null) { + TimerTask cu = new CertUpdate(aafcon); + cu.run(); // want this to run in this thread first... + new Timer("AAF Identity Refresh Timer",true).scheduleAtFixedRate(cu, EIGHT_HOURS,EIGHT_HOURS); + } + } + } + + public static Set trusted(String authMech) { + return trusted.get(authMech); + } + + public Principal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException { + if(cert==null && certBytes==null)return null; + if(certBytes==null)certBytes = cert.getEncoded(); + byte[] fingerprint = X509Taf.getFingerPrint(certBytes); + String id = certs.get(new ByteArrayHolder(fingerprint)); + if(id!=null) { // Caller is Validated + return new X509Principal(id,cert,certBytes); + } + return null; + } + + private static class ByteArrayHolder implements Comparable { + private byte[] ba; + public ByteArrayHolder(byte[] ba) { + this.ba = ba; + } + public int compareTo(ByteArrayHolder b) { + return Hash.compareTo(ba, b.ba); + } + } + + private class CertUpdate extends TimerTask { + + private AAFCon aafcon; + public CertUpdate(AAFCon con) { + aafcon = con; + } + + @Override + public void run() { + try { + TreeMap newCertsMap = new TreeMap(); + Map> newTrustMap = new TreeMap>(); + Set userLookup = new HashSet(); + for(String s : certIDs) { + userLookup.add(s); + } + for(String authMech : authMechanisms) { + Future fusr = aafcon.client(AAF_VERSION).read("/authz/users/perm/org.onap.aaf.trust/"+authMech+"/authenticate", Users.class, aafcon.usersDF); + if(fusr.get(5000)) { + List users = fusr.value.getUser(); + if(users.isEmpty()) { + aafcon.access.log(Level.WARN, "AAF Lookup-No IDs in Role com.att.aaf.trustForID <> "+authMech); + } else { + aafcon.access.log(Level.INFO,"Loading Trust Authentication Info for",authMech); + Set hsUser = new HashSet(); + for(User u : users) { + userLookup.add(u.getId()); + hsUser.add(u.getId()); + } + newTrustMap.put(authMech,hsUser); + } + } else { + aafcon.access.log(Level.WARN, "Could not get Users in Perm com.att.trust|tguard|authenticate",fusr.code(),fusr.body()); + } + + } + + for(String u : userLookup) { + Future fc = aafcon.client(AAF_VERSION).read("/authn/cert/id/"+u, Certs.class, aafcon.certsDF); + XMLGregorianCalendar now = Chrono.timeStamp(); + if(fc.get(5000)) { + List certs = fc.value.getCert(); + if(certs.isEmpty()) { + aafcon.access.log(Level.WARN, "No Cert Associations for",u); + } else { + for(Cert c : fc.value.getCert()) { + XMLGregorianCalendar then =c.getExpires(); + if(then !=null && then.compare(now)>0) { + newCertsMap.put(new ByteArrayHolder(c.getFingerprint()), c.getId()); + aafcon.access.log(Level.INIT,"Associating "+ c.getId() + " expiring " + Chrono.dateOnlyStamp(c.getExpires()) + " with " + c.getX500()); + } + } + } + } else { + aafcon.access.log(Level.WARN, "Could not get Certificates for",u); + } + } + + certs = newCertsMap; + trusted = newTrustMap; + } catch(Exception e) { + aafcon.access.log(e, "Failure to update Certificate Identities from AAF"); + } + } + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java new file mode 100644 index 0000000..c49113d --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/ErrMessage.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.client; + +import java.io.PrintStream; + +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.util.Vars; + +import aaf.v2_0.Error; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.rosetta.env.RosettaDF; +import org.onap.aaf.rosetta.env.RosettaEnv; + +public class ErrMessage { + private RosettaDF errDF; + + public ErrMessage(RosettaEnv env) throws APIException { + errDF = env.newDataFactory(Error.class); + } + + /** + * AT&T Requires a specific Error Format for RESTful Services, which AAF complies with. + * + * This code will create a meaningful string from this format. + * + * @param ps + * @param df + * @param r + * @throws APIException + */ + public void printErr(PrintStream ps, String attErrJson) throws APIException { + StringBuilder sb = new StringBuilder(); + Error err = errDF.newData().in(TYPE.JSON).load(attErrJson).asObject(); + ps.println(toMsg(sb,err)); + } + + /** + * AT&T Requires a specific Error Format for RESTful Services, which AAF complies with. + * + * This code will create a meaningful string from this format. + * + * @param sb + * @param df + * @param r + * @throws APIException + */ + public StringBuilder toMsg(StringBuilder sb, String attErrJson) throws APIException { + return toMsg(sb,errDF.newData().in(TYPE.JSON).load(attErrJson).asObject()); + } + + public StringBuilder toMsg(Future future) { + return toMsg(new StringBuilder(),future); + } + + public StringBuilder toMsg(StringBuilder sb, Future future) { + try { + toMsg(sb,errDF.newData().in(TYPE.JSON).load(future.body()).asObject()); + } catch(Exception e) { + //just print what we can + sb.append(future.code()); + sb.append(": "); + sb.append(future.body()); + } + return sb; + } + + public StringBuilder toMsg(StringBuilder sb, Error err) { + sb.append(err.getMessageId()); + sb.append(' '); + String[] vars = new String[err.getVariables().size()]; + err.getVariables().toArray(vars); + Vars.convert(sb, err.getText(),vars); + return sb; + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/Examples.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/Examples.java new file mode 100644 index 0000000..8867862 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/client/Examples.java @@ -0,0 +1,444 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.client; + + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.GregorianCalendar; + +import aaf.v2_0.Approval; +import aaf.v2_0.Approvals; +import aaf.v2_0.CredRequest; +import aaf.v2_0.Keys; +import aaf.v2_0.NsRequest; +import aaf.v2_0.Nss; +import aaf.v2_0.Nss.Ns; +import aaf.v2_0.Perm; +import aaf.v2_0.PermKey; +import aaf.v2_0.PermRequest; +import aaf.v2_0.Perms; +import aaf.v2_0.Pkey; +import aaf.v2_0.Request; +import aaf.v2_0.Role; +import aaf.v2_0.RoleKey; +import aaf.v2_0.RolePermRequest; +import aaf.v2_0.RoleRequest; +import aaf.v2_0.Roles; +import aaf.v2_0.UserRole; +import aaf.v2_0.UserRoleRequest; +import aaf.v2_0.UserRoles; +import aaf.v2_0.Users; +import aaf.v2_0.Users.User; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data; +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.inno.env.util.Chrono; +import org.onap.aaf.rosetta.env.RosettaDF; +import org.onap.aaf.rosetta.env.RosettaEnv; + +public class Examples { + public static String print(RosettaEnv env, String nameOrContentType, boolean optional) throws APIException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { + // Discover ClassName + String className = null; + String version = null; + TYPE type = TYPE.JSON; // default + if(nameOrContentType.startsWith("application/")) { + for(String ct : nameOrContentType.split("\\s*,\\s*")) { + for(String elem : ct.split("\\s*;\\s*")) { + if(elem.endsWith("+json")) { + type = TYPE.JSON; + className = elem.substring(elem.indexOf('/')+1, elem.length()-5); + } else if(elem.endsWith("+xml")) { + type = TYPE.XML; + className = elem.substring(elem.indexOf('/')+1, elem.length()-4); + } else if(elem.startsWith("version=")) { + version = elem.substring(8); + } + } + if(className!=null && version!=null)break; + } + if(className==null) { + throw new APIException(nameOrContentType + " does not contain Class Information"); + } + } else { + className = nameOrContentType; + } + + // No Void.class in aaf.v2_0 package causing errors when trying to use a newVoidv2_0 + // method similar to others in this class. This makes it work, but is it right? + if ("Void".equals(className)) return ""; + + if("1.1".equals(version)) { + version = "v1_0"; + } else if(version!=null) { + version = "v" + version.replace('.', '_'); + } else { + version = "v2_0"; + } + + Class cls; + try { + cls = Examples.class.getClassLoader().loadClass("aaf."+version+'.'+className); + } catch (ClassNotFoundException e) { + throw new APIException(e); + } + + Method meth; + try { + meth = Examples.class.getDeclaredMethod("new"+cls.getSimpleName()+version,boolean.class); + } catch (Exception e) { + throw new APIException("ERROR: " + cls.getName() + " does not have an Example in Code. Request from AAF Developers"); + } + + RosettaDF df = env.newDataFactory(cls); + df.option(Data.PRETTY); + + Object data = meth.invoke(null,optional); + + @SuppressWarnings("unchecked") + String rv = df.newData().load((C)data).out(type).asString(); +// Object obj = df.newData().in(type).load(rv).asObject(); + return rv; + } + + /* + * Set Base Class Request (easier than coding over and over) + */ + private static void setOptional(Request req) { + GregorianCalendar gc = new GregorianCalendar(); + req.setStart(Chrono.timeStamp(gc)); + gc.add(GregorianCalendar.MONTH, 6); + req.setEnd(Chrono.timeStamp(gc)); +// req.setForce("false"); + + } + + @SuppressWarnings("unused") + private static Request newRequestv2_0(boolean optional) { + Request r = new Request(); + setOptional(r); + return r; + } + @SuppressWarnings("unused") + private static RolePermRequest newRolePermRequestv2_0(boolean optional) { + RolePermRequest rpr = new RolePermRequest(); + Pkey pkey = new Pkey(); + pkey.setType("com.att.myns.mytype"); + pkey.setInstance("myInstance"); + pkey.setAction("myAction"); + rpr.setPerm(pkey); + rpr.setRole("com.att.myns.myrole"); + if(optional)setOptional(rpr); + return rpr; + } + + @SuppressWarnings("unused") + private static Roles newRolesv2_0(boolean optional) { + Role r; + Pkey p; + Roles rs = new Roles(); + rs.getRole().add(r = new Role()); + r.setName("com.att.myns.myRole"); + r.getPerms().add(p = new Pkey()); + p.setType("com.att.myns.myType"); + p.setInstance("myInstance"); + p.setAction("myAction"); + + r.getPerms().add(p = new Pkey()); + p.setType("com.att.myns.myType"); + p.setInstance("myInstance"); + p.setAction("myOtherAction"); + + rs.getRole().add(r = new Role()); + r.setName("com.att.myns.myOtherRole"); + r.getPerms().add(p = new Pkey()); + p.setType("com.att.myns.myOtherType"); + p.setInstance("myInstance"); + p.setAction("myAction"); + + r.getPerms().add(p = new Pkey()); + p.setType("com.att.myns.myOthertype"); + p.setInstance("myInstance"); + p.setAction("myOtherAction"); + + return rs; + } + + + @SuppressWarnings("unused") + private static PermRequest newPermRequestv2_0(boolean optional) { + PermRequest pr = new PermRequest(); + pr.setType("com.att.myns.myType"); + pr.setInstance("myInstance"); + pr.setAction("myAction"); + if(optional) { + pr.setDescription("Short and meaningful verbiage about the Permission"); + + setOptional(pr); + } + return pr; + } + + @SuppressWarnings("unused") + private static Perm newPermv2_0(boolean optional) { + Perm pr = new Perm(); + pr.setType("com.att.myns.myType"); + pr.setInstance("myInstance"); + pr.setAction("myAction"); + pr.getRoles().add("com.att.myns.myRole"); + pr.getRoles().add("com.att.myns.myRole2"); + pr.setDescription("This is my description, and I'm sticking with it"); + if(optional) { + pr.setDescription("Short and meaningful verbiage about the Permission"); + } + return pr; + } + + + @SuppressWarnings("unused") + private static PermKey newPermKeyv2_0(boolean optional) { + PermKey pr = new PermKey(); + pr.setType("com.att.myns.myType"); + pr.setInstance("myInstance"); + pr.setAction("myAction"); + return pr; + } + + @SuppressWarnings("unused") + private static Perms newPermsv2_0(boolean optional) { + Perms perms = new Perms(); + Perm p; + perms.getPerm().add(p=new Perm()); + p.setType("com.att.myns.myType"); + p.setInstance("myInstance"); + p.setAction("myAction"); + p.getRoles().add("com.att.myns.myRole"); + p.getRoles().add("com.att.myns.myRole2"); + + + perms.getPerm().add(p=new Perm()); + p.setType("com.att.myns.myOtherType"); + p.setInstance("myInstance"); + p.setAction("myOtherAction"); + p.getRoles().add("com.att.myns.myRole"); + p.getRoles().add("com.att.myns.myRole2"); + + return perms; + + } + + @SuppressWarnings("unused") + private static UserRoleRequest newUserRoleRequestv2_0(boolean optional) { + UserRoleRequest urr = new UserRoleRequest(); + urr.setRole("com.att.myns.myRole"); + urr.setUser("ab1234@csp.att.com"); + if(optional) setOptional(urr); + return urr; + } + + @SuppressWarnings("unused") + private static NsRequest newNsRequestv2_0(boolean optional) { + NsRequest nr = new NsRequest(); + nr.setName("com.att.myns"); + nr.getResponsible().add("ab1234@csp.att.com"); + nr.getResponsible().add("cd5678@csp.att.com"); + nr.getAdmin().add("zy9876@csp.att.com"); + nr.getAdmin().add("xw5432@csp.att.com"); + if(optional) { + nr.setDescription("This is my Namespace to set up"); + nr.setType("APP"); + setOptional(nr); + } + return nr; + } + + + @SuppressWarnings("unused") + private static Nss newNssv2_0(boolean optional) { + Ns ns; + + Nss nss = new Nss(); + nss.getNs().add(ns = new Nss.Ns()); + ns.setName("com.att.myns"); + ns.getResponsible().add("ab1234@csp.att.com"); + ns.getResponsible().add("cd5678@csp.att.com"); + ns.getAdmin().add("zy9876@csp.att.com"); + ns.getAdmin().add("xw5432@csp.att.com"); + ns.setDescription("This is my Namespace to set up"); + + nss.getNs().add(ns = new Nss.Ns()); + ns.setName("com.att.myOtherNs"); + ns.getResponsible().add("ab1234@csp.att.com"); + ns.getResponsible().add("cd5678@csp.att.com"); + ns.getAdmin().add("zy9876@csp.att.com"); + ns.getAdmin().add("xw5432@csp.att.com"); + + return nss; + } + @SuppressWarnings("unused") + private static RoleRequest newRoleRequestv2_0(boolean optional) { + RoleRequest rr = new RoleRequest(); + rr.setName("com.att.myns.myRole"); + if(optional) { + rr.setDescription("This is my Role"); + setOptional(rr); + } + return rr; + } + + @SuppressWarnings("unused") + private static CredRequest newCredRequestv2_0(boolean optional) { + CredRequest cr = new CredRequest(); + cr.setId("myID@fully.qualified.domain"); + if(optional) { + cr.setType(2); + cr.setEntry("0x125AB256344CE"); + } else { + cr.setPassword("This is my provisioned password"); + } + + return cr; + } + + @SuppressWarnings("unused") + private static Users newUsersv2_0(boolean optional) { + User user; + + Users users = new Users(); + users.getUser().add(user = new Users.User()); + user.setId("ab1234@csp.att.com"); + GregorianCalendar gc = new GregorianCalendar(); + user.setExpires(Chrono.timeStamp(gc)); + + users.getUser().add(user = new Users.User()); + user.setId("zy9876@csp.att.com"); + user.setExpires(Chrono.timeStamp(gc)); + + return users; + } + + @SuppressWarnings("unused") + private static Role newRolev2_0(boolean optional) { + Role r = new Role(); + Pkey p; + r.setName("com.att.myns.myRole"); + r.getPerms().add(p = new Pkey()); + p.setType("com.att.myns.myType"); + p.setInstance("myInstance"); + p.setAction("myAction"); + + return r; + } + + @SuppressWarnings("unused") + private static RoleKey newRoleKeyv2_0(boolean optional) { + RoleKey r = new RoleKey(); + Pkey p; + r.setName("com.att.myns.myRole"); + return r; + } + + @SuppressWarnings("unused") + private static Keys newKeysv2_0(boolean optional) { + Keys ks = new Keys(); + ks.getKey().add("Reponse 1"); + ks.getKey().add("Response 2"); + return ks; + } + + @SuppressWarnings("unused") + private static UserRoles newUserRolesv2_0(boolean optional) { + UserRoles urs = new UserRoles(); + UserRole ur = new UserRole(); + ur.setUser("xy1234"); + ur.setRole("com.test.myapp.myRole"); + ur.setExpires(Chrono.timeStamp()); + urs.getUserRole().add(ur); + + ur = new UserRole(); + ur.setUser("yx4321"); + ur.setRole("com.test.yourapp.yourRole"); + ur.setExpires(Chrono.timeStamp()); + urs.getUserRole().add(ur); + return urs; + } + + + @SuppressWarnings("unused") + private static Approvals newApprovalsv2_0(boolean optional) { + Approvals as = new Approvals(); + Approval a = new Approval(); + a.setApprover("MyApprover"); + a.setId("MyID"); + a.setMemo("My memo (and then some)"); + a.setOperation("MyOperation"); + a.setStatus("MyStatus"); + a.setTicket("MyTicket"); + a.setType("MyType"); + a.setUpdated(Chrono.timeStamp()); + a.setUser("MyUser"); + as.getApprovals().add(a); + a = new Approval(); + a.setApprover("MyApprover2"); + a.setId("MyID2"); + a.setMemo("My memo (and then some)2"); + a.setOperation("MyOperation2"); + a.setStatus("MyStatus2"); + a.setTicket("MyTicket2"); + a.setType("MyType2"); + a.setUpdated(Chrono.timeStamp()); + a.setUser("MyUser2"); + as.getApprovals().add(a); + return as; + } + + @SuppressWarnings("unused") + private static Approval newApprovalv2_0(boolean optional) { + Approval a = new Approval(); + a.setApprover("MyApprover"); + a.setId("MyID"); + a.setMemo("My memo (and then some)"); + a.setOperation("MyOperation"); + a.setStatus("MyStatus"); + a.setTicket("MyTicket"); + a.setType("MyType"); + a.setUpdated(Chrono.timeStamp()); + a.setUser("MyUser"); + return a; + } + + + + @SuppressWarnings("unused") + private static aaf.v2_0.Error newErrorv2_0(boolean optional) { + aaf.v2_0.Error err = new aaf.v2_0.Error(); + err.setMessageId("SVC1403"); + err.setText("MyText %s, %s: The last three digits are usually the HTTP Code"); + err.getVariables().add("Variable 1"); + err.getVariables().add("Variable 2"); + return err; + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertMarshal.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertMarshal.java new file mode 100644 index 0000000..8871969 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertMarshal.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.marshal; + +import javax.xml.datatype.XMLGregorianCalendar; + +import aaf.v2_0.Certs.Cert; + +import org.onap.aaf.rosetta.marshal.FieldDateTime; +import org.onap.aaf.rosetta.marshal.FieldHexBinary; +import org.onap.aaf.rosetta.marshal.FieldString; +import org.onap.aaf.rosetta.marshal.ObjMarshal; + +public class CertMarshal extends ObjMarshal { + public CertMarshal() { + add(new FieldHexBinary("fingerprint") { + @Override + protected byte[] data(Cert t) { + return t.getFingerprint(); + } + }); + + add(new FieldString("id") { + @Override + protected String data(Cert t) { + return t.getId(); + } + }); + + add(new FieldString("x500") { + @Override + protected String data(Cert t) { + return t.getX500(); + } + }); + + add(new FieldDateTime("expires") { + @Override + protected XMLGregorianCalendar data(Cert t) { + return t.getExpires(); + } + }); + + + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertsMarshal.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertsMarshal.java new file mode 100644 index 0000000..70a1c96 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/marshal/CertsMarshal.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.marshal; + +import java.util.List; + +import aaf.v2_0.Certs; +import aaf.v2_0.Certs.Cert; + +import org.onap.aaf.rosetta.marshal.ObjArray; +import org.onap.aaf.rosetta.marshal.ObjMarshal; + +public class CertsMarshal extends ObjMarshal { + + public CertsMarshal() { + add(new ObjArray("cert",new CertMarshal()) { + @Override + protected List data(Certs t) { + return t.getCert(); + } + }); + } + + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java new file mode 100644 index 0000000..6d6d947 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFAuthn.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.io.IOException; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.GetCred; +import org.onap.aaf.cadi.Hash; +import org.onap.aaf.cadi.User; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.lur.ConfigPrincipal; + +import com.att.aft.dme2.api.DME2Exception; +import org.onap.aaf.inno.env.APIException; + +public class AAFAuthn extends AbsUserCache { + private AAFCon con; + private String realm; + + /** + * Configure with Standard AAF properties, Stand alone + * @param con + * @throws Exception + */ + // Package on purpose + AAFAuthn(AAFCon con) throws Exception { + super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount); + this.con = con; + + try { + setRealm(); + } catch (APIException e) { + if(e.getCause() instanceof DME2Exception) { + // Can't contact AAF, assume default + realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); + } + } + } + + /** + * Configure with Standard AAF properties, but share the Cache (with AAF Lur) + * @param con + * @throws Exception + */ + // Package on purpose + AAFAuthn(AAFCon con, AbsUserCache cache) throws Exception { + super(cache); + this.con = con; + try { + setRealm(); + } catch (Exception e) { + if(e.getCause() instanceof DME2Exception) { + access.log(e); + // Can't contact AAF, assume default + realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm()); + } + } + } + + private void setRealm() throws Exception { + // Make a call without security set to get the 401 response, which + // includes the Realm of the server + // This also checks on Connectivity early on. + Future fp = con.client(AAFCon.AAF_LATEST_VERSION).read("/authn/basicAuth", "text/plain"); + if(fp.get(con.timeout)) { + throw new Exception("Do not preset Basic Auth Information for AAFAuthn"); + } else { + if(fp.code()==401) { + realm = fp.header("WWW-Authenticate"); + if(realm!=null && realm.startsWith("Basic realm=\"")) { + realm = realm.substring(13, realm.length()-1); + } else { + realm = "unknown.com"; + } + } + } + } + + /** + * Return Native Realm of AAF Instance. + * + * @return + */ + public String getRealm() { + return realm; + } + + /** + * Returns null if ok, or an Error String; + * + * @param user + * @param password + * @return + * @throws IOException + * @throws CadiException + * @throws Exception + */ + public String validate(String user, String password) throws IOException, CadiException { + User usr = getUser(user); + if(password.startsWith("enc:???")) { + password = access.decrypt(password, true); + } + + byte[] bytes = password.getBytes(); + if(usr != null && usr.principal != null && usr.principal.getName().equals(user) + && usr.principal instanceof GetCred) { + + if(Hash.isEqual(((GetCred)usr.principal).getCred(),bytes)) { + return null; + } else { + remove(usr); + usr = null; + } + } + + AAFCachedPrincipal cp = new AAFCachedPrincipal(this,con.app, user, bytes, con.cleanInterval); + // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch + // Statement + switch(cp.revalidate()) { + case REVALIDATED: + if(usr!=null) { + usr.principal = cp; + } else { + addUser(new User(cp,con.timeout)); + } + return null; + case INACCESSIBLE: + return "AAF Inaccessible"; + case UNVALIDATED: + return "User/Pass combo invalid for " + user; + case DENIED: + return "AAF denies API for " + user; + default: + return "AAFAuthn doesn't handle Principal " + user; + } + } + + private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal { + private long expires,timeToLive; + + public AAFCachedPrincipal(AAFAuthn aaf, String app, String name, byte[] pass, int timeToLive) { + super(name,pass); + this.timeToLive = timeToLive; + expires = timeToLive + System.currentTimeMillis(); + } + + public Resp revalidate() { + if(con.isDisabled()) { + return Resp.DENIED; + } + try { + Miss missed = missed(getName()); + if(missed==null || missed.mayContinue(getCred())) { + Rcli client = con.client(AAFCon.AAF_LATEST_VERSION).forUser(con.basicAuth(getName(), new String(getCred()))); + Future fp = client.read( + "/authn/basicAuth", + "text/plain" + ); + if(fp.get(con.timeout)) { + expires = System.currentTimeMillis() + timeToLive; + addUser(new User(this, expires)); + return Resp.REVALIDATED; + } else { + addMiss(getName(), getCred()); + return Resp.UNVALIDATED; + } + } else { + return Resp.UNVALIDATED; + } + } catch (Exception e) { + con.access.log(e); + return Resp.INACCESSIBLE; + } + } + + public long expires() { + return expires; + } + }; + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java new file mode 100644 index 0000000..3ec6fed --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFCon.java @@ -0,0 +1,396 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.net.URI; +import java.security.Principal; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Connector; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.marshal.CertsMarshal; +import org.onap.aaf.cadi.client.AbsBasicAuth; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.util.Vars; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.inno.env.util.Split; +import org.onap.aaf.rosetta.env.RosettaDF; +import org.onap.aaf.rosetta.env.RosettaEnv; + +import aaf.v2_0.Certs; +import aaf.v2_0.Error; +import aaf.v2_0.Perms; +import aaf.v2_0.Users; + +public abstract class AAFCon implements Connector { + public static final String AAF_LATEST_VERSION = "2.0"; + + final public PropAccess access; + // Package access + final public int timeout, cleanInterval, connTimeout; + final public int highCount, userExpires, usageRefreshTriggerCount; + private Map> clients = new ConcurrentHashMap>(); + final public RosettaDF permsDF; + final public RosettaDF certsDF; + final public RosettaDF usersDF; + final public RosettaDF errDF; + private String realm; + public final String app; + protected SecuritySetter ss; + protected SecurityInfoC si; + + private DisableCheck disableCheck; + + private AAFLurPerm lur; + + private RosettaEnv env; + protected abstract URI initURI(); + protected abstract void setInitURI(String uriString) throws CadiException; + + /** + * Use this call to get the appropriate client based on configuration (DME2, HTTP, future) + * + * @param apiVersion + * @return + * @throws CadiException + */ + public Rcli client(String apiVersion) throws CadiException { + Rcli client = clients.get(apiVersion); + if(client==null) { + client = rclient(initURI(),ss); + client.apiVersion(apiVersion) + .readTimeout(connTimeout); + clients.put(apiVersion, client); + } + return client; + } + + /** + * Use this API when you have permission to have your call act as the end client's ID. + * + * Your calls will get 403 errors if you do not have this permission. it is a special setup, rarely given. + * + * @param apiVersion + * @param req + * @return + * @throws CadiException + */ + public Rcli clientAs(String apiVersion, ServletRequest req) throws CadiException { + Rcli cl = client(apiVersion); + return cl.forUser(transferSS(((HttpServletRequest)req).getUserPrincipal())); + } + + protected AAFCon(AAFCon copy) { + access = copy.access; + timeout = copy.timeout; + cleanInterval = copy.cleanInterval; + connTimeout = copy.connTimeout; + highCount = copy.highCount; + userExpires = copy.userExpires; + usageRefreshTriggerCount = copy.usageRefreshTriggerCount; + permsDF = copy.permsDF; + certsDF = copy.certsDF; + usersDF = copy.usersDF; + errDF = copy.errDF; + app = copy.app; + ss = copy.ss; + si = copy.si; + env = copy.env; + disableCheck = copy.disableCheck; + realm = copy.realm; + } + + protected AAFCon(PropAccess access, String tag, SecurityInfoC si) throws CadiException{ + if(tag==null) { + throw new CadiException("AAFCon cannot be constructed with a tag=null"); + } + try { + this.access = access; + this.si = si; + this.ss = si.defSS; + if(ss==null) { + String mechid = access.getProperty(Config.AAF_MECHID, null); + String encpass = access.getProperty(Config.AAF_MECHPASS, null); + if(encpass==null) { + String alias = access.getProperty(Config.CADI_ALIAS, mechid); + if(alias==null) { + throw new CadiException(Config.CADI_ALIAS + " or " + Config.AAF_MECHID + " required."); + } + set(si.defSS=x509Alias(alias)); + } else { + if(mechid!=null && encpass !=null) { + set(si.defSS=basicAuth(mechid, encpass)); + } else { + set(si.defSS=new SecuritySetter() { + + @Override + public String getID() { + return ""; + } + + @Override + public void setSecurity(CLIENT client) throws CadiException { + throw new CadiException("AAFCon has not been initialized with Credentials (SecuritySetter)"); + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } + }); + } + } + } + + timeout = Integer.parseInt(access.getProperty(Config.AAF_READ_TIMEOUT, Config.AAF_READ_TIMEOUT_DEF)); + cleanInterval = Integer.parseInt(access.getProperty(Config.AAF_CLEAN_INTERVAL, Config.AAF_CLEAN_INTERVAL_DEF)); + highCount = Integer.parseInt(access.getProperty(Config.AAF_HIGH_COUNT, Config.AAF_HIGH_COUNT_DEF).trim()); + connTimeout = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF).trim()); + userExpires = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim()); + usageRefreshTriggerCount = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim())-1; // zero based + + String str = access.getProperty(tag,null); + if(str==null) { + throw new CadiException(tag + " property is required."); + } + setInitURI(str); + + app=reverseDomain(ss.getID()); + realm="openecomp.org"; + + env = new RosettaEnv(); + permsDF = env.newDataFactory(Perms.class); + usersDF = env.newDataFactory(Users.class); + certsDF = env.newDataFactory(Certs.class); + certsDF.rootMarshal(new CertsMarshal()); // Speedier Marshaling + errDF = env.newDataFactory(Error.class); + } catch (APIException e) { + throw new CadiException("AAFCon cannot be configured",e); + } + } + + public RosettaEnv env() { + return env; + } + + /** + * Return the backing AAFCon, if there is a Lur Setup that is AAF. + * + * If there is no AAFLur setup, it will return "null" + * @param servletRequest + * @return + */ + public static final AAFCon obtain(Object servletRequest) { + if(servletRequest instanceof CadiWrap) { + Lur lur = ((CadiWrap)servletRequest).getLur(); + if(lur != null) { + if(lur instanceof EpiLur) { + AbsAAFLur aal = (AbsAAFLur) ((EpiLur)lur).subLur(AbsAAFLur.class); + if(aal!=null) { + return aal.aaf; + } + } else { + if(lur instanceof AbsAAFLur) { + return ((AbsAAFLur)lur).aaf; + } + } + } + } + return null; + } + + public abstract AAFCon clone(String url) throws CadiException; + + public AAFAuthn newAuthn() throws APIException { + try { + return new AAFAuthn(this); + } catch (APIException e) { + throw e; + } catch (Exception e) { + throw new APIException(e); + } + } + + public AAFAuthn newAuthn(AbsUserCache c) throws APIException { + try { + return new AAFAuthn(this,c); + } catch (APIException e) { + throw e; + } catch (Exception e) { + throw new APIException(e); + } + } + + public AAFLurPerm newLur() throws CadiException { + try { + if(lur==null) { + return new AAFLurPerm(this); + } else { + return new AAFLurPerm(this,lur); + } + } catch (CadiException e) { + throw e; + } catch (Exception e) { + throw new CadiException(e); + } + } + + public AAFLurPerm newLur(AbsUserCache c) throws APIException { + try { + return new AAFLurPerm(this,c); + } catch (APIException e) { + throw e; + } catch (Exception e) { + throw new APIException(e); + } + } + + /** + * Take a Fully Qualified User, and get a Namespace from it. + * @param user + * @return + */ + public static String reverseDomain(String user) { + StringBuilder sb = null; + String[] split = Split.split('.',user); + 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(); + } + + protected abstract Rcli rclient(URI uri, SecuritySetter ss) throws CadiException; + + public abstract RET best(Retryable retryable) throws LocatorException, CadiException, APIException; + + + public abstract SecuritySetter basicAuth(String user, String password) throws CadiException; + + public abstract SecuritySetter transferSS(Principal principal) throws CadiException; + + public abstract SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException; + + public abstract SecuritySetter x509Alias(String alias) throws APIException, CadiException; + + + public String getRealm() { + return realm; + + } + + public SecuritySetter set(final SecuritySetter ss) { + this.ss = ss; + if(ss instanceof AbsBasicAuth) { + disableCheck = (ss instanceof AbsBasicAuth)? + new DisableCheck() { + AbsBasicAuth aba = (AbsBasicAuth)ss; + @Override + public boolean isDisabled() { + return aba.isDenied(); + } + }: + new DisableCheck() { + @Override + public boolean isDisabled() { + return this.isDisabled(); + } + }; + } + for(Rcli client : clients.values()) { + client.setSecuritySetter(ss); + } + return ss; + } + + public SecurityInfoC securityInfo() { + return si; + } + + public String defID() { + if(ss!=null) { + return ss.getID(); + } + return "unknown"; + } + + public void invalidate() throws CadiException { + for(Rcli client : clients.values()) { + client.invalidate(); + clients.remove(client); + } + } + + public String readableErrMsg(Future f) { + String text = f.body(); + if(text==null || text.length()==0) { + text = f.code() + ": **No Message**"; + } else if(text.contains("%")) { + try { + Error err = errDF.newData().in(TYPE.JSON).load(f.body()).asObject(); + return Vars.convert(err.getText(),err.getVariables()); + } catch (APIException e){ + // just return the body below + } + } + return text; + } + + private interface DisableCheck { + public boolean isDisabled(); + }; + + public boolean isDisabled() { + return disableCheck.isDisabled(); + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConDME2.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConDME2.java new file mode 100644 index 0000000..2757efc --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConDME2.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.GeneralSecurityException; +import java.security.Principal; +import java.util.Properties; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.dme2.DME2BasicAuth; +import org.onap.aaf.cadi.dme2.DME2TransferSS; +import org.onap.aaf.cadi.dme2.DME2x509SS; +import org.onap.aaf.cadi.dme2.DRcli; +import org.onap.aaf.cadi.principal.BasicPrincipal; + +import com.att.aft.dme2.api.DME2Client; +import com.att.aft.dme2.api.DME2Exception; +import com.att.aft.dme2.api.DME2Manager; +import org.onap.aaf.inno.env.APIException; + +public class AAFConDME2 extends AAFCon{ + private DME2Manager manager; + private boolean isProxy; + private URI initURI; + + public AAFConDME2(PropAccess access) throws CadiException, GeneralSecurityException, IOException{ + super(access,Config.AAF_URL,new SecurityInfoC (access)); + manager = newManager(access); + setIsProxy(); + } + + public AAFConDME2(PropAccess access, String url) throws CadiException, GeneralSecurityException, IOException{ + super(access,url,new SecurityInfoC (access)); + manager = newManager(access); + setIsProxy(); + } + + public AAFConDME2(PropAccess access, SecurityInfoC si) throws CadiException { + super(access,Config.AAF_URL,si); + manager = newManager(access); + setIsProxy(); + } + + public AAFConDME2(PropAccess access, String url, SecurityInfoC si) throws CadiException { + super(access,url,si); + manager = newManager(access); + setIsProxy(); + } + + /** + * Construct a Connector based on the AAF one. This is for remote access to OTHER than AAF, + * but using Credentials, etc + */ + private AAFConDME2(AAFCon aafcon, String url) throws CadiException { + super(aafcon); + try { + initURI = new URI(url); + } catch (URISyntaxException e) { + throw new CadiException(e); + } + manager = newManager(access); + } + + /** + * Create a Connector based on the AAF one. This is for remote access to OTHER than AAF, + * but using Credentials, etc + */ + public AAFCon clone(String url) throws CadiException { + return new AAFConDME2(this,url); + } + + private void setIsProxy() { + String str; + if((str=access.getProperty(Config.AAF_URL, null))!=null) { + isProxy = str.contains("service=com.att.authz.authz-gw/version="); + } + } + + private DME2Manager newManager(PropAccess access) throws CadiException { + Properties props = access.getDME2Properties(); + // Critical that TLS Settings not ignored + try { + return new DME2Manager("AAFCon",props); + } catch (DME2Exception e) { + throw new CadiException(e); + } + } + + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String) + */ + @Override + public SecuritySetter basicAuth(String user, String password) throws CadiException { + if(password.startsWith("enc:???")) { + try { + password = access.decrypt(password, true); + } catch (IOException e) { + throw new CadiException("Error Decrypting Password",e); + } + } + + try { + return set(new DME2BasicAuth(user,password,si)); + } catch (IOException e) { + throw new CadiException("Error setting up DME2BasicAuth",e); + } + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter) + */ + @Override + protected Rcli rclient(URI uri, SecuritySetter ss) { + DRcli dc = new DRcli(uri, ss); + dc.setProxy(isProxy); + dc.setManager(manager); + return dc; + } + + @Override + public SecuritySetter transferSS(Principal principal) throws CadiException { + try { + return principal==null?ss:new DME2TransferSS(principal, app, si); + } catch (IOException e) { + throw new CadiException("Error creating DME2TransferSS",e); + } + } + + @Override + public SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException { + try { + return new DME2BasicAuth(principal,si); + } catch (IOException e) { + throw new CadiException("Error creating DME2BasicAuth",e); + } + + } + + @Override + public SecuritySetter x509Alias(String alias) throws CadiException { + try { + presetProps(access, alias); + return new DME2x509SS(alias,si); + } catch (Exception e) { + throw new CadiException("Error creating DME2x509SS",e); + } + } + + @Override + public RET best(Retryable retryable) throws LocatorException, CadiException, APIException { + // NOTE: DME2 had Retry Logic embedded lower. + try { + return (retryable.code(rclient(initURI,ss))); + } catch (ConnectException e) { + // DME2 should catch + try { + manager.refresh(); + } catch (Exception e1) { + throw new CadiException(e1); + } + throw new CadiException(e); + } + } + + public static void presetProps(PropAccess access, String alias) throws IOException { + System.setProperty(Config.AFT_DME2_CLIENT_SSL_CERT_ALIAS, alias); + if(System.getProperty(Config.AFT_DME2_CLIENT_IGNORE_SSL_CONFIG)==null) { + access.getDME2Properties(); + } + + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#initURI() + */ + @Override + protected URI initURI() { + return initURI; + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#setInitURI(java.lang.String) + */ + @Override + protected void setInitURI(String uriString) throws CadiException { + try { + initURI = new URI(uriString); + } catch (URISyntaxException e) { + throw new CadiException(e); + } + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java new file mode 100644 index 0000000..5a38b0c --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFConHttp.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.security.GeneralSecurityException; +import java.security.Principal; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.client.AbsTransferSS; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.http.HBasicAuthSS; +import org.onap.aaf.cadi.http.HMangr; +import org.onap.aaf.cadi.http.HRcli; +import org.onap.aaf.cadi.http.HTransferSS; +import org.onap.aaf.cadi.http.HX509SS; +import org.onap.aaf.cadi.principal.BasicPrincipal; + +import org.onap.aaf.inno.env.APIException; + +public class AAFConHttp extends AAFCon { + private final HMangr hman; + + public AAFConHttp(PropAccess access) throws CadiException, GeneralSecurityException, IOException { + super(access,Config.AAF_URL,new SecurityInfoC(access)); + hman = new HMangr(access,Config.loadLocator(access, access.getProperty(Config.AAF_URL,null))); + } + + public AAFConHttp(PropAccess access, String tag) throws CadiException, GeneralSecurityException, IOException { + super(access,tag,new SecurityInfoC(access)); + hman = new HMangr(access,Config.loadLocator(access, access.getProperty(tag,null))); + } + + public AAFConHttp(PropAccess access, String urlTag, SecurityInfoC si) throws CadiException { + super(access,urlTag,si); + hman = new HMangr(access,Config.loadLocator(access, access.getProperty(urlTag,null))); + } + + public AAFConHttp(PropAccess access, Locator locator) throws CadiException, GeneralSecurityException, IOException { + super(access,Config.AAF_URL,new SecurityInfoC(access)); + hman = new HMangr(access,locator); + } + + public AAFConHttp(PropAccess access, Locator locator, SecurityInfoC si) throws CadiException { + super(access,Config.AAF_URL,si); + hman = new HMangr(access,locator); + } + + public AAFConHttp(PropAccess access, Locator locator, SecurityInfoC si, String tag) throws CadiException { + super(access,tag,si); + hman = new HMangr(access, locator); + } + + private AAFConHttp(AAFCon aafcon, String url) { + super(aafcon); + hman = new HMangr(aafcon.access,Config.loadLocator(access, url)); + } + + @Override + public AAFCon clone(String url) { + return new AAFConHttp(this,url); + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String) + */ + @Override + public SecuritySetter basicAuth(String user, String password) throws CadiException { + if(password.startsWith("enc:???")) { + try { + password = access.decrypt(password, true); + } catch (IOException e) { + throw new CadiException("Error decrypting password",e); + } + } + try { + return new HBasicAuthSS(user,password,si); + } catch (IOException e) { + throw new CadiException("Error creating HBasicAuthSS",e); + } + } + + public SecuritySetter x509Alias(String alias) throws APIException, CadiException { + try { + return set(new HX509SS(alias,si)); + } catch (Exception e) { + throw new CadiException("Error creating X509SS",e); + } + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter) + */ + @Override + protected Rcli rclient(URI ignoredURI, SecuritySetter ss) throws CadiException { + if(hman.loc==null) { + throw new CadiException("No Locator set in AAFConHttp"); + } + try { + return new HRcli(hman, hman.loc.best() ,ss); + } catch (Exception e) { + throw new CadiException(e); + } + } + + @Override + public AbsTransferSS transferSS(Principal principal) throws CadiException { + return new HTransferSS(principal, app,si); + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuthSS(java.security.Principal) + */ + @Override + public SecuritySetter basicAuthSS(BasicPrincipal principal) throws CadiException { + try { + return new HBasicAuthSS(principal,si); + } catch (IOException e) { + throw new CadiException("Error creating HBasicAuthSS",e); + } + } + + public HMangr hman() { + return hman; + } + + @Override + public RET best(Retryable retryable) throws LocatorException, CadiException, APIException { + return hman.best(ss, (Retryable)retryable); + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#initURI() + */ + @Override + protected URI initURI() { + try { + Item item = hman.loc.best(); + if(item!=null) { + return hman.loc.get(item); + } + } catch (LocatorException e) { + access.log(e, "Error in AAFConHttp obtaining initial URI"); + } + return null; + } + + /* (non-Javadoc) + * @see com.att.cadi.aaf.v2_0.AAFCon#setInitURI(java.lang.String) + */ + @Override + protected void setInitURI(String uriString) throws CadiException { + // TODO Auto-generated method stub + + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFLurPerm.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFLurPerm.java new file mode 100644 index 0000000..520d7ab --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFLurPerm.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.net.ConnectException; +import java.net.URISyntaxException; +import java.security.Principal; +import java.util.Map; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.User; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; +import org.onap.aaf.cadi.lur.LocalPermission; + +import com.att.aft.dme2.api.DME2Exception; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.util.Split; + +import aaf.v2_0.Perm; +import aaf.v2_0.Perms; + +/** + * Use AAF Service as Permission Service. + * + * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves. + * + * If you want a simple Role Lur, use AAFRoleLur + * + * + */ +public class AAFLurPerm extends AbsAAFLur { + /** + * Need to be able to transmutate a Principal into either ATTUID or MechID, which are the only ones accepted at this + * point by AAF. There is no "domain", aka, no "@att.com" in "ab1234@att.com". + * + * The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid. + * Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely + * @throws APIException + * @throws URISyntaxException + * @throws DME2Exception + */ + // Package on purpose + AAFLurPerm(AAFCon con) throws CadiException, DME2Exception, URISyntaxException, APIException { + super(con); + } + + // Package on purpose + AAFLurPerm(AAFCon con, AbsUserCache auc) throws DME2Exception, URISyntaxException, APIException { + super(con,auc); + } + + protected User loadUser(Principal p) { + // Note: The rules for AAF is that it only stores permissions for ATTUID and MechIDs, which don't + // have domains. We are going to make the Transitive Class (see this.transmutative) to convert + Principal principal = transmutate.mutate(p); + if(principal==null)return null; // if not a valid Transmutated credential, don't bother calling... + return loadUser(p, p.getName()); + } + + protected User loadUser(String name) { + return loadUser((Principal)null, name); + } + + private User loadUser(final Principal prin, final String name) { + + //TODO Create a dynamic way to declare domains supported. + final long start = System.nanoTime(); + final boolean[] success = new boolean[]{false}; + +// new Exception("loadUser").printStackTrace(); + try { + return aaf.best(new Retryable>() { + @Override + public User code(Rcli client) throws CadiException, ConnectException, APIException { + Future fp = client.read("/authz/perms/user/"+name,aaf.permsDF); + + // In the meantime, lookup User, create if necessary + User user = getUser(name); + Principal p; + if(prin == null) { + p = new Principal() {// Create a holder for lookups + private String n = name; + public String getName() { + return n; + } + }; + } else { + p = prin; + } + + if(user==null) { + addUser(user = new User(p,aaf.userExpires)); // no password + } + + // OK, done all we can, now get content + if(fp.get(aaf.timeout)) { + success[0]=true; + Map newMap = user.newMap(); + boolean willLog = aaf.access.willLog(Level.DEBUG); + for(Perm perm : fp.value.getPerm()) { + user.add(newMap,new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction())); + if(willLog) { + aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\''); + } + } + user.setMap(newMap); + user.renewPerm(); + } else { + int code; + switch(code=fp.code()) { + case 401: + aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls"); + break; + default: + aaf.access.log(Access.Level.ERROR, code, fp.body()); + } + } + + return user; + } + }); + } catch (Exception e) { + aaf.access.log(e,"Calling","/authz/perms/user/"+name); + success[0]=false; + return null; + } finally { + float time = (System.nanoTime()-start)/1000000f; + aaf.access.log(Level.INFO, success[0]?"Loaded":"Load Failure",name,"from AAF in",time,"ms"); + } + } + + public Resp reload(User user) { + final String name = user.principal.getName(); + long start = System.nanoTime(); + boolean success = false; + try { + Future fp = aaf.client(AAFCon.AAF_LATEST_VERSION).read( + "/authz/perms/user/"+name, + aaf.permsDF + ); + + // OK, done all we can, now get content + if(fp.get(aaf.timeout)) { + success = true; + Map newMap = user.newMap(); + boolean willLog = aaf.access.willLog(Level.DEBUG); + for(Perm perm : fp.value.getPerm()) { + user.add(newMap, new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction())); + if(willLog) { + aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction()); + } + } + user.renewPerm(); + return Resp.REVALIDATED; + } else { + int code; + switch(code=fp.code()) { + case 401: + aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls"); + break; + default: + aaf.access.log(Access.Level.ERROR, code, fp.body()); + } + return Resp.UNVALIDATED; + } + } catch (Exception e) { + aaf.access.log(e,"Calling","/authz/perms/user/"+name); + return Resp.INACCESSIBLE; + } finally { + float time = (System.nanoTime()-start)/1000000f; + aaf.access.log(Level.AUDIT, success?"Reloaded":"Reload Failure",name,"from AAF in",time,"ms"); + } + } + + @Override + protected boolean isCorrectPermType(Permission pond) { + return pond instanceof AAFPermission; + } + + /* (non-Javadoc) + * @see com.att.cadi.Lur#createPerm(java.lang.String) + */ + @Override + public Permission createPerm(String p) { + String[] params = Split.split('|', p); + if(params.length==3) { + return new AAFPermission(params[0],params[1],params[2]); + } else { + return new LocalPermission(p); + } + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java new file mode 100644 index 0000000..fb92108 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.io.IOException; +import java.security.Principal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.GetCred; +import org.onap.aaf.cadi.Hash; +import org.onap.aaf.cadi.User; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.Taf.LifeForm; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.principal.CachedBasicPrincipal; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; +import org.onap.aaf.cadi.taf.basic.BasicHttpTafResp; + +public class AAFTaf extends AbsUserCache implements HttpTaf { +// private static final String INVALID_AUTH_TOKEN = "Invalid Auth Token"; +// private static final String AUTHENTICATING_SERVICE_UNAVAILABLE = "Authenticating Service unavailable"; + private AAFCon aaf; + private boolean warn; + + public AAFTaf(AAFCon con, boolean turnOnWarning) { + super(con.access,con.cleanInterval,con.highCount, con.usageRefreshTriggerCount); + aaf = con; + warn = turnOnWarning; + } + + public AAFTaf(AAFCon con, boolean turnOnWarning, AbsUserCache other) { + super(other); + aaf = con; + warn = turnOnWarning; + } + + public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + //TODO Do we allow just anybody to validate? + + // Note: Either Carbon or Silicon based LifeForms ok + String authz = req.getHeader("Authorization"); + if(authz != null && authz.startsWith("Basic ")) { + if(warn&&!req.isSecure())aaf.access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel"); + try { + CachedBasicPrincipal bp; + if(req.getUserPrincipal() instanceof CachedBasicPrincipal) { + bp = (CachedBasicPrincipal)req.getUserPrincipal(); + } else { + bp = new CachedBasicPrincipal(this,authz,aaf.getRealm(),aaf.userExpires); + } + // First try Cache + User usr = getUser(bp); + if(usr != null && usr.principal != null) { + if(usr.principal instanceof GetCred) { + if(Hash.isEqual(bp.getCred(),((GetCred)usr.principal).getCred())) { + return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by cached AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false); + } + } + } + + Miss miss = missed(bp.getName()); + if(miss!=null && !miss.mayContinue(bp.getCred())) { + return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + "User/Pass Retry limit exceeded"), + RESP.FAIL,resp,aaf.getRealm(),true); + } + + Rcli userAAF = aaf.client(AAFCon.AAF_LATEST_VERSION).forUser(aaf.basicAuthSS(bp)); + Future fp = userAAF.read("/authn/basicAuth", "text/plain"); + if(fp.get(aaf.timeout)) { + if(usr!=null) { + usr.principal = bp; + } else { + addUser(new User(bp,aaf.userExpires)); + } + return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false); + } else { + // Note: AddMiss checks for miss==null, and is part of logic + boolean rv= addMiss(bp.getName(),bp.getCred()); + if(rv) { + return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + "User/Pass combo invalid via AAF"), + RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true); + } else { + return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req, + "User/Pass combo invalid via AAF - Retry limit exceeded"), + RESP.FAIL,resp,aaf.getRealm(),true); + } + } + } catch (IOException e) { + String msg = buildMsg(null,req,"Invalid Auth Token"); + aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); + return new BasicHttpTafResp(aaf.access,null,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true); + } catch (Exception e) { + String msg = buildMsg(null,req,"Authenticating Service unavailable"); + aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')'); + return new BasicHttpTafResp(aaf.access,null,msg, RESP.FAIL, resp, aaf.getRealm(),false); + } + } + return new BasicHttpTafResp(aaf.access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false); + } + + private String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) { + StringBuilder sb = new StringBuilder(); + for(Object s : msg) { + sb.append(s.toString()); + } + if(pr!=null) { + sb.append(" for "); + sb.append(pr.getName()); + } + sb.append(" from "); + sb.append(req.getRemoteAddr()); + sb.append(':'); + sb.append(req.getRemotePort()); + return sb.toString(); + } + + + + public Resp revalidate(CachedPrincipal prin) { + // !!!! TEST THIS.. Things may not be revalidated, if not BasicPrincipal + if(prin instanceof BasicPrincipal) { + Future fp; + try { + Rcli userAAF = aaf.client(AAFCon.AAF_LATEST_VERSION).forUser(aaf.transferSS(prin)); + fp = userAAF.read("/authn/basicAuth", "text/plain"); + return fp.get(aaf.timeout)?Resp.REVALIDATED:Resp.UNVALIDATED; + } catch (Exception e) { + aaf.access.log(e, "Cannot Revalidate",prin.getName()); + return Resp.INACCESSIBLE; + } + } + return Resp.NOT_MINE; + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTrustChecker.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTrustChecker.java new file mode 100644 index 0000000..c7644a5 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTrustChecker.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import javax.servlet.http.HttpServletRequest ; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.principal.TrustPrincipal; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TrustNotTafResp; +import org.onap.aaf.cadi.taf.TrustTafResp; + +import org.onap.aaf.inno.env.Env; +import org.onap.aaf.inno.env.util.Split; + +public class AAFTrustChecker implements TrustChecker { + private final String tag, id; + private final AAFPermission perm; + private Lur lur; + + /** + * + * Instance will be replaced by Identity + * @param lur + * + * @param tag + * @param perm + */ + public AAFTrustChecker(final Env env) { + tag = env.getProperty(Config.CADI_USER_CHAIN_TAG, Config.CADI_USER_CHAIN); + id = env.getProperty(Config.CADI_ALIAS,env.getProperty(Config.AAF_MECHID)); // share between components + String str = env.getProperty(Config.CADI_TRUST_PERM); + AAFPermission temp=null; + if(str!=null) { + String[] sp = Split.splitTrim('|', str); + if(sp.length==3) { + temp = new AAFPermission(sp[0],sp[1],sp[2]); + } + } + perm=temp; + } + + public AAFTrustChecker(final Access access) { + tag = access.getProperty(Config.CADI_USER_CHAIN_TAG, Config.CADI_USER_CHAIN); + id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_MECHID,null)); // share between components + String str = access.getProperty(Config.CADI_TRUST_PERM,null); + AAFPermission temp=null; + if(str!=null) { + String[] sp = Split.splitTrim('|', str); + if(sp.length==3) { + temp = new AAFPermission(sp[0],sp[1],sp[2]); + } + } + perm=temp; + } + + /* (non-Javadoc) + * @see com.att.cadi.TrustChecker#setLur(com.att.cadi.Lur) + */ + @Override + public void setLur(Lur lur) { + this.lur = lur; + } + + @Override + public TafResp mayTrust(TafResp tresp, HttpServletRequest req) { + String user_info = req.getHeader(tag); + if(user_info !=null ) { + String[] info = Split.split(',', user_info); + if(info.length>0) { + String[] flds = Split.splitTrim(':',info[0]); + if(flds.length>3 && "AS".equals(flds[3])) { // is it set for "AS" + String pn = tresp.getPrincipal().getName(); + if(pn.equals(id) // We do trust our own App Components: if a trust entry is made with self, always accept + || lur.fish(tresp.getPrincipal(), perm)) { // Have Perm set by Config.CADI_TRUST_PERM + return new TrustTafResp(tresp, + new TrustPrincipal(tresp.getPrincipal(), flds[0]), + " " + flds[0] + " validated using " + flds[2] + " by " + flds[1] + ',' + ); + } else if(pn.equals(flds[0])) { // Ignore if same identity + return tresp; + } else { + return new TrustNotTafResp(tresp, tresp.getPrincipal().getName() + " requested trust as " + + flds[0] + ", but does not have Authorization"); + } + } + } + } + return tresp; + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLur.java b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLur.java new file mode 100644 index 0000000..5bcf527 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLur.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.v2_0; + +import java.net.URISyntaxException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.CachingLur; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.StrLur; +import org.onap.aaf.cadi.Transmutate; +import org.onap.aaf.cadi.User; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.AAFTransmutate; +import org.onap.aaf.cadi.config.Config; + +import com.att.aft.dme2.api.DME2Exception; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.util.Split; + +public abstract class AbsAAFLur extends AbsUserCache implements StrLur, CachingLur { + protected static final byte[] BLANK_PASSWORD = new byte[0]; + protected static final Transmutate transmutate = new AAFTransmutate(); + private String[] debug = null; + public AAFCon aaf; + private String[] supports; + + public AbsAAFLur(AAFCon con) throws DME2Exception, URISyntaxException, APIException { + super(con.access, con.cleanInterval, con.highCount, con.usageRefreshTriggerCount); + aaf = con; + setLur(this); + supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*"); + } + + public AbsAAFLur(AAFCon con, AbsUserCache auc) throws DME2Exception, URISyntaxException, APIException { + super(auc); + aaf = con; + setLur(this); + supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*"); + } + + @Override + public void setDebug(String ids) { + this.debug = ids==null?null:Split.split(',', ids); + } + + protected abstract User loadUser(Principal bait); + protected abstract User loadUser(String name); + public final boolean supports(String userName) { + if(userName!=null) { + for(String s : supports) { + if(userName.endsWith(s)) + return true; + } + } + return false; + } + + protected abstract boolean isCorrectPermType(Permission pond); + + // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond" + public boolean fish(Principal bait, Permission pond) { + return fish(bait.getName(), pond); + } + + public void fishAll(Principal bait, List perms) { + fishAll(bait.getName(),perms); + } + + // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond" + public boolean fish(String bait, Permission pond) { + if(isDebug(bait)) { + boolean rv = false; + StringBuilder sb = new StringBuilder("Log for "); + sb.append(bait); + if(supports(bait)) { + User user = getUser(bait); + if(user==null) { + sb.append("\n\tUser is not in Cache"); + } else { + if(user.noPerms())sb.append("\n\tUser has no Perms"); + if(user.permExpired()) { + sb.append("\n\tUser's perm expired ["); + sb.append(new Date(user.permExpires())); + sb.append(']'); + } else { + sb.append("\n\tUser's perm expires ["); + sb.append(new Date(user.permExpires())); + sb.append(']'); + } + } + if(user==null || (user.noPerms() && user.permExpired())) { + user = loadUser(bait); + sb.append("\n\tloadUser called"); + } + if(user==null) { + sb.append("\n\tUser was not Loaded"); + } else if(user.contains(pond)) { + sb.append("\n\tUser contains "); + sb.append(pond.getKey()); + rv = true; + } else { + sb.append("\n\tUser does not contain "); + sb.append(pond.getKey()); + List perms = new ArrayList(); + user.copyPermsTo(perms); + for(Permission p : perms) { + sb.append("\n\t\t"); + sb.append(p.getKey()); + } + } + } else { + sb.append("AAF Lur does not support ["); + sb.append(bait); + sb.append("]"); + } + aaf.access.log(Level.INFO, sb); + return rv; + } else { + if(supports(bait)) { + User user = getUser(bait); + if(user==null || (user.noPerms() && user.permExpired())) { + user = loadUser(bait); + } + return user==null?false:user.contains(pond); + } + return false; + } + } + + public void fishAll(String bait, List perms) { + if(isDebug(bait)) { + StringBuilder sb = new StringBuilder("Log for "); + sb.append(bait); + if(supports(bait)) { + User user = getUser(bait); + if(user==null) { + sb.append("\n\tUser is not in Cache"); + } else { + if(user.noPerms())sb.append("\n\tUser has no Perms"); + if(user.permExpired()) { + sb.append("\n\tUser's perm expired ["); + sb.append(new Date(user.permExpires())); + sb.append(']'); + } else { + sb.append("\n\tUser's perm expires ["); + sb.append(new Date(user.permExpires())); + sb.append(']'); + } + } + if(user==null || (user.noPerms() && user.permExpired())) { + user = loadUser(bait); + sb.append("\n\tloadUser called"); + } + if(user==null) { + sb.append("\n\tUser was not Loaded"); + } else { + sb.append("\n\tCopying Perms "); + user.copyPermsTo(perms); + for(Permission p : perms) { + sb.append("\n\t\t"); + sb.append(p.getKey()); + } + } + } else { + sb.append("AAF Lur does not support ["); + sb.append(bait); + sb.append("]"); + } + aaf.access.log(Level.INFO, sb); + } else { + if(supports(bait)) { + User user = getUser(bait); + if(user==null || (user.noPerms() && user.permExpired())) user = loadUser(bait); + if(user!=null) { + user.copyPermsTo(perms); + } + } + } + } + + @Override + public void remove(String user) { + super.remove(user); + } + + private boolean isDebug(String bait) { + if(debug!=null) { + if(debug.length==1 && "all".equals(debug[0]))return true; + for(String s : debug) { + if(s.equals(bait))return true; + } + } + return false; + } + /** + * This special case minimizes loops, avoids multiple Set hits, and calls all the appropriate Actions found. + * + * @param bait + * @param obj + * @param type + * @param instance + * @param actions + */ + public void fishOneOf(String bait, A obj, String type, String instance, List> actions) { + User user = getUser(bait); + if(user==null || (user.noPerms() && user.permExpired()))user = loadUser(bait); +// return user==null?false:user.contains(pond); + if(user!=null) { + ReuseAAFPermission perm = new ReuseAAFPermission(type,instance); + for(Action action : actions) { + perm.setAction(action.getName()); + if(user.contains(perm)) { + if(action.exec(obj))return; + } + } + } + } + + public static interface Action { + public String getName(); + /** + * Return false to continue, True to end now + * @return + */ + public boolean exec(A a); + } + + private class ReuseAAFPermission extends AAFPermission { + public ReuseAAFPermission(String type, String instance) { + super(type,instance,null); + } + + public void setAction(String s) { + action = s; + } + + /** + * This function understands that AAF Keys are hierarchical, :A:B:C, + * Cassandra follows a similar method, so we'll short circuit and do it more efficiently when there isn't a first hit + * @return + */ + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/ArtifactDir.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/ArtifactDir.java new file mode 100644 index 0000000..af50682 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/ArtifactDir.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.security.KeyStore; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.util.Chmod; + +import org.onap.aaf.inno.env.Trans; +import org.onap.aaf.inno.env.util.Chrono; + +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; + +public abstract class ArtifactDir implements PlaceArtifact { + + protected static final String C_R = "\n"; + protected File dir; + private List encodeds = new ArrayList(); + + private Symm symm; + // This checks for multiple passes of Dir on the same objects. Run clear after done. + protected static Map processed = new HashMap(); + + + /** + * Note: Derived Classes should ALWAYS call "super.place(cert,arti)" first, and + * then "placeProperties(arti)" just after they implement + */ + @Override + public final boolean place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { + validate(arti); + + try { + // Obtain/setup directory as required + dir = new File(arti.getDir()); + if(processed.get("dir")==null) { + if(!dir.exists()) { + Chmod.to755.chmod(dir); + if(!dir.mkdirs()) { + throw new CadiException("Could not create " + dir); + } + } + + // Also place cm_url and Host Name + addProperty(Config.CM_URL,trans.getProperty(Config.CM_URL)); + addProperty(Config.HOSTNAME,arti.getMachine()); + //addProperty(Config.AAF_ENV,certInfo.getEnv()); + // Obtain Issuers + boolean first = true; + StringBuilder issuers = new StringBuilder(); +// for(String dn : certInfo.getCaIssuerDNs()) { +// if(first) { +// first=false; +// } else { +// issuers.append(':'); +// } +// issuers.append(dn); +// } + addProperty(Config.CADI_X509_ISSUERS,issuers.toString()); + } + symm = (Symm)processed.get("symm"); + if(symm==null) { + // CADI Key Gen + File f = new File(dir,arti.getAppName() + ".keyfile"); + if(!f.exists()) { + write(f,Chmod.to400,Symm.baseCrypt().keygen()); + } + symm = Symm.obtain(f); + + addEncProperty("ChallengePassword", certInfo.getChallenge()); + + processed.put("symm",symm); + } + + _place(trans, certInfo,arti); + + placeProperties(arti); + + processed.put("dir",dir); + + } catch (Exception e) { + throw new CadiException(e); + } + return true; + } + + /** + * Derived Classes implement this instead, so Dir can process first, and write any Properties last + * @param cert + * @param arti + * @return + * @throws CadiException + */ + protected abstract boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException; + + protected void addProperty(String tag, String value) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + sb.append('='); + sb.append(value); + encodeds.add(sb.toString()); + } + + protected void addEncProperty(String tag, String value) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + sb.append('='); + sb.append("enc:???"); + sb.append(symm.enpass(value)); + encodeds.add(sb.toString()); + } + + protected void write(File f, Chmod c, String ... data) throws IOException { + f.setWritable(true,true); + + FileOutputStream fos = new FileOutputStream(f); + PrintStream ps = new PrintStream(fos); + try { + for(String s : data) { + ps.print(s); + } + } finally { + ps.close(); + c.chmod(f); + } + } + + protected void write(File f, Chmod c, byte[] bytes) throws IOException { + f.setWritable(true,true); + + FileOutputStream fos = new FileOutputStream(f); + try { + fos.write(bytes); + } finally { + fos.close(); + c.chmod(f); + } + } + + protected void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException { + f.setWritable(true,true); + + FileOutputStream fos = new FileOutputStream(f); + try { + ks.store(fos, pass); + } catch (Exception e) { + throw new CadiException(e); + } finally { + fos.close(); + c.chmod(f); + } + } + + + private void validate(Artifact a) throws CadiException { + StringBuilder sb = new StringBuilder(); + if(a.getDir()==null) { + sb.append("File Artifacts require a path"); + } + + if(a.getAppName()==null) { + if(sb.length()>0) { + sb.append('\n'); + } + sb.append("File Artifacts require an AAF Namespace"); + } + + if(sb.length()>0) { + throw new CadiException(sb.toString()); + } + } + + private boolean placeProperties(Artifact arti) throws CadiException { + if(encodeds.size()==0) { + return true; + } + boolean first=processed.get("dir")==null; + try { + File f = new File(dir,arti.getAppName()+".props"); + if(f.exists()) { + if(first) { + f.delete(); + } else { + f.setWritable(true); + } + } + // Append if not first + PrintWriter pw = new PrintWriter(new FileWriter(f,!first)); + + // Write a Header + if(first) { + for(int i=0;i<60;++i) { + pw.print('#'); + } + pw.println(); + pw.println("# Properties Generated by AT&T Certificate Manager"); + pw.print("# by "); + pw.println(System.getProperty("user.name")); + pw.print("# on "); + pw.println(Chrono.dateStamp()); + pw.println("# @copyright 2016, AT&T"); + for(int i=0;i<60;++i) { + pw.print('#'); + } + pw.println(); + for(String prop : encodeds) { + if( prop.startsWith("cm_") + || prop.startsWith(Config.HOSTNAME) + || prop.startsWith(Config.AAF_ENV)) { + pw.println(prop); + } + } + } + + try { + for(String prop : encodeds) { + if(prop.startsWith("cadi")) { + pw.println(prop); + } + } + } finally { + pw.close(); + } + Chmod.to644.chmod(f); + + if(first) { + // Challenge + f = new File(dir,arti.getAppName()+".chal"); + if(f.exists()) { + f.delete(); + } + pw = new PrintWriter(new FileWriter(f)); + try { + for(String prop : encodeds) { + if(prop.startsWith("Challenge")) { + pw.println(prop); + } + } + } finally { + pw.close(); + } + Chmod.to400.chmod(f); + } + } catch(Exception e) { + throw new CadiException(e); + } + return true; + } + + public static void clear() { + processed.clear(); + } + +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/CertException.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/CertException.java new file mode 100644 index 0000000..bac4a17 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/CertException.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +public class CertException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1373028409048516401L; + + public CertException() { + } + + public CertException(String message) { + super(message); + } + + public CertException(Throwable cause) { + super(cause); + } + + public CertException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/CmAgent.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/CmAgent.java new file mode 100644 index 0000000..15ed5d0 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/CmAgent.java @@ -0,0 +1,712 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.aaf.client.ErrMessage; +import org.onap.aaf.cadi.aaf.v2_0.AAFCon; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.http.HBasicAuthSS; +import org.onap.aaf.cadi.sso.AAFSSO; + +import java.util.Properties; + +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.inno.env.Env; +import org.onap.aaf.inno.env.TimeTaken; +import org.onap.aaf.inno.env.Trans; +import org.onap.aaf.inno.env.util.Chrono; +import org.onap.aaf.inno.env.util.Split; +import org.onap.aaf.rosetta.env.RosettaDF; +import org.onap.aaf.rosetta.env.RosettaEnv; + +import certman.v1_0.Artifacts; +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; +import certman.v1_0.CertificateRequest; + +public class CmAgent { + private static final String PRINT = "print"; + private static final String FILE = "file"; + private static final String PKCS12 = "pkcs12"; + private static final String JKS = "jks"; + private static final String SCRIPT="script"; + + private static final String CM_VER = "1.0"; + public static final int PASS_SIZE = 24; + private static int TIMEOUT; + + private static RosettaDF reqDF; + private static RosettaDF certDF; + private static RosettaDF artifactsDF; + private static ErrMessage errMsg; + private static Map placeArtifact; + private static RosettaEnv env; + + public static void main(String[] args) { + int exitCode = 0; + try { + AAFSSO aafsso = new AAFSSO(args); + if(aafsso.loginOnly()) { + aafsso.setLogDefault(); + aafsso.writeFiles(); + System.out.println("AAF SSO information created in ~/.aaf"); + } else { + PropAccess access = aafsso.access(); + env = new RosettaEnv(access.getProperties()); + Deque cmds = new ArrayDeque(); + for(String p : args) { + if(p.indexOf('=')<0) { + cmds.add(p); + } + } + + if(cmds.size()==0) { + aafsso.setLogDefault(); + System.out.println("Usage: java -jar cmd []*"); + System.out.println(" create []"); + System.out.println(" read []"); + System.out.println(" update []"); + System.out.println(" delete []"); + System.out.println(" copy [,]*"); + System.out.println(" place []"); + System.out.println(" showpass []"); + System.out.println(" check []"); + System.exit(1); + } + + TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000")); + + reqDF = env.newDataFactory(CertificateRequest.class); + artifactsDF = env.newDataFactory(Artifacts.class); + certDF = env.newDataFactory(CertInfo.class); + errMsg = new ErrMessage(env); + + placeArtifact = new HashMap(); + placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS)); + placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12)); + placeArtifact.put(FILE, new PlaceArtifactInFiles()); + placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out)); + placeArtifact.put(SCRIPT, new PlaceArtifactScripts()); + + Trans trans = env.newTrans(); + try { + // show Std out again + aafsso.setLogDefault(); + aafsso.setStdErrDefault(); + + // if CM_URL can be obtained, add to sso.props, if written + String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": "); + if(cm_url!=null) { + aafsso.addProp(Config.CM_URL, cm_url); + } + aafsso.writeFiles(); + + AAFCon aafcon = new AAFConHttp(access,Config.CM_URL); + + String cmd = cmds.removeFirst(); + if("place".equals(cmd)) { + placeCerts(trans,aafcon,cmds); + } else if("create".equals(cmd)) { + createArtifact(trans, aafcon,cmds); + } else if("read".equals(cmd)) { + readArtifact(trans, aafcon, cmds); + } else if("copy".equals(cmd)) { + copyArtifact(trans, aafcon, cmds); + } else if("update".equals(cmd)) { + updateArtifact(trans, aafcon, cmds); + } else if("delete".equals(cmd)) { + deleteArtifact(trans, aafcon, cmds); + } else if("showpass".equals(cmd)) { + showPass(trans,aafcon,cmds); + } else if("check".equals(cmd)) { + try { + exitCode = check(trans,aafcon,cmds); + } catch (Exception e) { + exitCode = 1; + throw e; + } + } else { + AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd); + } + } finally { + StringBuilder sb = new StringBuilder(); + trans.auditTrail(4, sb, Trans.REMOTE); + if(sb.length()>0) { + trans.info().log("Trans Info\n",sb); + } + } + aafsso.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + if(exitCode!=0) { + System.exit(exitCode); + } + } + + private static String getProperty(PropAccess pa, Env env, boolean secure, String tag, String prompt, Object ... def) { + String value; + if((value=pa.getProperty(tag))==null) { + if(secure) { + value = new String(AAFSSO.cons.readPassword(prompt, def)); + } else { + value = AAFSSO.cons.readLine(prompt,def).trim(); + } + if(value!=null) { + if(value.length()>0) { + pa.setProperty(tag,value); + env.setProperty(tag,value); + } else if(def.length==1) { + value=def[0].toString(); + pa.setProperty(tag,value); + env.setProperty(tag,value); + } + } + } + return value; + } + + private static String mechID(Deque cmds) { + if(cmds.size()<1) { + String alias = env.getProperty(Config.CADI_ALIAS); + return alias!=null?alias:AAFSSO.cons.readLine("MechID: "); + } + return cmds.removeFirst(); + } + + private static String machine(Deque cmds) throws UnknownHostException { + if(cmds.size()>0) { + return cmds.removeFirst(); + } else { + String mach = env.getProperty(Config.HOSTNAME); + return mach!=null?mach:InetAddress.getLocalHost().getHostName(); + } + } + + private static String[] machines(Deque cmds) { + String machines; + if(cmds.size()>0) { + machines = cmds.removeFirst(); + } else { + machines = AAFSSO.cons.readLine("Machines (sep by ','): "); + } + return Split.split(',', machines); + } + + private static void createArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + Artifacts artifacts = new Artifacts(); + Artifact arti = new Artifact(); + artifacts.getArtifact().add(arti); + arti.setMechid(mechID!=null?mechID:AAFSSO.cons.readLine("MechID: ")); + arti.setMachine(machine!=null?machine:AAFSSO.cons.readLine("Machine (%s): ",InetAddress.getLocalHost().getHostName())); + arti.setCa(AAFSSO.cons.readLine("CA: (%s): ","aaf")); + + String resp = AAFSSO.cons.readLine("Types [file,jks,script] (%s): ", "jks"); + for(String s : Split.splitTrim(',', resp)) { + arti.getType().add(s); + } + // Always do Script + if(!resp.contains(SCRIPT)) { + arti.getType().add(SCRIPT); + } + + // Note: Sponsor is set on Creation by CM + String configRootName = AAFCon.reverseDomain(arti.getMechid()); + arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",configRootName)); + arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", System.getProperty("user.dir"))); + arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", System.getProperty("user.name"))); + arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renewal Days (%s):", "30"))); + arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (mailto owner):", ""))); + + TimeTaken tt = trans.start("Create Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER).create("/cert/artifacts", artifactsDF, artifacts); + if(future.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",arti.getMechid(), arti.getMachine()); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + + private static String toNotification(String notification) { + if(notification==null) { + notification=""; + } else if(notification.length()>0) { + if(notification.indexOf(':')<0) { + notification = "mailto:" + notification; + } + } + return notification; + } + + + private static void readArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Read Artifact", Env.SUB); + try { + Future future = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(future.get(TIMEOUT)) { + boolean printed = false; + for(Artifact a : future.value.getArtifact()) { + AAFSSO.cons.printf("MechID: %s\n",a.getMechid()); + AAFSSO.cons.printf(" Sponsor: %s\n",a.getSponsor()); + AAFSSO.cons.printf("Machine: %s\n",a.getMachine()); + AAFSSO.cons.printf("CA: %s\n",a.getCa()); + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(String t : a.getType()) { + if(first) {first=false;} + else{sb.append(',');} + sb.append(t); + } + AAFSSO.cons.printf("Types: %s\n",sb); + AAFSSO.cons.printf("Namespace: %s\n",a.getAppName()); + AAFSSO.cons.printf("Directory: %s\n",a.getDir()); + AAFSSO.cons.printf("O/S User: %s\n",a.getOsUser()); + AAFSSO.cons.printf("Renew Days: %d\n",a.getRenewDays()); + AAFSSO.cons.printf("Notification %s\n",a.getNotification()); + printed = true; + } + if(!printed) { + AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); + } + } else { + trans.error().log(errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + + private static void copyArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + String[] newmachs = machines(cmds); + if(newmachs==null || newmachs == null) { + trans.error().log("No machines listed to copy to"); + } else { + TimeTaken tt = trans.start("Copy Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(future.get(TIMEOUT)) { + boolean printed = false; + for(Artifact a : future.value.getArtifact()) { + for(String m : newmachs) { + a.setMachine(m); + Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, future.value); + if(fup.get(TIMEOUT)) { + trans.info().printf("Copy of %s %s successful to %s",mechID,machine,m); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(fup)); + } + + printed = true; + } + } + if(!printed) { + AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); + } + } else { + trans.error().log(errMsg.toMsg(future)); + } + } finally { + tt.done(); + } + } + } + + private static void updateArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Update Artifact", Env.REMOTE); + try { + Future fread = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + + if(fread.get(TIMEOUT)) { + Artifacts artifacts = new Artifacts(); + for(Artifact a : fread.value.getArtifact()) { + Artifact arti = new Artifact(); + artifacts.getArtifact().add(arti); + + AAFSSO.cons.printf("For %s on %s\n", a.getMechid(),a.getMachine()); + arti.setMechid(a.getMechid()); + arti.setMachine(a.getMachine()); + arti.setCa(AAFSSO.cons.readLine("CA: (%s): ",a.getCa())); + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(String t : a.getType()) { + if(first) {first=false;} + else{sb.append(',');} + sb.append(t); + } + + String resp = AAFSSO.cons.readLine("Types [file,jks,pkcs12] (%s): ", sb); + for(String s : Split.splitTrim(',', resp)) { + arti.getType().add(s); + } + // Always do Script + if(!resp.contains(SCRIPT)) { + arti.getType().add(SCRIPT); + } + + // Note: Sponsor is set on Creation by CM + arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",a.getAppName())); + arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", a.getDir())); + arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", a.getOsUser())); + arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renew Days (%s):", a.getRenewDays()))); + arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (%s):", a.getNotification()))); + + } + if(artifacts.getArtifact().size()==0) { + AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine); + } else { + Future fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, artifacts); + if(fup.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",mechID,machine); + } else { + trans.error().printf("Call to AAF Certman failed, %s", + errMsg.toMsg(fup)); + } + } + } else { + trans.error().printf("Call to AAF Certman failed, %s %s, %s", + errMsg.toMsg(fread),mechID,machine); + } + } finally { + tt.done(); + } + } + + private static void deleteArtifact(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechid = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Delete Artifact", Env.REMOTE); + try { + Future future = aafcon.client(CM_VER) + .delete("/cert/artifacts/"+mechid+"/"+machine,"application/json" ); + + if(future.get(TIMEOUT)) { + trans.info().printf("Call to AAF Certman successful %s, %s",mechid,machine); + } else { + trans.error().printf("Call to AAF Certman failed, %s %s, %s", + errMsg.toMsg(future),mechid,machine); + } + } finally { + tt.done(); + } + } + + + + private static boolean placeCerts(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + boolean rv = false; + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Place Artifact", Env.REMOTE); + try { + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + AAFSSO.cons.printf("===> There are no artifacts for %s %s", mechID, machine); + } else { + for(Artifact a : acf.value.getArtifact()) { + String osID = System.getProperty("user.name"); + if(a.getOsUser().equals(osID)) { + CertificateRequest cr = new CertificateRequest(); + cr.setMechid(a.getMechid()); + cr.setSponsor(a.getSponsor()); + cr.getFqdns().add(a.getMachine()); + Future f = aafcon.client(CM_VER) + .setQueryParams("withTrust") + .updateRespondString("/cert/" + a.getCa(),reqDF, cr); + if(f.get(TIMEOUT)) { + CertInfo capi = certDF.newData().in(TYPE.JSON).load(f.body()).asObject(); + for(String type : a.getType()) { + PlaceArtifact pa = placeArtifact.get(type); + if(pa!=null) { + if(rv = pa.place(trans, capi, a)) { + notifyPlaced(a,rv); + } + } + } + // Cover for the above multiple pass possibilities with some static Data, then clear per Artifact + } else { + trans.error().log(errMsg.toMsg(f)); + } + } else { + trans.error().log("You must be OS User \"" + a.getOsUser() +"\" to place Certificates on this box"); + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + } + } finally { + tt.done(); + } + return rv; + } + + private static void notifyPlaced(Artifact a, boolean rv) { + + + } + + private static void showPass(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Show Password", Env.REMOTE); + try { + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine); + } else { + String id = aafcon.defID(); + boolean allowed; + for(Artifact a : acf.value.getArtifact()) { + allowed = id!=null && (id.equals(a.getSponsor()) || + (id.equals(a.getMechid()) + && aafcon.securityInfo().defSS.getClass().isAssignableFrom(HBasicAuthSS.class))); + if(!allowed) { + Future pf = aafcon.client(CM_VER).read("/cert/may/" + + a.getAppName() + ".certman|"+a.getCa()+"|showpass","*/*"); + if(pf.get(TIMEOUT)) { + allowed = true; + } else { + trans.error().log(errMsg.toMsg(pf)); + } + } + if(allowed) { + File dir = new File(a.getDir()); + Properties props = new Properties(); + FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); + try { + props.load(fis); + fis.close(); + fis = new FileInputStream(new File(dir,a.getAppName()+".chal")); + props.load(fis); + } finally { + fis.close(); + } + + File f = new File(dir,a.getAppName()+".keyfile"); + if(f.exists()) { + Symm symm = Symm.obtain(f); + + for(Iterator> iter = props.entrySet().iterator(); iter.hasNext();) { + Entry en = iter.next(); + if(en.getValue().toString().startsWith("enc:???")) { + System.out.printf("%s=%s\n", en.getKey(), symm.depass(en.getValue().toString())); + } + } + } else { + trans.error().printf("%s.keyfile must exist to read passwords for %s on %s", + f.getAbsolutePath(),a.getMechid(), a.getMachine()); + } + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + } + } finally { + tt.done(); + } + + } + + + /** + * Check returns Error Codes, so that Scripts can know what to do + * + * 0 - Check Complete, nothing to do + * 1 - General Error + * 2 - Error for specific Artifact - read check.msg + * 10 - Certificate Updated - check.msg is email content + * + * @param trans + * @param aafcon + * @param cmds + * @return + * @throws Exception + */ + private static int check(Trans trans, AAFCon aafcon, Deque cmds) throws Exception { + int exitCode=1; + String mechID = mechID(cmds); + String machine = machine(cmds); + + TimeTaken tt = trans.start("Check Certificate", Env.REMOTE); + try { + + Future acf = aafcon.client(CM_VER) + .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF); + if(acf.get(TIMEOUT)) { + // Have to wait for JDK 1.7 source... + //switch(artifact.getType()) { + if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) { + AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine); + } else { + String id = aafcon.defID(); + GregorianCalendar now = new GregorianCalendar(); + for(Artifact a : acf.value.getArtifact()) { + if(id.equals(a.getMechid())) { + File dir = new File(a.getDir()); + Properties props = new Properties(); + FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props")); + try { + props.load(fis); + } finally { + fis.close(); + } + + String prop; + File f; + + if((prop=props.getProperty(Config.CADI_KEYFILE))==null || + !(f=new File(prop)).exists()) { + trans.error().printf("Keyfile must exist to check Certificates for %s on %s", + a.getMechid(), a.getMachine()); + } else { + String ksf = props.getProperty(Config.CADI_KEYSTORE); + String ksps = props.getProperty(Config.CADI_KEYSTORE_PASSWORD); + if(ksf==null || ksps == null) { + trans.error().printf("Properties %s and %s must exist to check Certificates for %s on %s", + Config.CADI_KEYSTORE, Config.CADI_KEYSTORE_PASSWORD,a.getMechid(), a.getMachine()); + } else { + KeyStore ks = KeyStore.getInstance("JKS"); + Symm symm = Symm.obtain(f); + + fis = new FileInputStream(ksf); + try { + ks.load(fis,symm.depass(ksps).toCharArray()); + } finally { + fis.close(); + } + X509Certificate cert = (X509Certificate)ks.getCertificate(mechID); + String msg = null; + + if(cert==null) { + msg = String.format("X509Certificate does not exist for %s on %s in %s", + a.getMechid(), a.getMachine(), ksf); + trans.error().log(msg); + exitCode = 2; + } else { + GregorianCalendar renew = new GregorianCalendar(); + renew.setTime(cert.getNotAfter()); + renew.add(GregorianCalendar.DAY_OF_MONTH,-1*a.getRenewDays()); + if(renew.after(now)) { + msg = String.format("X509Certificate for %s on %s has been checked on %s. It expires on %s; it will not be renewed until %s.\n", + a.getMechid(), a.getMachine(),Chrono.dateOnlyStamp(now),cert.getNotAfter(),Chrono.dateOnlyStamp(renew)); + trans.info().log(msg); + exitCode = 0; // OK + } else { + trans.info().printf("X509Certificate for %s on %s expiration, %s, needs Renewal.\n", + a.getMechid(), a.getMachine(),cert.getNotAfter()); + cmds.offerLast(mechID); + cmds.offerLast(machine); + if(placeCerts(trans,aafcon,cmds)) { + msg = String.format("X509Certificate for %s on %s has been renewed. Ensure services using are refreshed.\n", + a.getMechid(), a.getMachine()); + exitCode = 10; // Refreshed + } else { + msg = String.format("X509Certificate for %s on %s attempted renewal, but failed. Immediate Investigation is required!\n", + a.getMechid(), a.getMachine()); + exitCode = 1; // Error Renewing + } + } + } + if(msg!=null) { + FileOutputStream fos = new FileOutputStream(a.getDir()+'/'+a.getAppName()+".msg"); + try { + fos.write(msg.getBytes()); + } finally { + fos.close(); + } + } + } + + } + } + } + } + } else { + trans.error().log(errMsg.toMsg(acf)); + exitCode=1; + } + } finally { + tt.done(); + } + return exitCode; + } + +} + + + + diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/Factory.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/Factory.java new file mode 100644 index 0000000..1d488de --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/Factory.java @@ -0,0 +1,449 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Collection; +import java.util.List; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +import org.onap.aaf.cadi.Symm; + +import org.onap.aaf.inno.env.Env; +import org.onap.aaf.inno.env.TimeTaken; +import org.onap.aaf.inno.env.Trans; + +public class Factory { + private static final String PRIVATE_KEY_HEADER = "PRIVATE KEY"; + public static final String KEY_ALGO = "RSA"; + public static final String SIG_ALGO = "SHA256withRSA"; + + public static final int KEY_LENGTH = 2048; + private static final KeyPairGenerator keygen; + private static final KeyFactory keyFactory; + private static final CertificateFactory certificateFactory; + private static final SecureRandom random; + + + private static final Symm base64 = Symm.base64.copy(64); + + static { + random = new SecureRandom(); + KeyPairGenerator tempKeygen; + try { + tempKeygen = KeyPairGenerator.getInstance(KEY_ALGO);//,"BC"); + tempKeygen.initialize(KEY_LENGTH, random); + } catch (NoSuchAlgorithmException e) { + tempKeygen = null; + e.printStackTrace(System.err); + } + keygen = tempKeygen; + + KeyFactory tempKeyFactory; + try { + tempKeyFactory=KeyFactory.getInstance(KEY_ALGO);//,"BC" + } catch (NoSuchAlgorithmException e) { + tempKeyFactory = null; + e.printStackTrace(System.err); + }; + keyFactory = tempKeyFactory; + + CertificateFactory tempCertificateFactory; + try { + tempCertificateFactory = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + tempCertificateFactory = null; + e.printStackTrace(System.err); + } + certificateFactory = tempCertificateFactory; + + + } + + + public static KeyPair generateKeyPair(Trans trans) { + TimeTaken tt; + if(trans!=null) { + tt = trans.start("Generate KeyPair", Env.SUB); + } else { + tt = null; + } + try { + return keygen.generateKeyPair(); + } finally { + if(tt!=null) { + tt.done(); + } + } + } + + private static final String LINE_END = "-----\n"; + + protected static String textBuilder(String kind, byte[] bytes) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append("-----BEGIN "); + sb.append(kind); + sb.append(LINE_END); + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + base64.encode(bais, baos); + sb.append(new String(baos.toByteArray())); + + if(sb.charAt(sb.length()-1)!='\n') { + sb.append('\n'); + } + sb.append("-----END "); + sb.append(kind); + sb.append(LINE_END); + return sb.toString(); + } + + public static PrivateKey toPrivateKey(Trans trans, String pk) throws IOException, CertException { + byte[] bytes = decode(new StringReader(pk)); + return toPrivateKey(trans, bytes); + } + + public static PrivateKey toPrivateKey(Trans trans, byte[] bytes) throws IOException, CertException { + TimeTaken tt=trans.start("Reconstitute Private Key", Env.SUB); + try { + return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes)); + } catch (InvalidKeySpecException e) { + throw new CertException("Translating Private Key from PKCS8 KeySpec",e); + } finally { + tt.done(); + } + } + + public static PrivateKey toPrivateKey(Trans trans, File file) throws IOException, CertException { + TimeTaken tt = trans.start("Decode Private Key File", Env.SUB); + try { + return toPrivateKey(trans,decode(file)); + }finally { + tt.done(); + } + } + + public static String toString(Trans trans, PrivateKey pk) throws IOException { +// PKCS8EncodedKeySpec pemContents = new PKCS8EncodedKeySpec(pk.getEncoded()); + trans.debug().log("Private Key to String"); + return textBuilder(PRIVATE_KEY_HEADER,pk.getEncoded()); + } + + public static PublicKey toPublicKey(Trans trans, String pk) throws IOException { + TimeTaken tt = trans.start("Reconstitute Public Key", Env.SUB); + try { + ByteArrayInputStream bais = new ByteArrayInputStream(pk.getBytes()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Symm.base64noSplit.decode(bais, baos); + + return keyFactory.generatePublic(new X509EncodedKeySpec(baos.toByteArray())); + } catch (InvalidKeySpecException e) { + trans.error().log(e,"Translating Public Key from X509 KeySpec"); + return null; + } finally { + tt.done(); + } + } + + public static String toString(Trans trans, PublicKey pk) throws IOException { + trans.debug().log("Public Key to String"); + return textBuilder("PUBLIC KEY",pk.getEncoded()); + } + + public static Collection toX509Certificate(String x509) throws CertificateException { + return toX509Certificate(x509.getBytes()); + } + + public static Collection toX509Certificate(List x509s) throws CertificateException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + for(String x509 : x509s) { + baos.write(x509.getBytes()); + } + } catch (IOException e) { + throw new CertificateException(e); + } + return toX509Certificate(new ByteArrayInputStream(baos.toByteArray())); + } + + public static Collection toX509Certificate(byte[] x509) throws CertificateException { + return certificateFactory.generateCertificates(new ByteArrayInputStream(x509)); + } + + public static Collection toX509Certificate(Trans trans, File file) throws CertificateException, FileNotFoundException { + FileInputStream fis = new FileInputStream(file); + try { + return toX509Certificate(fis); + } finally { + try { + fis.close(); + } catch (IOException e) { + throw new CertificateException(e); + } + } + } + + public static Collection toX509Certificate(InputStream is) throws CertificateException { + return certificateFactory.generateCertificates(is); + } + + public static String toString(Trans trans, Certificate cert) throws IOException, CertException { + if(trans.debug().isLoggable()) { + StringBuilder sb = new StringBuilder("Certificate to String"); + if(cert instanceof X509Certificate) { + sb.append(" - "); + sb.append(((X509Certificate)cert).getSubjectDN()); + } + trans.debug().log(sb); + } + try { + if(cert==null) { + throw new CertException("Certificate not built"); + } + return textBuilder("CERTIFICATE",cert.getEncoded()); + } catch (CertificateEncodingException e) { + throw new CertException(e); + } + } + + public static Cipher pkCipher() throws NoSuchAlgorithmException, NoSuchPaddingException { + return Cipher.getInstance(KEY_ALGO); + } + + public static Cipher pkCipher(Key key, boolean encrypt) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException { + Cipher cipher = Cipher.getInstance(KEY_ALGO); + cipher.init(encrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE,key); + return cipher; + } + + public static byte[] strip(Reader rdr) throws IOException { + BufferedReader br = new BufferedReader(rdr); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + String line; + while((line=br.readLine())!=null) { + if(line.length()>0 && + !line.startsWith("-----") && + line.indexOf(':')<0) { // Header elements + baos.write(line.getBytes()); + } + } + return baos.toByteArray(); + } + + public static class StripperInputStream extends InputStream { + private Reader created; + private BufferedReader br; + private int idx; + private String line; + + public StripperInputStream(Reader rdr) { + if(rdr instanceof BufferedReader) { + br = (BufferedReader)rdr; + } else { + br = new BufferedReader(rdr); + } + created = null; + } + + public StripperInputStream(File file) throws FileNotFoundException { + this(new FileReader(file)); + created = br; + } + + public StripperInputStream(InputStream is) throws FileNotFoundException { + this(new InputStreamReader(is)); + created = br; + } + + @Override + public int read() throws IOException { + if(line==null || idx>=line.length()) { + while((line=br.readLine())!=null) { + if(line.length()>0 && + !line.startsWith("-----") && + line.indexOf(':')<0) { // Header elements + break; + } + } + + if(line==null) { + return -1; + } + idx = 0; + } + return line.charAt(idx++); + } + + /* (non-Javadoc) + * @see java.io.InputStream#close() + */ + @Override + public void close() throws IOException { + if(created!=null) { + created.close(); + } + } + } + + public static class Base64InputStream extends InputStream { + private InputStream created; + private InputStream is; + private byte trio[]; + private byte duo[]; + private int idx; + + + public Base64InputStream(File file) throws FileNotFoundException { + this(new FileInputStream(file)); + created = is; + } + + public Base64InputStream(InputStream is) throws FileNotFoundException { + this.is = is; + trio = new byte[3]; + idx = 4; + } + + @Override + public int read() throws IOException { + if(duo==null || idx>=duo.length) { + int read = is.read(trio); + if(read==-1) { + return -1; + } + duo = Symm.base64.decode(trio); + if(duo==null || duo.length==0) { + return -1; + } + idx=0; + } + + return duo[idx++]; + } + + /* (non-Javadoc) + * @see java.io.InputStream#close() + */ + @Override + public void close() throws IOException { + if(created!=null) { + created.close(); + } + } + } + + public static byte[] decode(byte[] bytes) throws IOException { + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Symm.base64.decode(bais, baos); + return baos.toByteArray(); + } + + public static byte[] decode(File f) throws IOException { + FileReader fr = new FileReader(f); + try { + return Factory.decode(fr); + } finally { + fr.close(); + } + + } + public static byte[] decode(Reader rdr) throws IOException { + return decode(strip(rdr)); + } + + + public static byte[] binary(File file) throws IOException { + DataInputStream dis = new DataInputStream(new FileInputStream(file)); + try { + byte[] bytes = new byte[(int)file.length()]; + dis.readFully(bytes); + return bytes; + } finally { + dis.close(); + } + } + + + public static byte[] sign(Trans trans, byte[] bytes, PrivateKey pk) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { + TimeTaken tt = trans.start("Sign Data", Env.SUB); + try { + Signature sig = Signature.getInstance(SIG_ALGO); + sig.initSign(pk, random); + sig.update(bytes); + return sig.sign(); + } finally { + tt.done(); + } + } + + public static String toSignatureString(byte[] signed) throws IOException { + return textBuilder("SIGNATURE", signed); + } + + public static boolean verify(Trans trans, byte[] bytes, byte[] signature, PublicKey pk) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { + TimeTaken tt = trans.start("Verify Data", Env.SUB); + try { + Signature sig = Signature.getInstance(SIG_ALGO); + sig.initVerify(pk); + sig.update(bytes); + return sig.verify(signature); + } finally { + tt.done(); + } + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifact.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifact.java new file mode 100644 index 0000000..a89b901 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifact.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; + +import org.onap.aaf.cadi.CadiException; + +import org.onap.aaf.inno.env.Trans; + +public interface PlaceArtifact { + public boolean place(Trans trans, CertInfo cert, Artifact arti) throws CadiException; +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInFiles.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInFiles.java new file mode 100644 index 0000000..eaefd58 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInFiles.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.File; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.util.Chmod; + +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; + +import org.onap.aaf.inno.env.Trans; + +public class PlaceArtifactInFiles extends ArtifactDir { + @Override + public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { + try { + // Setup Public Cert + File f = new File(dir,arti.getAppName()+".crt"); + write(f,Chmod.to644,certInfo.getCerts().get(0),C_R); + + // Setup Private Key + f = new File(dir,arti.getAppName()+".key"); + write(f,Chmod.to400,certInfo.getPrivatekey(),C_R); + + } catch (Exception e) { + throw new CadiException(e); + } + return true; + } +} + + diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInKeystore.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInKeystore.java new file mode 100644 index 0000000..ddda1db --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactInKeystore.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.File; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Collection; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.util.Chmod; + +import org.onap.aaf.inno.env.Trans; + +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; + +public class PlaceArtifactInKeystore extends ArtifactDir { + private String kst; + //TODO get ROOT DNs or Trusted DNs from Certificate Manager. +// private static String[] rootDNs = new String[]{ +// "CN=ATT CADI Root CA - Test, O=ATT, OU=CSO, C=US", // Lab. delete eventually +// "CN=ATT AAF CADI TEST CA, OU=CSO, O=ATT, C=US", +// "CN=ATT AAF CADI CA, OU=CSO, O=ATT, C=US" +// }; + + public PlaceArtifactInKeystore(String kst) { + this.kst = kst; + } + + @Override + public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { + File fks = new File(dir,arti.getAppName()+'.'+kst); + try { + KeyStore jks = KeyStore.getInstance(kst); + if(fks.exists()) { + fks.delete(); + } + + // Get the Cert(s)... Might include Trust store + Collection certColl = Factory.toX509Certificate(certInfo.getCerts()); + X509Certificate[] certs = new X509Certificate[certColl.size()]; + certColl.toArray(certs); + + + // Add CADI Keyfile Entry to Properties + addProperty(Config.CADI_KEYFILE,arti.getDir()+'/'+arti.getAppName() + ".keyfile"); + // Set Keystore Password + addProperty(Config.CADI_KEYSTORE,fks.getAbsolutePath()); + String keystorePass = Symm.randomGen(CmAgent.PASS_SIZE); + addEncProperty(Config.CADI_KEYSTORE_PASSWORD,keystorePass); + char[] keystorePassArray = keystorePass.toCharArray(); + jks.load(null,keystorePassArray); // load in + + // Add Private Key/Cert Entry for App + // Note: Java SSL security classes, while having a separate key from keystore, + // is documented to not actually work. + // java.security.UnrecoverableKeyException: Cannot recover key + // You can create a custom Key Manager to make it work, but Practicality + // dictates that you live with the default, meaning, they are the same + String keyPass = keystorePass; //Symm.randomGen(CmAgent.PASS_SIZE); + PrivateKey pk = Factory.toPrivateKey(trans, certInfo.getPrivatekey()); + addEncProperty(Config.CADI_KEY_PASSWORD, keyPass); + addProperty(Config.CADI_ALIAS, arti.getMechid()); +// Set attribs = new HashSet(); +// if(kst.equals("pkcs12")) { +// // Friendly Name +// attribs.add(new PKCS12Attribute("1.2.840.113549.1.9.20", arti.getAppName())); +// } +// + KeyStore.ProtectionParameter protParam = + new KeyStore.PasswordProtection(keyPass.toCharArray()); + + KeyStore.PrivateKeyEntry pkEntry = + new KeyStore.PrivateKeyEntry(pk, new Certificate[] {certs[0]}); + jks.setEntry(arti.getMechid(), + pkEntry, protParam); + + // Write out + write(fks,Chmod.to400,jks,keystorePassArray); + + // Change out to TrustStore + fks = new File(dir,arti.getAppName()+".trust."+kst); + jks = KeyStore.getInstance(kst); + + // Set Truststore Password + addProperty(Config.CADI_TRUSTSTORE,fks.getAbsolutePath()); + String trustStorePass = Symm.randomGen(CmAgent.PASS_SIZE); + addEncProperty(Config.CADI_TRUSTSTORE_PASSWORD,trustStorePass); + char[] truststorePassArray = trustStorePass.toCharArray(); + jks.load(null,truststorePassArray); // load in + + // Add Trusted Certificates + for(int i=1; i0) { + trans.info().printf("Warning: %s\n",capi.getNotes()); + } + out.printf("Challenge: %s\n",capi.getChallenge()); + out.printf("PrivateKey:\n%s\n",capi.getPrivatekey()); + out.println("Certificate Chain:"); + for(String c : capi.getCerts()) { + out.println(c); + } + return true; + } +} diff --git a/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactScripts.java b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactScripts.java new file mode 100644 index 0000000..d1b3141 --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/cm/PlaceArtifactScripts.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.cm; + +import java.io.File; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.util.Chmod; + +import org.onap.aaf.inno.env.Trans; +import org.onap.aaf.inno.env.util.Chrono; +import org.onap.aaf.inno.env.util.Split; + +import certman.v1_0.Artifacts.Artifact; +import certman.v1_0.CertInfo; + +public class PlaceArtifactScripts extends ArtifactDir { + @Override + public boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException { + try { + // Setup check.sh script + String filename = arti.getAppName()+".check.sh"; + File f1 = new File(dir,filename); + String email = arti.getNotification() + '\n'; + if(email.startsWith("mailto:")) { + email=email.substring(7); + } else { + email=arti.getOsUser() + '\n'; + } + + StringBuilder classpath = new StringBuilder(); + boolean first = true; + for(String pth : Split.split(File.pathSeparatorChar, System.getProperty("java.class.path"))) { + if(first) { + first=false; + } else { + classpath.append(File.pathSeparatorChar); + } + File f = new File(pth); + classpath.append(f.getCanonicalPath().replaceAll("[0-9]+\\.[0-9]+\\.[0-9]+","*")); + } + + write(f1,Chmod.to644, + "#!/bin/bash " + f1.getCanonicalPath()+'\n', + "# Certificate Manager Check Script\n", + "# Check on Certificate, and renew if needed.\n", + "# Generated by Certificate Manager " + Chrono.timeStamp()+'\n', + "DIR="+arti.getDir()+'\n', + "APP="+arti.getAppName()+'\n', + "EMAIL="+email, + "CP=\""+classpath.toString()+"\"\n", + checkScript + ); + + // Setup check.sh script + File f2 = new File(dir,arti.getAppName()+".crontab.sh"); + write(f2,Chmod.to644, + "#!/bin/bash " + f1.getCanonicalPath()+'\n', + "# Certificate Manager Crontab Loading Script\n", + "# Add/Update a Crontab entry, that adds a check on Certificate Manager generated Certificate nightly.\n", + "# Generated by Certificate Manager " + Chrono.timeStamp()+'\n', + "TFILE=\"/tmp/cmcron$$.temp\"\n", + "DIR=\""+arti.getDir()+"\"\n", + "CF=\""+arti.getAppName()+" Certificate Check Script\"\n", + "SCRIPT=\""+f1.getCanonicalPath()+"\"\n", + cronScript + ); + + } catch (Exception e) { + throw new CadiException(e); + } + return true; + } + + private final static String checkScript = + "> $DIR/$APP.msg\n\n" + + "function mailit {\n" + + " printf \"$*\" | /bin/mail -s \"AAF Certman Notification for `uname -n`\" $EMAIL\n"+ + "}\n\n" + + System.getProperty("java.home") + "/bin/" +"java -cp $CP " + + CmAgent.class.getName() + + " cadi_prop_files=$DIR/$APP.props check 2> $DIR/$APP.STDERR > $DIR/$APP.STDOUT\n" + + "case \"$?\" in\n" + + " 0)\n" + + " # Note: Validation will be mailed only the first day after any modification\n" + + " if [ \"`find $DIR -mtime 0 -name $APP.check.sh`\" != \"\" ] ; then\n" + + " mailit `echo \"Certficate Validated:\\n\\n\" | cat - $DIR/$APP.msg`\n" + + " else\n" + + " cat $DIR/$APP.msg\n" + + " fi\n" + + " ;;\n" + + " 1) mailit \"Error with Certificate Check:\\\\n\\\\nCheck logs $DIR/$APP.STDOUT and $DIR/$APP.STDERR on `uname -n`\"\n" + + " ;;\n" + + " 2) mailit `echo \"Certificate Check Error\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + + " ;;\n" + + " 10) mailit `echo \"Certificate Replaced\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + + " if [ -e $DIR/$APP.restart.sh ]; then\n" + + " # Note: it is THIS SCRIPT'S RESPONSIBILITY to notify upon success or failure as necessary!!\n" + + " /bin/sh $DIR/$APP.restart.sh\n" + + " fi\n" + + " ;;\n" + + " *) mailit `echo \"Unknown Error code for CM Agent\\\\n\\\\n\" | cat - $DIR/$APP.msg`\n" + + " ;;\n" + + " esac\n\n" + + " # Note: make sure to cover this sripts' exit Code\n"; + + private final static String cronScript = + "crontab -l | sed -n \"/#### BEGIN $CF/,/END $CF ####/!p\" > $TFILE\n" + + "# Note: Randomize Minutes (0-60) and hours (1-4)\n" + + "echo \"#### BEGIN $CF ####\" >> $TFILE\n" + + "echo \"$(( $RANDOM % 60)) $(( $(( $RANDOM % 3 )) + 1 )) * * * /bin/bash $SCRIPT " + + ">> $DIR/cronlog 2>&1 \" >> $TFILE\n" + + "echo \"#### END $CF ####\" >> $TFILE\n" + + "crontab $TFILE\n" + + "rm $TFILE\n"; +} + + + diff --git a/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java b/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java new file mode 100644 index 0000000..ed3254b --- /dev/null +++ b/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java @@ -0,0 +1,285 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.sso; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.util.MyConsole; +import org.onap.aaf.cadi.util.SubStandardConsole; +import org.onap.aaf.cadi.util.TheConsole; + + +public class AAFSSO { + public static final MyConsole cons = TheConsole.implemented()?new TheConsole():new SubStandardConsole(); + + private Properties diskprops = null; // use for temp storing User/Password on disk + private File dot_aaf = null, sso=null; // instantiated, if ever, with diskprops + + boolean removeSSO=false; + boolean loginOnly = false; + private PropAccess access; + private StringBuilder err; + private String user,encrypted_pass; + private boolean use_X509; + + private PrintStream os, stdout=null,stderr=null; + + private Method close; + + public AAFSSO(String[] args) throws IOException, CadiException { + List larg = new ArrayList(args.length); + + // Cover for bash's need to escape *... (\\*) + // also, remove SSO if required + for (int i = 0; i < args.length; ++i) { + if ("\\*".equals(args[i])) { + args[i] = "*"; + } + + if("-logout".equalsIgnoreCase(args[i])) { + removeSSO=true; + } else if("-login".equalsIgnoreCase(args[i])) { + loginOnly = true; + } else { + larg.add(args[i]); + } + } + + String[] nargs = new String[larg.size()]; + larg.toArray(nargs); + + dot_aaf = new File(System.getProperty("user.home")+"/.aaf"); + if(!dot_aaf.exists()) { + dot_aaf.mkdirs(); + } + File f = new File(dot_aaf,"sso.out"); + os = new PrintStream(new FileOutputStream(f,true)); + stdout = System.out; + stderr = System.err; + System.setOut(os); + System.setErr(os); + + access = new PropAccess(os,nargs); + Config.setDefaultRealm(access); + + user = access.getProperty(Config.AAF_MECHID); + encrypted_pass = access.getProperty(Config.AAF_MECHPASS); + + File dot_aaf_kf = new File(dot_aaf,"keyfile"); + + sso = new File(dot_aaf,"sso.props"); + if(removeSSO) { + if(dot_aaf_kf.exists()) { + dot_aaf_kf.setWritable(true,true); + dot_aaf_kf.delete(); + } + if(sso.exists()) { + sso.delete(); + } + System.out.println("AAF SSO information removed"); + System.exit(0); + } + + if(!dot_aaf_kf.exists()) { + FileOutputStream fos = new FileOutputStream(dot_aaf_kf); + try { + fos.write(Symm.encrypt.keygen()); + dot_aaf_kf.setExecutable(false,false); + dot_aaf_kf.setWritable(false,false); + dot_aaf_kf.setReadable(false,false); + dot_aaf_kf.setReadable(true, true); + } finally { + fos.close(); + } + } + + String keyfile = access.getProperty(Config.CADI_KEYFILE); // in case it's CertificateMan props + if(keyfile==null) { + access.setProperty(Config.CADI_KEYFILE, dot_aaf_kf.getAbsolutePath()); + } + + String alias = access.getProperty(Config.CADI_ALIAS); + if(user==null && alias!=null && access.getProperty(Config.CADI_KEYSTORE_PASSWORD)!=null) { + user = alias; + access.setProperty(Config.AAF_MECHID, user); + use_X509 = true; + } else { + use_X509 = false; + Symm decryptor = Symm.obtain(dot_aaf_kf); + if (user==null) { + if(sso.exists() && sso.lastModified()>System.currentTimeMillis()-(8*60*60*1000 /* 8 hours */)) { + String cm_url = access.getProperty(Config.CM_URL); // SSO might overwrite... + FileInputStream fos = new FileInputStream(sso); + try { + access.load(fos); + user = access.getProperty(Config.AAF_MECHID); + encrypted_pass = access.getProperty(Config.AAF_MECHPASS); + // decrypt with .aaf, and re-encrypt with regular Keyfile + access.setProperty(Config.AAF_MECHPASS, + access.encrypt(decryptor.depass(encrypted_pass))); + if(cm_url!=null) { //Command line CM_URL Overwrites ssofile. + access.setProperty(Config.CM_URL, cm_url); + } + } finally { + fos.close(); + } + } else { + diskprops = new Properties(); + String realm = Config.getDefaultRealm(); + // Turn on Console Sysout + System.setOut(stdout); + user=cons.readLine("aaf_id(%s@%s): ",System.getProperty("user.name"),realm); + if(user==null) { + user = System.getProperty("user.name")+'@'+realm; + } else if(user.length()==0) { // + user = System.getProperty("user.name")+'@' + realm; + } else if(user.indexOf('@')<0 && realm!=null) { + user = user+'@'+realm; + } + access.setProperty(Config.AAF_MECHID,user); + diskprops.setProperty(Config.AAF_MECHID,user); + encrypted_pass = new String(cons.readPassword("aaf_password: ")); + System.setOut(os); + encrypted_pass = Symm.ENC+decryptor.enpass(encrypted_pass); + access.setProperty(Config.AAF_MECHPASS,encrypted_pass); + diskprops.setProperty(Config.AAF_MECHPASS,encrypted_pass); + diskprops.setProperty(Config.CADI_KEYFILE, access.getProperty(Config.CADI_KEYFILE)); + } + } + } + if (user == null) { + err = new StringBuilder("Add -D" + Config.AAF_MECHID + "= "); + } + + if (encrypted_pass == null && alias==null) { + if (err == null) { + err = new StringBuilder(); + } else { + err.append("and "); + } + err.append("-D" + Config.AAF_MECHPASS + "= "); + } + } + + public void setLogDefault() { + access.setLogLevel(PropAccess.DEFAULT); + if(stdout!=null) { + System.setOut(stdout); + } + } + + public void setStdErrDefault() { + access.setLogLevel(PropAccess.DEFAULT); + if(stderr!=null) { + System.setErr(stderr); + } + } + + public void setLogDefault(Level level) { + access.setLogLevel(level); + if(stdout!=null) { + System.setOut(stdout); + } + } + + public boolean loginOnly() { + return loginOnly; + } + + public void addProp(String key, String value) { + if(diskprops!=null) { + diskprops.setProperty(key, value); + } + } + + public void writeFiles() throws IOException { + // Store Creds, if they work + if(diskprops!=null) { + if(!dot_aaf.exists()) { + dot_aaf.mkdirs(); + } + FileOutputStream fos = new FileOutputStream(sso); + try { + diskprops.store(fos, "AAF Single Signon"); + } finally { + fos.close(); + sso.setWritable(false,false); + sso.setExecutable(false,false); + sso.setReadable(false,false); + sso.setReadable(true,true); + } + } + if(sso!=null) { + sso.setReadable(false,false); + sso.setWritable(false,false); + sso.setExecutable(false,false); + sso.setReadable(true,true); + sso.setWritable(true,true); + } + } + + public PropAccess access() { + return access; + } + + public StringBuilder err() { + return err; + } + + public String user() { + return user; + } + + public String enc_pass() { + return encrypted_pass; + } + + public boolean useX509() { + return use_X509; + } + + public void close() { + if(close!=null) { + try { + close.invoke(null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // nothing to do here. + } + close = null; + } + } +} diff --git a/aaf/src/test/java/com/att/aaf/content/JU_Content.java b/aaf/src/test/java/com/att/aaf/content/JU_Content.java deleted file mode 100644 index 80215c9..0000000 --- a/aaf/src/test/java/com/att/aaf/content/JU_Content.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.content; - -import java.io.StringReader; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import aaf.v2_0.Error; - -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaData; -import com.att.rosetta.env.RosettaEnv; - -public class JU_Content { - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - - @Test - public void parseErrorJSON() throws Exception { - final String msg = "{\"messageId\":\"SVC2000\",\"text\":\"Select which cred to delete (or 0 to delete all):" + - "1) %1" + - "2) %2" + - "3) %3" + - "4) %4" + - "Run same command again with chosen entry as last parameter\"," + - "\"variables\":[" + - "\"m55555@jr583u.cred.test.com 1 Wed Oct 08 11:48:08 CDT 2014\"," + - "\"m55555@jr583u.cred.test.com 1 Thu Oct 09 12:54:46 CDT 2014\"," + - "\"m55555@jr583u.cred.test.com 1 Tue Jan 06 05:00:00 CST 2015\"," + - "\"m55555@jr583u.cred.test.com 1 Wed Jan 07 05:00:00 CST 2015\"]}"; - - Error err = new Error(); - err.setText("Hello"); - err.getVariables().add("I'm a teapot"); - err.setMessageId("12"); - - -// System.out.println(msg); - RosettaEnv env = new RosettaEnv(); - RosettaDF errDF = env.newDataFactory(aaf.v2_0.Error.class); - errDF.in(RosettaData.TYPE.JSON); - errDF.out(RosettaData.TYPE.JSON); - RosettaData data = errDF.newData(); - data.load(err); - System.out.println(data.asString()); - - data.load(new StringReader(msg)); - err = data.asObject(); - System.out.println(err.getText()); - } - - -} diff --git a/aaf/src/test/java/com/att/aaf/example/CadiTest.java b/aaf/src/test/java/com/att/aaf/example/CadiTest.java deleted file mode 100644 index f50d6ac..0000000 --- a/aaf/src/test/java/com/att/aaf/example/CadiTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.example; - -import java.net.HttpURLConnection; -import java.net.URI; - -import com.att.cadi.Access; -import com.att.cadi.PropAccess; -import com.att.cadi.client.Future; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.http.HClient; -import com.att.cadi.http.HX509SS; - -public class CadiTest { - public static void main(String args[]) { - Access access = new PropAccess(); - try { - SecurityInfoC si = new SecurityInfoC(access); - HClient hclient = new HClient( - new HX509SS(si), - new URI("https://mithrilcsp.sbc.com:8085"),3000); - hclient.setMethod("OPTIONS"); - hclient.setPathInfo("/gui/cadi/log/toggle/INFO"); - hclient.send(); - Future future = hclient.futureReadString(); - if(future.get(5000)) { - System.out.println(future.value); - } else { - System.out.printf("Error: %d-%s", future.code(),future.body()); - } - - } catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/aaf/src/test/java/com/att/aaf/example/ExampleAuthCheck.java b/aaf/src/test/java/com/att/aaf/example/ExampleAuthCheck.java deleted file mode 100644 index 53f8c8e..0000000 --- a/aaf/src/test/java/com/att/aaf/example/ExampleAuthCheck.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.example; - -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.locator.DNSLocator; - -public class ExampleAuthCheck { - public static void main(String args[]) { - // Link or reuse to your Logging mechanism - PropAccess myAccess = new PropAccess(); // - - try { - AAFConHttp acon = new AAFConHttp(myAccess, new DNSLocator( - myAccess,"https","localhost","8100")); - AAFAuthn authn = acon.newAuthn(); - long start; - for (int i=0;i<10;++i) { - start = System.nanoTime(); - String err = authn.validate("", "gritty"); - if(err!=null) System.err.println(err); - else System.out.println("I'm ok"); - - err = authn.validate("bogus", "gritty"); - if(err!=null) System.err.println(err + " (correct error)"); - else System.out.println("I'm ok"); - - System.out.println((System.nanoTime()-start)/1000000f + " ms"); - } - } catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0.java b/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0.java deleted file mode 100644 index 5f6179e..0000000 --- a/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.example; - -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; - -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFCon; -import com.att.cadi.aaf.v2_0.AAFConDME2; -import com.att.cadi.aaf.v2_0.AAFLurPerm; - -public class ExamplePerm2_0 { - public static void main(String args[]) { - - // Link or reuse to your Logging mechanism - PropAccess myAccess = new PropAccess(); - - // - try { - AAFCon acon = new AAFConDME2(myAccess); - - // AAFLur has pool of DME clients as needed, and Caches Client lookups - AAFLurPerm aafLur = acon.newLur(); - - // Note: If you need both Authn and Authz construct the following: - AAFAuthn aafAuthn = acon.newAuthn(aafLur); - - // Do not set Mech ID until after you construct AAFAuthn, - // because we initiate "401" info to determine the Realm of - // of the service we're after. - acon.basicAuth("mc0897@aaf.att.com", "XXXXXX"); - - try { - - // Normally, you obtain Principal from Authentication System. - // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() - // If you use CADI as Authenticator, it will get you these Principals from - // CSP or BasicAuth mechanisms. - String id = "mc0897@aaf.att.com"; //"cluster_admin@gridcore.att.com"; - - // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. - String ok = aafAuthn.validate(id, "XXXXXX"); - if(ok!=null)System.out.println(ok); - - ok = aafAuthn.validate(id, "wrongPass"); - if(ok!=null)System.out.println(ok); - - - // AAF Style permissions are in the form - // Type, Instance, Action - AAFPermission perm = new AAFPermission("com.att.grid.core.coh",":dev_cluster", "WRITE"); - - // Now you can ask the LUR (Local Representative of the User Repository about Authorization - // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object - // instead of creating your own LUR - System.out.println("Does " + id + " have " + perm); - if(aafLur.fish(id, perm)) { - System.out.println("Yes, you have permission"); - } else { - System.out.println("No, you don't have permission"); - } - - System.out.println("Does Bogus have " + perm); - if(aafLur.fish("Bogus", perm)) { - System.out.println("Yes, you have permission"); - } else { - System.out.println("No, you don't have permission"); - } - - // Or you can all for all the Permissions available - List perms = new ArrayList(); - - aafLur.fishAll(id,perms); - for(Permission prm : perms) { - System.out.println(prm.getKey()); - } - - // It might be helpful in some cases to clear the User's identity from the Cache - aafLur.remove(id); - } finally { - aafLur.destroy(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0_DME2.java b/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0_DME2.java deleted file mode 100644 index 5ebbe9f..0000000 --- a/aaf/src/test/java/com/att/aaf/example/ExamplePerm2_0_DME2.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.example; - -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; - -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.aaf.v2_0.AAFLurPerm; -import com.att.cadi.locator.DNSLocator; - -public class ExamplePerm2_0_DME2 { - public static void main(String args[]) { - // Link or reuse to your Logging mechanism - PropAccess myAccess = new PropAccess(); - - // - try { - AAFConHttp acon = new AAFConHttp(myAccess, new DNSLocator( - myAccess,"https","localhost","8100")); - - // AAFLur has pool of DME clients as needed, and Caches Client lookups - AAFLurPerm aafLur = acon.newLur(); - - // Note: If you need both Authn and Authz construct the following: - AAFAuthn aafAuthn = acon.newAuthn(aafLur); - - // Do not set Mech ID until after you construct AAFAuthn, - // because we initiate "401" info to determine the Realm of - // of the service we're after. - acon.basicAuth("mc0897@aaf.att.com", "XXXXXX"); - - try { - - // Normally, you obtain Principal from Authentication System. - // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() - // If you use CADI as Authenticator, it will get you these Principals from - // CSP or BasicAuth mechanisms. - String id = "mc0897@aaf.att.com"; //"cluster_admin@gridcore.att.com"; - - // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. - String ok = aafAuthn.validate(id, "XXXXXX"); - if(ok!=null)System.out.println(ok); - - ok = aafAuthn.validate(id, "wrongPass"); - if(ok!=null)System.out.println(ok); - - - // AAF Style permissions are in the form - // Type, Instance, Action - AAFPermission perm = new AAFPermission("com.att.grid.core.coh",":dev_cluster", "WRITE"); - - // Now you can ask the LUR (Local Representative of the User Repository about Authorization - // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object - // instead of creating your own LUR - System.out.println("Does " + id + " have " + perm); - if(aafLur.fish(id, perm)) { - System.out.println("Yes, you have permission"); - } else { - System.out.println("No, you don't have permission"); - } - - System.out.println("Does Bogus have " + perm); - if(aafLur.fish("Bogus", perm)) { - System.out.println("Yes, you have permission"); - } else { - System.out.println("No, you don't have permission"); - } - - // Or you can all for all the Permissions available - List perms = new ArrayList(); - - aafLur.fishAll(id,perms); - for(Permission prm : perms) { - System.out.println(prm.getKey()); - } - - // It might be helpful in some cases to clear the User's identity from the Cache - aafLur.remove(id); - } finally { - aafLur.destroy(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/aaf/src/test/java/com/att/aaf/example/X509Test.java b/aaf/src/test/java/com/att/aaf/example/X509Test.java deleted file mode 100644 index 517393f..0000000 --- a/aaf/src/test/java/com/att/aaf/example/X509Test.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.example; - -import java.security.Principal; - -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.aaf.v2_0.AAFLurPerm; -import com.att.cadi.client.Future; -import com.att.cadi.locator.DNSLocator; -import com.att.cadi.lur.LocalPermission; - -public class X509Test { - public static void main(String args[]) { - // Link or reuse to your Logging mechanism - - PropAccess myAccess = new PropAccess(); - - // - try { - AAFConHttp con = new AAFConHttp(myAccess, - new DNSLocator(myAccess,"https","mithrilcsp.sbc.com","8100")); - - // AAFLur has pool of DME clients as needed, and Caches Client lookups - AAFLurPerm aafLur = con.newLur(); - - // Note: If you need both Authn and Authz construct the following: -// AAFAuthn aafAuthn = con.newAuthn(aafLur); - - // con.x509Alias("aaf.att"); // alias in keystore - - try { - - // Normally, you obtain Principal from Authentication System. -// // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() -// // If you use CADI as Authenticator, it will get you these Principals from -// // CSP or BasicAuth mechanisms. -// String id = "cluster_admin@gridcore.att.com"; -// -// // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. - Future fs = - con.client("2.0").read("/authz/perms/com.att.aaf.ca","application/Perms+json"); - if(fs.get(3000)) { - System.out.println(fs.value); - } else { - System.out.println("Error: " + fs.code() + ':' + fs.body()); - } - - // Check on Perms with LUR - if(aafLur.fish(new Principal() { - @Override - public String getName() { - return "m12345@aaf.att.com"; - } - }, new LocalPermission("com.att.aaf.ca|aaf|request"))) { - System.out.println("Has Perm"); - } else { - System.out.println("Does NOT Have Perm"); - } - } finally { - aafLur.destroy(); - } - } catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_JMeter.java b/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_JMeter.java deleted file mode 100644 index d5f92c1..0000000 --- a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_JMeter.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.aaf.test; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.aaf.v2_0.AAFLurPerm; -import com.att.cadi.aaf.v2_0.AAFTaf; -import com.att.cadi.config.Config; -import com.att.cadi.locator.DNSLocator; -import com.att.cadi.principal.CachedBasicPrincipal; - -import junit.framework.Assert; - -public class JU_JMeter { - private static AAFConHttp aaf; - private static AAFAuthn aafAuthn; - private static AAFLurPerm aafLur; - private static ArrayList perfIDs; - - private static AAFTaf aafTaf; - private static PropAccess access; - - @BeforeClass - public static void before() throws Exception { - if(aafLur==null) { - Properties props = System.getProperties(); - props.setProperty("AFT_LATITUDE", "32.780140"); - props.setProperty("AFT_LONGITUDE", "-96.800451"); - props.setProperty("DME2_EP_REGISTRY_CLASS","DME2FS"); - props.setProperty("AFT_DME2_EP_REGISTRY_FS_DIR","/Volumes/Data/src/authz/dme2reg"); - props.setProperty("AFT_ENVIRONMENT", "AFTUAT"); - props.setProperty("SCLD_PLATFORM", "NON-PROD"); - props.setProperty(Config.AAF_URL,"https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE"); - props.setProperty(Config.AAF_READ_TIMEOUT, "2000"); - int timeToLive = 3000; - props.setProperty(Config.AAF_CLEAN_INTERVAL, Integer.toString(timeToLive)); - props.setProperty(Config.AAF_HIGH_COUNT, "4"); - - String aafPerfIDs = props.getProperty("AAF_PERF_IDS"); - perfIDs = new ArrayList(); - File perfFile = null; - if(aafPerfIDs!=null) { - perfFile = new File(aafPerfIDs); - } - - access = new PropAccess(); - aaf = new AAFConHttp(access, new DNSLocator(access,"https","localhost","8100")); - aafTaf = new AAFTaf(aaf,false); - aafLur = aaf.newLur(aafTaf); - aafAuthn = aaf.newAuthn(aafTaf); - aaf.basicAuth("testid@aaf.att.com", "whatever"); - - if(perfFile==null||!perfFile.exists()) { - perfIDs.add(new CachedBasicPrincipal(aafTaf, - "Basic dGVzdGlkOndoYXRldmVy", - "aaf.att.com",timeToLive)); - perfIDs.add(new Princ("ab1234@aaf.att.com")); // Example of Local ID, which isn't looked up - } else { - BufferedReader ir = new BufferedReader(new FileReader(perfFile)); - try { - String line; - while((line = ir.readLine())!=null) { - if((line=line.trim()).length()>0) - perfIDs.add(new Princ(line)); - } - } finally { - ir.close(); - } - } - Assert.assertNotNull(aafLur); - } - } - - private static class Princ implements Principal { - private String name; - public Princ(String name) { - this.name = name; - } - public String getName() { - return name; - } - - }; - - private static int index = -1; - - private synchronized Principal getIndex() { - if(perfIDs.size()<=++index)index=0; - return perfIDs.get(index); - } - @Test - public void test() { - try { - aafAuthn.validate("testid@aaf.att.com", "whatever"); - List perms = new ArrayList(); - aafLur.fishAll(getIndex(), perms); -// Assert.assertFalse(perms.isEmpty()); -// for(Permission p : perms) { -// //access.log(Access.Level.AUDIT, p.permType()); -// } - } catch (Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - Assert.assertFalse(sw.toString(),true); - } - } - -} diff --git a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_Lur2_0Call.java b/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_Lur2_0Call.java deleted file mode 100644 index f85a4e2..0000000 --- a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_Lur2_0Call.java +++ /dev/null @@ -1,575 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.aaf.test; - -import static org.junit.Assert.assertEquals; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.security.Principal; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.att.cadi.CadiException; -import com.att.cadi.Lur; -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.Symm; -import com.att.cadi.Taf.LifeForm; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.aaf.v2_0.AAFLurPerm; -import com.att.cadi.aaf.v2_0.AAFTaf; -import com.att.cadi.locator.DNSLocator; -import com.att.cadi.lur.ConfigPrincipal; -import com.att.cadi.lur.LocalPermission; -import com.att.cadi.taf.TafResp; - -public class JU_Lur2_0Call { - private static AAFConHttp aaf; - private static PropAccess access; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - access = new PropAccess(); - aaf = new AAFConHttp(access,new DNSLocator(access,"https","localhost","8100")); - aaf.basicAuth("testid", "whatever"); - } - - @Test - public void test() throws Exception { - - AAFLurPerm aafLur = aaf.newLur(); - - Principal pri = new ConfigPrincipal("testid@aaf.att.com","whatever"); - for (int i = 0; i < 10; ++i) { - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|write"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kumquat|write"),false); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|read"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kumquat|read"),true); - - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","write"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","kumquat","write"),false); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","read"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","kumquat","read"),true); - - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum.*|read"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|!wr*"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance"),true); - - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!kum.*","read"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","!wr*"),true); - - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum[Qq]uat|read"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my[iI]nstance|!wr*"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my[iI]nstance|!wr*"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|!wr*"),true); - - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!kum[Qq]uat","read"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!my[iI]nstance","!wr*"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!my[iI]nstance","!wr*"),true); - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","!wr*"),true); - - - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my.nstance|!wr*"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|my.nstance|!wr*"),false); - - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|my.nstance|!wr*"),false); - - //Maitrayee, aren't we going to have issues if we do RegExp with "."? - //Is it too expensive to only do Reg Ex in presence of special characters, []{}*, etc? Not sure this helps for GRID. - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kum.quat|read"),true); - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum..uat|read"),true); - - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance"),true); // ok if Stored Action is "*" - - // Key Evaluations - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*:!my.*|write"),true); // ok if Stored Action is "*" - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*|write"),false); // not ok if key lengths don't match "*" - print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*:myCF|write"),true); // ok if Stored Action is "*" - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*:!my.*","write"),true); // ok if Stored Action is "*" - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*:myCF","write"),true); // ok if Stored Action is "*" - print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*","write"),false); // not ok if key lengths don't match - - } - - print(aafLur, pri, new LocalPermission("bogus"),false); - -// try { -// Thread.sleep(7000); -// } catch (InterruptedException e) { -// e.printStackTrace(); -// } - for (int i = 0; i < 10; ++i) - print(aafLur, pri, new LocalPermission("supergroup"),false); - - System.out.println("All Done"); - } - @Test - public void testTaf() throws Exception { - AAFTaf aaft = new AAFTaf(aaf,true); - - TafResp resp; - // No Header - resp = aaft.validate(LifeForm.CBLF, new Req(), null); - assertEquals(TafResp.RESP.TRY_AUTHENTICATING, resp.isAuthenticated()); - - String auth = "Basic " + Symm.base64.encode("testid:whatever"); - resp = aaft.validate(LifeForm.CBLF, new Req("Authorization",auth), null); - assertEquals(TafResp.RESP.IS_AUTHENTICATED, resp.isAuthenticated()); - - } -// @Test -// public void testRole() throws CadiException { -// TestAccess ta = new TestAccess(); -// AAFLurRole1_0 aafLur = new AAFLurRole1_0( -// ta, -//// "http://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=1.0.0/envContext=UAT/routeOffer=BAU_SE", -// "http://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=1.0.0/envContext=DEV/routeOffer=D1", -// "m12345", "m12345pass", 50000, // dme Time -// // 5*60000); // 5 minutes User Expiration -// 50000, // 5 seconds after Expiration -// 200); // High Count of items.. These do not take much memory -// -// Principal pri = new ConfigPrincipal("xy1234","whatever); -// for (int i = 0; i < 10; ++i) { -//// print(aafLur, pri, new LocalPermission("*|*|*|com.att.authz")); -// print(aafLur, pri, new LocalPermission("service|myInstance|write"),false); -// print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|write"),false); -// print(aafLur, pri, new LocalPermission("com.att.cadi"),true); -// print(aafLur, pri, new LocalPermission("global"),true); -// print(aafLur, pri, new LocalPermission("kumquat"),false); -// } -// -// print(aafLur, pri, new LocalPermission("bogus"),false); -// -// for (int i = 0; i < 10; ++i) -// print(aafLur, pri, new LocalPermission("supergroup"),false); -// -// System.out.println("All Done"); -// } - - - private void print(Lur aafLur, Principal pri, Permission perm, boolean shouldBe) - throws CadiException { - long start = System.nanoTime(); - - // The Call - boolean ok = aafLur.fish(pri, perm); - - assertEquals(shouldBe,ok); - float ms = (System.nanoTime() - start) / 1000000f; - if (ok) { - System.out.println("Yes, part of " + perm.getKey() + " (" + ms - + "ms)"); - } else { - System.out.println("No, not part of " + perm.getKey() + " (" + ms - + "ms)"); - } - } - - @SuppressWarnings("rawtypes") - public class Req implements HttpServletRequest { - private String[] headers; - - public Req(String ... headers) { - this.headers = headers; - } - - public Object getAttribute(String name) { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - public Enumeration getAttributeNames() { - // TODO Auto-generated method stub - return null; - } - - public String getCharacterEncoding() { - // TODO Auto-generated method stub - return null; - } - - public void setCharacterEncoding(String env) - throws UnsupportedEncodingException { - // TODO Auto-generated method stub - - } - - public int getContentLength() { - // TODO Auto-generated method stub - return 0; - } - - public String getContentType() { - // TODO Auto-generated method stub - return null; - } - - public ServletInputStream getInputStream() throws IOException { - // TODO Auto-generated method stub - return null; - } - - public String getParameter(String name) { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - public Enumeration getParameterNames() { - // TODO Auto-generated method stub - return null; - } - - public String[] getParameterValues(String name) { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - public Map getParameterMap() { - // TODO Auto-generated method stub - return null; - } - - public String getProtocol() { - // TODO Auto-generated method stub - return null; - } - - public String getScheme() { - // TODO Auto-generated method stub - return null; - } - - public String getServerName() { - // TODO Auto-generated method stub - return null; - } - - public int getServerPort() { - // TODO Auto-generated method stub - return 0; - } - - public BufferedReader getReader() throws IOException { - // TODO Auto-generated method stub - return null; - } - - public String getRemoteAddr() { - // TODO Auto-generated method stub - return null; - } - - public String getRemoteHost() { - // TODO Auto-generated method stub - return null; - } - - public void setAttribute(String name, Object o) { - // TODO Auto-generated method stub - - } - - public void removeAttribute(String name) { - // TODO Auto-generated method stub - - } - - public Locale getLocale() { - // TODO Auto-generated method stub - return null; - } - - @SuppressWarnings("unchecked") - public Enumeration getLocales() { - // TODO Auto-generated method stub - return null; - } - - public boolean isSecure() { - // TODO Auto-generated method stub - return false; - } - - public RequestDispatcher getRequestDispatcher(String path) { - // TODO Auto-generated method stub - return null; - } - - public String getRealPath(String path) { - // TODO Auto-generated method stub - return null; - } - - public int getRemotePort() { - // TODO Auto-generated method stub - return 0; - } - - public String getLocalName() { - // TODO Auto-generated method stub - return null; - } - - public String getLocalAddr() { - // TODO Auto-generated method stub - return null; - } - - public int getLocalPort() { - // TODO Auto-generated method stub - return 0; - } - - public String getAuthType() { - // TODO Auto-generated method stub - return null; - } - - public Cookie[] getCookies() { - // TODO Auto-generated method stub - return null; - } - - public long getDateHeader(String name) { - // TODO Auto-generated method stub - return 0; - } - - public String getHeader(String name) { - for(int i=1;i getParts() throws IOException, ServletException { - // TODO Auto-generated method stub - return null; - } - - @Override - public Part getPart(String name) throws IOException, ServletException { - // TODO Auto-generated method stub - return null; - } - - } -} diff --git a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_PermEval.java b/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_PermEval.java deleted file mode 100644 index 8dee6cf..0000000 --- a/aaf/src/test/java/com/att/cadi/lur/aaf/test/JU_PermEval.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.aaf.test; - -import static org.junit.Assert.*; - -import org.junit.AfterClass; -import org.junit.Test; - -import com.att.cadi.aaf.PermEval; - -public class JU_PermEval { - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void test() { - assertTrue(PermEval.evalInstance(":com.att.temp:role:write",":!com.att.*:role:write")); - - // TRUE - assertTrue(PermEval.evalAction("fred","fred")); - assertTrue(PermEval.evalAction("fred,wilma","fred")); - assertTrue(PermEval.evalAction("barney,betty,fred,wilma","fred")); - assertTrue(PermEval.evalAction("*","fred")); - - assertTrue(PermEval.evalInstance("fred","fred")); - assertTrue(PermEval.evalInstance("fred,wilma","fred")); - assertTrue(PermEval.evalInstance("barney,betty,fred,wilma","fred")); - assertTrue(PermEval.evalInstance("*","fred")); - - assertTrue(PermEval.evalInstance(":fred:fred",":fred:fred")); - assertTrue(PermEval.evalInstance(":fred:fred,wilma",":fred:fred")); - assertTrue(PermEval.evalInstance(":fred:barney,betty,fred,wilma",":fred:fred")); - assertTrue(PermEval.evalInstance("*","fred")); - assertTrue(PermEval.evalInstance(":*:fred",":fred:fred")); - assertTrue(PermEval.evalInstance(":fred:*",":fred:fred")); - assertTrue(PermEval.evalInstance(":fred:fred",":!f.*:fred")); - assertTrue(PermEval.evalInstance(":fred:fred",":fred:!f.*")); - - /// FALSE - assertFalse(PermEval.evalInstance("fred","wilma")); - assertFalse(PermEval.evalInstance("fred,barney,betty","wilma")); - assertFalse(PermEval.evalInstance(":fred:fred",":fred:wilma")); - assertFalse(PermEval.evalInstance(":fred:fred",":wilma:fred")); - assertFalse(PermEval.evalInstance(":fred:fred",":wilma:!f.*")); - assertFalse(PermEval.evalInstance(":fred:fred",":!f.*:wilma")); - assertFalse(PermEval.evalInstance(":fred:fred",":!w.*:!f.*")); - assertFalse(PermEval.evalInstance(":fred:fred",":!f.*:!w.*")); - - assertFalse(PermEval.evalInstance(":fred:fred",":fred:!x.*")); - - // MSO Tests 12/3/2015 - assertFalse(PermEval.evalInstance("/v1/services/features/*","/v1/services/features")); - assertFalse(PermEval.evalInstance(":v1:services:features:*",":v1:services:features")); - assertTrue(PermEval.evalInstance("/v1/services/features/*","/v1/services/features/api1")); - assertTrue(PermEval.evalInstance(":v1:services:features:*",":v1:services:features:api2")); - // MSO - Xue Gao - assertTrue(PermEval.evalInstance(":v1:requests:*",":v1:requests:test0-service")); - - - - // Same tests, with Slashes - assertTrue(PermEval.evalInstance("/fred/fred","/fred/fred")); - assertTrue(PermEval.evalInstance("/fred/fred,wilma","/fred/fred")); - assertTrue(PermEval.evalInstance("/fred/barney,betty,fred,wilma","/fred/fred")); - assertTrue(PermEval.evalInstance("*","fred")); - assertTrue(PermEval.evalInstance("/*/fred","/fred/fred")); - assertTrue(PermEval.evalInstance("/fred/*","/fred/fred")); - assertTrue(PermEval.evalInstance("/fred/fred","/!f.*/fred")); - assertTrue(PermEval.evalInstance("/fred/fred","/fred/!f.*")); - - /// FALSE - assertFalse(PermEval.evalInstance("fred","wilma")); - assertFalse(PermEval.evalInstance("fred,barney,betty","wilma")); - assertFalse(PermEval.evalInstance("/fred/fred","/fred/wilma")); - assertFalse(PermEval.evalInstance("/fred/fred","/wilma/fred")); - assertFalse(PermEval.evalInstance("/fred/fred","/wilma/!f.*")); - assertFalse(PermEval.evalInstance("/fred/fred","/!f.*/wilma")); - assertFalse(PermEval.evalInstance("/fred/fred","/!w.*/!f.*")); - assertFalse(PermEval.evalInstance("/fred/fred","/!f.*/!w.*")); - - assertFalse(PermEval.evalInstance("/fred/fred","/fred/!x.*")); - - } - -} diff --git a/aaf/src/test/java/com/att/cadi/lur/aaf/test/MultiThreadPermHit.java b/aaf/src/test/java/com/att/cadi/lur/aaf/test/MultiThreadPermHit.java deleted file mode 100644 index c4f5f7c..0000000 --- a/aaf/src/test/java/com/att/cadi/lur/aaf/test/MultiThreadPermHit.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.aaf.test; - -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; - -import com.att.cadi.Access; -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.aaf.AAFPermission; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFConHttp; -import com.att.cadi.aaf.v2_0.AAFLurPerm; -import com.att.cadi.config.Config; -import com.att.cadi.locator.PropertyLocator; - -public class MultiThreadPermHit { - public static void main(String args[]) { - // Link or reuse to your Logging mechanism - PropAccess myAccess = new PropAccess(); // - - // - try { - AAFConHttp con = new AAFConHttp(myAccess,new PropertyLocator("https://mithrilcsp.sbc.com:8100")); - - // AAFLur has pool of DME clients as needed, and Caches Client lookups - final AAFLurPerm aafLur = con.newLur(); - aafLur.setDebug("m12345@aaf.att.com"); - - // Note: If you need both Authn and Authz construct the following: - AAFAuthn aafAuthn = con.newAuthn(aafLur); - - // Do not set Mech ID until after you construct AAFAuthn, - // because we initiate "401" info to determine the Realm of - // of the service we're after. - final String id = myAccess.getProperty(Config.AAF_MECHID,null); - final String pass = myAccess.decrypt(myAccess.getProperty(Config.AAF_MECHPASS,null),false); - if(id!=null && pass!=null) { - try { - - // Normally, you obtain Principal from Authentication System. - // // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() - // // If you use CADI as Authenticator, it will get you these Principals from - // // CSP or BasicAuth mechanisms. - // String id = "cluster_admin@gridcore.att.com"; - // - // // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. - String ok; - ok = aafAuthn.validate(id, pass); - if(ok!=null) { - System.out.println(ok); - } - - List pond = new ArrayList(); - for(int i=0;i<20;++i) { - pond.clear(); - aafLur.fishAll(i+id, pond); - if(ok!=null && i%1000==0) { - System.out.println(i + " " + ok); - } - } - - for(int i=0;i<1000000;++i) { - ok = aafAuthn.validate( i+ id, "wrongPass"); - if(ok!=null && i%1000==0) { - System.out.println(i + " " + ok); - } - } - - final AAFPermission perm = new AAFPermission("com.att.aaf.access","*","*"); - - // Now you can ask the LUR (Local Representative of the User Repository about Authorization - // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object - // instead of creating your own LUR - for(int i=0;i<4;++i) { - if(aafLur.fish(id, perm)) { - System.out.println("Yes, " + id + " has permission for " + perm.getKey()); - } else { - System.out.println("No, " + id + " does not have permission for " + perm.getKey()); - } - } - - - // Or you can all for all the Permissions available - List perms = new ArrayList(); - - - aafLur.fishAll(id,perms); - System.out.println("Perms for " + id); - for(Permission prm : perms) { - System.out.println(prm.getKey()); - } - - System.out.println("Press any key to continue"); - System.in.read(); - - for(int j=0;j<5;++j) { - new Thread(new Runnable() { - @Override - public void run() { - for(int i=0;i<20;++i) { - if(aafLur.fish(id, perm)) { - System.out.println("Yes, " + id + " has permission for " + perm.getKey()); - } else { - System.out.println("No, " + id + " does not have permission for " + perm.getKey()); - } - } - } - }).start(); - } - - - } finally { - aafLur.destroy(); - } - } else { // checked on IDs - System.err.println(Config.AAF_MECHID + " and/or " + Config.AAF_MECHPASS + " are not set."); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/aaf/src/test/java/com/att/cadi/lur/aaf/test/TestAccess.java b/aaf/src/test/java/com/att/cadi/lur/aaf/test/TestAccess.java deleted file mode 100644 index 7d83625..0000000 --- a/aaf/src/test/java/com/att/cadi/lur/aaf/test/TestAccess.java +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.aaf.test; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; - -import com.att.cadi.Access; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; - -public class TestAccess implements Access { - private Symm symm; - private PrintStream out; - - public TestAccess(PrintStream out) { - this.out = out; - InputStream is = ClassLoader.getSystemResourceAsStream("cadi.properties"); - try { - System.getProperties().load(is); - } catch (IOException e) { - e.printStackTrace(out); - } finally { - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(out); - } - } - - String keyfile = System.getProperty(Config.CADI_KEYFILE); - if(keyfile==null) { - System.err.println("No " + Config.CADI_KEYFILE + " in Classpath"); - } else { - try { - is = new FileInputStream(keyfile); - try { - symm = Symm.obtain(is); - } finally { - is.close(); - } - } catch (IOException e) { - e.printStackTrace(out); - } - } - - - - } - - public void log(Level level, Object... elements) { - boolean first = true; - for(int i=0;i aafAuthn; + private static AAFLurPerm aafLur; + private static ArrayList perfIDs; + + private static AAFTaf aafTaf; + private static PropAccess access; + + @BeforeClass + public static void before() throws Exception { + if(aafLur==null) { + Properties props = System.getProperties(); + props.setProperty("AFT_LATITUDE", "32.780140"); + props.setProperty("AFT_LONGITUDE", "-96.800451"); + props.setProperty("DME2_EP_REGISTRY_CLASS","DME2FS"); + props.setProperty("AFT_DME2_EP_REGISTRY_FS_DIR","/Volumes/Data/src/authz/dme2reg"); + props.setProperty("AFT_ENVIRONMENT", "AFTUAT"); + props.setProperty("SCLD_PLATFORM", "NON-PROD"); + props.setProperty(Config.AAF_URL,"https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE"); + props.setProperty(Config.AAF_READ_TIMEOUT, "2000"); + int timeToLive = 3000; + props.setProperty(Config.AAF_CLEAN_INTERVAL, Integer.toString(timeToLive)); + props.setProperty(Config.AAF_HIGH_COUNT, "4"); + + String aafPerfIDs = props.getProperty("AAF_PERF_IDS"); + perfIDs = new ArrayList(); + File perfFile = null; + if(aafPerfIDs!=null) { + perfFile = new File(aafPerfIDs); + } + + access = new PropAccess(); + aaf = new AAFConHttp(access, new DNSLocator(access,"https","localhost","8100")); + aafTaf = new AAFTaf(aaf,false); + aafLur = aaf.newLur(aafTaf); + aafAuthn = aaf.newAuthn(aafTaf); + aaf.basicAuth("testid@aaf.att.com", "whatever"); + + if(perfFile==null||!perfFile.exists()) { + perfIDs.add(new CachedBasicPrincipal(aafTaf, + "Basic dGVzdGlkOndoYXRldmVy", + "aaf.att.com",timeToLive)); + perfIDs.add(new Princ("ab1234@aaf.att.com")); // Example of Local ID, which isn't looked up + } else { + BufferedReader ir = new BufferedReader(new FileReader(perfFile)); + try { + String line; + while((line = ir.readLine())!=null) { + if((line=line.trim()).length()>0) + perfIDs.add(new Princ(line)); + } + } finally { + ir.close(); + } + } + Assert.assertNotNull(aafLur); + } + } + + private static class Princ implements Principal { + private String name; + public Princ(String name) { + this.name = name; + } + public String getName() { + return name; + } + + }; + + private static int index = -1; + + private synchronized Principal getIndex() { + if(perfIDs.size()<=++index)index=0; + return perfIDs.get(index); + } + @Test + public void test() { + try { + aafAuthn.validate("testid@aaf.att.com", "whatever"); + List perms = new ArrayList(); + aafLur.fishAll(getIndex(), perms); +// Assert.assertFalse(perms.isEmpty()); +// for(Permission p : perms) { +// //access.log(Access.Level.AUDIT, p.permType()); +// } + } catch (Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + Assert.assertFalse(sw.toString(),true); + } + } + +} diff --git a/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_Lur2_0Call.java b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_Lur2_0Call.java new file mode 100644 index 0000000..bd4e162 --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_Lur2_0Call.java @@ -0,0 +1,574 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur.aaf.test; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.security.Principal; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.Taf.LifeForm; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm; +import org.onap.aaf.cadi.aaf.v2_0.AAFTaf; +import org.onap.aaf.cadi.locator.DNSLocator; +import org.onap.aaf.cadi.lur.ConfigPrincipal; +import org.onap.aaf.cadi.lur.LocalPermission; +import org.onap.aaf.cadi.taf.TafResp; + +public class JU_Lur2_0Call { + private static AAFConHttp aaf; + private static PropAccess access; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + access = new PropAccess(); + aaf = new AAFConHttp(access,new DNSLocator(access,"https","localhost","8100")); + aaf.basicAuth("testid", "whatever"); + } + + @Test + public void test() throws Exception { + + AAFLurPerm aafLur = aaf.newLur(); + + Principal pri = new ConfigPrincipal("testid@aaf.att.com","whatever"); + for (int i = 0; i < 10; ++i) { + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|write"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kumquat|write"),false); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|read"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kumquat|read"),true); + + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","write"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","kumquat","write"),false); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","read"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","kumquat","read"),true); + + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum.*|read"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|!wr*"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance"),true); + + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!kum.*","read"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","!wr*"),true); + + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum[Qq]uat|read"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my[iI]nstance|!wr*"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my[iI]nstance|!wr*"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|!wr*"),true); + + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!kum[Qq]uat","read"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!my[iI]nstance","!wr*"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","!my[iI]nstance","!wr*"),true); + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service","myInstance","!wr*"),true); + + + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!my.nstance|!wr*"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|my.nstance|!wr*"),false); + + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|my.nstance|!wr*"),false); + + //Maitrayee, aren't we going to have issues if we do RegExp with "."? + //Is it too expensive to only do Reg Ex in presence of special characters, []{}*, etc? Not sure this helps for GRID. + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|kum.quat|read"),true); + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|!kum..uat|read"),true); + + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance"),true); // ok if Stored Action is "*" + + // Key Evaluations + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*:!my.*|write"),true); // ok if Stored Action is "*" + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*|write"),false); // not ok if key lengths don't match "*" + print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|:myCluster:*:myCF|write"),true); // ok if Stored Action is "*" + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*:!my.*","write"),true); // ok if Stored Action is "*" + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*:myCF","write"),true); // ok if Stored Action is "*" + print(aafLur, pri, new AAFPermission("com.test.JU_Lur2_0Call.service",":myCluster:*","write"),false); // not ok if key lengths don't match + + } + + print(aafLur, pri, new LocalPermission("bogus"),false); + +// try { +// Thread.sleep(7000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } + for (int i = 0; i < 10; ++i) + print(aafLur, pri, new LocalPermission("supergroup"),false); + + System.out.println("All Done"); + } + @Test + public void testTaf() throws Exception { + AAFTaf aaft = new AAFTaf(aaf,true); + + TafResp resp; + // No Header + resp = aaft.validate(LifeForm.CBLF, new Req(), null); + assertEquals(TafResp.RESP.TRY_AUTHENTICATING, resp.isAuthenticated()); + + String auth = "Basic " + Symm.base64.encode("testid:whatever"); + resp = aaft.validate(LifeForm.CBLF, new Req("Authorization",auth), null); + assertEquals(TafResp.RESP.IS_AUTHENTICATED, resp.isAuthenticated()); + + } +// @Test +// public void testRole() throws CadiException { +// TestAccess ta = new TestAccess(); +// AAFLurRole1_0 aafLur = new AAFLurRole1_0( +// ta, +//// "http://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=1.0.0/envContext=UAT/routeOffer=BAU_SE", +// "http://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=1.0.0/envContext=DEV/routeOffer=D1", +// "m12345", "m12345pass", 50000, // dme Time +// // 5*60000); // 5 minutes User Expiration +// 50000, // 5 seconds after Expiration +// 200); // High Count of items.. These do not take much memory +// +// Principal pri = new ConfigPrincipal("xy1234","whatever); +// for (int i = 0; i < 10; ++i) { +//// print(aafLur, pri, new LocalPermission("*|*|*|com.att.authz")); +// print(aafLur, pri, new LocalPermission("service|myInstance|write"),false); +// print(aafLur, pri, new LocalPermission("com.test.JU_Lur2_0Call.service|myInstance|write"),false); +// print(aafLur, pri, new LocalPermission("com.att.cadi"),true); +// print(aafLur, pri, new LocalPermission("global"),true); +// print(aafLur, pri, new LocalPermission("kumquat"),false); +// } +// +// print(aafLur, pri, new LocalPermission("bogus"),false); +// +// for (int i = 0; i < 10; ++i) +// print(aafLur, pri, new LocalPermission("supergroup"),false); +// +// System.out.println("All Done"); +// } + + + private void print(Lur aafLur, Principal pri, Permission perm, boolean shouldBe) + throws CadiException { + long start = System.nanoTime(); + + // The Call + boolean ok = aafLur.fish(pri, perm); + + assertEquals(shouldBe,ok); + float ms = (System.nanoTime() - start) / 1000000f; + if (ok) { + System.out.println("Yes, part of " + perm.getKey() + " (" + ms + + "ms)"); + } else { + System.out.println("No, not part of " + perm.getKey() + " (" + ms + + "ms)"); + } + } + + @SuppressWarnings("rawtypes") + public class Req implements HttpServletRequest { + private String[] headers; + + public Req(String ... headers) { + this.headers = headers; + } + + public Object getAttribute(String name) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + public Enumeration getAttributeNames() { + // TODO Auto-generated method stub + return null; + } + + public String getCharacterEncoding() { + // TODO Auto-generated method stub + return null; + } + + public void setCharacterEncoding(String env) + throws UnsupportedEncodingException { + // TODO Auto-generated method stub + + } + + public int getContentLength() { + // TODO Auto-generated method stub + return 0; + } + + public String getContentType() { + // TODO Auto-generated method stub + return null; + } + + public ServletInputStream getInputStream() throws IOException { + // TODO Auto-generated method stub + return null; + } + + public String getParameter(String name) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + public Enumeration getParameterNames() { + // TODO Auto-generated method stub + return null; + } + + public String[] getParameterValues(String name) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + public Map getParameterMap() { + // TODO Auto-generated method stub + return null; + } + + public String getProtocol() { + // TODO Auto-generated method stub + return null; + } + + public String getScheme() { + // TODO Auto-generated method stub + return null; + } + + public String getServerName() { + // TODO Auto-generated method stub + return null; + } + + public int getServerPort() { + // TODO Auto-generated method stub + return 0; + } + + public BufferedReader getReader() throws IOException { + // TODO Auto-generated method stub + return null; + } + + public String getRemoteAddr() { + // TODO Auto-generated method stub + return null; + } + + public String getRemoteHost() { + // TODO Auto-generated method stub + return null; + } + + public void setAttribute(String name, Object o) { + // TODO Auto-generated method stub + + } + + public void removeAttribute(String name) { + // TODO Auto-generated method stub + + } + + public Locale getLocale() { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + public Enumeration getLocales() { + // TODO Auto-generated method stub + return null; + } + + public boolean isSecure() { + // TODO Auto-generated method stub + return false; + } + + public RequestDispatcher getRequestDispatcher(String path) { + // TODO Auto-generated method stub + return null; + } + + public String getRealPath(String path) { + // TODO Auto-generated method stub + return null; + } + + public int getRemotePort() { + // TODO Auto-generated method stub + return 0; + } + + public String getLocalName() { + // TODO Auto-generated method stub + return null; + } + + public String getLocalAddr() { + // TODO Auto-generated method stub + return null; + } + + public int getLocalPort() { + // TODO Auto-generated method stub + return 0; + } + + public String getAuthType() { + // TODO Auto-generated method stub + return null; + } + + public Cookie[] getCookies() { + // TODO Auto-generated method stub + return null; + } + + public long getDateHeader(String name) { + // TODO Auto-generated method stub + return 0; + } + + public String getHeader(String name) { + for(int i=1;i getParts() throws IOException, ServletException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Part getPart(String name) throws IOException, ServletException { + // TODO Auto-generated method stub + return null; + } + + } +} diff --git a/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_PermEval.java b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_PermEval.java new file mode 100644 index 0000000..d60eedb --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/JU_PermEval.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur.aaf.test; + +import static org.junit.Assert.*; + +import org.junit.AfterClass; +import org.junit.Test; +import org.onap.aaf.cadi.aaf.PermEval; + +public class JU_PermEval { + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test() { + assertTrue(PermEval.evalInstance(":com.att.temp:role:write",":!com.att.*:role:write")); + + // TRUE + assertTrue(PermEval.evalAction("fred","fred")); + assertTrue(PermEval.evalAction("fred,wilma","fred")); + assertTrue(PermEval.evalAction("barney,betty,fred,wilma","fred")); + assertTrue(PermEval.evalAction("*","fred")); + + assertTrue(PermEval.evalInstance("fred","fred")); + assertTrue(PermEval.evalInstance("fred,wilma","fred")); + assertTrue(PermEval.evalInstance("barney,betty,fred,wilma","fred")); + assertTrue(PermEval.evalInstance("*","fred")); + + assertTrue(PermEval.evalInstance(":fred:fred",":fred:fred")); + assertTrue(PermEval.evalInstance(":fred:fred,wilma",":fred:fred")); + assertTrue(PermEval.evalInstance(":fred:barney,betty,fred,wilma",":fred:fred")); + assertTrue(PermEval.evalInstance("*","fred")); + assertTrue(PermEval.evalInstance(":*:fred",":fred:fred")); + assertTrue(PermEval.evalInstance(":fred:*",":fred:fred")); + assertTrue(PermEval.evalInstance(":fred:fred",":!f.*:fred")); + assertTrue(PermEval.evalInstance(":fred:fred",":fred:!f.*")); + + /// FALSE + assertFalse(PermEval.evalInstance("fred","wilma")); + assertFalse(PermEval.evalInstance("fred,barney,betty","wilma")); + assertFalse(PermEval.evalInstance(":fred:fred",":fred:wilma")); + assertFalse(PermEval.evalInstance(":fred:fred",":wilma:fred")); + assertFalse(PermEval.evalInstance(":fred:fred",":wilma:!f.*")); + assertFalse(PermEval.evalInstance(":fred:fred",":!f.*:wilma")); + assertFalse(PermEval.evalInstance(":fred:fred",":!w.*:!f.*")); + assertFalse(PermEval.evalInstance(":fred:fred",":!f.*:!w.*")); + + assertFalse(PermEval.evalInstance(":fred:fred",":fred:!x.*")); + + // MSO Tests 12/3/2015 + assertFalse(PermEval.evalInstance("/v1/services/features/*","/v1/services/features")); + assertFalse(PermEval.evalInstance(":v1:services:features:*",":v1:services:features")); + assertTrue(PermEval.evalInstance("/v1/services/features/*","/v1/services/features/api1")); + assertTrue(PermEval.evalInstance(":v1:services:features:*",":v1:services:features:api2")); + // MSO - Xue Gao + assertTrue(PermEval.evalInstance(":v1:requests:*",":v1:requests:test0-service")); + + + + // Same tests, with Slashes + assertTrue(PermEval.evalInstance("/fred/fred","/fred/fred")); + assertTrue(PermEval.evalInstance("/fred/fred,wilma","/fred/fred")); + assertTrue(PermEval.evalInstance("/fred/barney,betty,fred,wilma","/fred/fred")); + assertTrue(PermEval.evalInstance("*","fred")); + assertTrue(PermEval.evalInstance("/*/fred","/fred/fred")); + assertTrue(PermEval.evalInstance("/fred/*","/fred/fred")); + assertTrue(PermEval.evalInstance("/fred/fred","/!f.*/fred")); + assertTrue(PermEval.evalInstance("/fred/fred","/fred/!f.*")); + + /// FALSE + assertFalse(PermEval.evalInstance("fred","wilma")); + assertFalse(PermEval.evalInstance("fred,barney,betty","wilma")); + assertFalse(PermEval.evalInstance("/fred/fred","/fred/wilma")); + assertFalse(PermEval.evalInstance("/fred/fred","/wilma/fred")); + assertFalse(PermEval.evalInstance("/fred/fred","/wilma/!f.*")); + assertFalse(PermEval.evalInstance("/fred/fred","/!f.*/wilma")); + assertFalse(PermEval.evalInstance("/fred/fred","/!w.*/!f.*")); + assertFalse(PermEval.evalInstance("/fred/fred","/!f.*/!w.*")); + + assertFalse(PermEval.evalInstance("/fred/fred","/fred/!x.*")); + + } + +} diff --git a/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/MultiThreadPermHit.java b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/MultiThreadPermHit.java new file mode 100644 index 0000000..ef9dc36 --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/MultiThreadPermHit.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur.aaf.test; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.locator.PropertyLocator; + +public class MultiThreadPermHit { + public static void main(String args[]) { + // Link or reuse to your Logging mechanism + PropAccess myAccess = new PropAccess(); // + + // + try { + AAFConHttp con = new AAFConHttp(myAccess,new PropertyLocator("https://mithrilcsp.sbc.com:8100")); + + // AAFLur has pool of DME clients as needed, and Caches Client lookups + final AAFLurPerm aafLur = con.newLur(); + aafLur.setDebug("m12345@aaf.att.com"); + + // Note: If you need both Authn and Authz construct the following: + AAFAuthn aafAuthn = con.newAuthn(aafLur); + + // Do not set Mech ID until after you construct AAFAuthn, + // because we initiate "401" info to determine the Realm of + // of the service we're after. + final String id = myAccess.getProperty(Config.AAF_MECHID,null); + final String pass = myAccess.decrypt(myAccess.getProperty(Config.AAF_MECHPASS,null),false); + if(id!=null && pass!=null) { + try { + + // Normally, you obtain Principal from Authentication System. + // // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() + // // If you use CADI as Authenticator, it will get you these Principals from + // // CSP or BasicAuth mechanisms. + // String id = "cluster_admin@gridcore.att.com"; + // + // // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. + String ok; + ok = aafAuthn.validate(id, pass); + if(ok!=null) { + System.out.println(ok); + } + + List pond = new ArrayList(); + for(int i=0;i<20;++i) { + pond.clear(); + aafLur.fishAll(i+id, pond); + if(ok!=null && i%1000==0) { + System.out.println(i + " " + ok); + } + } + + for(int i=0;i<1000000;++i) { + ok = aafAuthn.validate( i+ id, "wrongPass"); + if(ok!=null && i%1000==0) { + System.out.println(i + " " + ok); + } + } + + final AAFPermission perm = new AAFPermission("com.att.aaf.access","*","*"); + + // Now you can ask the LUR (Local Representative of the User Repository about Authorization + // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object + // instead of creating your own LUR + for(int i=0;i<4;++i) { + if(aafLur.fish(id, perm)) { + System.out.println("Yes, " + id + " has permission for " + perm.getKey()); + } else { + System.out.println("No, " + id + " does not have permission for " + perm.getKey()); + } + } + + + // Or you can all for all the Permissions available + List perms = new ArrayList(); + + + aafLur.fishAll(id,perms); + System.out.println("Perms for " + id); + for(Permission prm : perms) { + System.out.println(prm.getKey()); + } + + System.out.println("Press any key to continue"); + System.in.read(); + + for(int j=0;j<5;++j) { + new Thread(new Runnable() { + @Override + public void run() { + for(int i=0;i<20;++i) { + if(aafLur.fish(id, perm)) { + System.out.println("Yes, " + id + " has permission for " + perm.getKey()); + } else { + System.out.println("No, " + id + " does not have permission for " + perm.getKey()); + } + } + } + }).start(); + } + + + } finally { + aafLur.destroy(); + } + } else { // checked on IDs + System.err.println(Config.AAF_MECHID + " and/or " + Config.AAF_MECHPASS + " are not set."); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/TestAccess.java b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/TestAccess.java new file mode 100644 index 0000000..2af452d --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/cadi/lur/aaf/test/TestAccess.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur.aaf.test; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; + +public class TestAccess implements Access { + private Symm symm; + private PrintStream out; + + public TestAccess(PrintStream out) { + this.out = out; + InputStream is = ClassLoader.getSystemResourceAsStream("cadi.properties"); + try { + System.getProperties().load(is); + } catch (IOException e) { + e.printStackTrace(out); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(out); + } + } + + String keyfile = System.getProperty(Config.CADI_KEYFILE); + if(keyfile==null) { + System.err.println("No " + Config.CADI_KEYFILE + " in Classpath"); + } else { + try { + is = new FileInputStream(keyfile); + try { + symm = Symm.obtain(is); + } finally { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(out); + } + } + + + + } + + public void log(Level level, Object... elements) { + boolean first = true; + for(int i=0;i errDF = env.newDataFactory(aaf.v2_0.Error.class); + errDF.in(RosettaData.TYPE.JSON); + errDF.out(RosettaData.TYPE.JSON); + RosettaData data = errDF.newData(); + data.load(err); + System.out.println(data.asString()); + + data.load(new StringReader(msg)); + err = data.asObject(); + System.out.println(err.getText()); + } + + +} diff --git a/aaf/src/test/java/org/onap/aaf/example/CadiTest.java b/aaf/src/test/java/org/onap/aaf/example/CadiTest.java new file mode 100644 index 0000000..34ed858 --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/example/CadiTest.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.example; + +import java.net.HttpURLConnection; +import java.net.URI; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.http.HClient; +import org.onap.aaf.cadi.http.HX509SS; + +public class CadiTest { + public static void main(String args[]) { + Access access = new PropAccess(); + try { + SecurityInfoC si = new SecurityInfoC(access); + HClient hclient = new HClient( + new HX509SS(si), + new URI("https://mithrilcsp.sbc.com:8085"),3000); + hclient.setMethod("OPTIONS"); + hclient.setPathInfo("/gui/cadi/log/toggle/INFO"); + hclient.send(); + Future future = hclient.futureReadString(); + if(future.get(5000)) { + System.out.println(future.value); + } else { + System.out.printf("Error: %d-%s", future.code(),future.body()); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/aaf/src/test/java/org/onap/aaf/example/ExampleAuthCheck.java b/aaf/src/test/java/org/onap/aaf/example/ExampleAuthCheck.java new file mode 100644 index 0000000..65972cd --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/example/ExampleAuthCheck.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.example; + +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.locator.DNSLocator; + +public class ExampleAuthCheck { + public static void main(String args[]) { + // Link or reuse to your Logging mechanism + PropAccess myAccess = new PropAccess(); // + + try { + AAFConHttp acon = new AAFConHttp(myAccess, new DNSLocator( + myAccess,"https","localhost","8100")); + AAFAuthn authn = acon.newAuthn(); + long start; + for (int i=0;i<10;++i) { + start = System.nanoTime(); + String err = authn.validate("", "gritty"); + if(err!=null) System.err.println(err); + else System.out.println("I'm ok"); + + err = authn.validate("bogus", "gritty"); + if(err!=null) System.err.println(err + " (correct error)"); + else System.out.println("I'm ok"); + + System.out.println((System.nanoTime()-start)/1000000f + " ms"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0.java b/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0.java new file mode 100644 index 0000000..f83b15b --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.example; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn; +import org.onap.aaf.cadi.aaf.v2_0.AAFCon; +import org.onap.aaf.cadi.aaf.v2_0.AAFConDME2; +import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm; + +public class ExamplePerm2_0 { + public static void main(String args[]) { + + // Link or reuse to your Logging mechanism + PropAccess myAccess = new PropAccess(); + + // + try { + AAFCon acon = new AAFConDME2(myAccess); + + // AAFLur has pool of DME clients as needed, and Caches Client lookups + AAFLurPerm aafLur = acon.newLur(); + + // Note: If you need both Authn and Authz construct the following: + AAFAuthn aafAuthn = acon.newAuthn(aafLur); + + // Do not set Mech ID until after you construct AAFAuthn, + // because we initiate "401" info to determine the Realm of + // of the service we're after. + acon.basicAuth("mc0897@aaf.att.com", "XXXXXX"); + + try { + + // Normally, you obtain Principal from Authentication System. + // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() + // If you use CADI as Authenticator, it will get you these Principals from + // CSP or BasicAuth mechanisms. + String id = "mc0897@aaf.att.com"; //"cluster_admin@gridcore.att.com"; + + // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. + String ok = aafAuthn.validate(id, "XXXXXX"); + if(ok!=null)System.out.println(ok); + + ok = aafAuthn.validate(id, "wrongPass"); + if(ok!=null)System.out.println(ok); + + + // AAF Style permissions are in the form + // Type, Instance, Action + AAFPermission perm = new AAFPermission("com.att.grid.core.coh",":dev_cluster", "WRITE"); + + // Now you can ask the LUR (Local Representative of the User Repository about Authorization + // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object + // instead of creating your own LUR + System.out.println("Does " + id + " have " + perm); + if(aafLur.fish(id, perm)) { + System.out.println("Yes, you have permission"); + } else { + System.out.println("No, you don't have permission"); + } + + System.out.println("Does Bogus have " + perm); + if(aafLur.fish("Bogus", perm)) { + System.out.println("Yes, you have permission"); + } else { + System.out.println("No, you don't have permission"); + } + + // Or you can all for all the Permissions available + List perms = new ArrayList(); + + aafLur.fishAll(id,perms); + for(Permission prm : perms) { + System.out.println(prm.getKey()); + } + + // It might be helpful in some cases to clear the User's identity from the Cache + aafLur.remove(id); + } finally { + aafLur.destroy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0_DME2.java b/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0_DME2.java new file mode 100644 index 0000000..f6024a5 --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/example/ExamplePerm2_0_DME2.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.example; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm; +import org.onap.aaf.cadi.locator.DNSLocator; + +public class ExamplePerm2_0_DME2 { + public static void main(String args[]) { + // Link or reuse to your Logging mechanism + PropAccess myAccess = new PropAccess(); + + // + try { + AAFConHttp acon = new AAFConHttp(myAccess, new DNSLocator( + myAccess,"https","localhost","8100")); + + // AAFLur has pool of DME clients as needed, and Caches Client lookups + AAFLurPerm aafLur = acon.newLur(); + + // Note: If you need both Authn and Authz construct the following: + AAFAuthn aafAuthn = acon.newAuthn(aafLur); + + // Do not set Mech ID until after you construct AAFAuthn, + // because we initiate "401" info to determine the Realm of + // of the service we're after. + acon.basicAuth("mc0897@aaf.att.com", "XXXXXX"); + + try { + + // Normally, you obtain Principal from Authentication System. + // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() + // If you use CADI as Authenticator, it will get you these Principals from + // CSP or BasicAuth mechanisms. + String id = "mc0897@aaf.att.com"; //"cluster_admin@gridcore.att.com"; + + // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. + String ok = aafAuthn.validate(id, "XXXXXX"); + if(ok!=null)System.out.println(ok); + + ok = aafAuthn.validate(id, "wrongPass"); + if(ok!=null)System.out.println(ok); + + + // AAF Style permissions are in the form + // Type, Instance, Action + AAFPermission perm = new AAFPermission("com.att.grid.core.coh",":dev_cluster", "WRITE"); + + // Now you can ask the LUR (Local Representative of the User Repository about Authorization + // With CADI, in J2EE, you can call isUserInRole("com.att.mygroup|mytype|write") on the Request Object + // instead of creating your own LUR + System.out.println("Does " + id + " have " + perm); + if(aafLur.fish(id, perm)) { + System.out.println("Yes, you have permission"); + } else { + System.out.println("No, you don't have permission"); + } + + System.out.println("Does Bogus have " + perm); + if(aafLur.fish("Bogus", perm)) { + System.out.println("Yes, you have permission"); + } else { + System.out.println("No, you don't have permission"); + } + + // Or you can all for all the Permissions available + List perms = new ArrayList(); + + aafLur.fishAll(id,perms); + for(Permission prm : perms) { + System.out.println(prm.getKey()); + } + + // It might be helpful in some cases to clear the User's identity from the Cache + aafLur.remove(id); + } finally { + aafLur.destroy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/aaf/src/test/java/org/onap/aaf/example/X509Test.java b/aaf/src/test/java/org/onap/aaf/example/X509Test.java new file mode 100644 index 0000000..ad5d4b2 --- /dev/null +++ b/aaf/src/test/java/org/onap/aaf/example/X509Test.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.example; + +import java.security.Principal; + +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp; +import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.locator.DNSLocator; +import org.onap.aaf.cadi.lur.LocalPermission; + +public class X509Test { + public static void main(String args[]) { + // Link or reuse to your Logging mechanism + + PropAccess myAccess = new PropAccess(); + + // + try { + AAFConHttp con = new AAFConHttp(myAccess, + new DNSLocator(myAccess,"https","mithrilcsp.sbc.com","8100")); + + // AAFLur has pool of DME clients as needed, and Caches Client lookups + AAFLurPerm aafLur = con.newLur(); + + // Note: If you need both Authn and Authz construct the following: +// AAFAuthn aafAuthn = con.newAuthn(aafLur); + + // con.x509Alias("aaf.att"); // alias in keystore + + try { + + // Normally, you obtain Principal from Authentication System. +// // For J2EE, you can ask the HttpServletRequest for getUserPrincipal() +// // If you use CADI as Authenticator, it will get you these Principals from +// // CSP or BasicAuth mechanisms. +// String id = "cluster_admin@gridcore.att.com"; +// +// // If Validate succeeds, you will get a Null, otherwise, you will a String for the reason. + Future fs = + con.client("2.0").read("/authz/perms/com.att.aaf.ca","application/Perms+json"); + if(fs.get(3000)) { + System.out.println(fs.value); + } else { + System.out.println("Error: " + fs.code() + ':' + fs.body()); + } + + // Check on Perms with LUR + if(aafLur.fish(new Principal() { + @Override + public String getName() { + return "m12345@aaf.att.com"; + } + }, new LocalPermission("com.att.aaf.ca|aaf|request"))) { + System.out.println("Has Perm"); + } else { + System.out.println("Does NOT Have Perm"); + } + } finally { + aafLur.destroy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/cass/pom.xml b/cass/pom.xml index 4e07ae8..9af30fa 100644 --- a/cass/pom.xml +++ b/cass/pom.xml @@ -22,7 +22,7 @@ --> - com.att.cadi + org.onap.aaf.cadi parent 1.0.0-SNAPSHOT .. @@ -34,10 +34,18 @@ https://github.com/att/AAF CADI cadi-cass - + + UTF-8 + 1.0.0-SNAPSHOT + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/${project.groupId}/${project.artifactId}/${project.version} + - com.att.cadi + org.onap.aaf.cadi cadi-aaf @@ -96,19 +104,61 @@ - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrhdme - https://oss.sonatype.org/ - true - - + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ${nexusproxy} + 176c31dfe190a + ecomp-staging + + - + + + + ecomp-releases + AAF Release Repository + ${nexusproxy}${releaseNexusPath} + + + ecomp-snapshots + AAF Snapshot Repository + ${nexusproxy}${snapshotNexusPath} + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + + + onap-plugin-snapshots + https://nexus.onap.org/content/repositories/snapshots/ + + + + + + central + Maven 2 repository 2 + http://repo2.maven.org/maven2/ + + + onap-jar-snapshots + https://nexus.onap.org/content/repositories/snapshots + + + spring-repo + Spring repo + https://artifacts.alfresco.com/nexus/content/repositories/public/ + + + repository.jboss.org-public + JBoss.org Maven repository + https://repository.jboss.org/nexus/content/groups/public + + diff --git a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticatedUser.java b/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticatedUser.java deleted file mode 100644 index e847bd0..0000000 --- a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticatedUser.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.cass; - -import java.security.Principal; - -import org.apache.cassandra.auth.AuthenticatedUser; - -import com.att.cadi.Access; - -public class AAFAuthenticatedUser extends AuthenticatedUser implements Principal { - private boolean anonymous = false, supr=false, local=false; - private String fullName; -// private Access access; - - public AAFAuthenticatedUser(Access access, String name) { - super(name); -// this.access = access; - int endIndex = name.indexOf("@"); - if(endIndex >= 0) { - fullName = name; - } else { - fullName = name + '@' + AAFBase.default_realm; - } - } - - public String getFullName() { - return fullName; - } - - public String getName() { - return fullName; - } - - /* (non-Javadoc) - * @see org.apache.cassandra.auth.AuthenticatedUser#isAnonymous() - */ - @Override - public boolean isAnonymous() { - return anonymous; - } - - public void setAnonymous(boolean anon) { - anonymous = anon; - } - - public boolean getAnonymous() { - return anonymous; - } - - /* (non-Javadoc) - * @see org.apache.cassandra.auth.AuthenticatedUser#isSuper() - */ - @Override - public boolean isSuper() { - return supr; - } - - public void setSuper(boolean supr) { - this.supr = supr; - } - - public boolean getSuper() { - return supr; - } - - /** - * We check Local so we can compare with the right Lur. This is AAF Plugin only. - * @return - */ - public boolean isLocal() { - return local; - } - - public void setLocal(boolean val) { - local = val; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof AAFAuthenticatedUser)) return false; - return ((AuthenticatedUser)o).getName().equals(this.getName()); - } - - @Override - public int hashCode() { - //access.log(Level.DEBUG, "AAFAuthentication hashcode ",getName().hashCode()); - return getName().hashCode(); - } -} diff --git a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticator.java b/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticator.java deleted file mode 100644 index 631a3fa..0000000 --- a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthenticator.java +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.cass; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.apache.cassandra.auth.AuthenticatedUser; -import org.apache.cassandra.auth.IAuthenticator; -import org.apache.cassandra.auth.ISaslAwareAuthenticator; -import org.apache.cassandra.exceptions.AuthenticationException; -import org.apache.cassandra.exceptions.InvalidRequestException; -import org.apache.cassandra.exceptions.RequestExecutionException; - -import com.att.cadi.Access.Level; -import com.att.cadi.CredVal.Type; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; - -public class AAFAuthenticator extends AAFBase implements ISaslAwareAuthenticator { - - public boolean requireAuthentication() { - return true; - } - - /** - * Invoked to authenticate an user - */ - public AuthenticatedUser authenticate(Map credentials) throws AuthenticationException { - String username = (String)credentials.get("username"); - if (username == null) { - throw new AuthenticationException("'username' is missing"); - } - - AAFAuthenticatedUser aau = new AAFAuthenticatedUser(access,username); - String fullName=aau.getFullName(); - access.log(Level.DEBUG, "Authenticating", aau.getName(),"(", fullName,")"); - - String password = (String)credentials.get("password"); - if (password == null) { - throw new AuthenticationException("'password' is missing"); - } else if(password.startsWith("bsf:")) { - try { - password = Symm.base64noSplit.depass(password); - } catch (IOException e) { - throw new AuthenticationException("AAF bnf: Password cannot be decoded"); - } - } else if(password.startsWith("enc:???")) { - try { - password = access.decrypt(password, true); - } catch (IOException e) { - throw new AuthenticationException("AAF Encrypted Password cannot be decrypted"); - } - } - - if(localLur!=null) { - access.log(Level.DEBUG, "Validating",fullName, "with LocalTaf", password); - if(localLur.validate(fullName, Type.PASSWORD, password.getBytes())) { - aau.setAnonymous(true); - aau.setLocal(true); - access.log(Level.DEBUG, fullName, "is authenticated locally"); - return aau; - } - } - - String aafResponse; - try { - access.log(Level.DEBUG, "Validating",fullName, "with AAF");//, password); - aafResponse = aafAuthn.validate(fullName, password); - if(aafResponse != null) { // Reason for failing. - access.log(Level.AUDIT, "AAF reports ",fullName,":",aafResponse); - throw new AuthenticationException(aafResponse); - } - access.log(Level.AUDIT, fullName, "is authenticated"); //,password); - // This tells Cassandra to skip checking it's own tables for User Entries. - aau.setAnonymous(true); - } catch (AuthenticationException ex) { - throw ex; - } catch(Exception ex) { - access.log(ex,"Exception validating user"); - throw new AuthenticationException("Exception validating user"); - } - - return aau; - } - - public void create(String username, Map options) throws InvalidRequestException, RequestExecutionException { - access.log(Level.INFO,"Use AAF CLI to create user"); - } - - public void alter(String username, Map options) throws RequestExecutionException { - access.log(Level.INFO,"Use AAF CLI to alter user"); - } - - public void drop(String username) throws RequestExecutionException { - access.log(Level.INFO,"Use AAF CLI to delete user"); - } - - public SaslAuthenticator newAuthenticator() { - return new ISaslAwareAuthenticator.SaslAuthenticator() { - private boolean complete = false; - private Map credentials; - - public byte[] evaluateResponse(byte[] clientResponse) throws AuthenticationException { - this.credentials = decodeCredentials(clientResponse); - this.complete = true; - return null; - } - - public boolean isComplete() { - return this.complete; - } - - public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException { - return AAFAuthenticator.this.authenticate(this.credentials); - } - - private Map decodeCredentials(byte[] bytes) throws AuthenticationException { - access.log(Level.DEBUG,"Decoding credentials from client token"); - byte[] user = null; - byte[] pass = null; - int end = bytes.length; - for (int i = bytes.length - 1; i >= 0; i--) - { - if (bytes[i] != 0) - continue; - if (pass == null) - pass = Arrays.copyOfRange(bytes, i + 1, end); - else if (user == null) - user = Arrays.copyOfRange(bytes, i + 1, end); - end = i; - } - - if (user == null) - throw new AuthenticationException("Authentication ID must not be null"); - if (pass == null) { - throw new AuthenticationException("Password must not be null"); - } - Map credentials = new HashMap(); - try { - credentials.put(IAuthenticator.USERNAME_KEY, new String(user, Config.UTF_8)); - credentials.put(IAuthenticator.PASSWORD_KEY, new String(pass, Config.UTF_8)); - } catch (UnsupportedEncodingException e) { - throw new AuthenticationException(e.getMessage()); - } - return credentials; - } - }; - } - -} - diff --git a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthorizer.java b/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthorizer.java deleted file mode 100644 index 650e570..0000000 --- a/cass/src/main/java/com/att/cadi/aaf/cass/AAFAuthorizer.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.cass; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -import org.apache.cassandra.auth.AuthenticatedUser; -import org.apache.cassandra.auth.IAuthorizer; -import org.apache.cassandra.auth.IResource; -import org.apache.cassandra.auth.Permission; -import org.apache.cassandra.auth.PermissionDetails; -import org.apache.cassandra.exceptions.RequestExecutionException; -import org.apache.cassandra.exceptions.RequestValidationException; - -import com.att.cadi.Access.Level; -import com.att.cadi.aaf.v2_0.AbsAAFLur; -import com.att.cadi.lur.LocalPermission; - -public class AAFAuthorizer extends AAFBase implements IAuthorizer { - // Returns every permission on the resource granted to the user. - public Set authorize(AuthenticatedUser user, IResource resource) { - String uname, rname; - access.log(Level.DEBUG,"Authorizing",uname=user.getName(),"for",rname=resource.getName()); - - Set permissions; - - if(user instanceof AAFAuthenticatedUser) { - AAFAuthenticatedUser aafUser = (AAFAuthenticatedUser) user; - aafUser.setAnonymous(false); - - if(aafUser.isLocal()) { - permissions = checkPermissions(aafUser, new LocalPermission( - rname.replaceFirst("data", cluster_name) - )); - } else { - permissions = checkPermissions( - aafUser, - perm_type, - ':'+rname.replaceFirst("data", cluster_name).replace('/', ':')); - } - } else { - permissions = Permission.NONE; - } - - access.log(Level.INFO,"Permissions on",rname,"for",uname,':', permissions); - - return permissions; - } - - /** - * Check only for Localized IDs (see cadi.properties) - * @param aau - * @param perm - * @return - */ - private Set checkPermissions(AAFAuthenticatedUser aau, LocalPermission perm) { - if(localLur.fish(aau.getFullName(), perm)) { -// aau.setSuper(true); - return Permission.ALL; - } else { - return Permission.NONE; - } - } - - /** - * Check remoted AAF Permissions - * @param aau - * @param type - * @param instance - * @return - */ - private Set checkPermissions(AAFAuthenticatedUser aau, String type, String instance) { - // Can perform ALL actions - String fullName = aau.getFullName(); - PermHolder ph = new PermHolder(aau); - aafLur.fishOneOf(fullName, ph,type,instance,actions); - return ph.permissions; - } - - private class PermHolder { - private AAFAuthenticatedUser aau; - public PermHolder(AAFAuthenticatedUser aau) { - this.aau = aau; - } - public Set permissions = Permission.NONE; - public void mutable() { - if(permissions==Permission.NONE) { - permissions = new HashSet(); - } - } - }; - - /** - * This specialty List avoid extra Object Creation, and allows the Lur to do a Vistor on all appropriate Perms - */ - private static final ArrayList> actions = new ArrayList>(); - static { - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "*"; - } - - public boolean exec(PermHolder a) { - a.aau.setSuper(true); - a.permissions = Permission.ALL; - return true; - } - }); - - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "SELECT"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.SELECT); - return false; - } - }); - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "MODIFY"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.MODIFY); - return false; - } - }); - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "CREATE"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.CREATE); - return false; - } - }); - - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "ALTER"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.ALTER); - return false; - } - }); - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "DROP"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.DROP); - return false; - } - }); - actions.add(new AbsAAFLur.Action() { - public String getName() { - return "AUTHORIZE"; - } - - public boolean exec(PermHolder ph) { - ph.mutable(); - ph.permissions.add(Permission.AUTHORIZE); - return false; - } - }); - - - }; - - - public void grant(AuthenticatedUser performer, Set permissions, IResource resource, String to) throws RequestExecutionException { - access.log(Level.INFO, "Use AAF CLI to grant permission(s) to user/role"); - } - - public void revoke(AuthenticatedUser performer, Set permissions, IResource resource, String from) throws RequestExecutionException { - access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role"); - } - - public Set list(AuthenticatedUser performer, Set permissions, IResource resource, String of) throws RequestValidationException, RequestExecutionException { - access.log(Level.INFO,"Use AAF CLI to find the list of permissions"); - return null; - } - - // Called prior to deleting the user with DROP USER query. Internal hook, so no permission checks are needed here. - public void revokeAll(String droppedUser) { - access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role"); - } - - // Called after a resource is removed (DROP KEYSPACE, DROP TABLE, etc.). - public void revokeAll(IResource droppedResource) { - access.log(Level.INFO,"Use AAF CLI to delete the unused permission", droppedResource.getName()); - } - -} diff --git a/cass/src/main/java/com/att/cadi/aaf/cass/AAFBase.java b/cass/src/main/java/com/att/cadi/aaf/cass/AAFBase.java deleted file mode 100644 index 4d82a6b..0000000 --- a/cass/src/main/java/com/att/cadi/aaf/cass/AAFBase.java +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.cass; - -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.net.URL; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; - -import org.apache.cassandra.auth.DataResource; -import org.apache.cassandra.auth.IAuthenticator; -import org.apache.cassandra.config.DatabaseDescriptor; -import org.apache.cassandra.exceptions.ConfigurationException; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Lur; -import com.att.cadi.SLF4JAccess; -import com.att.cadi.aaf.v2_0.AAFAuthn; -import com.att.cadi.aaf.v2_0.AAFCon; -import com.att.cadi.aaf.v2_0.AbsAAFLur; -import com.att.cadi.config.Config; -import com.att.cadi.lur.EpiLur; -import com.att.cadi.lur.LocalLur; -import com.att.cadi.aaf.AAFPermission; - -public abstract class AAFBase { - protected static final Set options; - protected static final Set dataResource; - - static { - options = new HashSet(); - options.add(IAuthenticator.Option.PASSWORD); - - dataResource = new HashSet(); - dataResource.add(DataResource.columnFamily("system_auth", "credentials")); - } - - protected static Access access; - protected static LocalLur localLur; - protected static AAFCon aafcon; - protected static AAFAuthn aafAuthn; - protected static AbsAAFLur aafLur; - protected static String default_realm; - protected static String cluster_name; - protected static String perm_type; - private static boolean props_ok = false; - - /** - * If you use your own Access Class, this must be called before - * "setup()" is invoked by Cassandra. - * - * Otherwise, it will default to reading Properties CADI style. - * - * @param access - */ - public static void setAccess(Access access) { - AAFBase.access = access; - } - - - public void validateConfiguration() throws ConfigurationException { - setup(); - if(!props_ok) { - throw new ConfigurationException("AAF not initialized"); - } - } - - @SuppressWarnings("unchecked") - public synchronized void setup() { - if(aafAuthn == null) { - try { - if(access==null) { - String value = System.getProperty(Config.CADI_PROP_FILES, "cadi.properties"); - Properties initial = new Properties(); - URL cadi_props = ClassLoader.getSystemResource(value); - if(cadi_props == null) { - File cp = new File(value); - if(cp.exists()) { - InputStream is = new FileInputStream(cp); - try { - initial.load(is); - } finally { - is.close(); - } - } else { - System.out.printf("%s does not exist as File or in Classpath\n",value); - initial.setProperty(Config.CADI_PROP_FILES, value); - } - } else { - InputStream is = cadi_props.openStream(); - try { - initial.load(is); - } finally { - is.close(); - } - } - access = new SLF4JAccess(initial); - } - props_ok = true; - if((perm_type = Config.logProp(access, "cass_group_name",null))==null) { - props_ok=false; - } else { - perm_type = perm_type + ".cass"; - } - - if((cluster_name = Config.logProp(access,"cass_cluster_name",null))==null) { - if((cluster_name = DatabaseDescriptor.getClusterName())==null) { - props_ok=false; - } - } - - if((default_realm = Config.logProp(access, Config.AAF_DEFAULT_REALM, null))==null) { - props_ok=false; - } - - if(props_ok==false) { - return; - } - - // AAFLur has pool of DME clients as needed, and Caches Client lookups - Lur lur = Config.configLur(access); - // Loop through to find AAFLur out of possible Lurs, to reuse AAFCon - if(lur instanceof EpiLur) { - EpiLur elur = (EpiLur)lur; - for(int i=0; (lur = elur.get(i))!=null;++i) { - if(lur instanceof AbsAAFLur) { - aafLur=(AbsAAFLur)lur; - aafcon = aafLur.aaf; - aafAuthn = aafLur.aaf.newAuthn(aafLur); - break; - } else if(lur instanceof LocalLur) { - localLur = (LocalLur)lur; - } - } - } else if(lur instanceof AbsAAFLur) { - aafLur=(AbsAAFLur)lur; - aafcon = aafLur.aaf; - aafAuthn = aafLur.aaf.newAuthn(aafLur); - } - if(aafAuthn==null) { - access.log(Level.INIT,"Failed to instantiate full AAF access"); - props_ok = false; - } - } catch (Exception e) { - aafAuthn=null; - if(access!=null)access.log(e, "Failed to initialize AAF"); - props_ok = false; - } - } - } - - public Set protectedResources() { - access.log(Level.DEBUG, "Data Resource asked for: it's",dataResource.isEmpty()?"":"not","empty"); - return dataResource; - } - - public Set supportedOptions() { - access.log(Level.DEBUG, "supportedOptions() called"); - return options; - } - - public Set alterableOptions() { - access.log(Level.DEBUG, "alterableOptions() called"); - return options; - } - - -} diff --git a/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticatedUser.java b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticatedUser.java new file mode 100644 index 0000000..30d979a --- /dev/null +++ b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticatedUser.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.cass; + +import java.security.Principal; + +import org.apache.cassandra.auth.AuthenticatedUser; +import org.onap.aaf.cadi.Access; + +public class AAFAuthenticatedUser extends AuthenticatedUser implements Principal { + private boolean anonymous = false, supr=false, local=false; + private String fullName; +// private Access access; + + public AAFAuthenticatedUser(Access access, String name) { + super(name); +// this.access = access; + int endIndex = name.indexOf("@"); + if(endIndex >= 0) { + fullName = name; + } else { + fullName = name + '@' + AAFBase.default_realm; + } + } + + public String getFullName() { + return fullName; + } + + public String getName() { + return fullName; + } + + /* (non-Javadoc) + * @see org.apache.cassandra.auth.AuthenticatedUser#isAnonymous() + */ + @Override + public boolean isAnonymous() { + return anonymous; + } + + public void setAnonymous(boolean anon) { + anonymous = anon; + } + + public boolean getAnonymous() { + return anonymous; + } + + /* (non-Javadoc) + * @see org.apache.cassandra.auth.AuthenticatedUser#isSuper() + */ + @Override + public boolean isSuper() { + return supr; + } + + public void setSuper(boolean supr) { + this.supr = supr; + } + + public boolean getSuper() { + return supr; + } + + /** + * We check Local so we can compare with the right Lur. This is AAF Plugin only. + * @return + */ + public boolean isLocal() { + return local; + } + + public void setLocal(boolean val) { + local = val; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AAFAuthenticatedUser)) return false; + return ((AuthenticatedUser)o).getName().equals(this.getName()); + } + + @Override + public int hashCode() { + //access.log(Level.DEBUG, "AAFAuthentication hashcode ",getName().hashCode()); + return getName().hashCode(); + } +} diff --git a/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticator.java b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticator.java new file mode 100644 index 0000000..6b8b29d --- /dev/null +++ b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthenticator.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.cass; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.apache.cassandra.auth.AuthenticatedUser; +import org.apache.cassandra.auth.IAuthenticator; +import org.apache.cassandra.auth.ISaslAwareAuthenticator; +import org.apache.cassandra.exceptions.AuthenticationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.exceptions.RequestExecutionException; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CredVal.Type; +import org.onap.aaf.cadi.config.Config; + +public class AAFAuthenticator extends AAFBase implements ISaslAwareAuthenticator { + + public boolean requireAuthentication() { + return true; + } + + /** + * Invoked to authenticate an user + */ + public AuthenticatedUser authenticate(Map credentials) throws AuthenticationException { + String username = (String)credentials.get("username"); + if (username == null) { + throw new AuthenticationException("'username' is missing"); + } + + AAFAuthenticatedUser aau = new AAFAuthenticatedUser(access,username); + String fullName=aau.getFullName(); + access.log(Level.DEBUG, "Authenticating", aau.getName(),"(", fullName,")"); + + String password = (String)credentials.get("password"); + if (password == null) { + throw new AuthenticationException("'password' is missing"); + } else if(password.startsWith("bsf:")) { + try { + password = Symm.base64noSplit.depass(password); + } catch (IOException e) { + throw new AuthenticationException("AAF bnf: Password cannot be decoded"); + } + } else if(password.startsWith("enc:???")) { + try { + password = access.decrypt(password, true); + } catch (IOException e) { + throw new AuthenticationException("AAF Encrypted Password cannot be decrypted"); + } + } + + if(localLur!=null) { + access.log(Level.DEBUG, "Validating",fullName, "with LocalTaf", password); + if(localLur.validate(fullName, Type.PASSWORD, password.getBytes())) { + aau.setAnonymous(true); + aau.setLocal(true); + access.log(Level.DEBUG, fullName, "is authenticated locally"); + return aau; + } + } + + String aafResponse; + try { + access.log(Level.DEBUG, "Validating",fullName, "with AAF");//, password); + aafResponse = aafAuthn.validate(fullName, password); + if(aafResponse != null) { // Reason for failing. + access.log(Level.AUDIT, "AAF reports ",fullName,":",aafResponse); + throw new AuthenticationException(aafResponse); + } + access.log(Level.AUDIT, fullName, "is authenticated"); //,password); + // This tells Cassandra to skip checking it's own tables for User Entries. + aau.setAnonymous(true); + } catch (AuthenticationException ex) { + throw ex; + } catch(Exception ex) { + access.log(ex,"Exception validating user"); + throw new AuthenticationException("Exception validating user"); + } + + return aau; + } + + public void create(String username, Map options) throws InvalidRequestException, RequestExecutionException { + access.log(Level.INFO,"Use AAF CLI to create user"); + } + + public void alter(String username, Map options) throws RequestExecutionException { + access.log(Level.INFO,"Use AAF CLI to alter user"); + } + + public void drop(String username) throws RequestExecutionException { + access.log(Level.INFO,"Use AAF CLI to delete user"); + } + + public SaslAuthenticator newAuthenticator() { + return new ISaslAwareAuthenticator.SaslAuthenticator() { + private boolean complete = false; + private Map credentials; + + public byte[] evaluateResponse(byte[] clientResponse) throws AuthenticationException { + this.credentials = decodeCredentials(clientResponse); + this.complete = true; + return null; + } + + public boolean isComplete() { + return this.complete; + } + + public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException { + return AAFAuthenticator.this.authenticate(this.credentials); + } + + private Map decodeCredentials(byte[] bytes) throws AuthenticationException { + access.log(Level.DEBUG,"Decoding credentials from client token"); + byte[] user = null; + byte[] pass = null; + int end = bytes.length; + for (int i = bytes.length - 1; i >= 0; i--) + { + if (bytes[i] != 0) + continue; + if (pass == null) + pass = Arrays.copyOfRange(bytes, i + 1, end); + else if (user == null) + user = Arrays.copyOfRange(bytes, i + 1, end); + end = i; + } + + if (user == null) + throw new AuthenticationException("Authentication ID must not be null"); + if (pass == null) { + throw new AuthenticationException("Password must not be null"); + } + Map credentials = new HashMap(); + try { + credentials.put(IAuthenticator.USERNAME_KEY, new String(user, Config.UTF_8)); + credentials.put(IAuthenticator.PASSWORD_KEY, new String(pass, Config.UTF_8)); + } catch (UnsupportedEncodingException e) { + throw new AuthenticationException(e.getMessage()); + } + return credentials; + } + }; + } + +} + diff --git a/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthorizer.java b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthorizer.java new file mode 100644 index 0000000..bea0e86 --- /dev/null +++ b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFAuthorizer.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.cass; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import org.apache.cassandra.auth.AuthenticatedUser; +import org.apache.cassandra.auth.IAuthorizer; +import org.apache.cassandra.auth.IResource; +import org.apache.cassandra.auth.Permission; +import org.apache.cassandra.auth.PermissionDetails; +import org.apache.cassandra.exceptions.RequestExecutionException; +import org.apache.cassandra.exceptions.RequestValidationException; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.aaf.v2_0.AbsAAFLur; +import org.onap.aaf.cadi.lur.LocalPermission; + +public class AAFAuthorizer extends AAFBase implements IAuthorizer { + // Returns every permission on the resource granted to the user. + public Set authorize(AuthenticatedUser user, IResource resource) { + String uname, rname; + access.log(Level.DEBUG,"Authorizing",uname=user.getName(),"for",rname=resource.getName()); + + Set permissions; + + if(user instanceof AAFAuthenticatedUser) { + AAFAuthenticatedUser aafUser = (AAFAuthenticatedUser) user; + aafUser.setAnonymous(false); + + if(aafUser.isLocal()) { + permissions = checkPermissions(aafUser, new LocalPermission( + rname.replaceFirst("data", cluster_name) + )); + } else { + permissions = checkPermissions( + aafUser, + perm_type, + ':'+rname.replaceFirst("data", cluster_name).replace('/', ':')); + } + } else { + permissions = Permission.NONE; + } + + access.log(Level.INFO,"Permissions on",rname,"for",uname,':', permissions); + + return permissions; + } + + /** + * Check only for Localized IDs (see cadi.properties) + * @param aau + * @param perm + * @return + */ + private Set checkPermissions(AAFAuthenticatedUser aau, LocalPermission perm) { + if(localLur.fish(aau.getFullName(), perm)) { +// aau.setSuper(true); + return Permission.ALL; + } else { + return Permission.NONE; + } + } + + /** + * Check remoted AAF Permissions + * @param aau + * @param type + * @param instance + * @return + */ + private Set checkPermissions(AAFAuthenticatedUser aau, String type, String instance) { + // Can perform ALL actions + String fullName = aau.getFullName(); + PermHolder ph = new PermHolder(aau); + aafLur.fishOneOf(fullName, ph,type,instance,actions); + return ph.permissions; + } + + private class PermHolder { + private AAFAuthenticatedUser aau; + public PermHolder(AAFAuthenticatedUser aau) { + this.aau = aau; + } + public Set permissions = Permission.NONE; + public void mutable() { + if(permissions==Permission.NONE) { + permissions = new HashSet(); + } + } + }; + + /** + * This specialty List avoid extra Object Creation, and allows the Lur to do a Vistor on all appropriate Perms + */ + private static final ArrayList> actions = new ArrayList>(); + static { + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "*"; + } + + public boolean exec(PermHolder a) { + a.aau.setSuper(true); + a.permissions = Permission.ALL; + return true; + } + }); + + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "SELECT"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.SELECT); + return false; + } + }); + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "MODIFY"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.MODIFY); + return false; + } + }); + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "CREATE"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.CREATE); + return false; + } + }); + + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "ALTER"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.ALTER); + return false; + } + }); + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "DROP"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.DROP); + return false; + } + }); + actions.add(new AbsAAFLur.Action() { + public String getName() { + return "AUTHORIZE"; + } + + public boolean exec(PermHolder ph) { + ph.mutable(); + ph.permissions.add(Permission.AUTHORIZE); + return false; + } + }); + + + }; + + + public void grant(AuthenticatedUser performer, Set permissions, IResource resource, String to) throws RequestExecutionException { + access.log(Level.INFO, "Use AAF CLI to grant permission(s) to user/role"); + } + + public void revoke(AuthenticatedUser performer, Set permissions, IResource resource, String from) throws RequestExecutionException { + access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role"); + } + + public Set list(AuthenticatedUser performer, Set permissions, IResource resource, String of) throws RequestValidationException, RequestExecutionException { + access.log(Level.INFO,"Use AAF CLI to find the list of permissions"); + return null; + } + + // Called prior to deleting the user with DROP USER query. Internal hook, so no permission checks are needed here. + public void revokeAll(String droppedUser) { + access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role"); + } + + // Called after a resource is removed (DROP KEYSPACE, DROP TABLE, etc.). + public void revokeAll(IResource droppedResource) { + access.log(Level.INFO,"Use AAF CLI to delete the unused permission", droppedResource.getName()); + } + +} diff --git a/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFBase.java b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFBase.java new file mode 100644 index 0000000..e422234 --- /dev/null +++ b/cass/src/main/java/org/onap/aaf/cadi/aaf/cass/AAFBase.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.cass; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import org.apache.cassandra.auth.DataResource; +import org.apache.cassandra.auth.IAuthenticator; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.SLF4JAccess; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn; +import org.onap.aaf.cadi.aaf.v2_0.AAFCon; +import org.onap.aaf.cadi.aaf.v2_0.AbsAAFLur; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.lur.LocalLur; + +public abstract class AAFBase { + protected static final Set options; + protected static final Set dataResource; + + static { + options = new HashSet(); + options.add(IAuthenticator.Option.PASSWORD); + + dataResource = new HashSet(); + dataResource.add(DataResource.columnFamily("system_auth", "credentials")); + } + + protected static Access access; + protected static LocalLur localLur; + protected static AAFCon aafcon; + protected static AAFAuthn aafAuthn; + protected static AbsAAFLur aafLur; + protected static String default_realm; + protected static String cluster_name; + protected static String perm_type; + private static boolean props_ok = false; + + /** + * If you use your own Access Class, this must be called before + * "setup()" is invoked by Cassandra. + * + * Otherwise, it will default to reading Properties CADI style. + * + * @param access + */ + public static void setAccess(Access access) { + AAFBase.access = access; + } + + + public void validateConfiguration() throws ConfigurationException { + setup(); + if(!props_ok) { + throw new ConfigurationException("AAF not initialized"); + } + } + + @SuppressWarnings("unchecked") + public synchronized void setup() { + if(aafAuthn == null) { + try { + if(access==null) { + String value = System.getProperty(Config.CADI_PROP_FILES, "cadi.properties"); + Properties initial = new Properties(); + URL cadi_props = ClassLoader.getSystemResource(value); + if(cadi_props == null) { + File cp = new File(value); + if(cp.exists()) { + InputStream is = new FileInputStream(cp); + try { + initial.load(is); + } finally { + is.close(); + } + } else { + System.out.printf("%s does not exist as File or in Classpath\n",value); + initial.setProperty(Config.CADI_PROP_FILES, value); + } + } else { + InputStream is = cadi_props.openStream(); + try { + initial.load(is); + } finally { + is.close(); + } + } + access = new SLF4JAccess(initial); + } + props_ok = true; + if((perm_type = Config.logProp(access, "cass_group_name",null))==null) { + props_ok=false; + } else { + perm_type = perm_type + ".cass"; + } + + if((cluster_name = Config.logProp(access,"cass_cluster_name",null))==null) { + if((cluster_name = DatabaseDescriptor.getClusterName())==null) { + props_ok=false; + } + } + + if((default_realm = Config.logProp(access, Config.AAF_DEFAULT_REALM, null))==null) { + props_ok=false; + } + + if(props_ok==false) { + return; + } + + // AAFLur has pool of DME clients as needed, and Caches Client lookups + Lur lur = Config.configLur(access); + // Loop through to find AAFLur out of possible Lurs, to reuse AAFCon + if(lur instanceof EpiLur) { + EpiLur elur = (EpiLur)lur; + for(int i=0; (lur = elur.get(i))!=null;++i) { + if(lur instanceof AbsAAFLur) { + aafLur=(AbsAAFLur)lur; + aafcon = aafLur.aaf; + aafAuthn = aafLur.aaf.newAuthn(aafLur); + break; + } else if(lur instanceof LocalLur) { + localLur = (LocalLur)lur; + } + } + } else if(lur instanceof AbsAAFLur) { + aafLur=(AbsAAFLur)lur; + aafcon = aafLur.aaf; + aafAuthn = aafLur.aaf.newAuthn(aafLur); + } + if(aafAuthn==null) { + access.log(Level.INIT,"Failed to instantiate full AAF access"); + props_ok = false; + } + } catch (Exception e) { + aafAuthn=null; + if(access!=null)access.log(e, "Failed to initialize AAF"); + props_ok = false; + } + } + } + + public Set protectedResources() { + access.log(Level.DEBUG, "Data Resource asked for: it's",dataResource.isEmpty()?"":"not","empty"); + return dataResource; + } + + public Set supportedOptions() { + access.log(Level.DEBUG, "supportedOptions() called"); + return options; + } + + public Set alterableOptions() { + access.log(Level.DEBUG, "alterableOptions() called"); + return options; + } + + +} diff --git a/cass/src/test/java/com/att/aaf/cass/JU_CASS.java b/cass/src/test/java/com/att/aaf/cass/JU_CASS.java deleted file mode 100644 index 9eca242..0000000 --- a/cass/src/test/java/com/att/aaf/cass/JU_CASS.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.aaf.cass; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.cassandra.auth.AuthenticatedUser; -import org.apache.cassandra.auth.IResource; -import org.apache.cassandra.auth.Permission; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.att.cadi.aaf.cass.AAFAuthenticator; -import com.att.cadi.aaf.cass.AAFAuthorizer; - -public class JU_CASS { - - private static AAFAuthenticator aa; - private static AAFAuthorizer an; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - System.setProperty("cadi_prop_files", "etc/cadi.properties"); - - aa = new AAFAuthenticator(); - an = new AAFAuthorizer(); - - aa.setup(); - an.setup(); // does nothing after aa. - - aa.validateConfiguration(); - - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void test() throws Exception { - Map creds = new HashMap(); - creds.put("username", "XXX@NS"); - creds.put("password", "enc:???"); - AuthenticatedUser aaf = aa.authenticate(creds); - - // Test out "aaf_default_domain - creds.put("username", "XX"); - aaf = aa.authenticate(creds); - - IResource resource = new IResource() { - public String getName() { - return "data/authz"; - } - - public IResource getParent() { - return null; - } - - public boolean hasParent() { - return false; - } - - public boolean exists() { - return true; - } - - }; - - Set perms = an.authorize(aaf, resource); - - // Test out "AAF" access - creds.put("username", "XXX@NS"); - creds.put("password", "enc:???"); - aaf = aa.authenticate(creds); - perms = an.authorize(aaf, resource); - Assert.assertFalse(perms.isEmpty()); - - perms = an.authorize(aaf, resource); - Assert.assertFalse(perms.isEmpty()); - - } - -} diff --git a/cass/src/test/java/com/att/cadi/aaf/cass/test/JU_CASS.java b/cass/src/test/java/com/att/cadi/aaf/cass/test/JU_CASS.java deleted file mode 100644 index 0eb95be..0000000 --- a/cass/src/test/java/com/att/cadi/aaf/cass/test/JU_CASS.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.aaf.cass.test; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.cassandra.auth.AuthenticatedUser; -import org.apache.cassandra.auth.IResource; -import org.apache.cassandra.auth.Permission; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.att.cadi.aaf.cass.AAFAuthenticator; -import com.att.cadi.aaf.cass.AAFAuthorizer; - -public class JU_CASS { - - private static AAFAuthenticator aa; - private static AAFAuthorizer an; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - System.setProperty("cadi_prop_files", "etc/cadi.properties"); - - aa = new AAFAuthenticator(); - an = new AAFAuthorizer(); - - aa.setup(); - an.setup(); // does nothing after aa. - - aa.validateConfiguration(); - - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void test() throws Exception { - Map creds = new HashMap(); - creds.put("username", "XXX@NS"); - creds.put("password", "enc:???"); - AuthenticatedUser aaf = aa.authenticate(creds); - - // Test out "aaf_default_domain - creds.put("username", "XX"); - aaf = aa.authenticate(creds); - - IResource resource = new IResource() { - public String getName() { - return "data/authz"; - } - - public IResource getParent() { - return null; - } - - public boolean hasParent() { - return false; - } - - public boolean exists() { - return true; - } - - }; - - Set perms = an.authorize(aaf, resource); - - // Test out "AAF" access - creds.put("username", "XXX@NS"); - creds.put("password", "enc:???"); - aaf = aa.authenticate(creds); - perms = an.authorize(aaf, resource); - Assert.assertFalse(perms.isEmpty()); - - perms = an.authorize(aaf, resource); - Assert.assertFalse(perms.isEmpty()); - - } - -} diff --git a/cass/src/test/java/org/onap/aaf/cadi/aaf/cass/test/JU_CASS.java b/cass/src/test/java/org/onap/aaf/cadi/aaf/cass/test/JU_CASS.java new file mode 100644 index 0000000..bedfa25 --- /dev/null +++ b/cass/src/test/java/org/onap/aaf/cadi/aaf/cass/test/JU_CASS.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.aaf.cass.test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.cassandra.auth.AuthenticatedUser; +import org.apache.cassandra.auth.IResource; +import org.apache.cassandra.auth.Permission; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.aaf.cadi.aaf.cass.AAFAuthenticator; +import org.onap.aaf.cadi.aaf.cass.AAFAuthorizer; + +public class JU_CASS { + + private static AAFAuthenticator aa; + private static AAFAuthorizer an; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("cadi_prop_files", "etc/cadi.properties"); + + aa = new AAFAuthenticator(); + an = new AAFAuthorizer(); + + aa.setup(); + an.setup(); // does nothing after aa. + + aa.validateConfiguration(); + + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test() throws Exception { + Map creds = new HashMap(); + creds.put("username", "XXX@NS"); + creds.put("password", "enc:???"); + AuthenticatedUser aaf = aa.authenticate(creds); + + // Test out "aaf_default_domain + creds.put("username", "XX"); + aaf = aa.authenticate(creds); + + IResource resource = new IResource() { + public String getName() { + return "data/authz"; + } + + public IResource getParent() { + return null; + } + + public boolean hasParent() { + return false; + } + + public boolean exists() { + return true; + } + + }; + + Set perms = an.authorize(aaf, resource); + + // Test out "AAF" access + creds.put("username", "XXX@NS"); + creds.put("password", "enc:???"); + aaf = aa.authenticate(creds); + perms = an.authorize(aaf, resource); + Assert.assertFalse(perms.isEmpty()); + + perms = an.authorize(aaf, resource); + Assert.assertFalse(perms.isEmpty()); + + } + +} diff --git a/cass/src/test/java/org/onap/aaf/cass/JU_CASS.java b/cass/src/test/java/org/onap/aaf/cass/JU_CASS.java new file mode 100644 index 0000000..f5ee310 --- /dev/null +++ b/cass/src/test/java/org/onap/aaf/cass/JU_CASS.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cass; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.cassandra.auth.AuthenticatedUser; +import org.apache.cassandra.auth.IResource; +import org.apache.cassandra.auth.Permission; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.aaf.cadi.aaf.cass.AAFAuthenticator; +import org.onap.aaf.cadi.aaf.cass.AAFAuthorizer; + +public class JU_CASS { + + private static AAFAuthenticator aa; + private static AAFAuthorizer an; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("cadi_prop_files", "etc/cadi.properties"); + + aa = new AAFAuthenticator(); + an = new AAFAuthorizer(); + + aa.setup(); + an.setup(); // does nothing after aa. + + aa.validateConfiguration(); + + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test() throws Exception { + Map creds = new HashMap(); + creds.put("username", "XXX@NS"); + creds.put("password", "enc:???"); + AuthenticatedUser aaf = aa.authenticate(creds); + + // Test out "aaf_default_domain + creds.put("username", "XX"); + aaf = aa.authenticate(creds); + + IResource resource = new IResource() { + public String getName() { + return "data/authz"; + } + + public IResource getParent() { + return null; + } + + public boolean hasParent() { + return false; + } + + public boolean exists() { + return true; + } + + }; + + Set perms = an.authorize(aaf, resource); + + // Test out "AAF" access + creds.put("username", "XXX@NS"); + creds.put("password", "enc:???"); + aaf = aa.authenticate(creds); + perms = an.authorize(aaf, resource); + Assert.assertFalse(perms.isEmpty()); + + perms = an.authorize(aaf, resource); + Assert.assertFalse(perms.isEmpty()); + + } + +} diff --git a/client/pom.xml b/client/pom.xml index 1b0d6e3..45615cb 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -22,7 +22,7 @@ --> - com.att.cadi + org.onap.aaf.cadi parent 1.0.0-SNAPSHOT .. @@ -34,14 +34,22 @@ https://github.com/att/AAF CADI 4.0.0 - + + UTF-8 + 1.0.0-SNAPSHOT + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/${project.groupId}/${project.artifactId}/${project.version} + - com.att.inno + org.onap.aaf.inno rosetta - com.att.cadi + org.onap.aaf.cadi cadi-core @@ -89,19 +97,61 @@ - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrhdme - https://oss.sonatype.org/ - true - - + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ${nexusproxy} + 176c31dfe190a + ecomp-staging + + + + + ecomp-releases + AAF Release Repository + ${nexusproxy}${releaseNexusPath} + + + ecomp-snapshots + AAF Snapshot Repository + ${nexusproxy}${snapshotNexusPath} + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + + + onap-plugin-snapshots + https://nexus.onap.org/content/repositories/snapshots/ + + + + + central + Maven 2 repository 2 + http://repo2.maven.org/maven2/ + + + onap-jar-snapshots + https://nexus.onap.org/content/repositories/snapshots + + + spring-repo + Spring repo + https://artifacts.alfresco.com/nexus/content/repositories/public/ + + + repository.jboss.org-public + JBoss.org Maven repository + https://repository.jboss.org/nexus/content/groups/public + + diff --git a/client/src/main/java/com/att/cadi/client/AAFClient.java b/client/src/main/java/com/att/cadi/client/AAFClient.java deleted file mode 100644 index 3f8fb47..0000000 --- a/client/src/main/java/com/att/cadi/client/AAFClient.java +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.net.HttpURLConnection; -import java.util.HashMap; -import java.util.Map; - -import com.att.aft.dme2.api.DME2Manager; -import com.att.cadi.Access; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.http.HBasicAuthSS; -import com.att.cadi.http.HMangr; -import com.att.cadi.locator.DME2Locator; -import com.att.inno.env.APIException; -import com.att.rosetta.env.RosettaDF; -import com.att.rosetta.env.RosettaEnv; - -public class AAFClient { - private RosettaEnv env; - private Map,RosettaDF> map = new HashMap,RosettaDF>(); - HMangr hman; - HBasicAuthSS ss; - - public AAFClient(RosettaEnv env) throws Exception { - this.env = env; - Access access = new EnvAccess(env); - String user = access.getProperty(Config.AAF_MECHID,null); - String password = access.decrypt(access.getProperty(Config.AAF_MECHPASS,null), true); - - SecurityInfoC si = new SecurityInfoC(access); - DME2Manager dm = new DME2Manager("APIclient DME2Manager", System.getProperties()); - DME2Locator loc = new DME2Locator(access, dm, access.getProperty(Config.AAF_URL,null)); - - int TIMEOUT = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, "30000")); - - hman = new HMangr(access, loc).readTimeout(TIMEOUT).apiVersion("2.0"); - ss = new HBasicAuthSS(user, password, si); - } - - public AAFClient(RosettaEnv env, DME2Manager dm) throws Exception { - this.env = env; - Access access = new EnvAccess(env); - String user = access.getProperty(Config.AAF_MECHID,null); - String password = access.decrypt(access.getProperty(Config.AAF_MECHPASS,null), true); - - SecurityInfoC si = new SecurityInfoC(access); - DME2Locator loc = new DME2Locator(access, dm, access.getProperty(Config.AAF_URL,null)); - - int TIMEOUT = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, "30000")); - - hman = new HMangr(access, loc).readTimeout(TIMEOUT).apiVersion("2.0"); - ss = new HBasicAuthSS(user, password, si); - } - - @SuppressWarnings("unchecked") - private synchronized RosettaDF getDF(Class cls) throws APIException { - RosettaDF rdf; - synchronized (env) { - rdf = map.get(cls); - if(rdf==null) { - rdf = env.newDataFactory(cls); - map.put(cls, rdf); - } - } - return (RosettaDF)rdf; - } - - // Package on purpose - static class Call { - protected final static String VOID_CONTENT_TYPE="application/Void+json;version=2.0"; - - protected RosettaDF df; - protected AAFClient client; - - public Call(AAFClient ac, RosettaDF df) { - this.client = ac; - this.df = df; - } - } - - - /////////// Calls ///////////////// - /** - * Returns a Get Object... same as "get" - * - * @param cls - * @return - * @throws APIException - */ - public Get read(Class cls) throws APIException { - return new Get(this,getDF(cls)); - } - - /** - * Returns a Get Object... same as "read" - * - * @param cls - * @return - * @throws APIException - */ - public Get get(Class cls) throws APIException { - return new Get(this,getDF(cls)); - } - - /** - * Returns a Post Object... same as "create" - * - * @param cls - * @return - * @throws APIException - */ - public Post post(Class cls) throws APIException { - return new Post(this,getDF(cls)); - } - - /** - * Returns a Post Object... same as "post" - * - * @param cls - * @return - * @throws APIException - */ - public Post create(Class cls) throws APIException { - return new Post(this,getDF(cls)); - } - - /** - * Returns a Put Object... same as "update" - * - * @param cls - * @return - * @throws APIException - */ - public Put put(Class cls) throws APIException { - return new Put(this,getDF(cls)); - } - - /** - * Returns a Put Object... same as "put" - * - * @param cls - * @return - * @throws APIException - */ - public Put update(Class cls) throws APIException { - return new Put(this,getDF(cls)); - } - - /** - * Returns a Delete Object - * - * @param cls - * @return - * @throws APIException - */ - public Delete delete(Class cls) throws APIException { - return new Delete(this,getDF(cls)); - } - - /** - * Returns a Delete Object - * - * @param cls - * @return - * @throws APIException - */ - public Delete delete() throws APIException { - return new Delete(this,null); - } - - public Put put() { - return new Put(this,null); - } - - -} diff --git a/client/src/main/java/com/att/cadi/client/AbsBasicAuth.java b/client/src/main/java/com/att/cadi/client/AbsBasicAuth.java deleted file mode 100644 index a0ab06d..0000000 --- a/client/src/main/java/com/att/cadi/client/AbsBasicAuth.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.io.IOException; - -import com.att.cadi.SecuritySetter; -import com.att.cadi.Symm; -import com.att.cadi.config.SecurityInfoC; - -public abstract class AbsBasicAuth implements SecuritySetter { - protected static final String REPEAT_OFFENDER="This call is aborted because of repeated usage of invalid Passwords"; - private static final int MAX_TEMP_COUNT = 10; - private static final int MAX_SPAM_COUNT = 10000; - private static final long WAIT_TIME = 1000*60*4; - - protected final String headValue; - protected SecurityInfoC securityInfo; - protected String user; - private long lastMiss; - private int count; - - public AbsBasicAuth(String user, String pass, SecurityInfoC si) throws IOException { - this.user = user; - headValue = "Basic " + Symm.base64.encode(user + ':' + pass); - securityInfo = si; - lastMiss=0L; - count=0; - } - - /* (non-Javadoc) - * @see com.att.cadi.SecuritySetter#getID() - */ - @Override - public String getID() { - return user; - } - - public boolean isDenied() { - if(lastMiss>0 && lastMiss>System.currentTimeMillis()) { - return true; - } else { - lastMiss=0L; - return false; - } - } - - public synchronized int setLastResponse(int httpcode) { - if(httpcode == 401) { - ++count; - if(lastMiss==0L && count>MAX_TEMP_COUNT) { - lastMiss=System.currentTimeMillis()+WAIT_TIME; - } -// if(count>MAX_SPAM_COUNT) { -// System.err.printf("Your service has %d consecutive bad service logins to AAF. \nIt will now exit\n", -// count); -// System.exit(401); -// } - if(count%1000==0) { - System.err.printf("Your service has %d consecutive bad service logins to AAF. AAF Access will be disabled after %d\n", - count,MAX_SPAM_COUNT); - } - - } else { - lastMiss=0; - } - return count; - } - - public int count() { - return count; - } -} diff --git a/client/src/main/java/com/att/cadi/client/AbsTransferSS.java b/client/src/main/java/com/att/cadi/client/AbsTransferSS.java deleted file mode 100644 index 69647e6..0000000 --- a/client/src/main/java/com/att/cadi/client/AbsTransferSS.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.security.Principal; - -import com.att.cadi.SecuritySetter; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.principal.BasicPrincipal; -import com.att.cadi.principal.TGuardPrincipal; -import com.att.cadi.principal.TrustPrincipal; - -public abstract class AbsTransferSS implements SecuritySetter { - protected String value; - protected SecurityInfoC securityInfo; - protected SecuritySetter defSS; - private Principal principal; - - //Format:::[:AS][,::]* - public AbsTransferSS(Principal principal, String app) { - init(principal, app); - } - - public AbsTransferSS(Principal principal, String app, SecurityInfoC si) { - init(principal,app); - securityInfo = si; - this.defSS = si.defSS; - } - - private void init(Principal principal, String app) { - this.principal=principal; - if(principal==null) { - return; - } else if(principal instanceof BasicPrincipal) { - value = principal.getName() + ':' + app + ":BasicAuth:AS"; - } else if(principal instanceof TrustPrincipal) { - TrustPrincipal tp = (TrustPrincipal)principal; - // recursive - init(tp.original(),app); - value += principal.getName() + ':' + app + ":Trust:AS" + ',' + tp.userChain(); - } else if(principal instanceof TGuardPrincipal) { - value = principal.getName() + ':' + app + ":TGUARD:AS"; - } - } - - /* (non-Javadoc) - * @see com.att.cadi.SecuritySetter#getID() - */ - @Override - public String getID() { - return principal==null?"":principal.getName(); - } -} diff --git a/client/src/main/java/com/att/cadi/client/Delete.java b/client/src/main/java/com/att/cadi/client/Delete.java deleted file mode 100644 index f780af1..0000000 --- a/client/src/main/java/com/att/cadi/client/Delete.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import com.att.cadi.CadiException; -import com.att.inno.env.APIException; -import com.att.rosetta.env.RosettaDF; - -public class Delete extends AAFClient.Call { - public Delete(AAFClient ac, RosettaDF df) { - super(ac,df); - } - - @SuppressWarnings("unchecked") - public Result delete(final String pathInfo, final T t) throws Exception { - if(t==null) { - return (Result)delete(pathInfo); - } - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.delete(pathInfo,df,t); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } - - public Result delete(final String pathInfo) throws Exception { - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.delete(pathInfo,VOID_CONTENT_TYPE); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } - - - -} diff --git a/client/src/main/java/com/att/cadi/client/EClient.java b/client/src/main/java/com/att/cadi/client/EClient.java deleted file mode 100644 index 166d150..0000000 --- a/client/src/main/java/com/att/cadi/client/EClient.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.io.IOException; -import java.io.OutputStream; - -import javax.servlet.http.HttpServletResponse; - -import com.att.inno.env.APIException; -import com.att.inno.env.Data; -import com.att.rosetta.env.RosettaDF; - - -public interface EClient { - public void setMethod(String meth); - public void setPathInfo(String pathinfo); - public void setPayload(Transfer transfer); - public void addHeader(String tag, String value); - public void setQueryParams(String q); - public void setFragment(String f); - public void send() throws APIException; - public Future futureCreate(Class t); - public Future futureReadString(); - public Future futureRead(RosettaDF df,Data.TYPE type); - public Future future(T t); - public Future future(HttpServletResponse resp, int expected) throws APIException; - - public interface Transfer { - public void transfer(OutputStream os) throws IOException, APIException; - } -} diff --git a/client/src/main/java/com/att/cadi/client/EnvAccess.java b/client/src/main/java/com/att/cadi/client/EnvAccess.java deleted file mode 100644 index f78f2ff..0000000 --- a/client/src/main/java/com/att/cadi/client/EnvAccess.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map.Entry; -import java.util.Properties; - -import com.att.cadi.Access; -import com.att.cadi.Symm; -import com.att.inno.env.Decryptor; -import com.att.inno.env.Env; -import com.att.inno.env.impl.BasicEnv; - -public class EnvAccess implements Access { - private Env env; - - /** - * String Property tag for files/resources that may contain properties. Can be null. - * Resources of ClassLoader will be checked first, if exist. Can be null. - * @param env - * @param tag - * @param cl - * @throws IOException - */ - public EnvAccess(BasicEnv env, ClassLoader cl) throws IOException { - this.env = env; - final Symm s = Symm.obtain(this); - env.set(new Decryptor() { - private Symm symm = s; - @Override - public String decrypt(String encrypted) { - try { - return (encrypted!=null && (encrypted.startsWith(Symm.ENC))) - ? symm.depass(encrypted) - : encrypted; - } catch (IOException e) { - return ""; - } - } - } - ); - } - - - /** - * Construct with the Classloader of Env and CADI_PROP_FILES, if possible - * - * @param env - * @throws IOException - */ - public EnvAccess(BasicEnv env) throws IOException { - this(env, env.getClass().getClassLoader()); - } - - @Override - public void log(Level level, Object... elements) { - switch(level) { - case AUDIT: - env.audit().log(elements); - break; - case DEBUG: - env.debug().log(elements); - break; - case ERROR: - env.error().log(elements); - break; - case INFO: - env.info().log(elements); - break; - case INIT: - env.init().log(elements); - break; - case WARN: - env.warn().log(elements); - break; - default: - break; - } - - } - - @Override - public void log(Exception e, Object... elements) { - env.error().log(e,elements); - } - - @Override - public void printf(Level level, String fmt, Object... elements) { - if(willLog(level)) { - log(level,String.format(fmt, elements)); - } - } - - - @Override - public boolean willLog(Level level) { - switch(level) { - case AUDIT: - return env.audit().isLoggable(); - case DEBUG: - return env.debug().isLoggable(); - case ERROR: - return env.error().isLoggable(); - case INFO: - return env.info().isLoggable(); - case INIT: - return env.init().isLoggable(); - case WARN: - return env.warn().isLoggable(); - default: - return false; - } - } - - - @Override - public void setLogLevel(Level level) { - // unused - } - - @Override - public ClassLoader classLoader() { - return env.getClass().getClassLoader(); - } - - @Override - public String getProperty(String string, String def) { - return env.getProperty(string, def); - } - - @Override - public void load(InputStream is) throws IOException { - Properties props = new Properties(); - props.load(is); - for(Entry es :props.entrySet()) { - env.setProperty(es.getKey().toString(), es.getValue().toString()); - } - } - - @Override - public String decrypt(String encrypted, boolean anytext) throws IOException { - return env.decryptor().decrypt(encrypted); - } - -} diff --git a/client/src/main/java/com/att/cadi/client/Future.java b/client/src/main/java/com/att/cadi/client/Future.java deleted file mode 100644 index 18987a6..0000000 --- a/client/src/main/java/com/att/cadi/client/Future.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import com.att.cadi.CadiException; - -public abstract class Future { - public T value; - public abstract boolean get(int timeout) throws CadiException; - - public abstract int code(); - public abstract String body(); - public abstract String header(String tag); -} diff --git a/client/src/main/java/com/att/cadi/client/Get.java b/client/src/main/java/com/att/cadi/client/Get.java deleted file mode 100644 index a39aaf1..0000000 --- a/client/src/main/java/com/att/cadi/client/Get.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import com.att.cadi.CadiException; -import com.att.inno.env.APIException; -import com.att.rosetta.env.RosettaDF; - -public class Get extends AAFClient.Call { - public Get(AAFClient ac, RosettaDF df) { - super(ac,df); - } - - public Result read(final String pathInfo) throws Exception { - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.read(pathInfo,df); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } -} diff --git a/client/src/main/java/com/att/cadi/client/Holder.java b/client/src/main/java/com/att/cadi/client/Holder.java deleted file mode 100644 index 3ad7ce3..0000000 --- a/client/src/main/java/com/att/cadi/client/Holder.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -/** - * Use to set Variables outside of Anonymous classes. - * - * - * @param - */ -public class Holder { - private T value; - public Holder(T t) { - value = t; - } - public void set(T t) { - value = t; - } - - public T get() { - return value; - } - -} diff --git a/client/src/main/java/com/att/cadi/client/Post.java b/client/src/main/java/com/att/cadi/client/Post.java deleted file mode 100644 index 001f1b3..0000000 --- a/client/src/main/java/com/att/cadi/client/Post.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import com.att.cadi.CadiException; -import com.att.cadi.LocatorException; -import com.att.inno.env.APIException; -import com.att.rosetta.env.RosettaDF; - -public class Post extends AAFClient.Call { - public Post(AAFClient ac, RosettaDF df) { - super(ac,df); - } - - public Result create(final String pathInfo, final T t) throws APIException, CadiException, LocatorException { - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.create(pathInfo,df,t); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } -} diff --git a/client/src/main/java/com/att/cadi/client/PropertyLocator.java b/client/src/main/java/com/att/cadi/client/PropertyLocator.java deleted file mode 100644 index acd3b4a..0000000 --- a/client/src/main/java/com/att/cadi/client/PropertyLocator.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Random; - -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; - -public class PropertyLocator implements Locator { - private final URI [] orig; - private PLItem[] current; - private int end; - private final Random random; - - /** - * comma delimited root url list - * - * @param locList - * @throws LocatorException - */ - public PropertyLocator(String locList) throws LocatorException { - if(locList==null)throw new LocatorException("No Location List given for PropertyLocator"); - String[] locarray = locList.split("\\s*,\\s*"); - orig = new URI[locarray.length]; - - random = new Random(); - - for(int i=0;i0?current[0]:null; - } - - @Override - public boolean hasItems() { - return end>0; - } - - @Override - public Item next(Item item) throws LocatorException { - int spot; - if((spot=(((PLItem)item).order+1))>=end)return null; - return current[spot]; - } - - @Override - public synchronized void invalidate(Item item) throws LocatorException { - if(--end<=0)return; - PLItem pli = (PLItem)item; - int i,order; - for(i=0;i extends AAFClient.Call { - public Put(AAFClient ac, RosettaDF df) { - super(ac,df); - } - - public Result update(final String pathInfo, final T t) throws Exception { - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.update(pathInfo,df,t); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } - - public Result update(final String pathInfo) throws Exception { - return client.hman.best(client.ss, - new Retryable>() { - @Override - public Result code(Rcli client) throws APIException, CadiException { - Future ft = client.update(pathInfo); - if(ft.get(client.readTimeout)) { - return Result.ok(ft.code(),ft.value); - } else { - return Result.err(ft.code(),ft.body()); - } - } - }); - } - -} diff --git a/client/src/main/java/com/att/cadi/client/RawClient.java b/client/src/main/java/com/att/cadi/client/RawClient.java deleted file mode 100644 index c1ad633..0000000 --- a/client/src/main/java/com/att/cadi/client/RawClient.java +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.PrintStream; -import java.net.URI; - -import com.att.aft.dme2.api.DME2Client; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; - -public abstract class RawClient { - protected static String aafid, aafpass, aafurl; - protected static Symm symm; - - protected static boolean init(PrintStream out) { - try { - String propfile = System.getProperty(Config.CADI_PROP_FILES); - if(propfile==null) { - propfile = "raw.props"; - } - File pfile = new File(propfile); - if(!pfile.exists()) { - if(propfile.equals("raw.props")) { - out.println("Creating 'raw.props'. Edit for proper values, then run again. Alternatively, set " - + Config.CADI_PROP_FILES+" to a cadi properties file"); - FileOutputStream fos = new FileOutputStream(pfile); - PrintStream ps = new PrintStream(fos); - try { - ps.println("# Use http://www.bing.com/maps to figure out LAT/LONG of an Address"); - ps.println("AFT_LATITUDE=38.432930"); - ps.println("AFT_LONGITUDE=-90.432480"); - ps.println("AFT_ENVIRONMENT=AFTUAT"); - ps.print(Config.AAF_URL); - ps.println("=aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE"); - ps.print(Config.CADI_KEYFILE); - ps.println("="); - ps.println(Config.AAF_MECHID); - ps.print("="); - ps.println(Config.AAF_MECHPASS); - ps.print("="); - } finally { - ps.close(); - } - } - } else { - FileInputStream fis = new FileInputStream(propfile); - try { - System.getProperties().load(fis); - } finally { - fis.close(); - } - - String cadiKeyFile = System.getProperty(Config.CADI_KEYFILE); - aafid = System.getProperty(Config.AAF_MECHID); - aafpass = System.getProperty(Config.AAF_MECHPASS); - aafurl = System.getProperty(Config.AAF_URL); - out.println("Contacting: " + aafurl); - - if(cadiKeyFile==null || aafid==null || aafpass==null || aafurl==null ) { - out.print(Config.CADI_KEYFILE); - out.print(", "); - out.print(Config.CADI_KEYFILE); - out.print(", "); - out.print(Config.CADI_KEYFILE); - out.print(", "); - out.print(Config.CADI_KEYFILE); - out.print(" need to be set in "); - out.println(propfile); - } else { - fis = new FileInputStream(cadiKeyFile); - try { - symm = Symm.obtain(fis); - } finally { - fis.close(); - } - } - return true; - } - } catch (Exception e) { - e.printStackTrace(out); - } - return false; - - } - - public abstract String call(final PrintStream out, final String meth, final String path) throws Exception; - - public static void main(String[] args) { - // Sonar idiocy - PrintStream out = System.out; - - try { - if(init(out)) { - if(args.length<2) { - System.out.println("Parameters: "); - } else { - RawClient client = new DME2(); - out.println(client.call(out,args[0],args[1])); - } - } - } catch (Exception e) { - e.printStackTrace(out); - } - } - - protected static class DME2 extends RawClient { - - public String call(final PrintStream out, final String meth, final String path) { - try { - DME2Client client = new DME2Client(new URI(aafurl),10000); - client.setCredentials(aafid, symm.depass(aafpass)); - client.setMethod(meth); - client.setContext(path); - - if("GET".equalsIgnoreCase(meth) || - "DELETE".equalsIgnoreCase(meth)) { - client.setPayload(""); - } else if("POST".equalsIgnoreCase(meth) || - "PUT".equalsIgnoreCase(meth)) { - int c; - StringBuilder sb = new StringBuilder(); - while((c=System.in.read()) >=0) { - sb.append((char)c); - } - client.setPayload(sb.toString()); - } - return client.sendAndWait(10000); - } catch (Exception e) { - e.printStackTrace(out); - return ""; - } - } - } -} diff --git a/client/src/main/java/com/att/cadi/client/Rcli.java b/client/src/main/java/com/att/cadi/client/Rcli.java deleted file mode 100644 index c25cb2b..0000000 --- a/client/src/main/java/com/att/cadi/client/Rcli.java +++ /dev/null @@ -1,696 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.util.Enumeration; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.CadiException; -import com.att.cadi.SecuritySetter; -import com.att.inno.env.APIException; -import com.att.inno.env.Data.TYPE; -import com.att.inno.env.util.Pool; -import com.att.inno.env.util.Pool.Pooled; -import com.att.rosetta.env.RosettaDF; - -public abstract class Rcli { - public static final String BLANK = ""; - public static final String CONTENT_TYPE = "Content-Type"; - public static final String ACCEPT = "Accept"; - - protected static final String POST = "POST"; - protected static final String GET = "GET"; - protected static final String PUT = "PUT"; - protected static final String DELETE = "DELETE"; - protected TYPE type; - protected String apiVersion; - protected int readTimeout = 5000; - protected int connectionTimeout = 3000; - protected URI uri; - private String queryParams, fragment; - public static Pool buffPool = new Pool(new Pool.Creator() { - @Override - public byte[] create() throws APIException { - return new byte[1024]; - } - - @Override - public void destroy(byte[] t) { - } - - @Override - public boolean isValid(byte[] t) { - return true; - } - - @Override - public void reuse(byte[] t) { - } - }); - - - public Rcli() { - super(); - } - - public abstract void setSecuritySetter(SecuritySetter ss); - public abstract SecuritySetter getSecuritySetter(); - - - public Rcli forUser(SecuritySetter ss) { - Rcli rv = clone(uri==null?this.uri:uri,ss); - setSecuritySetter(ss); - rv.type = type; - rv.apiVersion = apiVersion; - return rv; - } - - protected abstract Rcli clone(URI uri, SecuritySetter ss); - - public abstract void invalidate() throws CadiException; - - public Rcli readTimeout(int millis) { - readTimeout = millis; - return this; - } - - public Rcli connectionTimeout(int millis) { - connectionTimeout = millis; - return this; - } - - public Rcli type(TYPE type) { - this.type=type; - return this; - } - - public Rcli apiVersion(String apiVersion) { - this.apiVersion = apiVersion; - return this; - } - - public boolean isApiVersion(String prospective) { - return apiVersion.equals(prospective); - } - - - public String typeString(Class cls) { - return "application/"+cls.getSimpleName()+"+"+type.name().toLowerCase()+ - (apiVersion==null?BLANK:";version="+apiVersion); - } - - protected abstract EClient client() throws CadiException; - - - public Future create(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - EClient client = client(); - client.setMethod(POST); - client.addHeader(CONTENT_TYPE,contentType); - client.setPathInfo(pathinfo); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.futureCreate(df.getTypeClass()); - } - - public Future create(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - EClient client = client(); - client.setMethod(POST); - client.addHeader(CONTENT_TYPE,typeString(df.getTypeClass())); - client.setPathInfo(pathinfo); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.futureCreate(df.getTypeClass()); - } - - public Future create(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(POST); - client.addHeader(CONTENT_TYPE,typeString(cls)); - client.setPathInfo(pathinfo); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.futureCreate(df.getTypeClass()); - } - - public Future create(String pathinfo, Class cls) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(POST); - client.addHeader(CONTENT_TYPE,typeString(cls)); - client.setPathInfo(pathinfo); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPayload(null); - client.send(); - queryParams = fragment = null; - return client.futureCreate(cls); - } - - public Future create(String pathinfo, String contentType) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(POST); - client.addHeader(CONTENT_TYPE,contentType); - client.setPathInfo(pathinfo); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPayload(null); - client.send(); - queryParams = fragment = null; - return client.futureCreate(Void.class); - } - - - public Future read(String pathinfo, String accept, String ... headers) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(GET); - client.addHeader(ACCEPT, accept); - - for(int i=1;i Future read(String pathinfo, String accept, RosettaDF df, String ... headers) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(GET); - client.addHeader(ACCEPT, accept); - for(int i=1;i Future read(String pathinfo, RosettaDF df,String ... headers) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(GET); - client.addHeader(ACCEPT, typeString(df.getTypeClass())); - for(int i=1;i Future read(String pathinfo, Class cls, RosettaDF df) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(GET); - client.addHeader(ACCEPT, typeString(cls)); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - - client.setPayload(null); - client.send(); - queryParams = fragment = null; - return client.futureRead(df,type); - } - - public Future update(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(PUT); - client.addHeader(CONTENT_TYPE,contentType); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - public Future updateRespondString(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(PUT); - client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.futureReadString(); - } - - - public Future update(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(PUT); - client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - public Future update(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(PUT); - client.addHeader(CONTENT_TYPE, typeString(cls)); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - /** - * A method to update with a VOID - * @param pathinfo - * @param resp - * @param expected - * @return - * @throws APIException - * @throws CadiException - */ - public Future update(String pathinfo) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(PUT); - client.addHeader(CONTENT_TYPE, typeString(Void.class)); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); -// client.setPayload(new EClient.Transfer() { -// @Override -// public void transfer(OutputStream os) throws IOException, APIException { -// } -// }); - client.send(); - queryParams = fragment = null; - return client.future(null); - } - - public Future delete(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(DELETE); - client.addHeader(CONTENT_TYPE, contentType); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - public Future delete(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(DELETE); - client.addHeader(CONTENT_TYPE, typeString(cls)); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - public Future delete(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(DELETE); - client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - df.newData().out(type).direct(t,os); - } - }); - - client.send(); - queryParams = fragment = null; - return client.future(t); - } - - - public Future delete(String pathinfo, Class cls) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(DELETE); - client.addHeader(CONTENT_TYPE, typeString(cls)); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(null); - client.send(); - queryParams = fragment = null; - return client.future((T)null); - } - - public Future delete(String pathinfo, String contentType) throws APIException, CadiException { - final int idx = pathinfo.indexOf('?'); - final String qp; - if(idx>=0) { - qp=pathinfo.substring(idx+1); - pathinfo=pathinfo.substring(0,idx); - } else { - qp=queryParams; - } - - EClient client = client(); - client.setMethod(DELETE); - client.addHeader(CONTENT_TYPE, contentType); - client.setQueryParams(qp); - client.setFragment(fragment); - client.setPathInfo(pathinfo); - client.setPayload(null); - client.send(); - queryParams = fragment = null; - return client.future(null); - } - - public Future transfer(final HttpServletRequest req, final HttpServletResponse resp, final String pathParam, final int expected) throws CadiException, APIException { - EClient client = client(); - URI uri; - try { - uri = new URI(req.getRequestURI()); - } catch (Exception e) { - throw new CadiException("Invalid incoming URI",e); - } - String name; - for(Enumeration en = req.getHeaderNames();en.hasMoreElements();) { - name = en.nextElement(); - client.addHeader(name,req.getHeader(name)); - } - client.setQueryParams(req.getQueryString()); - client.setFragment(uri.getFragment()); - client.setPathInfo(pathParam); - String meth = req.getMethod(); - client.setMethod(meth); - if(!"GET".equals(meth)) { - client.setPayload(new EClient.Transfer() { - @Override - public void transfer(OutputStream os) throws IOException, APIException { - final ServletInputStream is = req.getInputStream(); - int read; - // reuse Buffers - Pooled pbuff = buffPool.get(); - try { - while((read=is.read(pbuff.content))>=0) { - os.write(pbuff.content,0,read); - } - } finally { - pbuff.done(); - } - } - }); - } - client.send(); - return client.future(resp, expected); - } - - public String toString() { - return uri.toString(); - } - - /** - * @param queryParams the queryParams to set - * @return - */ - public Rcli setQueryParams(String queryParams) { - this.queryParams = queryParams; - return this; - } - - - /** - * @param fragment the fragment to set - * @return - */ - public Rcli setFragment(String fragment) { - this.fragment = fragment; - return this; - } - - public URI getURI() { - return uri; - } - -} diff --git a/client/src/main/java/com/att/cadi/client/Result.java b/client/src/main/java/com/att/cadi/client/Result.java deleted file mode 100644 index b86d9b9..0000000 --- a/client/src/main/java/com/att/cadi/client/Result.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -public class Result { - public final int code; - public final T value; - public final String error; - - private Result(int code, T value, String error) { - this.code = code; - this.value = value; - this.error = error; - } - - public static Result ok(int code,T t) { - return new Result(code,t,null); - } - - public static Result err(int code,String body) { - return new Result(code,null,body); - } - - public boolean isOK() { - return error==null; - } - - public String toString() { - StringBuilder sb = new StringBuilder("Code: "); - sb.append(code); - if(error!=null) { - sb.append(" = "); - sb.append(error); - } - return sb.toString(); - } -} diff --git a/client/src/main/java/com/att/cadi/client/Retryable.java b/client/src/main/java/com/att/cadi/client/Retryable.java deleted file mode 100644 index 4f49a72..0000000 --- a/client/src/main/java/com/att/cadi/client/Retryable.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.client; - -import java.net.ConnectException; - -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.inno.env.APIException; - -/** - * - * - * @param - * @param - */ -public abstract class Retryable { - // be able to hold state for consistent Connections. Not required for all connection types. - public Rcli lastClient; - private Locator.Item item; - - public Retryable() { - lastClient = null; - item = null; - } - - public Retryable(Retryable ret) { - lastClient = ret.lastClient; - item = ret.item; - } - - public Locator.Item item(Locator.Item item) { - lastClient = null; - this.item = item; - return item; - } - public Locator.Item item() { - return item; - } - - public abstract RET code(Rcli client) throws CadiException, ConnectException, APIException; - - /** - * Note, Retryable is tightly coupled to the Client Utilizing. It will not be the wrong type. - * @return - */ - @SuppressWarnings("unchecked") - public Rcli lastClient() { - return (Rcli)lastClient; - } -} diff --git a/client/src/main/java/com/att/cadi/dme2/DEClient.java b/client/src/main/java/com/att/cadi/dme2/DEClient.java deleted file mode 100644 index 138fb63..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DEClient.java +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.URI; - -import javax.servlet.http.HttpServletResponse; - -import com.att.aft.dme2.api.DME2Client; -import com.att.aft.dme2.api.DME2Exception; -import com.att.aft.dme2.api.DME2Manager; -import com.att.aft.dme2.handler.DME2RestfulHandler; -import com.att.aft.dme2.handler.DME2RestfulHandler.ResponseInfo; -import com.att.cadi.CadiException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.EClient; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.inno.env.APIException; -import com.att.inno.env.Data; -import com.att.rosetta.env.RosettaDF; - -public class DEClient implements EClient { - private DME2Client client; - private DME2RestfulHandler replyHandler; - private EClient.Transfer payload; - private boolean isProxy; - private SecuritySetter ss; - - public DEClient(DME2Manager manager, SecuritySetter ss, URI uri, long timeout) throws DME2Exception, CadiException { - client = new DME2Client(manager,uri,timeout); - client.setAllowAllHttpReturnCodes(true); - this.ss = ss; - ss.setSecurity(client); - replyHandler = new DME2RestfulHandler(Rcli.BLANK); - client.setReplyHandler(replyHandler); - } - - @Override - public void setMethod(String meth) { - client.setMethod(meth); - } - - /** - * DME2 can't handle having QueryParams on the URL line, but it is the most natural way, so... - * - * Also, DME2 can't handle "/proxy" as part of Context in the main URI line, so we add it when we see authz-gw to "isProxy" - */ - public void setPathInfo(String pathinfo) { - int qp = pathinfo.indexOf('?'); - if(qp<0) { - client.setContext(isProxy?("/proxy"+pathinfo):pathinfo); - } else { - client.setContext(isProxy?("/proxy"+pathinfo.substring(0,qp)):pathinfo.substring(0,qp)); - client.setQueryParams(pathinfo.substring(qp+1)); - } - } - - @Override - public void setPayload(EClient.Transfer transfer) { - payload = transfer; - } - - @Override - public void addHeader(String tag, String value) { - client.addHeader(tag, value); - } - - - @Override - public void setQueryParams(String q) { - client.setQueryParams(q); - } - - @Override - public void setFragment(String f) { - // DME2 does not implement this - } - - @Override - public void send() throws APIException { - try { - if(payload!=null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - payload.transfer(baos); - client.setPayload(new String(baos.toByteArray())); - } else { - client.setPayload(""); - } - client.send(); - } catch (DME2Exception e) { - throw new APIException(e); - } catch (IOException e) { - throw new APIException(e); - } - } - - - public class DFuture extends Future { - protected final DME2RestfulHandler reply; - protected ResponseInfo info; - - public DFuture(DME2RestfulHandler reply) { - this.reply = reply; - } - - protected boolean evalInfo() throws APIException{ - //return info.getCode()==200; - return true; - }; - - public final boolean get(int timeout) throws CadiException { - try { - info = reply.getResponse(timeout); - ss.setLastResponse(info.getCode()); - return evalInfo(); - } catch (Exception e) { - throw new CadiException(e); - } - } - - @Override - public int code() { - return info.getCode(); - } - - @Override - public String body() { - return info.getBody(); - } - - @Override - public String header(String tag) { - return info.header(tag); - } - - } - - @Override - public Future futureCreate(Class t) { - return new DFuture(replyHandler) { - public boolean evalInfo() throws APIException { - - return info.getCode()==201; - } - }; - } - - - @Override - public Future futureReadString() { - return new DFuture(replyHandler) { - public boolean evalInfo() throws APIException { - if(info.getCode()==200) { - value = info.getBody(); - return true; - } - return false; - } - }; - } - - @Override - public Future futureRead(final RosettaDF df, final Data.TYPE type) { - return new DFuture(replyHandler) { - public boolean evalInfo() throws APIException { - if(info.getCode()==200) { - value = df.newData().in(type).load(info.getBody()).asObject(); - return true; - } - return false; - } - }; - } - - @Override - public Future future(final T t) { - return new DFuture(replyHandler) { - public boolean evalInfo() { - if(info.getCode()==200) { - value = t; - return true; - } - return false; - } - }; - } - - @Override - public Future future(HttpServletResponse resp,int expected) throws APIException { - // TODO Auto-generated method stub - return null; - } - - public void setProxy(boolean isProxy) { - this.isProxy=isProxy; - } - - -} diff --git a/client/src/main/java/com/att/cadi/dme2/DME2BasicAuth.java b/client/src/main/java/com/att/cadi/dme2/DME2BasicAuth.java deleted file mode 100644 index 3fb1f13..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DME2BasicAuth.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - -import java.io.IOException; -import java.security.GeneralSecurityException; - -import com.att.aft.dme2.api.DME2Client; -import com.att.cadi.Access; -import com.att.cadi.CadiException; -import com.att.cadi.client.AbsBasicAuth; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.principal.BasicPrincipal; - -public class DME2BasicAuth extends AbsBasicAuth { - public DME2BasicAuth(String user, String pass, SecurityInfoC si) throws IOException { - super(user,pass,si); - } - - public DME2BasicAuth(Access access, SecurityInfoC si) throws IOException { - super(access.getProperty(Config.AAF_MECHID, null), - access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), - si); - } - - public DME2BasicAuth(BasicPrincipal bp,SecurityInfoC si) throws IOException { - super(bp.getName(),new String(bp.getCred()),si); - } - - public DME2BasicAuth(Access access) throws IOException, GeneralSecurityException { - super(access.getProperty(Config.AAF_MECHID, null), - access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), - new SecurityInfoC(access)); - } - - public void setSecurity(DME2Client client) throws CadiException { - if(isDenied()) { - throw new CadiException(REPEAT_OFFENDER); - } - client.addHeader("Authorization", headValue); - } -} diff --git a/client/src/main/java/com/att/cadi/dme2/DME2ClientSS.java b/client/src/main/java/com/att/cadi/dme2/DME2ClientSS.java deleted file mode 100644 index 8895e9f..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DME2ClientSS.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - -import java.io.IOException; - -import com.att.aft.dme2.api.DME2Client; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.SecuritySetter; - -public class DME2ClientSS implements SecuritySetter { - private Access access; - private String user,crd; - - public DME2ClientSS(Access access, String user, String pass) throws IOException { - this.access = access; - this.user = user; - this.crd = pass; - } - - @Override - public void setSecurity(DME2Client client) { - try { - client.setCredentials(user, access.decrypt(crd, false)); - } catch (IOException e) { - access.log(Level.ERROR,e,"Error decrypting DME2 Password"); - } - } - - /* (non-Javadoc) - * @see com.att.cadi.SecuritySetter#getID() - */ - @Override - public String getID() { - return user; - } - - @Override - public int setLastResponse(int respCode) { - // TODO Auto-generated method stub - return 0; - } -} diff --git a/client/src/main/java/com/att/cadi/dme2/DME2Locator.java b/client/src/main/java/com/att/cadi/dme2/DME2Locator.java deleted file mode 100644 index f28fe94..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DME2Locator.java +++ /dev/null @@ -1,348 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - - -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Random; - -// -import com.att.aft.dme2.api.DME2Exception; -import com.att.aft.dme2.api.DME2Manager; -import com.att.aft.dme2.api.DME2Server; -import com.att.aft.dme2.manager.registry.DME2Endpoint; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; - -public class DME2Locator implements Locator { - private DME2Manager dm; - private DME2Endpoint[] endpoints; - private Access access; - private String service; - private String version; - private String routeOffer; - private String envContext; - private String thisMachine; - private String pathInfo; - private int thisPort; - private boolean removeSelf; - private final static Random random = new Random(); - - // Default is to not bother trying to remove self - public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer) throws DME2Exception, UnknownHostException, LocatorException { - this(access,dm,service,version,envContext,routeOffer,false); - } - - public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { - this.access = access; - if(dm==null) { - this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); - } else { - this.dm = dm; - } - this.service = service; - this.version = version; - this.envContext = envContext; - this.routeOffer = routeOffer; - refresh(); - DME2Server server = dm.getServer(); - if(server == null) { - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } else { - try { - thisMachine = server.getServerProperties().getHostname(); - //thisPort = server.getPort(); - thisPort = server.getServerProperties().getPort(); - } catch(NullPointerException np) { // BAD BOY, DME2... - access.log(Level.ERROR, "WARNING: DME2 threw a NullPointer Exception getting Server Machine and Port"); - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } - } - this.removeSelf = removeSelf; - } - - // Default is to not bother trying to remove self - public DME2Locator(Access access, DME2Manager dm, String aafurl) throws DME2Exception, UnknownHostException, LocatorException { - this(access,dm,aafurl,false); - } - - public DME2Locator(Access access, DME2Manager dm, String aafurl, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { - if(aafurl==null) throw new LocatorException("URL is null"); - this.access = access; - if(dm==null) { - dm = this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); - } else { - this.dm = dm; - } - String[] split = aafurl.split("/"); - StringBuilder sb = new StringBuilder(); - boolean dme2Entered = false; - for(String s : split) { - if(s.startsWith( "service=")) this.service = s.substring(8); - else if(s.startsWith("version=")) this.version = s.substring(8); - else if(s.startsWith("envContext=")) this.envContext = s.substring(11); - else if(s.startsWith("routeOffer=")) { - this.routeOffer = s.substring(11); - dme2Entered = true; - } - else if(dme2Entered) { - sb.append('/'); - sb.append(s); - } - pathInfo = sb.toString(); - } - DME2Server server = dm.getServer(); - if(server == null) { - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } else { - thisMachine = server.getServerProperties().getHostname(); - if(thisMachine==null) { // even if server !=null, apparently, it can be uninitialized - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } else { - try { - thisPort = server.getServerProperties().getPort(); - } catch (Exception e) { - thisPort = 0; - } - } - } - this.removeSelf=removeSelf; - refresh(); - } - - @Override - public boolean refresh() { - try { - dm.refresh(); - endpoints = dm.findEndpoints(service, version, envContext, routeOffer, true); - if(removeSelf) { - for(int i=0;i0; - } - - @Override - public void invalidate(Locator.Item item) throws LocatorException { - if(item instanceof Item) { - int idx = ((Item)item).idx; - if(idx () { - @Override - public int compare(DoubIndex a, DoubIndex b) { - if(a.db.d) return 1; - return (random.nextInt()%1)==0?1:0;// randomize if the same - } - - }); - return new Item(remote[0].idx); - } - } - } - - private class DoubIndex { - public final double d; - public final int idx; - - public DoubIndex(double doub, int i) { - d = doub; - idx = i; - } - } - @Override - public Item first() { - if(endpoints==null)return null; - for(int i=0;i { - - public DME2TransferSS(Principal principal, String app, SecurityInfoC si) throws IOException { - super(principal, app, si); - } - - @Override - public void setSecurity(DME2Client client) throws CadiException { - if(value!=null) { - if(defSS==null) { - throw new CadiException("Need App Credentials to send message"); - } - defSS.setSecurity(client); - client.addHeader(Config.CADI_USER_CHAIN, value); - } - } - - @Override - public int setLastResponse(int respCode) { - return 0; - } -} diff --git a/client/src/main/java/com/att/cadi/dme2/DME2x509SS.java b/client/src/main/java/com/att/cadi/dme2/DME2x509SS.java deleted file mode 100644 index 45978e4..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DME2x509SS.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - -import java.io.IOException; -import java.security.cert.CertificateEncodingException; - -import com.att.aft.dme2.api.DME2Client; -import com.att.cadi.CadiException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.inno.env.APIException; - - -public class DME2x509SS implements SecuritySetter { - private String alias; - - public DME2x509SS(final String sendAlias, SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { - if((alias=sendAlias) == null) { - if(si.default_alias == null) { - throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias"); - } else { - alias = si.default_alias; - } - } - } - - @Override - public void setSecurity(DME2Client dme2) throws CadiException { - // DME2Client has to have properties set before creation to work. - } - - /* (non-Javadoc) - * @see com.att.cadi.SecuritySetter#getID() - */ - @Override - public String getID() { - return alias; - } - - @Override - public int setLastResponse(int respCode) { - return 0; - } - -} diff --git a/client/src/main/java/com/att/cadi/dme2/DRcli.java b/client/src/main/java/com/att/cadi/dme2/DRcli.java deleted file mode 100644 index 8a1f5fb..0000000 --- a/client/src/main/java/com/att/cadi/dme2/DRcli.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dme2; - -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; - -import com.att.aft.dme2.api.DME2Client; -import com.att.aft.dme2.api.DME2Exception; -import com.att.aft.dme2.api.DME2Manager; -import com.att.aft.dme2.manager.registry.DME2Endpoint; -import com.att.aft.dme2.request.DmeUniformResource; -import com.att.cadi.CadiException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.EClient; -import com.att.cadi.client.Rcli; -import com.att.inno.env.APIException; -import com.att.inno.env.Data.TYPE; - -/** - * DME2 Rosetta Client - * - * JAXB defined JSON or XML over DME2 middleware - * - * - * @param - */ -public class DRcli extends Rcli { - // Can be more efficient if tied to manager, apparently. Can pass in null. - DME2Manager manager=null; - private SecuritySetter ss; - private boolean isProxy; - - public DRcli(URI uri, SecuritySetter secSet) { - this.uri = uri; - type = TYPE.JSON; - apiVersion = null; - ss=secSet; - } - - @Override - protected DRcli clone(URI uri, SecuritySetter ss) { - return new DRcli(uri,ss); - } - - - - /** - * Note from Thaniga on 11/5. DME2Client is not expected to be reused... need a fresh one - * on each transaction, which is expected to cover the Async aspects. - * - * @return - * @throws APIException - * @throws DME2Exception - */ - protected EClient client() throws CadiException { - try { - DEClient dc = new DEClient(manager,getSecuritySetter(),uri,readTimeout); - dc.setProxy(isProxy); - return dc; - } catch (DME2Exception e) { - throw new CadiException(e); - } - } - - public DRcli setManager(DME2Manager dme2Manager) { - manager = dme2Manager; - return this; - } - - public List all() throws DME2Exception, APIException { - ArrayList al = new ArrayList(); - - if(manager == null) { - manager = DME2Manager.getDefaultInstance(); - } - try { - DME2Endpoint[] endp = manager.getEndpoints(new DmeUniformResource(manager.getConfig(),uri)); - // Convert Searchable Endpoints to Direct Endpoints - for(DME2Endpoint de : endp) { - al.add(new DRcli( - new URI(uri.getScheme(),null,de.getHost(),de.getPort(),null,null,null),ss) -// new URI(uri.getScheme(),null,de.getHost(),de.getPort(),uri.getPath(),null,null),ss) - .setManager(manager) - ); - } - } catch (MalformedURLException e) { - throw new APIException("Invalid URL",e); - } catch (URISyntaxException e) { - throw new APIException("Invalid URI",e); - } - return al; - } - - @Override - public void invalidate() throws CadiException { - try { - manager.refresh(); - } catch (Exception e) { - throw new CadiException(e); - } - } - - @Override - public void setSecuritySetter(SecuritySetter ss) { - this.ss = ss; - } - - @Override - public SecuritySetter getSecuritySetter() { - return ss; - } - - public void setProxy(boolean isProxy) { - this.isProxy = isProxy; - } - -} diff --git a/client/src/main/java/com/att/cadi/dnsloc/DNSLocator.java b/client/src/main/java/com/att/cadi/dnsloc/DNSLocator.java deleted file mode 100644 index 3bf9080..0000000 --- a/client/src/main/java/com/att/cadi/dnsloc/DNSLocator.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.dnsloc; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; - -public class DNSLocator implements Locator { - private static enum Status {UNTRIED, OK, INVALID, SLOW}; - private static final int CHECK_TIME = 3000; - - private String host, protocol; - private Access access; - private Host[] hosts; - private int startPort, endPort; - private String suffix; - - public DNSLocator(Access access, String protocol, String host, String range) { - this.host = host; - this.protocol = protocol; - this.access = access; - int dash = range.indexOf('-'); - if(dash<0) { - startPort = endPort = Integer.parseInt(range); - } else { - startPort = Integer.parseInt(range.substring(0,dash)); - endPort = Integer.parseInt(range.substring(dash + 1)); - } - refresh(); - } - - @Override - public URI get(Item item) throws LocatorException { - return hosts[((DLItem)item).cnt].uri; - } - - @Override - public boolean hasItems() { - for(Host h : hosts) { - if(h.status==Status.OK) { - return true; - } - } - return false; - } - - @Override - public void invalidate(Item item) { - DLItem di = (DLItem)item; - hosts[di.cnt].status = Status.INVALID; - } - - @Override - public Item best() throws LocatorException { - // not a good "best" - for(int i=0;i { - public HBasicAuthSS(Access access, SecurityInfoC si) throws IOException { - super(access.getProperty(Config.AAF_MECHID, null), - access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), - si); - } - - public HBasicAuthSS(String user, String pass, SecurityInfoC si) throws IOException { - super(user,pass,si); - } - - public HBasicAuthSS(String user, String pass, SecurityInfoC si, boolean asDefault) throws IOException { - super(user,pass,si); - if(asDefault) { - si.set(this); - } - } - - public HBasicAuthSS(BasicPrincipal bp, SecurityInfoC si) throws IOException { - super(bp.getName(),new String(bp.getCred()),si); - } - - public HBasicAuthSS(BasicPrincipal bp, SecurityInfoC si, boolean asDefault) throws IOException { - super(bp.getName(),new String(bp.getCred()),si); - if(asDefault) { - si.set(this); - } - } - - @Override - public void setSecurity(HttpURLConnection huc) throws CadiException { - if(isDenied()) { - throw new CadiException(REPEAT_OFFENDER); - } - huc.addRequestProperty("Authorization" , headValue); - if(securityInfo!=null && huc instanceof HttpsURLConnection) { - securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); - } - } -} diff --git a/client/src/main/java/com/att/cadi/http/HClient.java b/client/src/main/java/com/att/cadi/http/HClient.java deleted file mode 100644 index 6704bf4..0000000 --- a/client/src/main/java/com/att/cadi/http/HClient.java +++ /dev/null @@ -1,433 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.http; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; - -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.CadiException; -import com.att.cadi.LocatorException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.EClient; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.inno.env.APIException; -import com.att.inno.env.Data; -import com.att.inno.env.Data.TYPE; -import com.att.inno.env.util.Pool.Pooled; -import com.att.rosetta.env.RosettaDF; - -/** - * Low Level Http Client Mechanism. Chances are, you want the high level "HRcli" - * for Rosetta Object Translation - * - * - */ -public class HClient implements EClient { - private URI uri; - private ArrayList
headers; - private String meth; - private String pathinfo; - private String query; - private String fragment; - private Transfer transfer; - private SecuritySetter ss; - private HttpURLConnection huc; - private int connectTimeout; - - public HClient(SecuritySetter ss, URI uri,int connectTimeout) throws LocatorException { - if (uri == null) { - throw new LocatorException("No Service available to call"); - } - this.uri = uri; - this.ss = ss; - this.connectTimeout = connectTimeout; - pathinfo = query = fragment = ""; - } - - @Override - public void setMethod(String meth) { - this.meth = meth; - } - - @Override - public void setPathInfo(String pathinfo) { - this.pathinfo = pathinfo; - } - - @Override - public void setPayload(Transfer transfer) { - this.transfer = transfer; - } - - @Override - public void addHeader(String tag, String value) { - if (headers == null) - headers = new ArrayList
(); - headers.add(new Header(tag, value)); - } - - @Override - public void setQueryParams(String q) { - query = q; - } - - @Override - public void setFragment(String f) { - fragment = f; - } - - @Override - public void send() throws APIException { - try { - // Build URL from given URI plus current Settings - if(uri.getPath()==null) { - throw new APIException("Invalid URL entered for HClient"); - } - StringBuilder pi = new StringBuilder(uri.getPath()); - if(!pathinfo.startsWith("/")) { - pi.append('/'); - } - pi.append(pathinfo); - URL url = new URI( - uri.getScheme(), - uri.getUserInfo(), - uri.getHost(), - uri.getPort(), - pi.toString(), - query, - fragment).toURL(); - pathinfo=null; - query=null; - fragment=null; - huc = (HttpURLConnection) url.openConnection(); - if(ss!=null) { - ss.setSecurity(huc); - } - huc.setRequestMethod(meth); - if (headers != null) - for (Header d : headers) { - huc.addRequestProperty(d.tag, d.value); - } - huc.setDoInput(true); - huc.setDoOutput(true); - huc.setUseCaches(false); - huc.setConnectTimeout(connectTimeout); - huc.connect(); - if (transfer != null) { - transfer.transfer(huc.getOutputStream()); - } - // TODO other settings? There's a bunch here. - } catch (Exception e) { - throw new APIException(e); - } finally { // ensure all these are reset after sends - meth=pathinfo=null; - if(headers!=null) { - headers.clear(); - } - pathinfo = query = fragment = ""; - } - } - - public abstract class HFuture extends Future { - protected HttpURLConnection huc; - protected int respCode; - protected String respMessage; - protected IOException exception; - protected StringBuilder errContent; - - public HFuture(final HttpURLConnection huc) { - this.huc = huc; - } - - protected boolean evalInfo(HttpURLConnection huc) throws APIException, IOException{ - return respCode == 200; - }; - - @Override - public final boolean get(int timeout) throws CadiException { - try { - huc.setReadTimeout(timeout); - respCode = huc.getResponseCode(); - ss.setLastResponse(respCode); - if(evalInfo(huc)) { - return true; - } else { - extractError(); - return false; - } - } catch (IOException | APIException e) { - throw new CadiException(e); - } finally { - close(); - } - } - - private void extractError() { - InputStream is = huc.getErrorStream(); - try { - if(is==null) { - is = huc.getInputStream(); - } - if(is!=null) { - errContent = new StringBuilder(); - int c; - while((c=is.read())>=0) { - errContent.append((char)c); - } - } - } catch (IOException e) { - exception = e; - } - } - - // Typically only used by Read - public StringBuilder inputStreamToString(InputStream is) { - // Avoids Carriage returns, and is reasonably efficient, given - // the buffer reads. - try { - StringBuilder sb = new StringBuilder(); - Reader rdr = new InputStreamReader(is); - try { - char[] buf = new char[256]; - int read; - while ((read = rdr.read(buf)) >= 0) { - sb.append(buf, 0, read); - } - } finally { - rdr.close(); - } - return sb; - } catch (IOException e) { - exception = e; - return null; - } - } - - - @Override - public int code() { - return respCode; - } - - public HttpURLConnection huc() { - return huc; - } - - public IOException exception() { - return exception; - } - - public String respMessage() { - return respMessage; - } - - @Override - public String header(String tag) { - return huc.getHeaderField(tag); - } - - public void close() { - if(huc!=null) { - huc.disconnect(); - } - } - } - - @Override - public Future futureCreate(Class t) { - return new HFuture(huc) { - public boolean evalInfo(HttpURLConnection huc) { - return respCode==201; - } - - @Override - public String body() { - if (errContent != null) { - return errContent.toString(); - - } else if (respMessage != null) { - return respMessage; - } - return ""; - } - }; - } - - @Override - public Future futureReadString() { - return new HFuture(huc) { - public boolean evalInfo(HttpURLConnection huc) throws IOException { - if (respCode == 200) { - StringBuilder sb = inputStreamToString(huc.getInputStream()); - if (sb != null) { - value = sb.toString(); - } - return true; - } - return false; - } - - @Override - public String body() { - if (value != null) { - return value; - } else if (errContent != null) { - return errContent.toString(); - } else if (respMessage != null) { - return respMessage; - } - return ""; - } - - }; - } - - @Override - public Future futureRead(final RosettaDF df, final TYPE type) { - return new HFuture(huc) { - private Data data; - - public boolean evalInfo(HttpURLConnection huc) throws APIException, IOException { - if (respCode == 200) { - data = df.newData().in(type).load(huc.getInputStream()); - value = data.asObject(); - return true; - } - return false; - } - - @Override - public String body() { - if (data != null) { - try { - return data.asString(); - } catch (APIException e) { - } - } else if (errContent != null) { - return errContent.toString(); - } else if (respMessage != null) { - return respMessage; - } - return ""; - } - }; - } - - @Override - public Future future(final T t) { - return new HFuture(huc) { - public boolean evalInfo(HttpURLConnection huc) { - if (respCode == 200) { - value = t; - return true; - } - return false; - } - - @Override - public String body() { - if (errContent != null) { - return errContent.toString(); - } else if (respMessage != null) { - return respMessage; - } - return Integer.toString(respCode); - } - }; - } - - @Override - public Future future(final HttpServletResponse resp, final int expected) throws APIException { - return new HFuture(huc) { - public boolean evalInfo(HttpURLConnection huc) throws IOException, APIException { - resp.setStatus(respCode); - int read; - InputStream is; - OutputStream os = resp.getOutputStream(); - if(respCode==expected) { - is = huc.getInputStream(); - // reuse Buffers - Pooled pbuff = Rcli.buffPool.get(); - try { - while((read=is.read(pbuff.content))>=0) { - os.write(pbuff.content,0,read); - } - } finally { - pbuff.done(); - } - return true; - } else { - is = huc.getErrorStream(); - if(is==null) { - is = huc.getInputStream(); - } - if(is!=null) { - errContent = new StringBuilder(); - Pooled pbuff = Rcli.buffPool.get(); - try { - while((read=is.read(pbuff.content))>=0) { - os.write(pbuff.content,0,read); - } - } finally { - pbuff.done(); - } - } - } - return false; - } - - @Override - public String body() { - return errContent==null?respMessage:errContent.toString(); - } - }; - } - - private static class Header { - public final String tag; - public final String value; - - public Header(String t, String v) { - this.tag = t; - this.value = v; - } - - public String toString() { - return tag + '=' + value; - } - } - - public String toString() { - return "HttpURLConnection Client configured to " + uri.toString(); - } -} diff --git a/client/src/main/java/com/att/cadi/http/HMangr.java b/client/src/main/java/com/att/cadi/http/HMangr.java deleted file mode 100644 index 13fe815..0000000 --- a/client/src/main/java/com/att/cadi/http/HMangr.java +++ /dev/null @@ -1,235 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.http; - -import java.net.ConnectException; -import java.net.HttpURLConnection; -import java.net.SocketException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.net.ssl.SSLHandshakeException; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator.Item; -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.inno.env.APIException; - -public class HMangr { - private String apiVersion; - private int readTimeout, connectionTimeout; - public final Locator loc; - private Access access; - - public HMangr(Access access, Locator loc) { - readTimeout = 10000; - connectionTimeout=3000; - this.loc = loc; - this.access = access; - } - - /** - * Reuse the same service. This is helpful for multiple calls that change service side cached data so that - * there is not a speed issue. - * - * If the service goes down, another service will be substituted, if available. - * - * @param access - * @param loc - * @param ss - * @param item - * @param retryable - * @return - * @throws URISyntaxException - * @throws Exception - */ - public RET same(SecuritySetter ss, Retryable retryable) throws APIException, CadiException, LocatorException { - RET ret = null; - boolean retry = true; - int retries = 0; - Rcli client = retryable.lastClient(); - try { - do { - // if no previous state, get the best - if(retryable.item()==null) { - retryable.item(loc.best()); - retryable.lastClient = null; - } - if(client==null) { - Item item = retryable.item(); - URI uri=loc.get(item); - if(uri==null) { - loc.invalidate(retryable.item()); - if(loc.hasItems()) { - retryable.item(loc.next(retryable.item())); - continue; - } else { - throw new LocatorException("No clients available for " + loc.toString()); - } - } - client = new HRcli(this, uri,item,ss) - .connectionTimeout(connectionTimeout) - .readTimeout(readTimeout) - .apiVersion(apiVersion); - } else { - client.setSecuritySetter(ss); - } - - retry = false; - try { - ret = retryable.code(client); - } catch (APIException | CadiException e) { - Item item = retryable.item(); - loc.invalidate(item); - retryable.item(loc.next(item)); - try { - Throwable ec = e.getCause(); - if(ec instanceof java.net.ConnectException) { - if(client!=null && ++retries<2) { - access.log(Level.WARN,"Connection refused, trying next available service"); - retry = true; - } else { - throw new CadiException("Connection refused, no more available connections to try"); - } - } else if(ec instanceof SSLHandshakeException) { - retryable.item(null); - throw e; - } else if(ec instanceof SocketException) { - if("java.net.SocketException: Connection reset".equals(ec.getMessage())) { - access.log(Level.ERROR, ec.getMessage(), " can mean Certificate Expiration or TLS Protocol issues"); - } - retryable.item(null); - throw e; - } else { - retryable.item(null); - throw e; - } - } finally { - client = null; - } - } catch (ConnectException e) { - Item item = retryable.item(); - loc.invalidate(item); - retryable.item(loc.next(item)); - } - } while(retry); - } finally { - retryable.lastClient = client; - } - return ret; - } - - - public RET best(SecuritySetter ss, Retryable retryable) throws LocatorException, CadiException, APIException { - if(loc==null) { - throw new LocatorException("No Locator Configured"); - } - retryable.item(loc.best()); - return same(ss,retryable); - } - public RET all(SecuritySetter ss, Retryable retryable) throws LocatorException, CadiException, APIException { - return oneOf(ss,retryable,true,null); - } - - public RET all(SecuritySetter ss, Retryable retryable,boolean notify) throws LocatorException, CadiException, APIException { - return oneOf(ss,retryable,notify,null); - } - - public RET oneOf(SecuritySetter ss, Retryable retryable,boolean notify,String host) throws LocatorException, CadiException, APIException { - RET ret = null; - // make sure we have all current references: - loc.refresh(); - for(Item li=loc.first();li!=null;li=loc.next(li)) { - URI uri=loc.get(li); - if(host!=null && !host.equals(uri.getHost())) { - break; - } - try { - ret = retryable.code(new HRcli(this,uri,li,ss)); - access.log(Level.DEBUG,"Success calling",uri,"during call to all services"); - } catch (APIException | CadiException e) { - Throwable t = e.getCause(); - if(t!=null && t instanceof ConnectException) { - loc.invalidate(li); - access.log(Level.ERROR,"Connection to",uri,"refused during call to all services"); - } else if(t instanceof SSLHandshakeException) { - access.log(Level.ERROR,t.getMessage()); - loc.invalidate(li); - } else if(t instanceof SocketException) { - if("java.net.SocketException: Connection reset".equals(t.getMessage())) { - access.log(Level.ERROR, t.getMessage(), " can mean Certificate Expiration or TLS Protocol issues"); - } - retryable.item(null); - throw e; - } else { - throw e; - } - } catch (ConnectException e) { - loc.invalidate(li); - access.log(Level.ERROR,"Connection to",uri,"refused during call to all services"); - } - } - - if(ret == null && notify) - throw new LocatorException("No available clients to call"); - return ret; - } - - - public void close() { - // TODO Anything here? - } - - public HMangr readTimeout(int timeout) { - this.readTimeout = timeout; - return this; - } - - public int readTimeout() { - return readTimeout; - } - - public void connectionTimeout(int t) { - connectionTimeout = t; - } - - public int connectionTimout() { - return connectionTimeout; - } - - public HMangr apiVersion(String version) { - apiVersion = version; - return this; - } - - public String apiVersion() { - return apiVersion; - } - -} diff --git a/client/src/main/java/com/att/cadi/http/HRcli.java b/client/src/main/java/com/att/cadi/http/HRcli.java deleted file mode 100644 index cfbb5c1..0000000 --- a/client/src/main/java/com/att/cadi/http/HRcli.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.http; - -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URISyntaxException; - -import com.att.aft.dme2.api.DME2Exception; -import com.att.cadi.CadiException; -import com.att.cadi.LocatorException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.Locator.Item; -import com.att.cadi.client.EClient; -import com.att.cadi.client.Rcli; -import com.att.inno.env.APIException; -import com.att.inno.env.Data.TYPE; - -/** - * DME2 Rosetta Client - * - * JAXB defined JSON or XML over DME2 middleware - * - * - * @param - */ -public class HRcli extends Rcli { - private HMangr hman; - private Item item; - private SecuritySetter ss; - - public HRcli(HMangr hman, Item locItem, SecuritySetter secSet) throws URISyntaxException, LocatorException { - item=locItem; - uri=hman.loc.get(locItem); - this.hman = hman; - ss=secSet; - type = TYPE.JSON; - apiVersion = hman.apiVersion(); - } - - public HRcli(HMangr hman, URI uri, Item locItem, SecuritySetter secSet) { - locItem=item; - this.uri = uri; - this.hman = hman; - ss=secSet; - type = TYPE.JSON; - apiVersion = hman.apiVersion(); - } - - @Override - protected HRcli clone(URI uri, SecuritySetter ss) { - return new HRcli(hman,uri,item,ss); - } - - - - /** - * Note from Thaniga on 11/5. DME2Client is not expected to be reused... need a fresh one - * on each transaction, which is expected to cover the Async aspects. - * - * @return - * @throws APIException - * @throws DME2Exception - */ - protected EClient client() throws CadiException { - try { - if(uri==null) { - Item item = hman.loc.best(); - if(item==null) { - throw new CadiException("No service available for " + hman.loc.toString()); - } - uri = hman.loc.get(item); - } - return new HClient(ss,uri,connectionTimeout); - } catch (Exception e) { - throw new CadiException(e); - } - } - - /* (non-Javadoc) - * @see com.att.cadi.client.Rcli#setSecuritySetter(com.att.cadi.SecuritySetter) - */ - @Override - public void setSecuritySetter(SecuritySetter ss) { - this.ss = ss; - } - - /* (non-Javadoc) - * @see com.att.cadi.client.Rcli#getSecuritySetter() - */ - @Override - public SecuritySetter getSecuritySetter() { - return ss; - } - - public void invalidate() throws CadiException { - try { - hman.loc.invalidate(item); - } catch (Exception e) { - throw new CadiException(e); - } - } - - public HRcli setManager(HMangr hman) { - this.hman = hman; - return this; - } - - public String toString() { - return uri.toString(); - } - -} diff --git a/client/src/main/java/com/att/cadi/http/HTransferSS.java b/client/src/main/java/com/att/cadi/http/HTransferSS.java deleted file mode 100644 index 89a38c3..0000000 --- a/client/src/main/java/com/att/cadi/http/HTransferSS.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.http; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.security.Principal; - -import javax.net.ssl.HttpsURLConnection; - -import com.att.cadi.CadiException; -import com.att.cadi.client.AbsTransferSS; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; - - -public class HTransferSS extends AbsTransferSS { - public HTransferSS(Principal principal, String app) throws IOException { - super(principal, app); - } - - public HTransferSS(Principal principal, String app, SecurityInfoC si) { - super(principal, app, si); - } - - @Override - public void setSecurity(HttpURLConnection huc) throws CadiException { - if(value!=null) { - if(defSS==null) { - throw new CadiException("Need App Credentials to send message"); - } - defSS.setSecurity(huc); - huc.addRequestProperty(Config.CADI_USER_CHAIN, value); - } - if(securityInfo!=null) { - securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); - } - } - - @Override - public int setLastResponse(int respCode) { - return 0; - } - -} diff --git a/client/src/main/java/com/att/cadi/http/HX509SS.java b/client/src/main/java/com/att/cadi/http/HX509SS.java deleted file mode 100644 index b790ede..0000000 --- a/client/src/main/java/com/att/cadi/http/HX509SS.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.http; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.security.PrivateKey; -import java.security.SecureRandom; -import java.security.Signature; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.X509KeyManager; - -import com.att.cadi.CadiException; -import com.att.cadi.SecuritySetter; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.inno.env.APIException; -import com.att.inno.env.util.Chrono; - - -public class HX509SS implements SecuritySetter { - private static final byte[] X509 = "x509 ".getBytes(); - private PrivateKey priv; - private byte[] pub; - private String cert; - private SecurityInfoC securityInfo; - private String algo; - private String alias; - private static int count = new SecureRandom().nextInt(); - - public HX509SS(SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { - this(null,si,false); - } - - public HX509SS(SecurityInfoC si, boolean asDefault) throws APIException, IOException, CertificateEncodingException { - this(null,si,asDefault); - } - - public HX509SS(final String sendAlias, SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { - this(sendAlias, si, false); - } - - public HX509SS(final String sendAlias, SecurityInfoC si, boolean asDefault) throws APIException, IOException, CertificateEncodingException { - securityInfo = si; - if((alias=sendAlias) == null) { - if(si.default_alias == null) { - throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias"); - } else { - alias = si.default_alias; - } - } - - priv=null; - X509KeyManager[] xkms = si.getKeyManagers(); - if(xkms==null || xkms.length==0) { - throw new APIException("There are no valid keys available in given Keystores. Wrong Keypass? Expired?"); - } - for(int i=0;priv==null&&i0) { - algo = chain[0].getSigAlgName(); - pub = chain[0].getEncoded(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(pub.length*2); - ByteArrayInputStream bais = new ByteArrayInputStream(pub); - Symm.base64noSplit.encode(bais,baos,X509); - cert = baos.toString(); - - /* - // Inner Test code, uncomment if fix needed - bais = new ByteArrayInputStream(baos.toByteArray()); - baos = new ByteArrayOutputStream(input.length*2); - Symm.base64noSplit().decode(bais,baos,5); - byte[] output = baos.toByteArray(); - String reconstitute = output.toString(); - System.out.println("ok"); - CertificateFactory certFactory; - try { - bais = new ByteArrayInputStream(output); - certFactory = CertificateFactory.getInstance("X.509"); - X509Certificate x509 = (X509Certificate)certFactory.generateCertificate(bais); - System.out.println(x509.toString()); - } catch (CertificateException e) { - e.printStackTrace(); - } - */ - } - } - if(algo==null) { - throw new APIException("X509 Security Setter not configured"); - } - } - - @Override - public void setSecurity(HttpURLConnection huc) throws CadiException { - if(huc instanceof HttpsURLConnection) { - securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); - } - if(alias==null) { // must be a one-way - huc.setRequestProperty("Authorization", cert); - - // Test Signed content - try { - String data = "SignedContent["+ inc() + ']' + Chrono.dateTime(); - huc.setRequestProperty("Data", data); - - Signature sig = Signature.getInstance(algo); - sig.initSign(priv); - sig.update(data.getBytes()); - byte[] signature = sig.sign(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(signature.length*1.3)); - ByteArrayInputStream bais = new ByteArrayInputStream(signature); - Symm.base64noSplit.encode(bais, baos); - huc.setRequestProperty("Signature", new String(baos.toByteArray())); - - } catch (Exception e) { - throw new CadiException(e); - } - } - } - - private synchronized int inc() { - return ++count; - } - - /* (non-Javadoc) - * @see com.att.cadi.SecuritySetter#getID() - */ - @Override - public String getID() { - return alias; - } - - @Override - public int setLastResponse(int respCode) { - return 0; - } -} diff --git a/client/src/main/java/com/att/cadi/locator/DME2Locator.java b/client/src/main/java/com/att/cadi/locator/DME2Locator.java deleted file mode 100644 index c750448..0000000 --- a/client/src/main/java/com/att/cadi/locator/DME2Locator.java +++ /dev/null @@ -1,345 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.locator; - - -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Properties; -import java.util.Random; -import java.security.SecureRandom; - -//import com.att.aft.dme2.api.DME2Endpoint; -import com.att.aft.dme2.api.DME2Exception; -import com.att.aft.dme2.api.DME2Manager; -import com.att.aft.dme2.api.DME2Server; -import com.att.aft.dme2.manager.registry.DME2Endpoint; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; -import com.att.cadi.PropAccess; - -public class DME2Locator implements Locator { - private DME2Manager dm; - private DME2Endpoint[] endpoints; - private Access access; - private String service; - private String version; - private String routeOffer; - private String envContext; - private String thisMachine; - private String pathInfo; - private int thisPort; - private boolean removeSelf; - private final static SecureRandom random = new SecureRandom(); - - // Default is to not bother trying to remove self - public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer) throws DME2Exception, UnknownHostException, LocatorException { - this(access,dm,service,version,envContext,routeOffer,false); - } - - public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { - this.access = access; - if(dm==null) { - this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); - } else { - this.dm = dm; - } - this.service = service; - this.version = version; - this.envContext = envContext; - this.routeOffer = routeOffer; - refresh(); - if(thisMachine==null) { - // Can't get from dm... - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } else { - thisPort = dm.getPort(); - } - - this.removeSelf = removeSelf; - } - - // Default is to not bother trying to remove self - public DME2Locator(Access access, DME2Manager dm, String aafurl) throws DME2Exception, UnknownHostException, LocatorException { - this(access,dm,aafurl,false); - } - - public DME2Locator(Access access, DME2Manager dm, String aafurl, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { - if(aafurl==null) { - throw new LocatorException("URL is null"); - } - this.access = access; - if(dm==null) { - Properties dprops; - if(access instanceof PropAccess) { - dprops = ((PropAccess)access).getDME2Properties(); - } else { - dprops = System.getProperties(); - } - dm = this.dm = new DME2Manager("DME2Locator created DME2Manager",dprops); - } else { - this.dm = dm; - } - String[] split = aafurl.split("/"); - StringBuilder sb = new StringBuilder(); - boolean dme2Entered = false; - for(String s : split) { - if(s.startsWith("service=")) { - this.service = s.substring(8); - } else if(s.startsWith("version=")) { - this.version = s.substring(8); - } else if(s.startsWith("envContext=")) { - this.envContext = s.substring(11); - } else if(s.startsWith("routeOffer=")) { - this.routeOffer = s.substring(11); - dme2Entered = true; - } else if(dme2Entered) { - sb.append('/'); - sb.append(s); - } - } - pathInfo = sb.toString(); - thisMachine = dm.getHostname(); - if(thisMachine==null) { - // Can't get from dm... - thisMachine = InetAddress.getLocalHost().getHostName(); - thisPort = 0; - } else { - thisPort = dm.getPort(); - } - this.removeSelf=removeSelf; - refresh(); - } - - @Override - public boolean refresh() { - try { - dm.refresh(); - //endpoints = dm.findEndpoints(service, version, envContext, routeOffer, true); - if(removeSelf) { -// for(int i=0;i0; - return true; - } - - @Override - public void invalidate(Locator.Item item) throws LocatorException { - if(item instanceof DME2Item) { - int idx = ((DME2Item)item).idx; -// if(idx () { - @Override - public int compare(DoubIndex a, DoubIndex b) { - if(a.db.d) return 1; - return (random.nextInt()%1)==0?1:0;// randomize if the same - } - - }); - return new DME2Item(remote[0].idx); - } - } - } - - private static class DoubIndex { - public final double d; - public final int idx; - - public DoubIndex(double doub, int i) { - d = doub; - idx = i; - } - } - @Override - public DME2Item first() { -// if(endpoints==null)return null; -// for(int i=0;i { - private static enum Status {UNTRIED, OK, INVALID, SLOW}; - private static final int CHECK_TIME = 3000; - - private String host, protocol; - private Access access; - private Host[] hosts; - private int startPort, endPort; - private String suffix; - - public DNSLocator(Access access, String protocol, String host, String range) { - this.host = host; - this.protocol = protocol; - this.access = access; - int dash = range.indexOf('-'); - if(dash<0) { - startPort = endPort = Integer.parseInt(range); - } else { - startPort = Integer.parseInt(range.substring(0,dash)); - endPort = Integer.parseInt(range.substring(dash + 1)); - } - refresh(); - } - - @Override - public URI get(Item item) throws LocatorException { - return hosts[((DLItem)item).cnt].uri; - } - - @Override - public boolean hasItems() { - for(Host h : hosts) { - if(h.status==Status.OK) { - return true; - } - } - return false; - } - - @Override - public void invalidate(Item item) { - DLItem di = (DLItem)item; - hosts[di.cnt].status = Status.INVALID; - } - - @Override - public Item best() throws LocatorException { - // not a good "best" - for(int i=0;i { - private final HX509SS ss; - - public HClientHotPeerLocator(Access access, String urlstr, long invalidateTime, String localLatitude, - String localLongitude, HX509SS ss) throws LocatorException { - super(access, urlstr, invalidateTime, localLatitude, localLongitude); - - this.ss = ss; - } - - @Override - protected HClient _newClient(String clientInfo) throws LocatorException { - try { - int idx = clientInfo.indexOf('/'); - return new HClient(ss,new URI("https://"+(idx<0?clientInfo:clientInfo.substring(0, idx))),3000); - } catch (URISyntaxException e) { - throw new LocatorException(e); - } - } - - @Override - protected HClient _invalidate(HClient client) { - return null; - } - - @Override - protected void _destroy(HClient client) { - } -} diff --git a/client/src/main/java/com/att/cadi/locator/HotPeerLocator.java b/client/src/main/java/com/att/cadi/locator/HotPeerLocator.java deleted file mode 100644 index 5b756b2..0000000 --- a/client/src/main/java/com/att/cadi/locator/HotPeerLocator.java +++ /dev/null @@ -1,303 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.locator; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator; -import com.att.cadi.LocatorException; -import com.att.cadi.routing.GreatCircle; -import com.att.inno.env.util.Split; - -/** - * This Locator is to handle Hot Peer load protection, when the Servers are - * 1) Static - * 2) Well known client URL - * - * The intention is to change traffic over to the Hot Peer, if a server goes down, and reinstate - * when it is back up. - * - * Example of this kind of Service is a MS Certificate Server - * - * - * - * @param - */ -public abstract class HotPeerLocator implements Locator { - private final String[] urlstrs; - private final CLIENT[] clients; - private final long[] failures; - private final double[] distances; - private int preferred; - private long invalidateTime; - private Thread refreshThread; - protected Access access; - - /** - * Construct: Expect one or more Strings in the form: - * 192.555.112.223:39/38.88087/-77.30122 - * separated by commas - * - * @param trans - * @param urlstr - * @param invalidateTime - * @param localLatitude - * @param localLongitude - * @throws LocatorException - */ - @SuppressWarnings("unchecked") - protected HotPeerLocator(Access access, final String urlstr, final long invalidateTime, final String localLatitude, final String localLongitude) throws LocatorException { - this.access = access; - urlstrs = Split.split(',', urlstr); - clients = (CLIENT[])new Object[urlstrs.length]; - failures = new long[urlstrs.length]; - distances= new double[urlstrs.length]; - this.invalidateTime = invalidateTime; - - double distance = Double.MAX_VALUE; - for(int i=0;iSystem.currentTimeMillis()) { - throw new LocatorException("Client requested is invalid"); - } else { - synchronized(clients) { - c = _newClient(urlstrs[hpi.idx]); - failures[hpi.idx]=0L; - } - } - } else if(failures[hpi.idx]>0){ - throw new LocatorException("Client requested is invalid"); - } - return c; - } - - public String info(Item item) { - HPItem hpi = (HPItem)item; - if(hpi!=null && hpi.idx=clients.length) { - return null; - } - return hpi; - } - - @Override - public boolean refresh() { - boolean force = !hasItems(); // If no Items at all, reset - boolean rv = true; - long now = System.currentTimeMillis(); - for(int i=0;i0L && (failures[i] { - private final URI [] orig; - private PLItem[] current; - private int end; - private final SecureRandom random; - private URI[] resolved; - private long lastRefreshed=0L; - private long minRefresh; - private long backgroundRefresh; - - public PropertyLocator(String locList) throws LocatorException { - this(locList,10000L, 1000*60*20); // defaults, do not refresh more than once in 10 seconds, Refresh Locator every 20 mins. - } - /** - * comma delimited root url list - * - * @param locList - * @throws LocatorException - */ - public PropertyLocator(String locList, long minRefreshMillis, long backgroundRefreshMillis) throws LocatorException { - minRefresh = minRefreshMillis; - backgroundRefresh = backgroundRefreshMillis; - if(locList==null) { - throw new LocatorException("No Location List given for PropertyLocator"); - } - String[] locarray = Split.split(',',locList); - List uriList = new ArrayList(); - - random = new SecureRandom(); - - for(int i=0;i0?current[0]:null; - } - - @Override - public boolean hasItems() { - return end>0; - } - - @Override - public Item next(Item item) throws LocatorException { - if(item==null) { - return null; - } else { - int spot; - if((spot=(((PLItem)item).order+1))>=end)return null; - return current[spot]; - } - } - - @Override - public synchronized void invalidate(Item item) throws LocatorException { - if(--end<=0) { - refresh(); - return; - } - PLItem pli = (PLItem)item; - int i,order; - for(i=0;ilastRefreshed) { - // Build up list - List resolve = new ArrayList(); - String realname; - for(int i = 0; i < orig.length ; ++i) { - try { - InetAddress ia[] = InetAddress.getAllByName(orig[i].getHost()); - - URI o,n; - for(int j=0;j,RosettaDF> map = new HashMap,RosettaDF>(); + HMangr hman; + HBasicAuthSS ss; + + public AAFClient(RosettaEnv env) throws Exception { + this.env = env; + Access access = new EnvAccess(env); + String user = access.getProperty(Config.AAF_MECHID,null); + String password = access.decrypt(access.getProperty(Config.AAF_MECHPASS,null), true); + + SecurityInfoC si = new SecurityInfoC(access); + DME2Manager dm = new DME2Manager("APIclient DME2Manager", System.getProperties()); + DME2Locator loc = new DME2Locator(access, dm, access.getProperty(Config.AAF_URL,null)); + + int TIMEOUT = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, "30000")); + + hman = new HMangr(access, loc).readTimeout(TIMEOUT).apiVersion("2.0"); + ss = new HBasicAuthSS(user, password, si); + } + + public AAFClient(RosettaEnv env, DME2Manager dm) throws Exception { + this.env = env; + Access access = new EnvAccess(env); + String user = access.getProperty(Config.AAF_MECHID,null); + String password = access.decrypt(access.getProperty(Config.AAF_MECHPASS,null), true); + + SecurityInfoC si = new SecurityInfoC(access); + DME2Locator loc = new DME2Locator(access, dm, access.getProperty(Config.AAF_URL,null)); + + int TIMEOUT = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, "30000")); + + hman = new HMangr(access, loc).readTimeout(TIMEOUT).apiVersion("2.0"); + ss = new HBasicAuthSS(user, password, si); + } + + @SuppressWarnings("unchecked") + private synchronized RosettaDF getDF(Class cls) throws APIException { + RosettaDF rdf; + synchronized (env) { + rdf = map.get(cls); + if(rdf==null) { + rdf = env.newDataFactory(cls); + map.put(cls, rdf); + } + } + return (RosettaDF)rdf; + } + + // Package on purpose + static class Call { + protected final static String VOID_CONTENT_TYPE="application/Void+json;version=2.0"; + + protected RosettaDF df; + protected AAFClient client; + + public Call(AAFClient ac, RosettaDF df) { + this.client = ac; + this.df = df; + } + } + + + /////////// Calls ///////////////// + /** + * Returns a Get Object... same as "get" + * + * @param cls + * @return + * @throws APIException + */ + public Get read(Class cls) throws APIException { + return new Get(this,getDF(cls)); + } + + /** + * Returns a Get Object... same as "read" + * + * @param cls + * @return + * @throws APIException + */ + public Get get(Class cls) throws APIException { + return new Get(this,getDF(cls)); + } + + /** + * Returns a Post Object... same as "create" + * + * @param cls + * @return + * @throws APIException + */ + public Post post(Class cls) throws APIException { + return new Post(this,getDF(cls)); + } + + /** + * Returns a Post Object... same as "post" + * + * @param cls + * @return + * @throws APIException + */ + public Post create(Class cls) throws APIException { + return new Post(this,getDF(cls)); + } + + /** + * Returns a Put Object... same as "update" + * + * @param cls + * @return + * @throws APIException + */ + public Put put(Class cls) throws APIException { + return new Put(this,getDF(cls)); + } + + /** + * Returns a Put Object... same as "put" + * + * @param cls + * @return + * @throws APIException + */ + public Put update(Class cls) throws APIException { + return new Put(this,getDF(cls)); + } + + /** + * Returns a Delete Object + * + * @param cls + * @return + * @throws APIException + */ + public Delete delete(Class cls) throws APIException { + return new Delete(this,getDF(cls)); + } + + /** + * Returns a Delete Object + * + * @param cls + * @return + * @throws APIException + */ + public Delete delete() throws APIException { + return new Delete(this,null); + } + + public Put put() { + return new Put(this,null); + } + + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/AbsBasicAuth.java b/client/src/main/java/org/onap/aaf/cadi/client/AbsBasicAuth.java new file mode 100644 index 0000000..e714e3a --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/AbsBasicAuth.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.io.IOException; + +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.SecurityInfoC; + +public abstract class AbsBasicAuth implements SecuritySetter { + protected static final String REPEAT_OFFENDER="This call is aborted because of repeated usage of invalid Passwords"; + private static final int MAX_TEMP_COUNT = 10; + private static final int MAX_SPAM_COUNT = 10000; + private static final long WAIT_TIME = 1000*60*4; + + protected final String headValue; + protected SecurityInfoC securityInfo; + protected String user; + private long lastMiss; + private int count; + + public AbsBasicAuth(String user, String pass, SecurityInfoC si) throws IOException { + this.user = user; + headValue = "Basic " + Symm.base64.encode(user + ':' + pass); + securityInfo = si; + lastMiss=0L; + count=0; + } + + /* (non-Javadoc) + * @see com.att.cadi.SecuritySetter#getID() + */ + @Override + public String getID() { + return user; + } + + public boolean isDenied() { + if(lastMiss>0 && lastMiss>System.currentTimeMillis()) { + return true; + } else { + lastMiss=0L; + return false; + } + } + + public synchronized int setLastResponse(int httpcode) { + if(httpcode == 401) { + ++count; + if(lastMiss==0L && count>MAX_TEMP_COUNT) { + lastMiss=System.currentTimeMillis()+WAIT_TIME; + } +// if(count>MAX_SPAM_COUNT) { +// System.err.printf("Your service has %d consecutive bad service logins to AAF. \nIt will now exit\n", +// count); +// System.exit(401); +// } + if(count%1000==0) { + System.err.printf("Your service has %d consecutive bad service logins to AAF. AAF Access will be disabled after %d\n", + count,MAX_SPAM_COUNT); + } + + } else { + lastMiss=0; + } + return count; + } + + public int count() { + return count; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/AbsTransferSS.java b/client/src/main/java/org/onap/aaf/cadi/client/AbsTransferSS.java new file mode 100644 index 0000000..e731f09 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/AbsTransferSS.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.security.Principal; + +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.principal.TGuardPrincipal; +import org.onap.aaf.cadi.principal.TrustPrincipal; + +public abstract class AbsTransferSS implements SecuritySetter { + protected String value; + protected SecurityInfoC securityInfo; + protected SecuritySetter defSS; + private Principal principal; + + //Format:::[:AS][,::]* + public AbsTransferSS(Principal principal, String app) { + init(principal, app); + } + + public AbsTransferSS(Principal principal, String app, SecurityInfoC si) { + init(principal,app); + securityInfo = si; + this.defSS = si.defSS; + } + + private void init(Principal principal, String app) { + this.principal=principal; + if(principal==null) { + return; + } else if(principal instanceof BasicPrincipal) { + value = principal.getName() + ':' + app + ":BasicAuth:AS"; + } else if(principal instanceof TrustPrincipal) { + TrustPrincipal tp = (TrustPrincipal)principal; + // recursive + init(tp.original(),app); + value += principal.getName() + ':' + app + ":Trust:AS" + ',' + tp.userChain(); + } else if(principal instanceof TGuardPrincipal) { + value = principal.getName() + ':' + app + ":TGUARD:AS"; + } + } + + /* (non-Javadoc) + * @see com.att.cadi.SecuritySetter#getID() + */ + @Override + public String getID() { + return principal==null?"":principal.getName(); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Delete.java b/client/src/main/java/org/onap/aaf/cadi/client/Delete.java new file mode 100644 index 0000000..9f03aab --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Delete.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import org.onap.aaf.cadi.CadiException; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.rosetta.env.RosettaDF; + +public class Delete extends AAFClient.Call { + public Delete(AAFClient ac, RosettaDF df) { + super(ac,df); + } + + @SuppressWarnings("unchecked") + public Result delete(final String pathInfo, final T t) throws Exception { + if(t==null) { + return (Result)delete(pathInfo); + } + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.delete(pathInfo,df,t); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } + + public Result delete(final String pathInfo) throws Exception { + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.delete(pathInfo,VOID_CONTENT_TYPE); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } + + + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/EClient.java b/client/src/main/java/org/onap/aaf/cadi/client/EClient.java new file mode 100644 index 0000000..a880331 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/EClient.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data; +import org.onap.aaf.rosetta.env.RosettaDF; + + +public interface EClient { + public void setMethod(String meth); + public void setPathInfo(String pathinfo); + public void setPayload(Transfer transfer); + public void addHeader(String tag, String value); + public void setQueryParams(String q); + public void setFragment(String f); + public void send() throws APIException; + public Future futureCreate(Class t); + public Future futureReadString(); + public Future futureRead(RosettaDF df,Data.TYPE type); + public Future future(T t); + public Future future(HttpServletResponse resp, int expected) throws APIException; + + public interface Transfer { + public void transfer(OutputStream os) throws IOException, APIException; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/EnvAccess.java b/client/src/main/java/org/onap/aaf/cadi/client/EnvAccess.java new file mode 100644 index 0000000..bcf41f8 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/EnvAccess.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map.Entry; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; + +import java.util.Properties; + +import org.onap.aaf.inno.env.Decryptor; +import org.onap.aaf.inno.env.Env; +import org.onap.aaf.inno.env.impl.BasicEnv; + +public class EnvAccess implements Access { + private Env env; + + /** + * String Property tag for files/resources that may contain properties. Can be null. + * Resources of ClassLoader will be checked first, if exist. Can be null. + * @param env + * @param tag + * @param cl + * @throws IOException + */ + public EnvAccess(BasicEnv env, ClassLoader cl) throws IOException { + this.env = env; + final Symm s = Symm.obtain(this); + env.set(new Decryptor() { + private Symm symm = s; + @Override + public String decrypt(String encrypted) { + try { + return (encrypted!=null && (encrypted.startsWith(Symm.ENC))) + ? symm.depass(encrypted) + : encrypted; + } catch (IOException e) { + return ""; + } + } + } + ); + } + + + /** + * Construct with the Classloader of Env and CADI_PROP_FILES, if possible + * + * @param env + * @throws IOException + */ + public EnvAccess(BasicEnv env) throws IOException { + this(env, env.getClass().getClassLoader()); + } + + @Override + public void log(Level level, Object... elements) { + switch(level) { + case AUDIT: + env.audit().log(elements); + break; + case DEBUG: + env.debug().log(elements); + break; + case ERROR: + env.error().log(elements); + break; + case INFO: + env.info().log(elements); + break; + case INIT: + env.init().log(elements); + break; + case WARN: + env.warn().log(elements); + break; + default: + break; + } + + } + + @Override + public void log(Exception e, Object... elements) { + env.error().log(e,elements); + } + + @Override + public void printf(Level level, String fmt, Object... elements) { + if(willLog(level)) { + log(level,String.format(fmt, elements)); + } + } + + + @Override + public boolean willLog(Level level) { + switch(level) { + case AUDIT: + return env.audit().isLoggable(); + case DEBUG: + return env.debug().isLoggable(); + case ERROR: + return env.error().isLoggable(); + case INFO: + return env.info().isLoggable(); + case INIT: + return env.init().isLoggable(); + case WARN: + return env.warn().isLoggable(); + default: + return false; + } + } + + + @Override + public void setLogLevel(Level level) { + // unused + } + + @Override + public ClassLoader classLoader() { + return env.getClass().getClassLoader(); + } + + @Override + public String getProperty(String string, String def) { + return env.getProperty(string, def); + } + + @Override + public void load(InputStream is) throws IOException { + Properties props = new Properties(); + props.load(is); + for(Entry es :props.entrySet()) { + env.setProperty(es.getKey().toString(), es.getValue().toString()); + } + } + + @Override + public String decrypt(String encrypted, boolean anytext) throws IOException { + return env.decryptor().decrypt(encrypted); + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Future.java b/client/src/main/java/org/onap/aaf/cadi/client/Future.java new file mode 100644 index 0000000..01a85b8 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Future.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import org.onap.aaf.cadi.CadiException; + +public abstract class Future { + public T value; + public abstract boolean get(int timeout) throws CadiException; + + public abstract int code(); + public abstract String body(); + public abstract String header(String tag); +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Get.java b/client/src/main/java/org/onap/aaf/cadi/client/Get.java new file mode 100644 index 0000000..920b476 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Get.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import org.onap.aaf.cadi.CadiException; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.rosetta.env.RosettaDF; + +public class Get extends AAFClient.Call { + public Get(AAFClient ac, RosettaDF df) { + super(ac,df); + } + + public Result read(final String pathInfo) throws Exception { + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.read(pathInfo,df); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Holder.java b/client/src/main/java/org/onap/aaf/cadi/client/Holder.java new file mode 100644 index 0000000..577fa5f --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Holder.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +/** + * Use to set Variables outside of Anonymous classes. + * + * + * @param + */ +public class Holder { + private T value; + public Holder(T t) { + value = t; + } + public void set(T t) { + value = t; + } + + public T get() { + return value; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Post.java b/client/src/main/java/org/onap/aaf/cadi/client/Post.java new file mode 100644 index 0000000..5c9bde2 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Post.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.LocatorException; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.rosetta.env.RosettaDF; + +public class Post extends AAFClient.Call { + public Post(AAFClient ac, RosettaDF df) { + super(ac,df); + } + + public Result create(final String pathInfo, final T t) throws APIException, CadiException, LocatorException { + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.create(pathInfo,df,t); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/PropertyLocator.java b/client/src/main/java/org/onap/aaf/cadi/client/PropertyLocator.java new file mode 100644 index 0000000..15705ab --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/PropertyLocator.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Random; + +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; + +public class PropertyLocator implements Locator { + private final URI [] orig; + private PLItem[] current; + private int end; + private final Random random; + + /** + * comma delimited root url list + * + * @param locList + * @throws LocatorException + */ + public PropertyLocator(String locList) throws LocatorException { + if(locList==null)throw new LocatorException("No Location List given for PropertyLocator"); + String[] locarray = locList.split("\\s*,\\s*"); + orig = new URI[locarray.length]; + + random = new Random(); + + for(int i=0;i0?current[0]:null; + } + + @Override + public boolean hasItems() { + return end>0; + } + + @Override + public Item next(Item item) throws LocatorException { + int spot; + if((spot=(((PLItem)item).order+1))>=end)return null; + return current[spot]; + } + + @Override + public synchronized void invalidate(Item item) throws LocatorException { + if(--end<=0)return; + PLItem pli = (PLItem)item; + int i,order; + for(i=0;i extends AAFClient.Call { + public Put(AAFClient ac, RosettaDF df) { + super(ac,df); + } + + public Result update(final String pathInfo, final T t) throws Exception { + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.update(pathInfo,df,t); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } + + public Result update(final String pathInfo) throws Exception { + return client.hman.best(client.ss, + new Retryable>() { + @Override + public Result code(Rcli client) throws APIException, CadiException { + Future ft = client.update(pathInfo); + if(ft.get(client.readTimeout)) { + return Result.ok(ft.code(),ft.value); + } else { + return Result.err(ft.code(),ft.body()); + } + } + }); + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/RawClient.java b/client/src/main/java/org/onap/aaf/cadi/client/RawClient.java new file mode 100644 index 0000000..0386383 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/RawClient.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.net.URI; + +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; + +import com.att.aft.dme2.api.DME2Client; + +public abstract class RawClient { + protected static String aafid, aafpass, aafurl; + protected static Symm symm; + + protected static boolean init(PrintStream out) { + try { + String propfile = System.getProperty(Config.CADI_PROP_FILES); + if(propfile==null) { + propfile = "raw.props"; + } + File pfile = new File(propfile); + if(!pfile.exists()) { + if(propfile.equals("raw.props")) { + out.println("Creating 'raw.props'. Edit for proper values, then run again. Alternatively, set " + + Config.CADI_PROP_FILES+" to a cadi properties file"); + FileOutputStream fos = new FileOutputStream(pfile); + PrintStream ps = new PrintStream(fos); + try { + ps.println("# Use http://www.bing.com/maps to figure out LAT/LONG of an Address"); + ps.println("AFT_LATITUDE=38.432930"); + ps.println("AFT_LONGITUDE=-90.432480"); + ps.println("AFT_ENVIRONMENT=AFTUAT"); + ps.print(Config.AAF_URL); + ps.println("=aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE"); + ps.print(Config.CADI_KEYFILE); + ps.println("="); + ps.println(Config.AAF_MECHID); + ps.print("="); + ps.println(Config.AAF_MECHPASS); + ps.print("="); + } finally { + ps.close(); + } + } + } else { + FileInputStream fis = new FileInputStream(propfile); + try { + System.getProperties().load(fis); + } finally { + fis.close(); + } + + String cadiKeyFile = System.getProperty(Config.CADI_KEYFILE); + aafid = System.getProperty(Config.AAF_MECHID); + aafpass = System.getProperty(Config.AAF_MECHPASS); + aafurl = System.getProperty(Config.AAF_URL); + out.println("Contacting: " + aafurl); + + if(cadiKeyFile==null || aafid==null || aafpass==null || aafurl==null ) { + out.print(Config.CADI_KEYFILE); + out.print(", "); + out.print(Config.CADI_KEYFILE); + out.print(", "); + out.print(Config.CADI_KEYFILE); + out.print(", "); + out.print(Config.CADI_KEYFILE); + out.print(" need to be set in "); + out.println(propfile); + } else { + fis = new FileInputStream(cadiKeyFile); + try { + symm = Symm.obtain(fis); + } finally { + fis.close(); + } + } + return true; + } + } catch (Exception e) { + e.printStackTrace(out); + } + return false; + + } + + public abstract String call(final PrintStream out, final String meth, final String path) throws Exception; + + public static void main(String[] args) { + // Sonar idiocy + PrintStream out = System.out; + + try { + if(init(out)) { + if(args.length<2) { + System.out.println("Parameters: "); + } else { + RawClient client = new DME2(); + out.println(client.call(out,args[0],args[1])); + } + } + } catch (Exception e) { + e.printStackTrace(out); + } + } + + protected static class DME2 extends RawClient { + + public String call(final PrintStream out, final String meth, final String path) { + try { + DME2Client client = new DME2Client(new URI(aafurl),10000); + client.setCredentials(aafid, symm.depass(aafpass)); + client.setMethod(meth); + client.setContext(path); + + if("GET".equalsIgnoreCase(meth) || + "DELETE".equalsIgnoreCase(meth)) { + client.setPayload(""); + } else if("POST".equalsIgnoreCase(meth) || + "PUT".equalsIgnoreCase(meth)) { + int c; + StringBuilder sb = new StringBuilder(); + while((c=System.in.read()) >=0) { + sb.append((char)c); + } + client.setPayload(sb.toString()); + } + return client.sendAndWait(10000); + } catch (Exception e) { + e.printStackTrace(out); + return ""; + } + } + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java b/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java new file mode 100644 index 0000000..23158ef --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Rcli.java @@ -0,0 +1,697 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; +import java.util.Enumeration; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.SecuritySetter; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.inno.env.util.Pool; +import org.onap.aaf.inno.env.util.Pool.Pooled; +import org.onap.aaf.rosetta.env.RosettaDF; + +public abstract class Rcli { + public static final String BLANK = ""; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String ACCEPT = "Accept"; + + protected static final String POST = "POST"; + protected static final String GET = "GET"; + protected static final String PUT = "PUT"; + protected static final String DELETE = "DELETE"; + protected TYPE type; + protected String apiVersion; + protected int readTimeout = 5000; + protected int connectionTimeout = 3000; + protected URI uri; + private String queryParams, fragment; + public static Pool buffPool = new Pool(new Pool.Creator() { + @Override + public byte[] create() throws APIException { + return new byte[1024]; + } + + @Override + public void destroy(byte[] t) { + } + + @Override + public boolean isValid(byte[] t) { + return true; + } + + @Override + public void reuse(byte[] t) { + } + }); + + + public Rcli() { + super(); + } + + public abstract void setSecuritySetter(SecuritySetter ss); + public abstract SecuritySetter getSecuritySetter(); + + + public Rcli forUser(SecuritySetter ss) { + Rcli rv = clone(uri==null?this.uri:uri,ss); + setSecuritySetter(ss); + rv.type = type; + rv.apiVersion = apiVersion; + return rv; + } + + protected abstract Rcli clone(URI uri, SecuritySetter ss); + + public abstract void invalidate() throws CadiException; + + public Rcli readTimeout(int millis) { + readTimeout = millis; + return this; + } + + public Rcli connectionTimeout(int millis) { + connectionTimeout = millis; + return this; + } + + public Rcli type(TYPE type) { + this.type=type; + return this; + } + + public Rcli apiVersion(String apiVersion) { + this.apiVersion = apiVersion; + return this; + } + + public boolean isApiVersion(String prospective) { + return apiVersion.equals(prospective); + } + + + public String typeString(Class cls) { + return "application/"+cls.getSimpleName()+"+"+type.name().toLowerCase()+ + (apiVersion==null?BLANK:";version="+apiVersion); + } + + protected abstract EClient client() throws CadiException; + + + public Future create(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + EClient client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,contentType); + client.setPathInfo(pathinfo); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.futureCreate(df.getTypeClass()); + } + + public Future create(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + EClient client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,typeString(df.getTypeClass())); + client.setPathInfo(pathinfo); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.futureCreate(df.getTypeClass()); + } + + public Future create(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,typeString(cls)); + client.setPathInfo(pathinfo); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.futureCreate(df.getTypeClass()); + } + + public Future create(String pathinfo, Class cls) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,typeString(cls)); + client.setPathInfo(pathinfo); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPayload(null); + client.send(); + queryParams = fragment = null; + return client.futureCreate(cls); + } + + public Future create(String pathinfo, String contentType) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(POST); + client.addHeader(CONTENT_TYPE,contentType); + client.setPathInfo(pathinfo); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPayload(null); + client.send(); + queryParams = fragment = null; + return client.futureCreate(Void.class); + } + + + public Future read(String pathinfo, String accept, String ... headers) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(GET); + client.addHeader(ACCEPT, accept); + + for(int i=1;i Future read(String pathinfo, String accept, RosettaDF df, String ... headers) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(GET); + client.addHeader(ACCEPT, accept); + for(int i=1;i Future read(String pathinfo, RosettaDF df,String ... headers) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(GET); + client.addHeader(ACCEPT, typeString(df.getTypeClass())); + for(int i=1;i Future read(String pathinfo, Class cls, RosettaDF df) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(GET); + client.addHeader(ACCEPT, typeString(cls)); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + + client.setPayload(null); + client.send(); + queryParams = fragment = null; + return client.futureRead(df,type); + } + + public Future update(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE,contentType); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + public Future updateRespondString(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.futureReadString(); + } + + + public Future update(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + public Future update(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE, typeString(cls)); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + /** + * A method to update with a VOID + * @param pathinfo + * @param resp + * @param expected + * @return + * @throws APIException + * @throws CadiException + */ + public Future update(String pathinfo) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(PUT); + client.addHeader(CONTENT_TYPE, typeString(Void.class)); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); +// client.setPayload(new EClient.Transfer() { +// @Override +// public void transfer(OutputStream os) throws IOException, APIException { +// } +// }); + client.send(); + queryParams = fragment = null; + return client.future(null); + } + + public Future delete(String pathinfo, String contentType, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(DELETE); + client.addHeader(CONTENT_TYPE, contentType); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + public Future delete(String pathinfo, Class cls, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(DELETE); + client.addHeader(CONTENT_TYPE, typeString(cls)); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + public Future delete(String pathinfo, final RosettaDF df, final T t) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(DELETE); + client.addHeader(CONTENT_TYPE, typeString(df.getTypeClass())); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + df.newData().out(type).direct(t,os); + } + }); + + client.send(); + queryParams = fragment = null; + return client.future(t); + } + + + public Future delete(String pathinfo, Class cls) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(DELETE); + client.addHeader(CONTENT_TYPE, typeString(cls)); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(null); + client.send(); + queryParams = fragment = null; + return client.future((T)null); + } + + public Future delete(String pathinfo, String contentType) throws APIException, CadiException { + final int idx = pathinfo.indexOf('?'); + final String qp; + if(idx>=0) { + qp=pathinfo.substring(idx+1); + pathinfo=pathinfo.substring(0,idx); + } else { + qp=queryParams; + } + + EClient client = client(); + client.setMethod(DELETE); + client.addHeader(CONTENT_TYPE, contentType); + client.setQueryParams(qp); + client.setFragment(fragment); + client.setPathInfo(pathinfo); + client.setPayload(null); + client.send(); + queryParams = fragment = null; + return client.future(null); + } + + public Future transfer(final HttpServletRequest req, final HttpServletResponse resp, final String pathParam, final int expected) throws CadiException, APIException { + EClient client = client(); + URI uri; + try { + uri = new URI(req.getRequestURI()); + } catch (Exception e) { + throw new CadiException("Invalid incoming URI",e); + } + String name; + for(Enumeration en = req.getHeaderNames();en.hasMoreElements();) { + name = en.nextElement(); + client.addHeader(name,req.getHeader(name)); + } + client.setQueryParams(req.getQueryString()); + client.setFragment(uri.getFragment()); + client.setPathInfo(pathParam); + String meth = req.getMethod(); + client.setMethod(meth); + if(!"GET".equals(meth)) { + client.setPayload(new EClient.Transfer() { + @Override + public void transfer(OutputStream os) throws IOException, APIException { + final ServletInputStream is = req.getInputStream(); + int read; + // reuse Buffers + Pooled pbuff = buffPool.get(); + try { + while((read=is.read(pbuff.content))>=0) { + os.write(pbuff.content,0,read); + } + } finally { + pbuff.done(); + } + } + }); + } + client.send(); + return client.future(resp, expected); + } + + public String toString() { + return uri.toString(); + } + + /** + * @param queryParams the queryParams to set + * @return + */ + public Rcli setQueryParams(String queryParams) { + this.queryParams = queryParams; + return this; + } + + + /** + * @param fragment the fragment to set + * @return + */ + public Rcli setFragment(String fragment) { + this.fragment = fragment; + return this; + } + + public URI getURI() { + return uri; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Result.java b/client/src/main/java/org/onap/aaf/cadi/client/Result.java new file mode 100644 index 0000000..5b3d8fd --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Result.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +public class Result { + public final int code; + public final T value; + public final String error; + + private Result(int code, T value, String error) { + this.code = code; + this.value = value; + this.error = error; + } + + public static Result ok(int code,T t) { + return new Result(code,t,null); + } + + public static Result err(int code,String body) { + return new Result(code,null,body); + } + + public boolean isOK() { + return error==null; + } + + public String toString() { + StringBuilder sb = new StringBuilder("Code: "); + sb.append(code); + if(error!=null) { + sb.append(" = "); + sb.append(error); + } + return sb.toString(); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/client/Retryable.java b/client/src/main/java/org/onap/aaf/cadi/client/Retryable.java new file mode 100644 index 0000000..9c701ef --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/client/Retryable.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.client; + +import java.net.ConnectException; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; + +import org.onap.aaf.inno.env.APIException; + +/** + * + * + * @param + * @param + */ +public abstract class Retryable { + // be able to hold state for consistent Connections. Not required for all connection types. + public Rcli lastClient; + private Locator.Item item; + + public Retryable() { + lastClient = null; + item = null; + } + + public Retryable(Retryable ret) { + lastClient = ret.lastClient; + item = ret.item; + } + + public Locator.Item item(Locator.Item item) { + lastClient = null; + this.item = item; + return item; + } + public Locator.Item item() { + return item; + } + + public abstract RET code(Rcli client) throws CadiException, ConnectException, APIException; + + /** + * Note, Retryable is tightly coupled to the Client Utilizing. It will not be the wrong type. + * @return + */ + @SuppressWarnings("unchecked") + public Rcli lastClient() { + return (Rcli)lastClient; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DEClient.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DEClient.java new file mode 100644 index 0000000..7bbdc25 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DEClient.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URI; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.client.EClient; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; + +import com.att.aft.dme2.api.DME2Client; +import com.att.aft.dme2.api.DME2Exception; +import com.att.aft.dme2.api.DME2Manager; +import com.att.aft.dme2.handler.DME2RestfulHandler; +import com.att.aft.dme2.handler.DME2RestfulHandler.ResponseInfo; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data; +import org.onap.aaf.rosetta.env.RosettaDF; + +public class DEClient implements EClient { + private DME2Client client; + private DME2RestfulHandler replyHandler; + private EClient.Transfer payload; + private boolean isProxy; + private SecuritySetter ss; + + public DEClient(DME2Manager manager, SecuritySetter ss, URI uri, long timeout) throws DME2Exception, CadiException { + client = new DME2Client(manager,uri,timeout); + client.setAllowAllHttpReturnCodes(true); + this.ss = ss; + ss.setSecurity(client); + replyHandler = new DME2RestfulHandler(Rcli.BLANK); + client.setReplyHandler(replyHandler); + } + + @Override + public void setMethod(String meth) { + client.setMethod(meth); + } + + /** + * DME2 can't handle having QueryParams on the URL line, but it is the most natural way, so... + * + * Also, DME2 can't handle "/proxy" as part of Context in the main URI line, so we add it when we see authz-gw to "isProxy" + */ + public void setPathInfo(String pathinfo) { + int qp = pathinfo.indexOf('?'); + if(qp<0) { + client.setContext(isProxy?("/proxy"+pathinfo):pathinfo); + } else { + client.setContext(isProxy?("/proxy"+pathinfo.substring(0,qp)):pathinfo.substring(0,qp)); + client.setQueryParams(pathinfo.substring(qp+1)); + } + } + + @Override + public void setPayload(EClient.Transfer transfer) { + payload = transfer; + } + + @Override + public void addHeader(String tag, String value) { + client.addHeader(tag, value); + } + + + @Override + public void setQueryParams(String q) { + client.setQueryParams(q); + } + + @Override + public void setFragment(String f) { + // DME2 does not implement this + } + + @Override + public void send() throws APIException { + try { + if(payload!=null) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + payload.transfer(baos); + client.setPayload(new String(baos.toByteArray())); + } else { + client.setPayload(""); + } + client.send(); + } catch (DME2Exception e) { + throw new APIException(e); + } catch (IOException e) { + throw new APIException(e); + } + } + + + public class DFuture extends Future { + protected final DME2RestfulHandler reply; + protected ResponseInfo info; + + public DFuture(DME2RestfulHandler reply) { + this.reply = reply; + } + + protected boolean evalInfo() throws APIException{ + //return info.getCode()==200; + return true; + }; + + public final boolean get(int timeout) throws CadiException { + try { + info = reply.getResponse(timeout); + ss.setLastResponse(info.getCode()); + return evalInfo(); + } catch (Exception e) { + throw new CadiException(e); + } + } + + @Override + public int code() { + return info.getCode(); + } + + @Override + public String body() { + return info.getBody(); + } + + @Override + public String header(String tag) { + return info.header(tag); + } + + } + + @Override + public Future futureCreate(Class t) { + return new DFuture(replyHandler) { + public boolean evalInfo() throws APIException { + + return info.getCode()==201; + } + }; + } + + + @Override + public Future futureReadString() { + return new DFuture(replyHandler) { + public boolean evalInfo() throws APIException { + if(info.getCode()==200) { + value = info.getBody(); + return true; + } + return false; + } + }; + } + + @Override + public Future futureRead(final RosettaDF df, final Data.TYPE type) { + return new DFuture(replyHandler) { + public boolean evalInfo() throws APIException { + if(info.getCode()==200) { + value = df.newData().in(type).load(info.getBody()).asObject(); + return true; + } + return false; + } + }; + } + + @Override + public Future future(final T t) { + return new DFuture(replyHandler) { + public boolean evalInfo() { + if(info.getCode()==200) { + value = t; + return true; + } + return false; + } + }; + } + + @Override + public Future future(HttpServletResponse resp,int expected) throws APIException { + // TODO Auto-generated method stub + return null; + } + + public void setProxy(boolean isProxy) { + this.isProxy=isProxy; + } + + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DME2BasicAuth.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2BasicAuth.java new file mode 100644 index 0000000..b29074f --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2BasicAuth.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.client.AbsBasicAuth; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.principal.BasicPrincipal; + +import com.att.aft.dme2.api.DME2Client; + +public class DME2BasicAuth extends AbsBasicAuth { + public DME2BasicAuth(String user, String pass, SecurityInfoC si) throws IOException { + super(user,pass,si); + } + + public DME2BasicAuth(Access access, SecurityInfoC si) throws IOException { + super(access.getProperty(Config.AAF_MECHID, null), + access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), + si); + } + + public DME2BasicAuth(BasicPrincipal bp,SecurityInfoC si) throws IOException { + super(bp.getName(),new String(bp.getCred()),si); + } + + public DME2BasicAuth(Access access) throws IOException, GeneralSecurityException { + super(access.getProperty(Config.AAF_MECHID, null), + access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), + new SecurityInfoC(access)); + } + + public void setSecurity(DME2Client client) throws CadiException { + if(isDenied()) { + throw new CadiException(REPEAT_OFFENDER); + } + client.addHeader("Authorization", headValue); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DME2ClientSS.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2ClientSS.java new file mode 100644 index 0000000..167fe3b --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2ClientSS.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + +import java.io.IOException; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Access.Level; + +import com.att.aft.dme2.api.DME2Client; + +public class DME2ClientSS implements SecuritySetter { + private Access access; + private String user,crd; + + public DME2ClientSS(Access access, String user, String pass) throws IOException { + this.access = access; + this.user = user; + this.crd = pass; + } + + @Override + public void setSecurity(DME2Client client) { + try { + client.setCredentials(user, access.decrypt(crd, false)); + } catch (IOException e) { + access.log(Level.ERROR,e,"Error decrypting DME2 Password"); + } + } + + /* (non-Javadoc) + * @see com.att.cadi.SecuritySetter#getID() + */ + @Override + public String getID() { + return user; + } + + @Override + public int setLastResponse(int respCode) { + // TODO Auto-generated method stub + return 0; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DME2Locator.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2Locator.java new file mode 100644 index 0000000..47af9ea --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2Locator.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + + +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Random; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.Access.Level; + +// +import com.att.aft.dme2.api.DME2Exception; +import com.att.aft.dme2.api.DME2Manager; +import com.att.aft.dme2.api.DME2Server; +import com.att.aft.dme2.manager.registry.DME2Endpoint; + +public class DME2Locator implements Locator { + private DME2Manager dm; + private DME2Endpoint[] endpoints; + private Access access; + private String service; + private String version; + private String routeOffer; + private String envContext; + private String thisMachine; + private String pathInfo; + private int thisPort; + private boolean removeSelf; + private final static Random random = new Random(); + + // Default is to not bother trying to remove self + public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer) throws DME2Exception, UnknownHostException, LocatorException { + this(access,dm,service,version,envContext,routeOffer,false); + } + + public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { + this.access = access; + if(dm==null) { + this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); + } else { + this.dm = dm; + } + this.service = service; + this.version = version; + this.envContext = envContext; + this.routeOffer = routeOffer; + refresh(); + DME2Server server = dm.getServer(); + if(server == null) { + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } else { + try { + thisMachine = server.getServerProperties().getHostname(); + //thisPort = server.getPort(); + thisPort = server.getServerProperties().getPort(); + } catch(NullPointerException np) { // BAD BOY, DME2... + access.log(Level.ERROR, "WARNING: DME2 threw a NullPointer Exception getting Server Machine and Port"); + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } + } + this.removeSelf = removeSelf; + } + + // Default is to not bother trying to remove self + public DME2Locator(Access access, DME2Manager dm, String aafurl) throws DME2Exception, UnknownHostException, LocatorException { + this(access,dm,aafurl,false); + } + + public DME2Locator(Access access, DME2Manager dm, String aafurl, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { + if(aafurl==null) throw new LocatorException("URL is null"); + this.access = access; + if(dm==null) { + dm = this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); + } else { + this.dm = dm; + } + String[] split = aafurl.split("/"); + StringBuilder sb = new StringBuilder(); + boolean dme2Entered = false; + for(String s : split) { + if(s.startsWith( "service=")) this.service = s.substring(8); + else if(s.startsWith("version=")) this.version = s.substring(8); + else if(s.startsWith("envContext=")) this.envContext = s.substring(11); + else if(s.startsWith("routeOffer=")) { + this.routeOffer = s.substring(11); + dme2Entered = true; + } + else if(dme2Entered) { + sb.append('/'); + sb.append(s); + } + pathInfo = sb.toString(); + } + DME2Server server = dm.getServer(); + if(server == null) { + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } else { + thisMachine = server.getServerProperties().getHostname(); + if(thisMachine==null) { // even if server !=null, apparently, it can be uninitialized + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } else { + try { + thisPort = server.getServerProperties().getPort(); + } catch (Exception e) { + thisPort = 0; + } + } + } + this.removeSelf=removeSelf; + refresh(); + } + + @Override + public boolean refresh() { + try { + dm.refresh(); + endpoints = dm.findEndpoints(service, version, envContext, routeOffer, true); + if(removeSelf) { + for(int i=0;i0; + } + + @Override + public void invalidate(Locator.Item item) throws LocatorException { + if(item instanceof Item) { + int idx = ((Item)item).idx; + if(idx () { + @Override + public int compare(DoubIndex a, DoubIndex b) { + if(a.db.d) return 1; + return (random.nextInt()%1)==0?1:0;// randomize if the same + } + + }); + return new Item(remote[0].idx); + } + } + } + + private class DoubIndex { + public final double d; + public final int idx; + + public DoubIndex(double doub, int i) { + d = doub; + idx = i; + } + } + @Override + public Item first() { + if(endpoints==null)return null; + for(int i=0;i { + + public DME2TransferSS(Principal principal, String app, SecurityInfoC si) throws IOException { + super(principal, app, si); + } + + @Override + public void setSecurity(DME2Client client) throws CadiException { + if(value!=null) { + if(defSS==null) { + throw new CadiException("Need App Credentials to send message"); + } + defSS.setSecurity(client); + client.addHeader(Config.CADI_USER_CHAIN, value); + } + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DME2x509SS.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2x509SS.java new file mode 100644 index 0000000..af803c1 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DME2x509SS.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + +import java.io.IOException; +import java.security.cert.CertificateEncodingException; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; + +import com.att.aft.dme2.api.DME2Client; +import org.onap.aaf.inno.env.APIException; + + +public class DME2x509SS implements SecuritySetter { + private String alias; + + public DME2x509SS(final String sendAlias, SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { + if((alias=sendAlias) == null) { + if(si.default_alias == null) { + throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias"); + } else { + alias = si.default_alias; + } + } + } + + @Override + public void setSecurity(DME2Client dme2) throws CadiException { + // DME2Client has to have properties set before creation to work. + } + + /* (non-Javadoc) + * @see com.att.cadi.SecuritySetter#getID() + */ + @Override + public String getID() { + return alias; + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dme2/DRcli.java b/client/src/main/java/org/onap/aaf/cadi/dme2/DRcli.java new file mode 100644 index 0000000..cd95bcc --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dme2/DRcli.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dme2; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.client.EClient; +import org.onap.aaf.cadi.client.Rcli; + +import com.att.aft.dme2.api.DME2Client; +import com.att.aft.dme2.api.DME2Exception; +import com.att.aft.dme2.api.DME2Manager; +import com.att.aft.dme2.manager.registry.DME2Endpoint; +import com.att.aft.dme2.request.DmeUniformResource; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data.TYPE; + +/** + * DME2 Rosetta Client + * + * JAXB defined JSON or XML over DME2 middleware + * + * + * @param + */ +public class DRcli extends Rcli { + // Can be more efficient if tied to manager, apparently. Can pass in null. + DME2Manager manager=null; + private SecuritySetter ss; + private boolean isProxy; + + public DRcli(URI uri, SecuritySetter secSet) { + this.uri = uri; + type = TYPE.JSON; + apiVersion = null; + ss=secSet; + } + + @Override + protected DRcli clone(URI uri, SecuritySetter ss) { + return new DRcli(uri,ss); + } + + + + /** + * Note from Thaniga on 11/5. DME2Client is not expected to be reused... need a fresh one + * on each transaction, which is expected to cover the Async aspects. + * + * @return + * @throws APIException + * @throws DME2Exception + */ + protected EClient client() throws CadiException { + try { + DEClient dc = new DEClient(manager,getSecuritySetter(),uri,readTimeout); + dc.setProxy(isProxy); + return dc; + } catch (DME2Exception e) { + throw new CadiException(e); + } + } + + public DRcli setManager(DME2Manager dme2Manager) { + manager = dme2Manager; + return this; + } + + public List all() throws DME2Exception, APIException { + ArrayList al = new ArrayList(); + + if(manager == null) { + manager = DME2Manager.getDefaultInstance(); + } + try { + DME2Endpoint[] endp = manager.getEndpoints(new DmeUniformResource(manager.getConfig(),uri)); + // Convert Searchable Endpoints to Direct Endpoints + for(DME2Endpoint de : endp) { + al.add(new DRcli( + new URI(uri.getScheme(),null,de.getHost(),de.getPort(),null,null,null),ss) +// new URI(uri.getScheme(),null,de.getHost(),de.getPort(),uri.getPath(),null,null),ss) + .setManager(manager) + ); + } + } catch (MalformedURLException e) { + throw new APIException("Invalid URL",e); + } catch (URISyntaxException e) { + throw new APIException("Invalid URI",e); + } + return al; + } + + @Override + public void invalidate() throws CadiException { + try { + manager.refresh(); + } catch (Exception e) { + throw new CadiException(e); + } + } + + @Override + public void setSecuritySetter(SecuritySetter ss) { + this.ss = ss; + } + + @Override + public SecuritySetter getSecuritySetter() { + return ss; + } + + public void setProxy(boolean isProxy) { + this.isProxy = isProxy; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/dnsloc/DNSLocator.java b/client/src/main/java/org/onap/aaf/cadi/dnsloc/DNSLocator.java new file mode 100644 index 0000000..105ccf1 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/dnsloc/DNSLocator.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.dnsloc; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.Access.Level; + +public class DNSLocator implements Locator { + private static enum Status {UNTRIED, OK, INVALID, SLOW}; + private static final int CHECK_TIME = 3000; + + private String host, protocol; + private Access access; + private Host[] hosts; + private int startPort, endPort; + private String suffix; + + public DNSLocator(Access access, String protocol, String host, String range) { + this.host = host; + this.protocol = protocol; + this.access = access; + int dash = range.indexOf('-'); + if(dash<0) { + startPort = endPort = Integer.parseInt(range); + } else { + startPort = Integer.parseInt(range.substring(0,dash)); + endPort = Integer.parseInt(range.substring(dash + 1)); + } + refresh(); + } + + @Override + public URI get(Item item) throws LocatorException { + return hosts[((DLItem)item).cnt].uri; + } + + @Override + public boolean hasItems() { + for(Host h : hosts) { + if(h.status==Status.OK) { + return true; + } + } + return false; + } + + @Override + public void invalidate(Item item) { + DLItem di = (DLItem)item; + hosts[di.cnt].status = Status.INVALID; + } + + @Override + public Item best() throws LocatorException { + // not a good "best" + for(int i=0;i { + public HBasicAuthSS(Access access, SecurityInfoC si) throws IOException { + super(access.getProperty(Config.AAF_MECHID, null), + access.decrypt(access.getProperty(Config.AAF_MECHPASS, null), false), + si); + } + + public HBasicAuthSS(String user, String pass, SecurityInfoC si) throws IOException { + super(user,pass,si); + } + + public HBasicAuthSS(String user, String pass, SecurityInfoC si, boolean asDefault) throws IOException { + super(user,pass,si); + if(asDefault) { + si.set(this); + } + } + + public HBasicAuthSS(BasicPrincipal bp, SecurityInfoC si) throws IOException { + super(bp.getName(),new String(bp.getCred()),si); + } + + public HBasicAuthSS(BasicPrincipal bp, SecurityInfoC si, boolean asDefault) throws IOException { + super(bp.getName(),new String(bp.getCred()),si); + if(asDefault) { + si.set(this); + } + } + + @Override + public void setSecurity(HttpURLConnection huc) throws CadiException { + if(isDenied()) { + throw new CadiException(REPEAT_OFFENDER); + } + huc.addRequestProperty("Authorization" , headValue); + if(securityInfo!=null && huc instanceof HttpsURLConnection) { + securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); + } + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/http/HClient.java b/client/src/main/java/org/onap/aaf/cadi/http/HClient.java new file mode 100644 index 0000000..70a703e --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/http/HClient.java @@ -0,0 +1,434 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.client.EClient; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data; +import org.onap.aaf.inno.env.Data.TYPE; +import org.onap.aaf.inno.env.util.Pool.Pooled; +import org.onap.aaf.rosetta.env.RosettaDF; + +/** + * Low Level Http Client Mechanism. Chances are, you want the high level "HRcli" + * for Rosetta Object Translation + * + * + */ +public class HClient implements EClient { + private URI uri; + private ArrayList
headers; + private String meth; + private String pathinfo; + private String query; + private String fragment; + private Transfer transfer; + private SecuritySetter ss; + private HttpURLConnection huc; + private int connectTimeout; + + public HClient(SecuritySetter ss, URI uri,int connectTimeout) throws LocatorException { + if (uri == null) { + throw new LocatorException("No Service available to call"); + } + this.uri = uri; + this.ss = ss; + this.connectTimeout = connectTimeout; + pathinfo = query = fragment = ""; + } + + @Override + public void setMethod(String meth) { + this.meth = meth; + } + + @Override + public void setPathInfo(String pathinfo) { + this.pathinfo = pathinfo; + } + + @Override + public void setPayload(Transfer transfer) { + this.transfer = transfer; + } + + @Override + public void addHeader(String tag, String value) { + if (headers == null) + headers = new ArrayList
(); + headers.add(new Header(tag, value)); + } + + @Override + public void setQueryParams(String q) { + query = q; + } + + @Override + public void setFragment(String f) { + fragment = f; + } + + @Override + public void send() throws APIException { + try { + // Build URL from given URI plus current Settings + if(uri.getPath()==null) { + throw new APIException("Invalid URL entered for HClient"); + } + StringBuilder pi = new StringBuilder(uri.getPath()); + if(!pathinfo.startsWith("/")) { + pi.append('/'); + } + pi.append(pathinfo); + URL url = new URI( + uri.getScheme(), + uri.getUserInfo(), + uri.getHost(), + uri.getPort(), + pi.toString(), + query, + fragment).toURL(); + pathinfo=null; + query=null; + fragment=null; + huc = (HttpURLConnection) url.openConnection(); + if(ss!=null) { + ss.setSecurity(huc); + } + huc.setRequestMethod(meth); + if (headers != null) + for (Header d : headers) { + huc.addRequestProperty(d.tag, d.value); + } + huc.setDoInput(true); + huc.setDoOutput(true); + huc.setUseCaches(false); + huc.setConnectTimeout(connectTimeout); + huc.connect(); + if (transfer != null) { + transfer.transfer(huc.getOutputStream()); + } + // TODO other settings? There's a bunch here. + } catch (Exception e) { + throw new APIException(e); + } finally { // ensure all these are reset after sends + meth=pathinfo=null; + if(headers!=null) { + headers.clear(); + } + pathinfo = query = fragment = ""; + } + } + + public abstract class HFuture extends Future { + protected HttpURLConnection huc; + protected int respCode; + protected String respMessage; + protected IOException exception; + protected StringBuilder errContent; + + public HFuture(final HttpURLConnection huc) { + this.huc = huc; + } + + protected boolean evalInfo(HttpURLConnection huc) throws APIException, IOException{ + return respCode == 200; + }; + + @Override + public final boolean get(int timeout) throws CadiException { + try { + huc.setReadTimeout(timeout); + respCode = huc.getResponseCode(); + ss.setLastResponse(respCode); + if(evalInfo(huc)) { + return true; + } else { + extractError(); + return false; + } + } catch (IOException | APIException e) { + throw new CadiException(e); + } finally { + close(); + } + } + + private void extractError() { + InputStream is = huc.getErrorStream(); + try { + if(is==null) { + is = huc.getInputStream(); + } + if(is!=null) { + errContent = new StringBuilder(); + int c; + while((c=is.read())>=0) { + errContent.append((char)c); + } + } + } catch (IOException e) { + exception = e; + } + } + + // Typically only used by Read + public StringBuilder inputStreamToString(InputStream is) { + // Avoids Carriage returns, and is reasonably efficient, given + // the buffer reads. + try { + StringBuilder sb = new StringBuilder(); + Reader rdr = new InputStreamReader(is); + try { + char[] buf = new char[256]; + int read; + while ((read = rdr.read(buf)) >= 0) { + sb.append(buf, 0, read); + } + } finally { + rdr.close(); + } + return sb; + } catch (IOException e) { + exception = e; + return null; + } + } + + + @Override + public int code() { + return respCode; + } + + public HttpURLConnection huc() { + return huc; + } + + public IOException exception() { + return exception; + } + + public String respMessage() { + return respMessage; + } + + @Override + public String header(String tag) { + return huc.getHeaderField(tag); + } + + public void close() { + if(huc!=null) { + huc.disconnect(); + } + } + } + + @Override + public Future futureCreate(Class t) { + return new HFuture(huc) { + public boolean evalInfo(HttpURLConnection huc) { + return respCode==201; + } + + @Override + public String body() { + if (errContent != null) { + return errContent.toString(); + + } else if (respMessage != null) { + return respMessage; + } + return ""; + } + }; + } + + @Override + public Future futureReadString() { + return new HFuture(huc) { + public boolean evalInfo(HttpURLConnection huc) throws IOException { + if (respCode == 200) { + StringBuilder sb = inputStreamToString(huc.getInputStream()); + if (sb != null) { + value = sb.toString(); + } + return true; + } + return false; + } + + @Override + public String body() { + if (value != null) { + return value; + } else if (errContent != null) { + return errContent.toString(); + } else if (respMessage != null) { + return respMessage; + } + return ""; + } + + }; + } + + @Override + public Future futureRead(final RosettaDF df, final TYPE type) { + return new HFuture(huc) { + private Data data; + + public boolean evalInfo(HttpURLConnection huc) throws APIException, IOException { + if (respCode == 200) { + data = df.newData().in(type).load(huc.getInputStream()); + value = data.asObject(); + return true; + } + return false; + } + + @Override + public String body() { + if (data != null) { + try { + return data.asString(); + } catch (APIException e) { + } + } else if (errContent != null) { + return errContent.toString(); + } else if (respMessage != null) { + return respMessage; + } + return ""; + } + }; + } + + @Override + public Future future(final T t) { + return new HFuture(huc) { + public boolean evalInfo(HttpURLConnection huc) { + if (respCode == 200) { + value = t; + return true; + } + return false; + } + + @Override + public String body() { + if (errContent != null) { + return errContent.toString(); + } else if (respMessage != null) { + return respMessage; + } + return Integer.toString(respCode); + } + }; + } + + @Override + public Future future(final HttpServletResponse resp, final int expected) throws APIException { + return new HFuture(huc) { + public boolean evalInfo(HttpURLConnection huc) throws IOException, APIException { + resp.setStatus(respCode); + int read; + InputStream is; + OutputStream os = resp.getOutputStream(); + if(respCode==expected) { + is = huc.getInputStream(); + // reuse Buffers + Pooled pbuff = Rcli.buffPool.get(); + try { + while((read=is.read(pbuff.content))>=0) { + os.write(pbuff.content,0,read); + } + } finally { + pbuff.done(); + } + return true; + } else { + is = huc.getErrorStream(); + if(is==null) { + is = huc.getInputStream(); + } + if(is!=null) { + errContent = new StringBuilder(); + Pooled pbuff = Rcli.buffPool.get(); + try { + while((read=is.read(pbuff.content))>=0) { + os.write(pbuff.content,0,read); + } + } finally { + pbuff.done(); + } + } + } + return false; + } + + @Override + public String body() { + return errContent==null?respMessage:errContent.toString(); + } + }; + } + + private static class Header { + public final String tag; + public final String value; + + public Header(String t, String v) { + this.tag = t; + this.value = v; + } + + public String toString() { + return tag + '=' + value; + } + } + + public String toString() { + return "HttpURLConnection Client configured to " + uri.toString(); + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java b/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java new file mode 100644 index 0000000..833434f --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java @@ -0,0 +1,236 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.http; + +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.SocketException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.net.ssl.SSLHandshakeException; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; + +import org.onap.aaf.inno.env.APIException; + +public class HMangr { + private String apiVersion; + private int readTimeout, connectionTimeout; + public final Locator loc; + private Access access; + + public HMangr(Access access, Locator loc) { + readTimeout = 10000; + connectionTimeout=3000; + this.loc = loc; + this.access = access; + } + + /** + * Reuse the same service. This is helpful for multiple calls that change service side cached data so that + * there is not a speed issue. + * + * If the service goes down, another service will be substituted, if available. + * + * @param access + * @param loc + * @param ss + * @param item + * @param retryable + * @return + * @throws URISyntaxException + * @throws Exception + */ + public RET same(SecuritySetter ss, Retryable retryable) throws APIException, CadiException, LocatorException { + RET ret = null; + boolean retry = true; + int retries = 0; + Rcli client = retryable.lastClient(); + try { + do { + // if no previous state, get the best + if(retryable.item()==null) { + retryable.item(loc.best()); + retryable.lastClient = null; + } + if(client==null) { + Item item = retryable.item(); + URI uri=loc.get(item); + if(uri==null) { + loc.invalidate(retryable.item()); + if(loc.hasItems()) { + retryable.item(loc.next(retryable.item())); + continue; + } else { + throw new LocatorException("No clients available for " + loc.toString()); + } + } + client = new HRcli(this, uri,item,ss) + .connectionTimeout(connectionTimeout) + .readTimeout(readTimeout) + .apiVersion(apiVersion); + } else { + client.setSecuritySetter(ss); + } + + retry = false; + try { + ret = retryable.code(client); + } catch (APIException | CadiException e) { + Item item = retryable.item(); + loc.invalidate(item); + retryable.item(loc.next(item)); + try { + Throwable ec = e.getCause(); + if(ec instanceof java.net.ConnectException) { + if(client!=null && ++retries<2) { + access.log(Level.WARN,"Connection refused, trying next available service"); + retry = true; + } else { + throw new CadiException("Connection refused, no more available connections to try"); + } + } else if(ec instanceof SSLHandshakeException) { + retryable.item(null); + throw e; + } else if(ec instanceof SocketException) { + if("java.net.SocketException: Connection reset".equals(ec.getMessage())) { + access.log(Level.ERROR, ec.getMessage(), " can mean Certificate Expiration or TLS Protocol issues"); + } + retryable.item(null); + throw e; + } else { + retryable.item(null); + throw e; + } + } finally { + client = null; + } + } catch (ConnectException e) { + Item item = retryable.item(); + loc.invalidate(item); + retryable.item(loc.next(item)); + } + } while(retry); + } finally { + retryable.lastClient = client; + } + return ret; + } + + + public RET best(SecuritySetter ss, Retryable retryable) throws LocatorException, CadiException, APIException { + if(loc==null) { + throw new LocatorException("No Locator Configured"); + } + retryable.item(loc.best()); + return same(ss,retryable); + } + public RET all(SecuritySetter ss, Retryable retryable) throws LocatorException, CadiException, APIException { + return oneOf(ss,retryable,true,null); + } + + public RET all(SecuritySetter ss, Retryable retryable,boolean notify) throws LocatorException, CadiException, APIException { + return oneOf(ss,retryable,notify,null); + } + + public RET oneOf(SecuritySetter ss, Retryable retryable,boolean notify,String host) throws LocatorException, CadiException, APIException { + RET ret = null; + // make sure we have all current references: + loc.refresh(); + for(Item li=loc.first();li!=null;li=loc.next(li)) { + URI uri=loc.get(li); + if(host!=null && !host.equals(uri.getHost())) { + break; + } + try { + ret = retryable.code(new HRcli(this,uri,li,ss)); + access.log(Level.DEBUG,"Success calling",uri,"during call to all services"); + } catch (APIException | CadiException e) { + Throwable t = e.getCause(); + if(t!=null && t instanceof ConnectException) { + loc.invalidate(li); + access.log(Level.ERROR,"Connection to",uri,"refused during call to all services"); + } else if(t instanceof SSLHandshakeException) { + access.log(Level.ERROR,t.getMessage()); + loc.invalidate(li); + } else if(t instanceof SocketException) { + if("java.net.SocketException: Connection reset".equals(t.getMessage())) { + access.log(Level.ERROR, t.getMessage(), " can mean Certificate Expiration or TLS Protocol issues"); + } + retryable.item(null); + throw e; + } else { + throw e; + } + } catch (ConnectException e) { + loc.invalidate(li); + access.log(Level.ERROR,"Connection to",uri,"refused during call to all services"); + } + } + + if(ret == null && notify) + throw new LocatorException("No available clients to call"); + return ret; + } + + + public void close() { + // TODO Anything here? + } + + public HMangr readTimeout(int timeout) { + this.readTimeout = timeout; + return this; + } + + public int readTimeout() { + return readTimeout; + } + + public void connectionTimeout(int t) { + connectionTimeout = t; + } + + public int connectionTimout() { + return connectionTimeout; + } + + public HMangr apiVersion(String version) { + apiVersion = version; + return this; + } + + public String apiVersion() { + return apiVersion; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/http/HRcli.java b/client/src/main/java/org/onap/aaf/cadi/http/HRcli.java new file mode 100644 index 0000000..1ad0fcc --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/http/HRcli.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.http; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.client.EClient; +import org.onap.aaf.cadi.client.Rcli; + +import com.att.aft.dme2.api.DME2Exception; +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.Data.TYPE; + +/** + * DME2 Rosetta Client + * + * JAXB defined JSON or XML over DME2 middleware + * + * + * @param + */ +public class HRcli extends Rcli { + private HMangr hman; + private Item item; + private SecuritySetter ss; + + public HRcli(HMangr hman, Item locItem, SecuritySetter secSet) throws URISyntaxException, LocatorException { + item=locItem; + uri=hman.loc.get(locItem); + this.hman = hman; + ss=secSet; + type = TYPE.JSON; + apiVersion = hman.apiVersion(); + } + + public HRcli(HMangr hman, URI uri, Item locItem, SecuritySetter secSet) { + locItem=item; + this.uri = uri; + this.hman = hman; + ss=secSet; + type = TYPE.JSON; + apiVersion = hman.apiVersion(); + } + + @Override + protected HRcli clone(URI uri, SecuritySetter ss) { + return new HRcli(hman,uri,item,ss); + } + + + + /** + * Note from Thaniga on 11/5. DME2Client is not expected to be reused... need a fresh one + * on each transaction, which is expected to cover the Async aspects. + * + * @return + * @throws APIException + * @throws DME2Exception + */ + protected EClient client() throws CadiException { + try { + if(uri==null) { + Item item = hman.loc.best(); + if(item==null) { + throw new CadiException("No service available for " + hman.loc.toString()); + } + uri = hman.loc.get(item); + } + return new HClient(ss,uri,connectionTimeout); + } catch (Exception e) { + throw new CadiException(e); + } + } + + /* (non-Javadoc) + * @see com.att.cadi.client.Rcli#setSecuritySetter(com.att.cadi.SecuritySetter) + */ + @Override + public void setSecuritySetter(SecuritySetter ss) { + this.ss = ss; + } + + /* (non-Javadoc) + * @see com.att.cadi.client.Rcli#getSecuritySetter() + */ + @Override + public SecuritySetter getSecuritySetter() { + return ss; + } + + public void invalidate() throws CadiException { + try { + hman.loc.invalidate(item); + } catch (Exception e) { + throw new CadiException(e); + } + } + + public HRcli setManager(HMangr hman) { + this.hman = hman; + return this; + } + + public String toString() { + return uri.toString(); + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/http/HTransferSS.java b/client/src/main/java/org/onap/aaf/cadi/http/HTransferSS.java new file mode 100644 index 0000000..db456f2 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/http/HTransferSS.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.http; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.security.Principal; + +import javax.net.ssl.HttpsURLConnection; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.client.AbsTransferSS; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; + + +public class HTransferSS extends AbsTransferSS { + public HTransferSS(Principal principal, String app) throws IOException { + super(principal, app); + } + + public HTransferSS(Principal principal, String app, SecurityInfoC si) { + super(principal, app, si); + } + + @Override + public void setSecurity(HttpURLConnection huc) throws CadiException { + if(value!=null) { + if(defSS==null) { + throw new CadiException("Need App Credentials to send message"); + } + defSS.setSecurity(huc); + huc.addRequestProperty(Config.CADI_USER_CHAIN, value); + } + if(securityInfo!=null) { + securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); + } + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } + +} diff --git a/client/src/main/java/org/onap/aaf/cadi/http/HX509SS.java b/client/src/main/java/org/onap/aaf/cadi/http/HX509SS.java new file mode 100644 index 0000000..0bdc843 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/http/HX509SS.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.http; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.Signature; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.X509KeyManager; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; + +import org.onap.aaf.inno.env.APIException; +import org.onap.aaf.inno.env.util.Chrono; + + +public class HX509SS implements SecuritySetter { + private static final byte[] X509 = "x509 ".getBytes(); + private PrivateKey priv; + private byte[] pub; + private String cert; + private SecurityInfoC securityInfo; + private String algo; + private String alias; + private static int count = new SecureRandom().nextInt(); + + public HX509SS(SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { + this(null,si,false); + } + + public HX509SS(SecurityInfoC si, boolean asDefault) throws APIException, IOException, CertificateEncodingException { + this(null,si,asDefault); + } + + public HX509SS(final String sendAlias, SecurityInfoC si) throws APIException, IOException, CertificateEncodingException { + this(sendAlias, si, false); + } + + public HX509SS(final String sendAlias, SecurityInfoC si, boolean asDefault) throws APIException, IOException, CertificateEncodingException { + securityInfo = si; + if((alias=sendAlias) == null) { + if(si.default_alias == null) { + throw new APIException("JKS Alias is required to use X509SS Security. Use " + Config.CADI_ALIAS +" to set default alias"); + } else { + alias = si.default_alias; + } + } + + priv=null; + X509KeyManager[] xkms = si.getKeyManagers(); + if(xkms==null || xkms.length==0) { + throw new APIException("There are no valid keys available in given Keystores. Wrong Keypass? Expired?"); + } + for(int i=0;priv==null&&i0) { + algo = chain[0].getSigAlgName(); + pub = chain[0].getEncoded(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(pub.length*2); + ByteArrayInputStream bais = new ByteArrayInputStream(pub); + Symm.base64noSplit.encode(bais,baos,X509); + cert = baos.toString(); + + /* + // Inner Test code, uncomment if fix needed + bais = new ByteArrayInputStream(baos.toByteArray()); + baos = new ByteArrayOutputStream(input.length*2); + Symm.base64noSplit().decode(bais,baos,5); + byte[] output = baos.toByteArray(); + String reconstitute = output.toString(); + System.out.println("ok"); + CertificateFactory certFactory; + try { + bais = new ByteArrayInputStream(output); + certFactory = CertificateFactory.getInstance("X.509"); + X509Certificate x509 = (X509Certificate)certFactory.generateCertificate(bais); + System.out.println(x509.toString()); + } catch (CertificateException e) { + e.printStackTrace(); + } + */ + } + } + if(algo==null) { + throw new APIException("X509 Security Setter not configured"); + } + } + + @Override + public void setSecurity(HttpURLConnection huc) throws CadiException { + if(huc instanceof HttpsURLConnection) { + securityInfo.setSocketFactoryOn((HttpsURLConnection)huc); + } + if(alias==null) { // must be a one-way + huc.setRequestProperty("Authorization", cert); + + // Test Signed content + try { + String data = "SignedContent["+ inc() + ']' + Chrono.dateTime(); + huc.setRequestProperty("Data", data); + + Signature sig = Signature.getInstance(algo); + sig.initSign(priv); + sig.update(data.getBytes()); + byte[] signature = sig.sign(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(signature.length*1.3)); + ByteArrayInputStream bais = new ByteArrayInputStream(signature); + Symm.base64noSplit.encode(bais, baos); + huc.setRequestProperty("Signature", new String(baos.toByteArray())); + + } catch (Exception e) { + throw new CadiException(e); + } + } + } + + private synchronized int inc() { + return ++count; + } + + /* (non-Javadoc) + * @see com.att.cadi.SecuritySetter#getID() + */ + @Override + public String getID() { + return alias; + } + + @Override + public int setLastResponse(int respCode) { + return 0; + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/locator/DME2Locator.java b/client/src/main/java/org/onap/aaf/cadi/locator/DME2Locator.java new file mode 100644 index 0000000..656fd19 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/locator/DME2Locator.java @@ -0,0 +1,347 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.locator; + + +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Properties; +import java.util.Random; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Access.Level; + +import java.security.SecureRandom; + +//import com.att.aft.dme2.api.DME2Endpoint; +import com.att.aft.dme2.api.DME2Exception; +import com.att.aft.dme2.api.DME2Manager; +import com.att.aft.dme2.api.DME2Server; +import com.att.aft.dme2.manager.registry.DME2Endpoint; + +public class DME2Locator implements Locator { + private DME2Manager dm; + private DME2Endpoint[] endpoints; + private Access access; + private String service; + private String version; + private String routeOffer; + private String envContext; + private String thisMachine; + private String pathInfo; + private int thisPort; + private boolean removeSelf; + private final static SecureRandom random = new SecureRandom(); + + // Default is to not bother trying to remove self + public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer) throws DME2Exception, UnknownHostException, LocatorException { + this(access,dm,service,version,envContext,routeOffer,false); + } + + public DME2Locator(Access access, DME2Manager dm, String service, String version, String envContext, String routeOffer, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { + this.access = access; + if(dm==null) { + this.dm = new DME2Manager("DME2Locator created DME2Manager",System.getProperties()); + } else { + this.dm = dm; + } + this.service = service; + this.version = version; + this.envContext = envContext; + this.routeOffer = routeOffer; + refresh(); + if(thisMachine==null) { + // Can't get from dm... + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } else { + thisPort = dm.getPort(); + } + + this.removeSelf = removeSelf; + } + + // Default is to not bother trying to remove self + public DME2Locator(Access access, DME2Manager dm, String aafurl) throws DME2Exception, UnknownHostException, LocatorException { + this(access,dm,aafurl,false); + } + + public DME2Locator(Access access, DME2Manager dm, String aafurl, boolean removeSelf) throws DME2Exception, UnknownHostException, LocatorException { + if(aafurl==null) { + throw new LocatorException("URL is null"); + } + this.access = access; + if(dm==null) { + Properties dprops; + if(access instanceof PropAccess) { + dprops = ((PropAccess)access).getDME2Properties(); + } else { + dprops = System.getProperties(); + } + dm = this.dm = new DME2Manager("DME2Locator created DME2Manager",dprops); + } else { + this.dm = dm; + } + String[] split = aafurl.split("/"); + StringBuilder sb = new StringBuilder(); + boolean dme2Entered = false; + for(String s : split) { + if(s.startsWith("service=")) { + this.service = s.substring(8); + } else if(s.startsWith("version=")) { + this.version = s.substring(8); + } else if(s.startsWith("envContext=")) { + this.envContext = s.substring(11); + } else if(s.startsWith("routeOffer=")) { + this.routeOffer = s.substring(11); + dme2Entered = true; + } else if(dme2Entered) { + sb.append('/'); + sb.append(s); + } + } + pathInfo = sb.toString(); + thisMachine = dm.getHostname(); + if(thisMachine==null) { + // Can't get from dm... + thisMachine = InetAddress.getLocalHost().getHostName(); + thisPort = 0; + } else { + thisPort = dm.getPort(); + } + this.removeSelf=removeSelf; + refresh(); + } + + @Override + public boolean refresh() { + try { + dm.refresh(); + //endpoints = dm.findEndpoints(service, version, envContext, routeOffer, true); + if(removeSelf) { +// for(int i=0;i0; + return true; + } + + @Override + public void invalidate(Locator.Item item) throws LocatorException { + if(item instanceof DME2Item) { + int idx = ((DME2Item)item).idx; +// if(idx () { + @Override + public int compare(DoubIndex a, DoubIndex b) { + if(a.db.d) return 1; + return (random.nextInt()%1)==0?1:0;// randomize if the same + } + + }); + return new DME2Item(remote[0].idx); + } + } + } + + private static class DoubIndex { + public final double d; + public final int idx; + + public DoubIndex(double doub, int i) { + d = doub; + idx = i; + } + } + @Override + public DME2Item first() { +// if(endpoints==null)return null; +// for(int i=0;i { + private static enum Status {UNTRIED, OK, INVALID, SLOW}; + private static final int CHECK_TIME = 3000; + + private String host, protocol; + private Access access; + private Host[] hosts; + private int startPort, endPort; + private String suffix; + + public DNSLocator(Access access, String protocol, String host, String range) { + this.host = host; + this.protocol = protocol; + this.access = access; + int dash = range.indexOf('-'); + if(dash<0) { + startPort = endPort = Integer.parseInt(range); + } else { + startPort = Integer.parseInt(range.substring(0,dash)); + endPort = Integer.parseInt(range.substring(dash + 1)); + } + refresh(); + } + + @Override + public URI get(Item item) throws LocatorException { + return hosts[((DLItem)item).cnt].uri; + } + + @Override + public boolean hasItems() { + for(Host h : hosts) { + if(h.status==Status.OK) { + return true; + } + } + return false; + } + + @Override + public void invalidate(Item item) { + DLItem di = (DLItem)item; + hosts[di.cnt].status = Status.INVALID; + } + + @Override + public Item best() throws LocatorException { + // not a good "best" + for(int i=0;i { + private final HX509SS ss; + + public HClientHotPeerLocator(Access access, String urlstr, long invalidateTime, String localLatitude, + String localLongitude, HX509SS ss) throws LocatorException { + super(access, urlstr, invalidateTime, localLatitude, localLongitude); + + this.ss = ss; + } + + @Override + protected HClient _newClient(String clientInfo) throws LocatorException { + try { + int idx = clientInfo.indexOf('/'); + return new HClient(ss,new URI("https://"+(idx<0?clientInfo:clientInfo.substring(0, idx))),3000); + } catch (URISyntaxException e) { + throw new LocatorException(e); + } + } + + @Override + protected HClient _invalidate(HClient client) { + return null; + } + + @Override + protected void _destroy(HClient client) { + } +} diff --git a/client/src/main/java/org/onap/aaf/cadi/locator/HotPeerLocator.java b/client/src/main/java/org/onap/aaf/cadi/locator/HotPeerLocator.java new file mode 100644 index 0000000..04d2a28 --- /dev/null +++ b/client/src/main/java/org/onap/aaf/cadi/locator/HotPeerLocator.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.locator; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.routing.GreatCircle; + +import org.onap.aaf.inno.env.util.Split; + +/** + * This Locator is to handle Hot Peer load protection, when the Servers are + * 1) Static + * 2) Well known client URL + * + * The intention is to change traffic over to the Hot Peer, if a server goes down, and reinstate + * when it is back up. + * + * Example of this kind of Service is a MS Certificate Server + * + * + * + * @param + */ +public abstract class HotPeerLocator implements Locator { + private final String[] urlstrs; + private final CLIENT[] clients; + private final long[] failures; + private final double[] distances; + private int preferred; + private long invalidateTime; + private Thread refreshThread; + protected Access access; + + /** + * Construct: Expect one or more Strings in the form: + * 192.555.112.223:39/38.88087/-77.30122 + * separated by commas + * + * @param trans + * @param urlstr + * @param invalidateTime + * @param localLatitude + * @param localLongitude + * @throws LocatorException + */ + @SuppressWarnings("unchecked") + protected HotPeerLocator(Access access, final String urlstr, final long invalidateTime, final String localLatitude, final String localLongitude) throws LocatorException { + this.access = access; + urlstrs = Split.split(',', urlstr); + clients = (CLIENT[])new Object[urlstrs.length]; + failures = new long[urlstrs.length]; + distances= new double[urlstrs.length]; + this.invalidateTime = invalidateTime; + + double distance = Double.MAX_VALUE; + for(int i=0;iSystem.currentTimeMillis()) { + throw new LocatorException("Client requested is invalid"); + } else { + synchronized(clients) { + c = _newClient(urlstrs[hpi.idx]); + failures[hpi.idx]=0L; + } + } + } else if(failures[hpi.idx]>0){ + throw new LocatorException("Client requested is invalid"); + } + return c; + } + + public String info(Item item) { + HPItem hpi = (HPItem)item; + if(hpi!=null && hpi.idx=clients.length) { + return null; + } + return hpi; + } + + @Override + public boolean refresh() { + boolean force = !hasItems(); // If no Items at all, reset + boolean rv = true; + long now = System.currentTimeMillis(); + for(int i=0;i0L && (failures[i] { + private final URI [] orig; + private PLItem[] current; + private int end; + private final SecureRandom random; + private URI[] resolved; + private long lastRefreshed=0L; + private long minRefresh; + private long backgroundRefresh; + + public PropertyLocator(String locList) throws LocatorException { + this(locList,10000L, 1000*60*20); // defaults, do not refresh more than once in 10 seconds, Refresh Locator every 20 mins. + } + /** + * comma delimited root url list + * + * @param locList + * @throws LocatorException + */ + public PropertyLocator(String locList, long minRefreshMillis, long backgroundRefreshMillis) throws LocatorException { + minRefresh = minRefreshMillis; + backgroundRefresh = backgroundRefreshMillis; + if(locList==null) { + throw new LocatorException("No Location List given for PropertyLocator"); + } + String[] locarray = Split.split(',',locList); + List uriList = new ArrayList(); + + random = new SecureRandom(); + + for(int i=0;i0?current[0]:null; + } + + @Override + public boolean hasItems() { + return end>0; + } + + @Override + public Item next(Item item) throws LocatorException { + if(item==null) { + return null; + } else { + int spot; + if((spot=(((PLItem)item).order+1))>=end)return null; + return current[spot]; + } + } + + @Override + public synchronized void invalidate(Item item) throws LocatorException { + if(--end<=0) { + refresh(); + return; + } + PLItem pli = (PLItem)item; + int i,order; + for(i=0;ilastRefreshed) { + // Build up list + List resolve = new ArrayList(); + String realname; + for(int i = 0; i < orig.length ; ++i) { + try { + InetAddress ia[] = InetAddress.getAllByName(orig[i].getHost()); + + URI o,n; + for(int j=0;j0?args[0]:"xx9999"); - System.out.printf("Path: %s\n",path); - client.addHeader("Accept", "application/Perms+json;q=1.0;charset=utf-8;version=2.0,application/json;q=1.0;version=2.0,*"); - client.setMethod("GET"); - client.setContext(path); - client.setPayload("");// Note: Even on "GET", you need a String in DME2 - - String o = client.sendAndWait(5000); // There are other Asynchronous call options, see DME2 Docs - if(o==null) { - System.out.println('[' + o + ']' + " (blank is good)"); - } - - - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/client/src/test/java/com/client/test/JU_DNSLocator.java b/client/src/test/java/com/client/test/JU_DNSLocator.java deleted file mode 100644 index 04a4f17..0000000 --- a/client/src/test/java/com/client/test/JU_DNSLocator.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.client.test; - -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; - -import org.junit.AfterClass; -import org.junit.Test; - -import com.att.cadi.locator.DNSLocator; -import com.att.cadi.PropAccess; -import com.att.cadi.Locator.Item; - -public class JU_DNSLocator { - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void test() { - - DNSLocator dl = new DNSLocator(new PropAccess(), "https", "aaf.it.att.com","8150-8152"); - try { - Item item = dl.best(); - URI uri = dl.get(item); - URL url = uri.toURL(); - URLConnection conn = url.openConnection(); - conn.connect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/client/src/test/java/com/client/test/JU_PropertyLocator.java b/client/src/test/java/com/client/test/JU_PropertyLocator.java deleted file mode 100644 index 89bef62..0000000 --- a/client/src/test/java/com/client/test/JU_PropertyLocator.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.client.test; - -import java.net.URI; - -import org.junit.AfterClass; -import org.junit.Test; - -import static org.junit.Assert.*; - -import com.att.cadi.Locator.Item; -import com.att.cadi.locator.PropertyLocator; - -public class JU_PropertyLocator { - - @AfterClass - public static void tearDownAfterClass() throws Exception { - } - - @Test - public void test() throws Exception { - PropertyLocator pl = new PropertyLocator("https://localhost:2345,https://fred.wilma.com:26444,https://tom.jerry.com:534"); - - Item i; - int count; - boolean print = false; - for(int j=0;j<900000;++j) { - count = 0; - for(i = pl.first();i!=null;i=pl.next(i)) { - URI loc = pl.get(i); - if(print)System.out.println(loc.toString()); - ++count; - } - assertEquals(3,count); - assertTrue(pl.hasItems()); - if(print)System.out.println("---"); - pl.invalidate(pl.best()); - - count = 0; - for(i = pl.first();i!=null;i=pl.next(i)) { - URI loc = pl.get(i); - if(print)System.out.println(loc.toString()); - ++count; - } - - assertEquals(2,count); - assertTrue(pl.hasItems()); - if(print)System.out.println("---"); - pl.invalidate(pl.best()); - - count = 0; - for(i = pl.first();i!=null;i=pl.next(i)) { - URI loc = pl.get(i); - if(print)System.out.println(loc.toString()); - ++count; - } - - assertEquals(1,count); - assertTrue(pl.hasItems()); - if(print)System.out.println("---"); - pl.invalidate(pl.best()); - - count = 0; - for(i = pl.first();i!=null;i=pl.next(i)) { - URI loc = pl.get(i); - if(print)System.out.println(loc.toString()); - ++count; - } - - assertEquals(0,count); - assertFalse(pl.hasItems()); - - pl.refresh(); - } - } - -} diff --git a/client/src/test/java/com/client/test/PaulUzee.java b/client/src/test/java/com/client/test/PaulUzee.java deleted file mode 100644 index 24aeb49..0000000 --- a/client/src/test/java/com/client/test/PaulUzee.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.client.test; - -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.net.URI; -import java.util.Properties; - -import com.att.aft.dme2.api.DME2Manager; -import com.att.cadi.Access; -import com.att.cadi.Locator; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator.Item; -import com.att.cadi.dme2.DME2Locator; - -public class PaulUzee { - public static void main(String[] args) { - try { - // You'll want to put this on Command line "-D" probably - Properties props = System.getProperties(); - props.put("AFT_LATITUDE","32.780140"); - props.put("AFT_LONGITUDE","-96.800451"); - props.put("AFT_ENVIRONMENT","AFTPRD"); - - // - // Use an "Access" class to hook up logging, properties, etc. - // Make one that ties into your code's logging, property mechanism, etc. - // - Access access = new PaulAccess(); - - DME2Manager dm = new DME2Manager("Paul Uzee's Test",props); - Locator loc = new DME2Locator(access ,dm,"com.att.authz.AuthorizationService","2.0","PROD","DEFAULT"); - - - for(Item item = loc.first(); item!=null; item=loc.next(item)) { - URI location = (URI) loc.get(item); - access.log(Level.INFO,location); - access.log(Level.INFO,location.getScheme()); - access.log(Level.INFO,location.getHost()); - access.log(Level.INFO, location.getPort()); - } - } catch (Exception e) { - e.printStackTrace(); - } - - } - - private static class PaulAccess implements Access { - private Level willWrite = Level.INFO; - - @Override - public ClassLoader classLoader() { - return getClass().getClassLoader(); - } - - @Override - public String decrypt(String data, boolean def) throws IOException { - return data; - } - - @Override - public String getProperty(String tag, String def) { - return System.getProperty(tag, def); - } - - @Override - public void load(InputStream is) throws IOException { - System.getProperties().load(is); - } - - @Override - public void log(Level level, Object... obj) { - if(level.compareTo(willWrite)<0) return; - PrintStream ps; - switch(level) { - case DEBUG: - case AUDIT: - case ERROR: - case WARN: - ps = System.err; - break; - case INFO: - case INIT: - default: - ps = System.out; - } - boolean first = true; - for(Object o : obj) { - if(first)first=false; - else ps.print(' '); - ps.print(o.toString()); - } - ps.println(); - } - - @Override - public void log(Exception e, Object... obj) { - Object[] objs = new Object[obj.length+1]; - objs[0]=e.getMessage(); - System.arraycopy(objs, 1, obj, 0, obj.length); - log(Level.ERROR,e,objs); - } - - @Override - public void setLogLevel(Level l) { - willWrite = l; - } - - /* (non-Javadoc) - * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) - */ - @Override - public boolean willLog(Level level) { - return true; - } - - @Override - public void printf(Level level, String fmt, Object... elements) { - // TODO Auto-generated method stub - - } - }; -} diff --git a/client/src/test/java/com/client/test/TestAccess.java b/client/src/test/java/com/client/test/TestAccess.java deleted file mode 100644 index 434ae62..0000000 --- a/client/src/test/java/com/client/test/TestAccess.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.client.test; - -import java.io.IOException; -import java.io.InputStream; - -import com.att.cadi.Access; -import com.att.cadi.Symm; - -public class TestAccess implements Access { - private Symm symm; - - public TestAccess() { - symm = Symm.obtain(this); - } - - public void log(Level level, Object... elements) { - boolean first = true; - for(int i=0;i ft = client.read("/authz/nss/com.att.aaf","text/json"); - if(ft.get(10000)) { - System.out.println("Hurray,\n"+ft.body()); - } else { - System.out.println("not quite: " + ft.code()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/client/src/test/java/com/client/test/TestHClient.java b/client/src/test/java/com/client/test/TestHClient.java deleted file mode 100644 index 7fcd113..0000000 --- a/client/src/test/java/com/client/test/TestHClient.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.client.test; - -import java.net.HttpURLConnection; -import java.net.URI; -import java.util.Properties; - -import com.att.aft.dme2.api.DME2Manager; -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.cadi.Locator.Item; -import com.att.cadi.PropAccess; -import com.att.cadi.SecuritySetter; -import com.att.cadi.client.Future; -import com.att.cadi.client.Rcli; -import com.att.cadi.client.Retryable; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.http.HBasicAuthSS; -import com.att.cadi.http.HMangr; -import com.att.cadi.locator.DME2Locator; -import com.att.inno.env.APIException; - -public class TestHClient { - public static void main(String[] args) { - try { - PropAccess access = new PropAccess(); - DME2Manager dm = new DME2Manager("DME2Manager TestHClient",access.getProperties()); - Locator loc = new DME2Locator(access,dm,"com.att.authz.AuthorizationService","2.0","DEV","BAU_SE"); - - for(Item item = loc.first(); item!=null; item=loc.next(item)) { - System.out.println(loc.get(item)); - } - - - SecurityInfoC si = new SecurityInfoC(access); - SecuritySetter ss = new HBasicAuthSS("m12345@aaf.att.com", - access.decrypt("enc:7K6yjLQqha_S9yApkIul2K_by5Moemcos1HRAVnhMXu",false), si); -// SecuritySetter ss = new X509SS(si, "aaf"); - - HMangr hman = new HMangr(access,loc); - try { - hman.best(ss, new Retryable() { - @Override - public Void code(Rcli cli) throws APIException, CadiException { - Future ft = cli.read("/authz/nss/com.att.aaf","text/json"); - if(ft.get(10000)) { - System.out.println("Hurray,\n"+ft.body()); - } else { - System.out.println("not quite: " + ft.code()); - } - return null; - }}); - } finally { - hman.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/client/src/test/java/org/onap/aaf/client/test/BasicDME2Client.java b/client/src/test/java/org/onap/aaf/client/test/BasicDME2Client.java new file mode 100644 index 0000000..4619a0f --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/BasicDME2Client.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.net.URI; +import java.util.Properties; + +import com.att.aft.dme2.api.DME2Client; +import com.att.aft.dme2.api.DME2Manager; + +public class BasicDME2Client { + public static void main(String[] args) { + try { + Properties props = System.getProperties(); + + DME2Manager dm = new DME2Manager("DME2Manager TestBasicDME2Client",props); + URI uri = new URI(System.getProperty("aaf_url")); + DME2Client client = new DME2Client(dm,uri,3000); + + System.out.println(props.getProperty("aaf_id")); + client.setCredentials(props.getProperty("aaf_id"),props.getProperty("aaf_password")); + + String path = String.format("/authz/perms/user/%s@csp.att.com",args.length>0?args[0]:"xx9999"); + System.out.printf("Path: %s\n",path); + client.addHeader("Accept", "application/Perms+json;q=1.0;charset=utf-8;version=2.0,application/json;q=1.0;version=2.0,*"); + client.setMethod("GET"); + client.setContext(path); + client.setPayload("");// Note: Even on "GET", you need a String in DME2 + + String o = client.sendAndWait(5000); // There are other Asynchronous call options, see DME2 Docs + if(o==null) { + System.out.println('[' + o + ']' + " (blank is good)"); + } + + + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/client/src/test/java/org/onap/aaf/client/test/JU_DNSLocator.java b/client/src/test/java/org/onap/aaf/client/test/JU_DNSLocator.java new file mode 100644 index 0000000..8cac8d1 --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/JU_DNSLocator.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; + +import org.junit.AfterClass; +import org.junit.Test; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.locator.DNSLocator; + +public class JU_DNSLocator { + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test() { + + DNSLocator dl = new DNSLocator(new PropAccess(), "https", "aaf.it.att.com","8150-8152"); + try { + Item item = dl.best(); + URI uri = dl.get(item); + URL url = uri.toURL(); + URLConnection conn = url.openConnection(); + conn.connect(); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/client/src/test/java/org/onap/aaf/client/test/JU_PropertyLocator.java b/client/src/test/java/org/onap/aaf/client/test/JU_PropertyLocator.java new file mode 100644 index 0000000..c09d697 --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/JU_PropertyLocator.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.net.URI; + +import org.junit.AfterClass; +import org.junit.Test; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.locator.PropertyLocator; + +import static org.junit.Assert.*; + +public class JU_PropertyLocator { + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Test + public void test() throws Exception { + PropertyLocator pl = new PropertyLocator("https://localhost:2345,https://fred.wilma.com:26444,https://tom.jerry.com:534"); + + Item i; + int count; + boolean print = false; + for(int j=0;j<900000;++j) { + count = 0; + for(i = pl.first();i!=null;i=pl.next(i)) { + URI loc = pl.get(i); + if(print)System.out.println(loc.toString()); + ++count; + } + assertEquals(3,count); + assertTrue(pl.hasItems()); + if(print)System.out.println("---"); + pl.invalidate(pl.best()); + + count = 0; + for(i = pl.first();i!=null;i=pl.next(i)) { + URI loc = pl.get(i); + if(print)System.out.println(loc.toString()); + ++count; + } + + assertEquals(2,count); + assertTrue(pl.hasItems()); + if(print)System.out.println("---"); + pl.invalidate(pl.best()); + + count = 0; + for(i = pl.first();i!=null;i=pl.next(i)) { + URI loc = pl.get(i); + if(print)System.out.println(loc.toString()); + ++count; + } + + assertEquals(1,count); + assertTrue(pl.hasItems()); + if(print)System.out.println("---"); + pl.invalidate(pl.best()); + + count = 0; + for(i = pl.first();i!=null;i=pl.next(i)) { + URI loc = pl.get(i); + if(print)System.out.println(loc.toString()); + ++count; + } + + assertEquals(0,count); + assertFalse(pl.hasItems()); + + pl.refresh(); + } + } + +} diff --git a/client/src/test/java/org/onap/aaf/client/test/PaulUzee.java b/client/src/test/java/org/onap/aaf/client/test/PaulUzee.java new file mode 100644 index 0000000..4bec3fd --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/PaulUzee.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.net.URI; +import java.util.Properties; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.dme2.DME2Locator; + +import com.att.aft.dme2.api.DME2Manager; + +public class PaulUzee { + public static void main(String[] args) { + try { + // You'll want to put this on Command line "-D" probably + Properties props = System.getProperties(); + props.put("AFT_LATITUDE","32.780140"); + props.put("AFT_LONGITUDE","-96.800451"); + props.put("AFT_ENVIRONMENT","AFTPRD"); + + // + // Use an "Access" class to hook up logging, properties, etc. + // Make one that ties into your code's logging, property mechanism, etc. + // + Access access = new PaulAccess(); + + DME2Manager dm = new DME2Manager("Paul Uzee's Test",props); + Locator loc = new DME2Locator(access ,dm,"com.att.authz.AuthorizationService","2.0","PROD","DEFAULT"); + + + for(Item item = loc.first(); item!=null; item=loc.next(item)) { + URI location = (URI) loc.get(item); + access.log(Level.INFO,location); + access.log(Level.INFO,location.getScheme()); + access.log(Level.INFO,location.getHost()); + access.log(Level.INFO, location.getPort()); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private static class PaulAccess implements Access { + private Level willWrite = Level.INFO; + + @Override + public ClassLoader classLoader() { + return getClass().getClassLoader(); + } + + @Override + public String decrypt(String data, boolean def) throws IOException { + return data; + } + + @Override + public String getProperty(String tag, String def) { + return System.getProperty(tag, def); + } + + @Override + public void load(InputStream is) throws IOException { + System.getProperties().load(is); + } + + @Override + public void log(Level level, Object... obj) { + if(level.compareTo(willWrite)<0) return; + PrintStream ps; + switch(level) { + case DEBUG: + case AUDIT: + case ERROR: + case WARN: + ps = System.err; + break; + case INFO: + case INIT: + default: + ps = System.out; + } + boolean first = true; + for(Object o : obj) { + if(first)first=false; + else ps.print(' '); + ps.print(o.toString()); + } + ps.println(); + } + + @Override + public void log(Exception e, Object... obj) { + Object[] objs = new Object[obj.length+1]; + objs[0]=e.getMessage(); + System.arraycopy(objs, 1, obj, 0, obj.length); + log(Level.ERROR,e,objs); + } + + @Override + public void setLogLevel(Level l) { + willWrite = l; + } + + /* (non-Javadoc) + * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) + */ + @Override + public boolean willLog(Level level) { + return true; + } + + @Override + public void printf(Level level, String fmt, Object... elements) { + // TODO Auto-generated method stub + + } + }; +} diff --git a/client/src/test/java/org/onap/aaf/client/test/TestAccess.java b/client/src/test/java/org/onap/aaf/client/test/TestAccess.java new file mode 100644 index 0000000..c054bc0 --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/TestAccess.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.io.IOException; +import java.io.InputStream; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; + +public class TestAccess implements Access { + private Symm symm; + + public TestAccess() { + symm = Symm.obtain(this); + } + + public void log(Level level, Object... elements) { + boolean first = true; + for(int i=0;i ft = client.read("/authz/nss/com.att.aaf","text/json"); + if(ft.get(10000)) { + System.out.println("Hurray,\n"+ft.body()); + } else { + System.out.println("not quite: " + ft.code()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/client/src/test/java/org/onap/aaf/client/test/TestHClient.java b/client/src/test/java/org/onap/aaf/client/test/TestHClient.java new file mode 100644 index 0000000..2476caf --- /dev/null +++ b/client/src/test/java/org/onap/aaf/client/test/TestHClient.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.client.test; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.Properties; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.SecuritySetter; +import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.client.Future; +import org.onap.aaf.cadi.client.Rcli; +import org.onap.aaf.cadi.client.Retryable; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.http.HBasicAuthSS; +import org.onap.aaf.cadi.http.HMangr; +import org.onap.aaf.cadi.locator.DME2Locator; + +import com.att.aft.dme2.api.DME2Manager; +import org.onap.aaf.inno.env.APIException; + +public class TestHClient { + public static void main(String[] args) { + try { + PropAccess access = new PropAccess(); + DME2Manager dm = new DME2Manager("DME2Manager TestHClient",access.getProperties()); + Locator loc = new DME2Locator(access,dm,"com.att.authz.AuthorizationService","2.0","DEV","BAU_SE"); + + for(Item item = loc.first(); item!=null; item=loc.next(item)) { + System.out.println(loc.get(item)); + } + + + SecurityInfoC si = new SecurityInfoC(access); + SecuritySetter ss = new HBasicAuthSS("m12345@aaf.att.com", + access.decrypt("enc:7K6yjLQqha_S9yApkIul2K_by5Moemcos1HRAVnhMXu",false), si); +// SecuritySetter ss = new X509SS(si, "aaf"); + + HMangr hman = new HMangr(access,loc); + try { + hman.best(ss, new Retryable() { + @Override + public Void code(Rcli cli) throws APIException, CadiException { + Future ft = cli.read("/authz/nss/com.att.aaf","text/json"); + if(ft.get(10000)) { + System.out.println("Hurray,\n"+ft.body()); + } else { + System.out.println("not quite: " + ft.code()); + } + return null; + }}); + } finally { + hman.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/core/pom.xml b/core/pom.xml index 3cfdeb1..80fb699 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ --> - com.att.cadi + org.onap.aaf.cadi parent .. 1.0.0-SNAPSHOT @@ -34,7 +34,15 @@ jar https://github.com/att/AAF CADI - + + UTF-8 + 1.0.0-SNAPSHOT + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/${project.groupId}/${project.artifactId}/${project.version} + @@ -112,19 +120,61 @@ - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrhdme - https://oss.sonatype.org/ - true - - + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ${nexusproxy} + 176c31dfe190a + ecomp-staging + + - + + + ecomp-releases + AAF Release Repository + ${nexusproxy}${releaseNexusPath} + + + ecomp-snapshots + AAF Snapshot Repository + ${nexusproxy}${snapshotNexusPath} + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + + + onap-plugin-snapshots + https://nexus.onap.org/content/repositories/snapshots/ + + + + + + central + Maven 2 repository 2 + http://repo2.maven.org/maven2/ + + + onap-jar-snapshots + https://nexus.onap.org/content/repositories/snapshots + + + spring-repo + Spring repo + https://artifacts.alfresco.com/nexus/content/repositories/public/ + + + repository.jboss.org-public + JBoss.org Maven repository + https://repository.jboss.org/nexus/content/groups/public + + diff --git a/core/src/main/java/com/att/cadi/AES.java b/core/src/main/java/com/att/cadi/AES.java deleted file mode 100644 index 7304932..0000000 --- a/core/src/main/java/com/att/cadi/AES.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.KeyGenerator; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import com.att.cadi.util.Chmod; - -public class AES { - public static final String AES = AES.class.getSimpleName(); - public static final int AES_KEY_SIZE = 128; // 256 isn't supported on all JDKs. - - private Cipher aesCipher; - private SecretKeySpec aeskeySpec; - - public AES() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { - aesCipher = Cipher.getInstance(AES); - aeskeySpec = new SecretKeySpec(newKey().getEncoded(), AES); - } - - public static SecretKey newKey() throws NoSuchAlgorithmException { - KeyGenerator kgen = KeyGenerator.getInstance(AES); - kgen.init(AES_KEY_SIZE); - return kgen.generateKey(); - } - - public AES(File keyfile) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { - aesCipher = Cipher.getInstance(AES); - byte[] aesKey = new byte[AES_KEY_SIZE/8]; - FileInputStream fis = new FileInputStream(keyfile); - try { - fis.read(aesKey); - } finally { - fis.close(); - } - aeskeySpec = new SecretKeySpec(aesKey,AES); - } - - public AES(byte[] aeskey, int offset, int len) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { - aesCipher = Cipher.getInstance(AES); - aeskeySpec = new SecretKeySpec(aeskey,offset,len,AES); - } - - public byte[] encrypt(byte[] in) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); - return aesCipher.doFinal(in); - } - - public byte[] decrypt(byte[] in) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { - aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); - return aesCipher.doFinal(in); - } - - 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 { - if(encrypt) { - aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); - } else { - aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); - } - } catch (InvalidKeyException e) { - // KeySpec created earlier... no chance being wrong. - } - return new CipherOutputStream(os,aesCipher); - } - - public CipherInputStream inputStream(InputStream is, boolean encrypt) { - try { - if(encrypt) { - aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); - } else { - aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); - } - } catch (InvalidKeyException e) { - // KeySpec created earlier... no chance being wrong. - } - - return new CipherInputStream(is,aesCipher); - } -} diff --git a/core/src/main/java/com/att/cadi/AbsCachedPrincipal.java b/core/src/main/java/com/att/cadi/AbsCachedPrincipal.java deleted file mode 100644 index f244d09..0000000 --- a/core/src/main/java/com/att/cadi/AbsCachedPrincipal.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -public abstract class AbsCachedPrincipal implements CachedPrincipal { - protected TAF taf; - - protected AbsCachedPrincipal(TAF taf) { - this.taf = taf; - } - -} diff --git a/core/src/main/java/com/att/cadi/AbsUserCache.java b/core/src/main/java/com/att/cadi/AbsUserCache.java deleted file mode 100644 index d374faa..0000000 --- a/core/src/main/java/com/att/cadi/AbsUserCache.java +++ /dev/null @@ -1,408 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; - -import com.att.cadi.Access.Level; -import com.att.cadi.CachedPrincipal.Resp; - -/** - * Implement Fast lookup and Cache for Local User Info - * - * Include ability to add and remove Users - * - * Also includes a Timer Thread (when necessary) to invoke cleanup on expiring Credentials - * - * - */ -public abstract class AbsUserCache { - static final int MIN_INTERVAL = 15000; - static final int MAX_INTERVAL = 1000*60*5; // 5 mins - private static Timer timer; - // Map of userName to User - private final Map> userMap; - private final Map missMap; - private Clean clean; - protected Access access; -// private final static Permission teaser = new LocalPermission("***NoPERM****"); - - protected AbsUserCache(Access access, long cleanInterval, int highCount, int usageCount) { - this.access = access; - userMap = new ConcurrentHashMap>(); - missMap = new TreeMap(); - 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 cache) { - this.access = cache.access; - userMap = cache.userMap; - missMap = cache.missMap; - synchronized(AbsUserCache.class) { - if(cache.clean!=null && cache.clean.lur==null && this instanceof CachingLur) { - cache.clean.lur=(CachingLur)this; - } - } - } - - protected void setLur(CachingLur lur) { - if(clean!=null)clean.lur = lur; - - } - - protected void addUser(User user) { - userMap.put(user.principal.getName(), user); - } - - // Useful for looking up by WebToken, etc. - protected void addUser(String key, User 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 - */ - protected boolean addMiss(String key, byte[] bs) { - Miss miss = missMap.get(key); - if(miss==null) { - synchronized(missMap) { - missMap.put(key, new Miss(bs,clean==null?MIN_INTERVAL:clean.timeInterval)); - } - return true; - } - return miss.add(bs); - } - - protected Miss missed(String key) { - return missMap.get(key); - } - - protected User getUser(String userName) { - User u = userMap.get(userName); - if(u!=null) { - u.incCount(); - } - return u; - } - - protected User getUser(Principal principal) { - return getUser(principal.getName()); - } - - /** - * Removes User from the Cache - * @param user - */ - protected void remove(User 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() { - List rv = new ArrayList(); - for(User 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(); - } - } - - - - // Simple map of Group name to a set of User Names - // private Map> 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 perms; - - public DumpInfo(User 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. - * - * - */ - private final class Clean extends TimerTask { - private final Access access; - private CachingLur 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> al = new ArrayList>(userMap.values().size()); - al.addAll(0, userMap.values()); - long now = System.currentTimeMillis() + advance; - for(User user : al) { - ++total; - if(user.count>usageTriggerCount) { - // access.log(Level.AUDIT, "Checking Thread", new Date(now)); - boolean touched = false, removed=false; - if(user.principal instanceof CachedPrincipal) { - CachedPrincipal cp = (CachedPrincipal)user.principal; - if(cp.expires() < now) { - switch(cp.revalidate()) { - case INACCESSIBLE: - access.log(Level.AUDIT, "AAF Inaccessible. Keeping credentials"); - break; - case REVALIDATED: - user.resetCount(); - // access.log(Level.AUDIT, "CACHE revalidated credentials"); - touched = true; - break; - default: - user.resetCount(); - remove(user); - ++count; - removed = true; - break; - } - } - } - - // access.log(Level.AUDIT, "User Perm Expires", new Date(user.permExpires)); - if(!removed && lur!=null && user.permExpires<= now ) { - // access.log(Level.AUDIT, "Reloading"); - 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 keys = new ArrayList(missTotal); - keys.addAll(missMap.keySet()); - for(String key : keys) { - Miss m = missMap.get(key); - if(m!=null && m.timestamp0) { - 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()); - } - } - } - - public static class Miss { - private static final int MAX_TRIES = 3; - - long timestamp; - byte[][] array; - - private long timetolive; - - private int tries; - - public Miss(byte[] first, long timeInterval) { - array = new byte[MAX_TRIES][]; - array[0]=first; - timestamp = System.currentTimeMillis() + timeInterval; - this.timetolive = timeInterval; - tries = 1; - } - - public boolean mayContinue(byte[] bs) { - if(++tries > MAX_TRIES) return false; - for(byte[] a : array) { - if(a==null)return true; - if(equals(a,bs)) { - return false; - } - } - return true; - } - - public synchronized boolean add(byte[] bc) { - if(++tries>MAX_TRIES)return false; - timestamp = System.currentTimeMillis()+timetolive; - for(int i=0;i=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; - } - - // @Override - public int read(byte[] b) throws IOException { - return read(b,0,b.length); - } - - - // @Override - 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); -// System.out.println("Capacitor read " + count); - if(count<=0) { - capacitor.done(); - capacitor=null; // all done with buffer - } - if(count0) { // watch for -1 - count+=temp; - } else { - if(count<=0)count = temp; // must account for Stream coming back -1 - } - } - break; - } - } -// System.out.println("read reports " + count); - return count; - } - - // @Override - public long skip(long n) throws IOException { - long skipped = capacitor.skip(n); - if(skipped extends Lur { - public abstract void remove(String user); - public abstract Resp reload(User user); - public abstract void setDebug(String commaDelimIDsOrNull); - public abstract void clear(Principal p, StringBuilder sb); -} diff --git a/core/src/main/java/com/att/cadi/CadiException.java b/core/src/main/java/com/att/cadi/CadiException.java deleted file mode 100644 index 66b7b5b..0000000 --- a/core/src/main/java/com/att/cadi/CadiException.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -/** - * CADI Specific Exception - */ -public class CadiException extends Exception { - /** - * Generated ID - */ - private static final long serialVersionUID = -4180145363107742619L; - - public CadiException() { - super(); - } - - public CadiException(String message) { - super(message); - } - - public CadiException(Throwable cause) { - super(cause); - } - - public CadiException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/core/src/main/java/com/att/cadi/CadiWrap.java b/core/src/main/java/com/att/cadi/CadiWrap.java deleted file mode 100644 index 64c565f..0000000 --- a/core/src/main/java/com/att/cadi/CadiWrap.java +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -import com.att.cadi.Access.Level; -import com.att.cadi.filter.NullPermConverter; -import com.att.cadi.filter.PermConverter; -import com.att.cadi.lur.EpiLur; -import com.att.cadi.taf.TafResp; - - - -/** - * Inherit the HttpServletRequestWrapper, which calls methods of delegate it's created with, but - * overload the key security mechanisms with CADI mechanisms - * - * This works with mechanisms working strictly with HttpServletRequest (i.e. Servlet Filters) - * - * Specialty cases, i.e. Tomcat, which for their containers utilize their own mechanisms and Wrappers, you may - * need something similar. See AppServer specific code (i.e. tomcat) for these. - * - * - */ -public class CadiWrap extends HttpServletRequestWrapper implements HttpServletRequest, BasicCred { - private Principal 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,"(HttpRequest)",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 { - perm = pconv.convert(perm); - if(lur.fish(principal,lur.createPerm(perm))) { - access.log(Level.DEBUG,caller, principal.getName(), "has", perm); - return true; - } else { - access.log(Level.DEBUG,caller, principal.getName(), "does not have", perm); - 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 getPermissions(Principal p) { - List 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; - } -} diff --git a/core/src/main/java/com/att/cadi/Capacitor.java b/core/src/main/java/com/att/cadi/Capacitor.java deleted file mode 100644 index 73fd83c..0000000 --- a/core/src/main/java/com/att/cadi/Capacitor.java +++ /dev/null @@ -1,240 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.nio.ByteBuffer; -import java.util.ArrayList; - -/** - * Capacitor - * - * Storage mechanism for read data, specifically designed for InputStreams. - * - * The Standard BufferedInputStream requires a limit to be set for buffered reading, which is - * impractical for reading SOAP headers, which can be quite large. - * - */ -public class Capacitor { - private static final int DEFAULT_CHUNK = 256; - private ArrayList 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(idx0) { // 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(idx0) { - 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; - 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(idx15)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/core/src/main/java/com/att/cadi/CmdLine.java b/core/src/main/java/com/att/cadi/CmdLine.java deleted file mode 100644 index 89685e2..0000000 --- a/core/src/main/java/com/att/cadi/CmdLine.java +++ /dev/null @@ -1,356 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.NoSuchAlgorithmException; - -import com.att.cadi.util.Chmod; -import com.att.cadi.util.JsonOutputStream; - - - -/** - * A Class to run on command line to determine suitability of environment for certain TAFs. - * - * For instance, CSP supports services only in certain domains, and while dynamic host - * lookups on the machine work in most cases, sometimes, names and IPs are unexpected (and - * invalid) for CSP because of multiple NetworkInterfaces, etc - * - * - */ -public class CmdLine { - - /** - * @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]; - } 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() + '"'); - } -// . 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 reguritate 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 - && (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.encryptMD5asStringHex(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 salt = Integer.parseInt(args[2]); - 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.baseCrypt().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.baseCrypt().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,repeats; - do { - pass = Symm.randomGen(numDigits); - noLower=noUpper=noDigits=noSpecial=true; - repeats=false; - int c=-1,last; - for(int i=0;i=0x61 && c<=0x7A); - continue; - } - if(noUpper) { - noUpper=!(c>=0x41 && c<=0x5A); - continue; - } - if(noDigits) { - noDigits=!(c>=0x30 && c<=0x39); - continue; - } - if(noSpecial) { - noSpecial = "+!@#$%^&*(){}[]?:;,.".indexOf(c)<0; - continue; - } - - break; - } - } while(noLower || noUpper || noDigits || noSpecial || repeats); - 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 if("csptest".equalsIgnoreCase(args[0])) { - try { - System.out.println("CSP Compatibility test"); - - String hostName = InetAddress.getLocalHost().getCanonicalHostName(); - - System.out.println(" Your automatic hostname is reported as \"" + hostName + "\"\n"); - System.out.flush(); - return; - } catch (UnknownHostException e) { - e.printStackTrace(System.err); - } - } - } else { - System.out.println("Usage: java -jar ..."); - System.out.println(" keygen [] (Generates Key on file, or Std Out)"); - System.out.println(" digest (Encrypts to Key with \"keyfile\")"); - System.out.println(" passgen (Generate Password of given size)"); - System.out.println(" urlgen (Generate URL field of given size)"); - System.out.println(" csptest (Tests for CSP compatibility)"); - System.out.println(" encode64 (Encodes to Base64)"); - System.out.println(" decode64 (Decodes from Base64)"); - System.out.println(" encode64url (Encodes to Base64 URL charset)"); - System.out.println(" decode64url (Decodes from Base64 URL charset)"); - System.out.println(" sha256 (Digest String into SHA256 Hash)"); - System.out.println(" md5 (Digest String into MD5 Hash)"); - } - System.exit(1); - } - -} diff --git a/core/src/main/java/com/att/cadi/Connector.java b/core/src/main/java/com/att/cadi/Connector.java deleted file mode 100644 index ab96010..0000000 --- a/core/src/main/java/com/att/cadi/Connector.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -public interface Connector { - public Lur newLur() throws CadiException; -} diff --git a/core/src/main/java/com/att/cadi/CredVal.java b/core/src/main/java/com/att/cadi/CredVal.java deleted file mode 100644 index 4fe0a28..0000000 --- a/core/src/main/java/com/att/cadi/CredVal.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -/** - * UserPass - * - * The essential interface required by BasicAuth to determine if a given User/Password combination is - * valid. This is done as an interface. - * - */ -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); -} diff --git a/core/src/main/java/com/att/cadi/GetCred.java b/core/src/main/java/com/att/cadi/GetCred.java deleted file mode 100644 index d2c99f2..0000000 --- a/core/src/main/java/com/att/cadi/GetCred.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -public interface GetCred { - byte[] getCred(); -} diff --git a/core/src/main/java/com/att/cadi/Hash.java b/core/src/main/java/com/att/cadi/Hash.java deleted file mode 100644 index b4e114f..0000000 --- a/core/src/main/java/com/att/cadi/Hash.java +++ /dev/null @@ -1,202 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.nio.ByteBuffer; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class Hash { - private static char hexDigit[] = "0123456789abcdef".toCharArray(); - -///////////////////////////////// -// MD5 -///////////////////////////////// - /** - * Encrypt MD5 from Byte Array to Byte Array - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - public static byte[] encryptMD5 (byte[] input) throws NoSuchAlgorithmException { - 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[] encryptMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException { - 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 encryptMD5asStringHex(String input) throws NoSuchAlgorithmException { - byte[] output = encryptMD5(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 { - 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 { - 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 { - byte[] output = hashSHA256(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: 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()); - byte[] output = Hash.hashSHA256(bb.array()); - StringBuilder sb = new StringBuilder("0x"); - for (byte b : output) { - sb.append(hexDigit[(b >> 4) & 0x0f]); - sb.append(hexDigit[b & 0x0f]); - } - return sb.toString(); - } - - /** - * 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> 4) & 0x0f]); - sb.append(hexDigit[b & 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=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; - } - -} diff --git a/core/src/main/java/com/att/cadi/Locator.java b/core/src/main/java/com/att/cadi/Locator.java deleted file mode 100644 index ab1a7f9..0000000 --- a/core/src/main/java/com/att/cadi/Locator.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -public interface Locator { - 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/core/src/main/java/com/att/cadi/LocatorException.java b/core/src/main/java/com/att/cadi/LocatorException.java deleted file mode 100644 index 9c3b804..0000000 --- a/core/src/main/java/com/att/cadi/LocatorException.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -public class LocatorException extends Exception { - /** - * - */ - private static final long serialVersionUID = -4267929804321134469L; - - public LocatorException(String arg0) { - super(arg0); - } - - public LocatorException(Throwable arg0) { - super(arg0); - } - - public LocatorException(String arg0, Throwable arg1) { - super(arg0, arg1); - } - - public LocatorException(CharSequence cs) { - super(cs.toString()); - } - -} diff --git a/core/src/main/java/com/att/cadi/Lur.java b/core/src/main/java/com/att/cadi/Lur.java deleted file mode 100644 index d8ae6a3..0000000 --- a/core/src/main/java/com/att/cadi/Lur.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.security.Principal; -import java.util.List; - - - -/** - * LUR: Local User Registry - * - * Concept by Robert Garskof, Implementation by Jonathan Gathman - * - * Where we can keep local copies of users and roles for faster Authorization when asked. - * - * Note: Author cannot resist the mental image of using a Fishing Lure to this LUR pattern - * - * - */ -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); - - /** - * 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 permissions); - - /** - * 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); - - /** - * What domain of User does this LUR support? (used to avoid asking when not possible) - * - * @param bait - * @return - */ - public boolean supports(String userName); - - /** - * Clear: Clear any Caching, if exists - */ - public void clear(Principal p, StringBuilder report); -} diff --git a/core/src/main/java/com/att/cadi/Permission.java b/core/src/main/java/com/att/cadi/Permission.java deleted file mode 100644 index adb80a1..0000000 --- a/core/src/main/java/com/att/cadi/Permission.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -public interface Permission { - public String permType(); - public String getKey(); - public boolean match(Permission p); -} diff --git a/core/src/main/java/com/att/cadi/PropAccess.java b/core/src/main/java/com/att/cadi/PropAccess.java deleted file mode 100644 index d7c9d99..0000000 --- a/core/src/main/java/com/att/cadi/PropAccess.java +++ /dev/null @@ -1,320 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; - -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfo; - -public class PropAccess implements Access { - private static final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - public static Level DEFAULT = Level.AUDIT; - - private Symm symm; - private int level; - private Properties props; - private List recursionProtection = null; - private PrintStream out; - - private String name; - - public PropAccess() { - out=System.out; - init(null); - } - - /** - * This Constructor soley exists to instantiate Servlet Context Based Logging that will call "init" later. - * @param sc - */ - protected PropAccess(Object o) { - out=System.out; - props = new Properties(); - } - - public PropAccess(String ... args) { - this(System.out,args); - } - - public PropAccess(PrintStream ps, String[] args) { - out=ps==null?System.out:ps; - 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); - } - - public PropAccess(Properties p) { - this(System.out,p); - } - - public PropAccess(PrintStream ps, Properties p) { - out=ps==null?System.out:ps; - init(p); - } - - 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 es : System.getProperties().entrySet()) { - String key = es.getKey().toString(); - for(String start : new String[] {"cadi_","aaf_","cm_","csp_"}) { - 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) { - symm = Symm.obtain(this); - } - - name = props.getProperty(Config.CADI_LOGNAME, name); - - // 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); - } - } - - private void load(String cadi_prop_files) { - String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); - - if(cadi_prop_files!=null) { - int prev = 0, end = cadi_prop_files.length(); - int idx; - String filename; - while(prev(); - 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; - } - } - // Reset Symm if Keyfile Changes: - String newKeyFile = props.getProperty(Config.CADI_KEYFILE); - if((prevKeyFile==null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) { - symm = Symm.obtain(this); - 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); - } - } - } - - @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)) { - StringBuilder sb = buildMsg(level, elements); - out.println(sb); - out.flush(); - } - } - - protected StringBuilder buildMsg(Level level, Object[] elements) { - StringBuilder sb = new StringBuilder(iso8601.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 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 boolean willLog(Level level) { - return level.inMask(this.level); - } - - @Override - public ClassLoader classLoader() { - return ClassLoader.getSystemClassLoader(); - } - - @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); - } - - ////////////////// - // Additional - ////////////////// - public String getProperty(String tag) { - return props.getProperty(tag); - } - - - 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 - symm = Symm.obtain(this); - } - } - } - - public Properties getDME2Properties() { - return Config.getDME2Props(this); - } - -} diff --git a/core/src/main/java/com/att/cadi/Revalidator.java b/core/src/main/java/com/att/cadi/Revalidator.java deleted file mode 100644 index 5d492aa..0000000 --- a/core/src/main/java/com/att/cadi/Revalidator.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -public interface Revalidator { - /** - * Re-Validate Credential - * - * @param prin - * @return - */ - public CachedPrincipal.Resp revalidate(TRANS trans, CachedPrincipal prin); - -} diff --git a/core/src/main/java/com/att/cadi/SLF4JAccess.java b/core/src/main/java/com/att/cadi/SLF4JAccess.java deleted file mode 100644 index b222e35..0000000 --- a/core/src/main/java/com/att/cadi/SLF4JAccess.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SLF4JAccess extends PropAccess { - private static final Logger slf4j = LoggerFactory.getLogger("AAF"); - - public SLF4JAccess(final Properties initial) throws CadiException { - super(initial); - } - - public void log(Level level, Object... elements) { - switch(level) { - case AUDIT: - slf4j.info(msg(elements).toString()); - break; - case DEBUG: - slf4j.debug(msg(elements).toString()); - break; - case ERROR: - slf4j.error(msg(elements).toString()); - break; - case INFO: - slf4j.info(msg(elements).toString()); - break; - case INIT: - slf4j.info(msg(elements).toString()); - break; - case WARN: - slf4j.warn(msg(elements).toString()); - break; - default: - slf4j.info(msg(elements).toString()); - break; - } - } - - /* (non-Javadoc) - * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) - */ - @Override - public boolean willLog(Level level) { - switch(level) { - case DEBUG: - return slf4j.isDebugEnabled(); - case ERROR: - return slf4j.isErrorEnabled(); - case WARN: - return slf4j.isWarnEnabled(); -// case INFO: -// case INIT: -// case AUDIT: - default: - return slf4j.isInfoEnabled(); - } - } - - private StringBuilder msg(Object ... elements) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for(Object o : elements) { - if(first) first = false; - else { - sb.append(' '); - } - sb.append(o.toString()); - } - return sb; - } - - public void log(Exception e, Object... elements) { - slf4j.error(msg(elements).toString(),e); - } - -} diff --git a/core/src/main/java/com/att/cadi/SecuritySetter.java b/core/src/main/java/com/att/cadi/SecuritySetter.java deleted file mode 100644 index 295148f..0000000 --- a/core/src/main/java/com/att/cadi/SecuritySetter.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -/** - * Apply any particular security mechanism - * - * This allows the definition of various mechanisms involved outside of DRcli jars - * - * - */ -public interface SecuritySetter { - 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/core/src/main/java/com/att/cadi/ServletContextAccess.java b/core/src/main/java/com/att/cadi/ServletContextAccess.java deleted file mode 100644 index 2d1cfa1..0000000 --- a/core/src/main/java/com/att/cadi/ServletContextAccess.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; -import java.util.Enumeration; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; - -import com.att.cadi.config.Config; - -public class ServletContextAccess extends PropAccess { - - private ServletContext context; - - public ServletContextAccess(FilterConfig filterConfig) { - super(filterConfig); // protected contstructor... 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()); - Config.getDME2Props(this); - } - - /* (non-Javadoc) - * @see com.att.cadi.PropAccess#log(com.att.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 com.att.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; - } -} diff --git a/core/src/main/java/com/att/cadi/StrLur.java b/core/src/main/java/com/att/cadi/StrLur.java deleted file mode 100644 index f191203..0000000 --- a/core/src/main/java/com/att/cadi/StrLur.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.util.List; - - - -/** - * StrLUR: Implements fish with String, skipping the need to be a Principal where it doesn't make sense. - * - * - */ -public interface StrLur extends Lur { - /** - * 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(String 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(String bait, List permissions); -} diff --git a/core/src/main/java/com/att/cadi/Symm.java b/core/src/main/java/com/att/cadi/Symm.java deleted file mode 100644 index 1504c2d..0000000 --- a/core/src/main/java/com/att/cadi/Symm.java +++ /dev/null @@ -1,811 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Random; - -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; - -import com.att.cadi.Access.Level; -import com.att.cadi.config.Config; - -/** - * Key Conversion, primarily "Base64" - * - * Base64 is required for "Basic Authorization", which is an important part of the overall CADI Package. - * - * Note: This author found that there is not a "standard" library for Base64 conversion within Java. - * The source code implementations available elsewhere were surprisingly inefficient, requiring, for - * instance, multiple string creation, on a transaction pass. Integrating other packages that might be - * efficient enough would put undue Jar File Dependencies given this Framework should have none-but-Java - * dependencies. - * - * The essential algorithm is good for a symmetrical key system, as Base64 is really just - * a symmetrical key that everyone knows the values. - * - * This code is quite fast, taking about .016 ms for encrypting, decrypting and even .08 for key - * generation. The speed quality, especially of key generation makes this a candidate for a short term token - * used for identity. - * - * It may be used to easily avoid placing Clear-Text passwords in configurations, etc. and contains - * supporting functions such as 2048 keyfile generation (see keygen). This keyfile should, of course, - * be set to "400" (Unix) and protected as any other mechanism requires. - * - * However, this algorithm has not been tested against hackers. Until such a time, utilize more tested - * packages to protect Data, especially sensitive data at rest (long term). - * - */ -public class Symm { - private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; - public static final String ENC = "enc:"; - 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; - //Note: AES Encryption is not Thread Safe. It is Synchronized - private static 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); - - /** - * 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(); - - - - /** - * 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 la = new ArrayList(); - for(int i=0;icodeset.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; - } - - /* - * Note: AES Encryption is NOT thread-safe. Must surround entire use with synchronized - */ - private synchronized void exec(AESExec exec) throws IOException { - if(aes == null) { - try { - byte[] bytes = new byte[AES.AES_KEY_SIZE/8]; - int offset = (Math.abs(codeset[0])+47)%(codeset.length-bytes.length); - for(int i=0;i=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 { - is.skip(skip); - decode(is,os); - } - - /** - * 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(); - } - - /** - * Interface to allow this class to choose which algorithm to find index of character in Key - * - */ - private interface Convert { - public int convert(int read) throws IOException; - } - - /** - * Ordered uses a range of orders to compare against, rather than requiring the investigation - * of every character needed. - * - */ - private static final class Ordered implements Convert { - private int[][] range; - public Ordered(int[][] range) { - this.range = range; - } - public int convert(int read) throws IOException { - switch(read) { - case -1: - case '=': - case '\n': - return -1; - } - for(int i=0;i= range[i][0] && read<=range[i][1]) { - return read-range[i][2]; - } - } - throw new IOException("Unacceptable Character in Stream"); - } - } - - /** - * Unordered, i.e. the key is purposely randomized, simply has to investigate each character - * until we find a match. - * - */ - 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': - return -1; - } - for(int i=0;i=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=0;--j) { - if(seq[j]==0) { - seq[j]=codeset[filled]; - --filled; - break; - } - } - right = true; - } - } - return new Symm(seq,this); - } -} diff --git a/core/src/main/java/com/att/cadi/Taf.java b/core/src/main/java/com/att/cadi/Taf.java deleted file mode 100644 index 4017866..0000000 --- a/core/src/main/java/com/att/cadi/Taf.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import com.att.cadi.taf.TafResp; - - -/** - * TAF - Transmutative Assertion Framework. - * - * This main Interface embodies the essential of the assertion, where a number of different TAFs might be used to authenticate - * and that authentication to be recognized through other elements. - * - * Concept by Robert Garskof. Implemented by Jonathan Gathman - * - * - */ -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. JG 10/18/2012 - * - * @param lifeForm - * @param info - * @return - */ - public TafResp validate(LifeForm reading, String ... info); - -} diff --git a/core/src/main/java/com/att/cadi/Transmutate.java b/core/src/main/java/com/att/cadi/Transmutate.java deleted file mode 100644 index 1d6ff6f..0000000 --- a/core/src/main/java/com/att/cadi/Transmutate.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.security.Principal; - -/** - * The unique element of TAF is that we establish the relationship/mechanism to mutate the Principal derived from - * one Authentication mechanism into a trustable Principal of another. The mechanism needs to be decided by system - * trusting. - * - * The Generic "T" is used so that the code used will be very specific for the implementation, enforced by Compiler - * - * This interface will allow differences of trusting Transmutation of Authentication - * - */ -public interface Transmutate { - /** - * 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/core/src/main/java/com/att/cadi/TrustChecker.java b/core/src/main/java/com/att/cadi/TrustChecker.java deleted file mode 100644 index 60b9a17..0000000 --- a/core/src/main/java/com/att/cadi/TrustChecker.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - - -import javax.servlet.http.HttpServletRequest; - -import com.att.cadi.taf.TafResp; - -/** - * Change to another Principal based on Trust of caller and User Chain (if desired) - * - * - */ -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; - } - - @Override - public void setLur(Lur lur) { - } - }; - - public void setLur(Lur lur); -} diff --git a/core/src/main/java/com/att/cadi/User.java b/core/src/main/java/com/att/cadi/User.java deleted file mode 100644 index bde3488..0000000 --- a/core/src/main/java/com/att/cadi/User.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.security.Principal; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import com.att.cadi.lur.LocalPermission; - -/** - * Class to hold info from the User Perspective. - * - * - */ -public final class User { - private static Map NULL_MAP = new HashMap(); - public Principal principal; - Map 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; - 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; - perms = NULL_MAP; - expireInterval = Math.max(expireInterval, 0); // avoid < 1 - interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); - permExpires = 0; - count = 0; - } - - 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.values().size()==0; - } - - public void setNoPerms() { - perms=NULL_MAP; - permExpires = System.currentTimeMillis() + interval; - } - - public boolean permsUnloaded() { - return perms==null; - } - - public synchronized void incCount() { - ++count; - } - - public synchronized void resetCount() { - count=0; - } - - public Map newMap() { - return new ConcurrentHashMap(); - } - - public void add(LocalPermission permission) { - if(perms==NULL_MAP)perms=newMap(); - perms.put(permission.getKey(),permission); - } - - public void add(Map newMap, PERM permission) { - newMap.put(permission.getKey(),permission); - } - - public void setMap(Map newMap) { - perms = newMap; - } - - public boolean contains(Permission perm) { - for (Permission p : perms.values()) { - if (p.match(perm)) return true; - } - return false; - } - - public void copyPermsTo(List 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(); - } - -} diff --git a/core/src/main/java/com/att/cadi/UserChain.java b/core/src/main/java/com/att/cadi/UserChain.java deleted file mode 100644 index df493c5..0000000 --- a/core/src/main/java/com/att/cadi/UserChain.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -/** - * Interface to add a User Chain String to Principal - * - * - * - * Where - * APP is name suitable for Logging (i.e. official App Acronym) - * ID is official User or MechID, best if includes Identity Source (i.e. ab1234@csp.att.com) - * Protocol is the Security protocol, - * - * Format:::[:AS][,::]* - * - * - * - */ -public interface UserChain { - public enum Protocol {BasicAuth,Cookie,Cert,OAuth}; - public String userChain(); -} diff --git a/core/src/main/java/com/att/cadi/config/Config.java b/core/src/main/java/com/att/cadi/config/Config.java deleted file mode 100644 index ada6117..0000000 --- a/core/src/main/java/com/att/cadi/config/Config.java +++ /dev/null @@ -1,814 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.URI; -import java.net.UnknownHostException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.TimerTask; - -import com.att.cadi.AbsUserCache; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CachingLur; -import com.att.cadi.CadiException; -import com.att.cadi.CredVal; -import com.att.cadi.Locator; -import com.att.cadi.Lur; -import com.att.cadi.PropAccess; -import com.att.cadi.Symm; -import com.att.cadi.TrustChecker; -import com.att.cadi.lur.EpiLur; -import com.att.cadi.lur.LocalLur; -import com.att.cadi.lur.NullLur; -import com.att.cadi.taf.HttpEpiTaf; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.basic.BasicHttpTaf; -import com.att.cadi.taf.cert.X509Taf; -import com.att.cadi.taf.dos.DenialOfServiceTaf; - -/** - * Create a Consistent Configuration mechanism, even when configuration styles are as vastly different as - * Properties vs JavaBeans vs FilterConfigs... - * - * - */ -public class Config { - - private static final String HIDE_PASS = "***************"; - - 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_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_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 CSP_DOMAIN = "csp_domain"; - public static final String CSP_HOSTNAME = "csp_hostname"; - public static final String CSP_DEVL_LOCALHOST = "csp_devl_localhost"; - public static final String CSP_USER_HEADER = "CSP_USER"; - public static final String CSP_SYSTEMS_CONF = "CSPSystems.conf"; - public static final String CSP_SYSTEMS_CONF_FILE = "csp_systems_conf_file"; - - - public static final String TGUARD_ENV="tguard_env"; - public static final String TGUARD_DOMAIN = "tguard_domain"; - public static final String TGUARD_TIMEOUT = "tguard_timeout"; - public static final String TGUARD_TIMEOUT_DEF = "5000"; - public static final String TGUARD_CERTS = "tguard_certs"; // comma delimited SHA-256 finger prints -// public static final String TGUARD_DEVL_LOCALHOST = "tguard_devl_localhost"; -// public static final String TGUARD_USER_HEADER = "TGUARD_USER"; - - 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 AAF_ENV = "aaf_env"; - public static final String AAF_ROOT_NS = "aaf_root_ns"; - public static final String AAF_ROOT_COMPANY = "aaf_root_company"; - public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration - public static final String AAF_MECHID = "aaf_id"; - public static final String AAF_MECHPASS = "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_READ_TIMEOUT = "aaf_timeout"; - public static final String AAF_READ_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_DEPLOYED_VERSION = "DEPLOYED_VERSION"; - 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 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"; - - public static final String AFT_DME2_TRUSTSTORE_PASSWORD = "AFT_DME2_TRUSTSTORE_PASSWORD"; - public static final String AFT_DME2_TRUSTSTORE = "AFT_DME2_TRUSTSTORE"; - public static final String AFT_DME2_KEYSTORE_PASSWORD = "AFT_DME2_KEYSTORE_PASSWORD"; - public static final String AFT_DME2_KEY_PASSWORD = "AFT_DME2_KEY_PASSWORD"; - public static final String AFT_DME2_KEYSTORE = "AFT_DME2_KEYSTORE"; - public static final String AFT_DME2_SSL_TRUST_ALL = "AFT_DME2_SSL_TRUST_ALL"; - public static final String AFT_DME2_SSL_INCLUDE_PROTOCOLS = "AFT_DME2_SSL_INCLUDE_PROTOCOLS"; - - - // DME2 Client. First property must be set to "false", and the others set in order to use SSL Client - public static final String AFT_DME2_CLIENT_IGNORE_SSL_CONFIG="AFT_DME2_CLIENT_IGNORE_SSL_CONFIG"; - public static final String AFT_DME2_CLIENT_KEYSTORE = "AFT_DME2_CLIENT_KEYSTORE"; - public static final String AFT_DME2_CLIENT_KEYSTORE_PASSWORD = "AFT_DME2_CLIENT_KEYSTORE_PASSWORD"; - public static final String AFT_DME2_CLIENT_TRUSTSTORE = "AFT_DME2_CLIENT_TRUSTSTORE"; - public static final String AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD = "AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD"; - public static final String AFT_DME2_CLIENT_SSL_CERT_ALIAS = "AFT_DME2_CLIENT_SSL_CERT_ALIAS"; - public static final String AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS = "AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS"; - - - // 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"; - public static final String AAF_DOMAIN_SUPPORT_DEF = ".org"; - - - public static void setDefaultRealm(Access access) throws CadiException { - try { - boolean hasCSP; - try { - Class.forName("com.att.cadi.taf.csp.CSPTaf"); - hasCSP=true; - } catch(ClassNotFoundException e) { - hasCSP = logProp(access,Config.CSP_DOMAIN, null)!=null; - } - defaultRealm = logProp(access,Config.AAF_DEFAULT_REALM, - hasCSP?"csp.att.com": - logProp(access,Config.BASIC_REALM, - logProp(access,HOSTNAME,InetAddress.getLocalHost().getHostName()) - ) - ); - } catch (UnknownHostException e) { - //defaultRealm="none"; - } - } - - - public static HttpTaf configHttpTaf(Access access, TrustChecker tc, CredVal up, Lur lur, Object ... additionalTafLurs) throws CadiException { - ///////////////////////////////////////////////////// - // Setup AAFCon for any following - ///////////////////////////////////////////////////// - Object aafcon = null; - if(lur != null) { - Field f = null; - try { - f = lur.getClass().getField("aaf"); - aafcon = f.get(lur); - } catch (Exception nsfe) { - } - } - // IMPORTANT! Don't attempt to load AAF Connector if there is no AAF URL - String aafURL = access.getProperty(AAF_URL,null); - if(aafcon==null && aafURL!=null) { - aafcon = loadAAFConnector(access, 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 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 LocalHost - ///////////////////////////////////////////////////// - - String truststore = logProp(access, CADI_TRUSTSTORE, access.getProperty("AFT_DME2_TRUSTSTORE", null)); - if(truststore!=null) { - String truststore_pwd = access.getProperty(CADI_TRUSTSTORE_PASSWORD, access.getProperty("AFT_DME2_TRUSTSTORE_PASSWORD",null)); - if(truststore_pwd!=null) { - if(truststore_pwd.startsWith(Symm.ENC)) { - try { - truststore_pwd = access.decrypt(truststore_pwd,false); - } catch (IOException e) { - throw new CadiException(CADI_TRUSTSTORE_PASSWORD + " cannot be decrypted",e); - } - } - try { - htlist.add(new X509Taf(access,lur)); - access.log(Level.INIT,"Certificate Authorization enabled"); - } catch (SecurityException e) { - access.log(Level.INIT,"AAFListedCertIdentity cannot be instantiated. Certificate Authorization is now disabled",e); - } catch (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) - ///////////////////////////////////////////////////// - String basic_realm = logProp(access, BASIC_REALM,null); - boolean basic_warn = "TRUE".equals(access.getProperty(BASIC_WARN,"FALSE")); - if(basic_realm!=null && up!=null) { - access.log(Level.INIT,"Basic Authorization is enabled using realm",basic_realm); - // Allow warning about insecure channel to be turned off - if(!basic_warn)access.log(Level.INIT,"WARNING! The basic_warn property has been set to false.", - " There will be no additional warning if Basic Auth is used on an insecure channel" - ); - String aafCleanup = logProp(access, AAF_USER_EXPIRES,AAF_USER_EXPIRES_DEF); // Default is 10 mins - long userExp = Long.parseLong(aafCleanup); - - htlist.add(new BasicHttpTaf(access, up, basic_realm, userExp, basic_warn)); - } else { - access.log(Level.INIT,"Local Basic Authorization is disabled. Enable by setting basic_realm="); - } - - ///////////////////////////////////////////////////// - // Configure AAF Driven Basic Auth - ///////////////////////////////////////////////////// - boolean getRemoteAAF = true; - if(additionalTafLurs!=null) { - for(Object o : additionalTafLurs) { - if(o.getClass().getSimpleName().equals("DirectAAFLur")) { - getRemoteAAF = false; - break; - } - } - } - HttpTaf aaftaf=null; - if(getRemoteAAF) { - 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 defName = aafURL.contains("version=2.0")?"com.att.cadi.aaf.v2_0.AAFTaf":""; - String aafTafClassName = logProp(access, AAF_TAF_CLASS,defName); - // Only 2.0 available at this time - if("com.att.cadi.aaf.v2_0.AAFTaf".equals(aafTafClassName)) { - try { - Class aafTafClass = loadClass(access,aafTafClassName); - Class aafConClass = loadClass(access,"com.att.cadi.aaf.v2_0.AAFCon"); - - Constructor cstr = aafTafClass.getConstructor(aafConClass,boolean.class,AbsUserCache.class); - if(cstr!=null) { - aaftaf = (HttpTaf)cstr.newInstance(aafcon,basic_warn,lur); - 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 - } - } - } catch(Exception e) { - access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured"); - } - } - } - } - - - String alias = logProp(access, CADI_ALIAS,null); - - ///////////////////////////////////////////////////// - // Configure tGuard... (AT&T Client Repo) - ///////////////////////////////////////////////////// - // TGUARD Environment, translated to any other remote Environment validation mechanism... - String tGuard_domain = logProp(access, TGUARD_DOMAIN,null); - String tGuard_env = logProp(access, TGUARD_ENV, null); - - if(!("PROD".equals(tGuard_env) || "STAGE".equals(tGuard_env))) { - access.log(Level.INIT, "tGuard Authorization is disabled. Enable by setting", TGUARD_ENV, "to \"PROD\" or \"STAGE\""); - } else if(tGuard_domain==null) { - access.log(Level.INIT,TGUARD_DOMAIN + " must be set: tGuard Authorization is disabled."); - } else if(alias == null) { - access.log(Level.INIT,CADI_ALIAS + " must be set: tGuard Authorization is disabled."); - } else { - try { - Class tGuardClass = loadClass(access,"com.att.cadi.tguard.TGuardHttpTaf"); - if(aaftaf!=null) { - Constructor tGuardCnst = tGuardClass.getConstructor(new Class[]{Access.class, AbsUserCache.class}); - htlist.add((HttpTaf)tGuardCnst.newInstance(new Object[] {access,aaftaf})); - access.log(Level.INIT,"tGuard Authorization is enabled on",tGuard_env,"on the",tGuard_domain," tGuard Domain"); - } else { - Constructor tGuardCnst = tGuardClass.getConstructor(new Class[]{Access.class, int.class, int.class, int.class}); - htlist.add((HttpTaf)tGuardCnst.newInstance(new Object[] { - access, - Integer.parseInt(logProp(access, AAF_CLEAN_INTERVAL,AAF_CLEAN_INTERVAL_DEF)), - Integer.parseInt(logProp(access, AAF_HIGH_COUNT, AAF_HIGH_COUNT_DEF)), - Integer.parseInt(logProp(access, AAF_REFRESH_TRIGGER_COUNT, AAF_REFRESH_TRIGGER_COUNT_DEF)) - })); - access.log(Level.INIT,"tGuard Authorization is enabled on",tGuard_env,"on the",tGuard_domain," tGuard Domain"); - } - } catch(Exception e) { - access.log(e, Level.INIT,"tGuard Class cannot be loaded: tGuard Authorization is disabled."); - } - } - - ///////////////////////////////////////////////////// - // 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 HttpTaf) { - htlist.add((HttpTaf)additional); - access.log(Level.INIT,additional); - } - } - } - - ///////////////////////////////////////////////////// - // 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 locator = loadLocator(access, logProp(access, CADI_LOGINPAGE_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 set"); - } else { - access.log(Level.INIT,tag,"is set to",rv); - } - return rv; - } - - public static Lur configLur(Access access, Object ... additionalTafLurs) throws CadiException { - List 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; - lurs.add(ll = new LocalLur(access, users, groups)); // note b64==null is ok.. just means no encryption. - - 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 AAF Lur (if any) - ///////////////////////////////////////////////////// - String aafURL = logProp(access,AAF_URL,null); // Trigger Property - String aaf_env = access.getProperty(AAF_ENV,null); - if(aaf_env == 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) { - aaf_env = aafURL.substring(ec, slash); - ((PropAccess)access).setProperty(AAF_ENV, aaf_env); - access.printf(Level.INIT, "Setting aaf_env to %s from aaf_url value",aaf_env); - } - } - } - - 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,"com.att.cadi.aaf.v2_0.AAFLurPerm"); - ////////////AAF Lur 2.0 ///////////// - if(aafLurClassStr.startsWith("com.att.cadi.aaf.v2_0")) { - try { - Object aafcon = loadAAFConnector(access, aafURL); - if(aafcon==null) { - access.log(Level.INIT,"AAF LUR class,",aafLurClassStr,"cannot be constructed without valid AAFCon object."); - } else { - Class aafAbsAAFCon = loadClass(access, "com.att.cadi.aaf.v2_0.AAFCon"); - 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 final String COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2 = "com.att.cadi.aaf.v2_0.AAFConDME2"; - private static final String COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP = "com.att.cadi.aaf.v2_0.AAFConHttp"; - public static Object loadAAFConnector(Access access, String aafURL) { - Object aafcon = null; - Class aafConClass = null; - - try { - if(aafURL!=null) { - String aafConnector = access.getProperty(AAF_CONNECTOR_CLASS, COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP); - if(COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2.equals(aafConnector) || aafURL.contains("/service=")) { - aafConClass = loadClass(access, COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2); - if(aafConClass!=null) { - Constructor cons = aafConClass.getConstructor(PropAccess.class); - aafcon = cons.newInstance(access); - } else { - access.log(Level.ERROR, "URL contains '/service=', which requires DME2"); - } - } else if(COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP.equals(aafConnector)) { - aafConClass = loadClass(access, COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP); - for(Constructor c : aafConClass.getConstructors()) { - List lo = new ArrayList(); - for(Class pc : c.getParameterTypes()) { - if(pc.equals(PropAccess.class)) { - lo.add(access); - } else if(pc.equals(Locator.class)) { - lo.add(loadLocator(access, aafURL)); - } else { - continue; - } - } - 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_MECHID, null); - String pass = access.getProperty(Config.AAF_MECHPASS, null); - if(mechid!=null && pass!=null) { - try { - Method basicAuth = aafConClass.getMethod("basicAuth", String.class, String.class); - basicAuth.invoke(aafcon, mechid,pass); - } catch (NoSuchMethodException 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) { - try { - cls = access.getClass().getClassLoader().loadClass(className); - } catch (ClassNotFoundException cnfe2) { - // just return null - } - } - return cls; - } - - @SuppressWarnings("unchecked") - public static Locator loadLocator(Access access, String url) { - Locator locator = null; - if(url==null) { - access.log(Level.INIT,"No URL for AAF Login Page. Disabled"); - } else { - if(url.contains("DME2RESOLVE")) { - try { - Class lcls = loadClass(access,"com.att.cadi.locator.DME2Locator"); - Class dmcls = loadClass(access,"com.att.aft.dme2.api.DME2Manager"); - Constructor cnst = lcls.getConstructor(new Class[] {Access.class,dmcls,String.class}); - locator = (Locator)cnst.newInstance(new Object[] {access,null,url}); - access.log(Level.INFO, "DME2Locator enabled with " + url); - } catch (Exception e) { - access.log(Level.INIT,"AAF Login Page accessed by " + url + " requires DME2. It is now disabled",e); - } - } else { - try { - Class cls = loadClass(access,"com.att.cadi.locator.PropertyLocator"); - Constructor cnst = cls.getConstructor(new Class[] {String.class}); - locator = (Locator)cnst.newInstance(new Object[] {url}); - access.log(Level.INFO, "PropertyLocator enabled with " + url); - } catch (Exception e) { - access.log(Level.INIT,"AAF Login Page accessed by " + url + " requires PropertyLocator. It is now disabled",e); - } - } - } - return locator; - } - - /* - * DME2 can only read Passwords as clear text properties. Leaving in "System Properties" un-encrypted exposes these passwords - */ - public static class PasswordRemoval extends TimerTask { - private Access access; - - private final List pws; - - public PasswordRemoval(Access access) { - this.access = access; - pws = new ArrayList(); - } - - @Override - public void run() { - for(String key:pws) { - access.log(Level.INIT, "Scrubbing " + key); - System.clearProperty(key); - } - } - public void add(String key) { - pws.add(key); - } - } - - private static final String Y = "Y"; - - private static String[][] CONVERTER_STRINGS=new String[][] { - {AFT_DME2_KEYSTORE,CADI_KEYSTORE,null}, - {AFT_DME2_KEYSTORE_PASSWORD,CADI_KEYSTORE_PASSWORD,null}, - {AFT_DME2_KEY_PASSWORD,CADI_KEY_PASSWORD,null}, - {AFT_DME2_TRUSTSTORE,CADI_TRUSTSTORE,null}, - {AFT_DME2_TRUSTSTORE_PASSWORD,CADI_TRUSTSTORE_PASSWORD,null}, - {AFT_DME2_CLIENT_KEYSTORE,CADI_KEYSTORE,null}, - {AFT_DME2_CLIENT_KEYSTORE_PASSWORD,CADI_KEYSTORE_PASSWORD,null}, - {AFT_DME2_CLIENT_TRUSTSTORE,CADI_TRUSTSTORE,null}, - {AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD,CADI_TRUSTSTORE_PASSWORD,null}, - {AFT_DME2_CLIENT_SSL_CERT_ALIAS,CADI_ALIAS,null}, - {AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS,CADI_PROTOCOLS,null}, - {"AFT_DME2_HOSTNAME",HOSTNAME,null}, - {"AFT_LATITUDE",null,Y}, - {"AFT_LONGITUDE",null,Y}, - {"AFT_ENVIRONMENT",null,Y}, - {"SCLD_PLATFORM",null,Y}, - {"DME2_EP_REGISTRY_CLASS",null,Y},// for Developer local access - {"AFT_DME2_EP_REGISTRY_FS_DIR",null,Y}, - {"DME2.DEBUG",null,null}, - {"AFT_DME2_HTTP_EXCHANGE_TRACE_ON",null,null}, - {"AFT_DME2_SSL_ENABLE",null,null}, - {"AFT_DME2_SSL_WANT_CLIENT_AUTH",null,null}, - {AFT_DME2_SSL_INCLUDE_PROTOCOLS,CADI_PROTOCOLS,null}, - {"AFT_DME2_SSL_VALIDATE_CERTS",null,null}, - {AFT_DME2_CLIENT_IGNORE_SSL_CONFIG,null,null}, - {"https.protocols",CADI_PROTOCOLS,Y}, - }; - - - - public static Properties getDME2Props(PropAccess access) { - Properties dprops = new Properties(); - String value = null; - boolean reqClientConfig = false; - for(String[] row : CONVERTER_STRINGS) { - value = access.getProperty(row[0],null); - if(value==null) { - value = System.getProperty(row[0]); - if(value==null && row[1]!=null) { - value = access.getProperty(row[1],null); - if(value == null) { - value = System.getProperty(row[1]); - } - } - } - if(value!=null) { - if(row[0].contains("_SSL_")) { - reqClientConfig = true; - } - if(row[0].startsWith("AFT") || row[0].startsWith("SCLD") || row[0].contains("DME2")) { - if(value.startsWith("enc:")) { - try { - value = access.decrypt(value, true); - } catch (IOException e) { - access.log(Level.ERROR, e); - } - System.setProperty(row[0], value); - } else if(Y.equals(row[2])) { - System.setProperty(row[0], value); - dprops.setProperty(row[0], value); - } else if(row[0].contains("PASSWORD") || row[0].contains("STORE")) { - System.setProperty(row[0], value); - } else { - dprops.setProperty(row[0], value); - } - } - - } - - } - - Properties sprops = System.getProperties(); - if(reqClientConfig && sprops.getProperty(AFT_DME2_CLIENT_IGNORE_SSL_CONFIG)==null) { - sprops.put(AFT_DME2_CLIENT_IGNORE_SSL_CONFIG, "false"); - replaceKeyWithTrust(sprops,AFT_DME2_KEYSTORE,AFT_DME2_TRUSTSTORE); - replaceKeyWithTrust(sprops,AFT_DME2_KEYSTORE_PASSWORD,AFT_DME2_TRUSTSTORE_PASSWORD); - replaceKeyWithTrust(sprops,AFT_DME2_CLIENT_KEYSTORE,AFT_DME2_CLIENT_TRUSTSTORE); - replaceKeyWithTrust(sprops,AFT_DME2_CLIENT_KEYSTORE_PASSWORD,AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD); - } - - if(sprops.getProperty(AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS)==null) { - sprops.setProperty(AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS, access.getProperty(CADI_PROTOCOLS,SecurityInfo.HTTPS_PROTOCOLS_DEFAULT)); - } - - if(sprops.getProperty(AFT_DME2_SSL_INCLUDE_PROTOCOLS)==null) { - sprops.setProperty(AFT_DME2_SSL_INCLUDE_PROTOCOLS, access.getProperty(CADI_PROTOCOLS,SecurityInfo.HTTPS_PROTOCOLS_DEFAULT)); - } - - if(access.willLog(Level.DEBUG)) { - if(access instanceof PropAccess) { - access.log(Level.DEBUG,"Access Properties"); - for(Entry es : ((PropAccess)access).getProperties().entrySet()) { - access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),es.getValue().toString()); - } - } - access.log(Level.DEBUG,"DME2 Properties()"); - for(Entry es : dprops.entrySet()) { - value = es.getValue().toString(); - if(es.getKey().toString().contains("PASS")) { - if(value==null || !value.contains("enc:")) { - value = HIDE_PASS; - } - } - access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),value); - } - - access.log(Level.DEBUG,"System (AFT) Properties"); - for(Entry es : System.getProperties().entrySet()) { - if(es.getKey().toString().startsWith("AFT")) { - value = es.getValue().toString(); - if(es.getKey().toString().contains("PASS")) { - if(value==null || !value.contains("enc:")) { - value = HIDE_PASS; - } - } - access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),value); - } - } - } - // Cover any not specific AFT props - String key; - for(Entry es : access.getProperties().entrySet()) { - if((key=es.getKey().toString()).startsWith("AFT_") && - !key.contains("PASSWORD") && - dprops.get(key)==null) { - dprops.put(key, es.getValue()); - } - } - return dprops; - } - - private static void replaceKeyWithTrust(Properties props, String ks, String ts) { - String value; - if(props.get(ks)==null && (value=props.getProperty(ts))!=null) { - props.put(ks,value); - props.remove(ts); - } - } - // Set by CSP, or is hostname. - public static String getDefaultRealm() { - return defaultRealm; - } - -} diff --git a/core/src/main/java/com/att/cadi/config/Get.java b/core/src/main/java/com/att/cadi/config/Get.java deleted file mode 100644 index 7a2eab5..0000000 --- a/core/src/main/java/com/att/cadi/config/Get.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -import java.lang.reflect.Method; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; - -public interface Get { - public String get(String name, String def, boolean print); - - - /** - * A class for Getting info out of "JavaBean" format - * - */ - 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 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/core/src/main/java/com/att/cadi/config/GetAccess.java b/core/src/main/java/com/att/cadi/config/GetAccess.java deleted file mode 100644 index 1df9b0e..0000000 --- a/core/src/main/java/com/att/cadi/config/GetAccess.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -import com.att.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 com.att.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 com.att.cadi.PropAccess#getProperty(java.lang.String) - */ - @Override - public String getProperty(String tag) { - String rv; - rv = super.getProperty(tag, null); - if(rv==null && getter!=null) { - rv = getter.get(tag, null, true); - } - return rv; - } - - public Get get() { - return getter; - } -} diff --git a/core/src/main/java/com/att/cadi/config/MultiGet.java b/core/src/main/java/com/att/cadi/config/MultiGet.java deleted file mode 100644 index 83cd21d..0000000 --- a/core/src/main/java/com/att/cadi/config/MultiGet.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -public class MultiGet implements Get { - private Get[] getters; - - public MultiGet(Get ... getters) { - this.getters = getters; - } - - @Override - public String get(String name, String def, boolean print) { - String str; - for(Get getter : getters) { - str = getter.get(name, null, print); - if(str!=null) - return str; - } - return def; - } - -} diff --git a/core/src/main/java/com/att/cadi/config/SecurityInfo.java b/core/src/main/java/com/att/cadi/config/SecurityInfo.java deleted file mode 100644 index 6d0f3c2..0000000 --- a/core/src/main/java/com/att/cadi/config/SecurityInfo.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.rmi.AccessException; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509KeyManager; -import javax.net.ssl.X509TrustManager; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.util.MaskFormatException; -import com.att.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"; - - public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; - public static final String REGEX_COMMA = "\\s*,\\s*"; - public static final String SslKeyManagerFactoryAlgorithm; - - private SSLSocketFactory scf; - private X509KeyManager[] km; - private X509TrustManager[] tm; - public final String default_alias; - private NetMask[] trustMasks; - private SSLContext ctx; - private HostnameVerifier maskHV; - - // Change Key Algorithms for IBM's VM. Could put in others, if needed. - static { - if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) { - SslKeyManagerFactoryAlgorithm = "IbmX509"; - } else { - SslKeyManagerFactoryAlgorithm = "SunX509"; - } - } - - - public SecurityInfo(final Access access) throws GeneralSecurityException, IOException { - // reuse DME2 Properties for convenience if specific Properties don't exist - String keyStore = access.getProperty(Config.CADI_KEYSTORE, - access.getProperty(Config.AFT_DME2_KEYSTORE,null)); - String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, - access.getProperty(Config.AFT_DME2_KEYSTORE_PASSWORD, null)); - keyStorePasswd = keyStorePasswd==null?null:access.decrypt(keyStorePasswd,false); - String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, - access.getProperty(Config.AFT_DME2_TRUSTSTORE, null)); - String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, - access.getProperty(Config.AFT_DME2_TRUSTSTORE_PASSWORD,null)); - trustStorePasswd = trustStorePasswd==null?null:access.decrypt(trustStorePasswd,false); - default_alias = access.getProperty(Config.CADI_ALIAS, - access.getProperty(Config.AFT_DME2_CLIENT_SSL_CERT_ALIAS,null)); - - String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD,null); - keyPasswd = keyPasswd==null?keyStorePasswd:access.decrypt(keyPasswd,false); - String tips=access.getProperty(Config.CADI_TRUST_MASKS, null); - if(tips!=null) { - 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 kmal = new ArrayList(); - for(String ksname : keyStore.split(REGEX_COMMA)) { - file = new File(ksname); - String keystoreFormat; - if(ksname.endsWith("pkcs12")) { - keystoreFormat = "PKCS12"; - } else { - keystoreFormat = "JKS"; - } - if(file.exists()) { - FileInputStream fis = new FileInputStream(file); - try { - KeyStore ks = KeyStore.getInstance(keystoreFormat); - ks.load(fis, keyStorePasswd.toCharArray()); - kmf.init(ks, keyPasswd.toCharArray()); - } finally { - fis.close(); - } - } - } - for(KeyManager km : kmf.getKeyManagers()) { - if(km instanceof X509KeyManager) { - kmal.add((X509KeyManager)km); - } - } - km = new X509KeyManager[kmal.size()]; - kmal.toArray(km); - } - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm); - if(trustStore!=null) { - for(String tsname : trustStore.split(REGEX_COMMA)) { - file = new File(tsname); - if(file.exists()) { - FileInputStream fis = new FileInputStream(file); - try { - KeyStore ts = KeyStore.getInstance("JKS"); - ts.load(fis, trustStorePasswd.toCharArray()); - tmf.init(ts); - } finally { - fis.close(); - } - } - } - TrustManager tms[] = tmf.getTrustManagers(); - tm = new X509TrustManager[tms==null?0:tms.length]; - for(int i=0;i extends SecurityInfo { - public SecuritySetter defSS; - - public SecurityInfoC(Access access) throws GeneralSecurityException, IOException { - super(access); - } - - public SecurityInfoC set(SecuritySetter defSS) { - this.defSS = defSS; - return this; - } - -} diff --git a/core/src/main/java/com/att/cadi/config/UsersDump.java b/core/src/main/java/com/att/cadi/config/UsersDump.java deleted file mode 100644 index 992b365..0000000 --- a/core/src/main/java/com/att/cadi/config/UsersDump.java +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.config; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.Date; -import java.util.HashSet; - -import com.att.cadi.AbsUserCache; -import com.att.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(""); - ps.println(""); - ps.println(""); - - // We loop through Users, but want to write Groups first... therefore, save off print - StringBuilder sb = new StringBuilder(); - - // Obtain all unique role names - HashSet groups = new HashSet(); - for(AbsUserCache.DumpInfo di : lur.dumpInfo()) { - sb.append("\n "); - - } - - // Print roles - for(String group : groups) { - ps.print(" "); - } - - ps.println(sb); - - ps.println(""); - ps.flush(); - } catch (Throwable 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()]; - try { - fis.read(orig); - } finally { - fis.close(); - } - // Starting at third "<" ( line) - int startA=0, startB=0; - for(int i=0;startA value(); -} diff --git a/core/src/main/java/com/att/cadi/filter/AUTHZServlet.java b/core/src/main/java/com/att/cadi/filter/AUTHZServlet.java deleted file mode 100644 index c1ad627..0000000 --- a/core/src/main/java/com/att/cadi/filter/AUTHZServlet.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.io.IOException; - -import javax.servlet.Servlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * - */ -public class AUTHZServlet implements Servlet { - private String[] roles; - private Servlet delegate; - - protected AUTHZServlet(Class 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 void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { - if(roles==null) { - delegate.service(req,resp); - } else { // Validate - try { - HttpServletRequest hreq = (HttpServletRequest)req; - boolean proceed = false; - for(String role : roles) { - if(hreq.isUserInRole(role)) { - proceed = true; - break; - } - } - if(proceed) { - delegate.service(req,resp); - } else { - //baseRequest.getServletContext().log(hreq.getUserPrincipal().getName()+" Refused " + roles); - ((HttpServletResponse)resp).sendError(403); // forbidden - } - } catch(ClassCastException e) { - throw new ServletException("JASPIServlet only supports HTTPServletRequest/HttpServletResponse"); - } - } - } - - public void destroy() { - delegate.destroy(); - } - - -} diff --git a/core/src/main/java/com/att/cadi/filter/AccessGetter.java b/core/src/main/java/com/att/cadi/filter/AccessGetter.java deleted file mode 100644 index 37d2c04..0000000 --- a/core/src/main/java/com/att/cadi/filter/AccessGetter.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import com.att.cadi.Access; -import com.att.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); - } - -} diff --git a/core/src/main/java/com/att/cadi/filter/CadiAccess.java b/core/src/main/java/com/att/cadi/filter/CadiAccess.java deleted file mode 100644 index e9bc5a8..0000000 --- a/core/src/main/java/com/att/cadi/filter/CadiAccess.java +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -import javax.servlet.ServletContext; - -import com.att.cadi.Access; -import com.att.cadi.Symm; -import com.att.cadi.config.Config; -import com.att.cadi.config.Get; - -public class CadiAccess implements Access { - // constants for a couple of very commonly used strings. - protected static final String FROM = "from"; - protected static final String FOR = "for"; - - // Properties derived from sources (could be property files, Valve Configurations, Filter - // configs, etc. - protected Properties props; - - // Will we write Logs? - protected Level willWrite = Level.INFO; - - protected ServletContext context; - protected Get getter = Get.NULL; // replace with Derived Class getter - private Symm symm; - - public CadiAccess(Map map) { - if(map!=null && !map.isEmpty()) { - props = new Properties(); - for(Entry es : map.entrySet()) { - Object v = es.getValue(); - if(v!=null) { - props.put(es.getKey(), v.toString()); - } - } - Object keyfile = props.get(Config.CADI_KEYFILE); - if(keyfile!=null) { - try { - FileInputStream fis = new FileInputStream(keyfile.toString()); - symm = Symm.obtain(fis); - } catch (Exception e) { - } - } - - } - } - - public Level willWrite() { - return willWrite; - } - - /* (non-Javadoc) - * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) - */ - @Override - public boolean willLog(Level level) { - return willWrite.compareTo(level)<=0; - } - - /** - * Add the "Level" to the Buildline for Logging types that don't specify, or straight Streams, etc. Then buildline - * - * Build a line of code onto a StringBuilder based on Objects. Analyze whether - * spaces need including. - * - * @param level - * @param sb - * @param elements - * @return - */ - public final static StringBuilder buildLine(Level level, StringBuilder sb, Object[] elements) { - sb.append(level.name()); - return buildLine(sb,elements); - } - - /* - * Build a line of code onto a StringBuilder based on Objects. Analyze whether - * spaces need including. - * - * @param sb - * @param elements - * @return - */ - public final static StringBuilder buildLine(StringBuilder sb, Object[] elements) { - sb.append(' '); - String str; - boolean notFirst = false; - for(Object o : elements) { - if(o!=null) { - str = o.toString(); - - if(str.length()>0) { - if(notFirst && shouldAddSpace(str,true) && shouldAddSpace(sb,false)) { - sb.append(' '); - } else { - notFirst=true; - } - sb.append(str); - } - } - } - return sb; - } - - private static boolean shouldAddSpace(CharSequence c,boolean start) { - if(c.length()>0) - switch(c.charAt(start?0:c.length()-1)) { - case ' ': - case '\t': - case '\n': - case '\'': - case '"': - case '|': - return false; - } - return true; - } - - /** - * Standard mechanism for logging, given being within a Servlet Context - * - * Here, we treat - * - * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup - * scenarios) - * - */ - public void log(Level level, Object... elements) { - if(willWrite.compareTo(level)<=0) { - StringBuilder sb = buildLine(level, new StringBuilder(),elements); - if(context==null) { - System.out.println(sb.toString()); - } else { - context.log(sb.toString()); - } - } - } - - /** - * Standard mechanism for logging an Exception, given being within a Servlet Context, etc - * - * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup - * scenarios) - * - */ - public void log(Exception e, Object... elements) { - if(willWrite.compareTo(Level.ERROR)<=0) { - StringBuilder sb = buildLine(Level.ERROR, new StringBuilder(),elements); - - if(context==null) { - sb.append(e.toString()); - System.out.println(sb.toString()); - } else { - context.log(sb.toString(),e); - } - } - } - - public void setLogLevel(Level level) { - willWrite = level; - } - - /** - * Pass back the classloader of the Servlet Context, if it exists. Otherwise, get the classloader - * of this object. - */ - public ClassLoader classLoader() { // Use the Classloader that Context was created with - return (context==null?this:context).getClass().getClassLoader(); - } - - /** - * Get the Property from Context - */ - public String getProperty(String string, String def) { - String rv = null; - - if ( props != null ) - rv = props.getProperty( string, def ); - - if(rv==null) { - rv = context.getInitParameter(string); - } - return rv==null?def:rv; - - } - - public void load(InputStream is) throws IOException { - if(this.props==null) { - this.props = new Properties(); - } - this.props.load(is); - symm = Symm.obtain(this); - } - - public String decrypt(String encrypted, boolean anytext) throws IOException { - if(symm==null) { - String keyfile = getter.get(Config.CADI_KEYFILE, null, true); - if(keyfile!=null) { - FileInputStream fis = new FileInputStream(keyfile); - symm=Symm.obtain(fis); - fis.close(); - } - } - return (symm!=null && encrypted!=null && (anytext || encrypted.startsWith(Symm.ENC))) - ? symm.depass(encrypted) - : encrypted; - } - - @Override - public void printf(Level level, String fmt, Object[] elements) { - // TODO Auto-generated method stub - - } - -} diff --git a/core/src/main/java/com/att/cadi/filter/CadiFilter.java b/core/src/main/java/com/att/cadi/filter/CadiFilter.java deleted file mode 100644 index da24f44..0000000 --- a/core/src/main/java/com/att/cadi/filter/CadiFilter.java +++ /dev/null @@ -1,305 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CadiException; -import com.att.cadi.CadiWrap; -import com.att.cadi.Lur; -import com.att.cadi.PropAccess; -import com.att.cadi.ServletContextAccess; -import com.att.cadi.TrustChecker; -import com.att.cadi.config.Config; -import com.att.cadi.config.Get; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TafResp.RESP; - -/** - * CadiFilter - * - * This class implements Servlet Filter, and ties together CADI implementations - * - * This class can be used in a standard J2EE Servlet manner. Optimal usage is for POJO operations, where - * one can enforce this Filter being first and primary. Depending on the Container, it - * may be more effective, in some cases, to utilize features that allow earlier determination of - * AUTHN (Authorization). An example would be "Tomcat Valve". These implementations, however, should - * be modeled after the "init" and "doFilter" functions, and be kept up to date as this class changes. - * - * - * - */ -public class CadiFilter implements Filter { - private static CadiHTTPManip httpChecker; - private static String[] pathExceptions; - private static List mapPairs; - private Access access; - private Object[] additionalTafLurs; - 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)); - } - - - /** - * 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; - if(init) { - init(new AccessGetter(access)); - } - additionalTafLurs = moreTafLurs; - } - - /** - * 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)); - } - - - private void init(Get getter) throws ServletException { - // Start with the assumption of "Don't trust anyone". - TrustChecker tc = TrustChecker.NOTRUST; // default position - try { - @SuppressWarnings("unchecked") - Class ctc = (Class) Class.forName("com.att.cadi.aaf.v2_0.AAFTrustChecker"); - if(ctc!=null) { - Constructor 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()); - } - - - // 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 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"); - } - } - } - } - } - } - } - } - - // 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; - } - } - } - - /** - * 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 { - try { - HttpServletRequest hreq = (HttpServletRequest)request; - if(noAuthn(hreq)) { - chain.doFilter(request, response); - } else { - HttpServletResponse hresp = (HttpServletResponse)response; - TafResp tresp = httpChecker.validate(hreq, hresp); - if(tresp.isAuthenticated()==RESP.IS_AUTHENTICATED) { - CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq)); - if(httpChecker.notCadi(cw, hresp)) { - chain.doFilter(cw,response); - } - } - } - } catch (ClassCastException e) { - throw new ServletException("CadiFilter expects Servlet to be an HTTP Servlet",e); - } - } - - - /** - * 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 - * - */ - private class Pair { - public Pair(String key, PermConverter pc) { - name = key; - this.pc = pc; - } - public String name; - public PermConverter pc; - } - -} - diff --git a/core/src/main/java/com/att/cadi/filter/CadiHTTPManip.java b/core/src/main/java/com/att/cadi/filter/CadiHTTPManip.java deleted file mode 100644 index 6969b8c..0000000 --- a/core/src/main/java/com/att/cadi/filter/CadiHTTPManip.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CadiException; -import com.att.cadi.CadiWrap; -import com.att.cadi.Connector; -import com.att.cadi.CredVal; -import com.att.cadi.Lur; -import com.att.cadi.Taf; -import com.att.cadi.TrustChecker; -import com.att.cadi.config.Config; -import com.att.cadi.lur.EpiLur; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.TafResp; -import com.att.cadi.util.UserChainManip; - -/** - * Encapsulate common HTTP Manipulation Behavior. It will appropriately set - * HTTPServletResponse for Redirect or Forbidden, as needed. - * - * Further, this is useful, because it avoids multiple creates of Connections, where some Filters - * are created and destroyed regularly. - * - * - * - */ -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 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 { - synchronized(CADI) { - this.access = access; -// Get getter = new AccessGetter(access); - Config.setDefaultRealm(access); - - aaf_id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_MECHID, null)); - if(aaf_id==null) { - access.printf(Level.INIT, "%s is not set. %s can be used instead",Config.AAF_MECHID,Config.CADI_ALIAS); - } else { - access.printf(Level.INIT, "%s is set to %s",Config.AAF_MECHID,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; - } - - if(con!=null) { // try to reutilize connector - List ll = null; - for(Object tl : additionalTafLurs) { - if(tl instanceof Lur) { - if(ll==null) { - ll = new ArrayList(); - ll.add(con.newLur()); - } - ll.add((Lur)tl); - } - } - if(ll==null) { - lur = con.newLur(); - } else { - lur = new EpiLur((Lur[])ll.toArray()); - } - } else { - lur = Config.configLur(access, 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(access, tc, up, lur, additionalTafLurs); - } - } - - public TafResp validate(HttpServletRequest hreq, HttpServletResponse hresp) 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; - } - - 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; - } - -} diff --git a/core/src/main/java/com/att/cadi/filter/FCGet.java b/core/src/main/java/com/att/cadi/filter/FCGet.java deleted file mode 100644 index b8f95da..0000000 --- a/core/src/main/java/com/att/cadi/filter/FCGet.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.config.Get; - -/* - * A private method to query the Filter config and if not exists, return the default. This - * cleans up the initialization code. - */ -class FCGet implements Get { - /** - * - */ - 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 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/core/src/main/java/com/att/cadi/filter/MapPermConverter.java b/core/src/main/java/com/att/cadi/filter/MapPermConverter.java deleted file mode 100644 index 09b6f93..0000000 --- a/core/src/main/java/com/att/cadi/filter/MapPermConverter.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.util.HashMap; -import java.util.Map; - -public class MapPermConverter implements PermConverter { - private HashMap map; - - /** - * 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 map() { - return map; - } - - public String convert(String minimal) { - String rv = map.get(minimal); - return rv==null?minimal:rv; - } - -} diff --git a/core/src/main/java/com/att/cadi/filter/NullPermConverter.java b/core/src/main/java/com/att/cadi/filter/NullPermConverter.java deleted file mode 100644 index d73008e..0000000 --- a/core/src/main/java/com/att/cadi/filter/NullPermConverter.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - - -/** - * A NullPermConverter - * - * Obey the PermConverter Interface, but passed in "minimal" String is not converted. - * - * - */ -public class NullPermConverter implements PermConverter { - - private NullPermConverter() {} - private static final NullPermConverter singleton = new NullPermConverter(); - public static NullPermConverter singleton() {return singleton;} - - public String convert(String minimal) { - return minimal; - } - -} diff --git a/core/src/main/java/com/att/cadi/filter/PathFilter.java b/core/src/main/java/com/att/cadi/filter/PathFilter.java deleted file mode 100644 index 328977d..0000000 --- a/core/src/main/java/com/att/cadi/filter/PathFilter.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.config.Config; - -/** - * PathFilter - * - * This class implements Servlet Filter, and uses AAF to validate access to a Path. - * - * This class can be used in a standard J2EE Servlet manner. - * - * - */ -public class PathFilter implements Filter { - private ServletContext context; - private String aaf_type; - private String not_authorized_msg; - private final Log log; - - /** - * 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('|'); - - aaf_type = sb.toString(); - - attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG); - if(attr==null) { - not_authorized_msg = "Forbidden - Not Authorized to access this Path"; - } else { - not_authorized_msg = 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 = aaf_type+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,not_authorized_msg); - } - } - - /** - * Containers call "destroy" when time to cleanup - */ - public void destroy() { - log.info("PathFilter destroyed."); - } - - - -} - diff --git a/core/src/main/java/com/att/cadi/filter/PermConverter.java b/core/src/main/java/com/att/cadi/filter/PermConverter.java deleted file mode 100644 index ba098c4..0000000 --- a/core/src/main/java/com/att/cadi/filter/PermConverter.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.filter; - -/** - * Convert a simplistic, single string Permission into an Enterprise Scoped Perm - * - * - */ -public interface PermConverter { - public String convert(String minimal); -} diff --git a/core/src/main/java/com/att/cadi/filter/RolesAllowed.java b/core/src/main/java/com/att/cadi/filter/RolesAllowed.java deleted file mode 100644 index 97a8f54..0000000 --- a/core/src/main/java/com/att/cadi/filter/RolesAllowed.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -/** - * RolesAllowed - * - * - * Similar to Java EE's Spec from Annotations 1.1, 2.8 - * - * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined - * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in - * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation - * - */ -package com.att.cadi.filter; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * JASPI Style Annotation of RolesAllowed when the coding style is desired but actually including all - * JEE jars is not. If using actual JASPI, use official @interface classes, not this one... - * - */ -@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(); -} diff --git a/core/src/main/java/com/att/cadi/filter/ServletImpl.java b/core/src/main/java/com/att/cadi/filter/ServletImpl.java deleted file mode 100644 index 13a251c..0000000 --- a/core/src/main/java/com/att/cadi/filter/ServletImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -/** - * RolesAllowed - * - * - * Similar to Java EE's Spec from Annotations 1.1, 2.8 - * - * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined - * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in - * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation - * - */ -package com.att.cadi.filter; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -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 value(); -} diff --git a/core/src/main/java/com/att/cadi/lur/ConfigPrincipal.java b/core/src/main/java/com/att/cadi/lur/ConfigPrincipal.java deleted file mode 100644 index 443d7e7..0000000 --- a/core/src/main/java/com/att/cadi/lur/ConfigPrincipal.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.GetCred; -import com.att.cadi.Symm; - -public class ConfigPrincipal implements Principal, GetCred { - 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, byte[] cred) { - this.name = name; - this.cred = cred; - content = null; - } - - 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; - } -} diff --git a/core/src/main/java/com/att/cadi/lur/EpiLur.java b/core/src/main/java/com/att/cadi/lur/EpiLur.java deleted file mode 100644 index 1eff70e..0000000 --- a/core/src/main/java/com/att/cadi/lur/EpiLur.java +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur; - -import java.security.Principal; -import java.util.List; - -import com.att.cadi.CachingLur; -import com.att.cadi.CadiException; -import com.att.cadi.CredVal; -import com.att.cadi.Lur; -import com.att.cadi.Permission; - -/** - * EpiLUR - * - * Short for "Epic LUR". Be able to run through a series of LURs to obtain the validation needed. - * - * The pun is better for the other pattern... "TAF" (aka EpiTaf), but it's still the larger picture of - * LURs that will be accomplished. - * - * FYI, the reason we separate LURs, rather than combine, is that Various User Repository Resources have - * different Caching requirements. For instance, the Local User Repo (with stand alone names), never expire, but might be - * refreshed with a change in Configuration File, while the Remote Service based LURs will need to expire at prescribed intervals - * - * - */ -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"); - } - - public boolean fish(Principal bait, Permission pond) { - if(pond==null) { - return false; - } - boolean rv = false; - Lur lur; - for(int i=0;!rv && i permissions) { - for(Lur lur : lurs) { - lur.fishAll(bait, permissions); - } - } - - 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; - } - - // 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)l).remove(id); - } - } - } - - public Lur subLur(Class cls ) { - for(Lur l : lurs) { - if(l.getClass().isAssignableFrom(cls)) { - return l; - } - } - return null; - } - - @Override - public Permission createPerm(String p) { - return new LocalPermission(p); - } - - /* (non-Javadoc) - * @see com.att.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/core/src/main/java/com/att/cadi/lur/LocalLur.java b/core/src/main/java/com/att/cadi/lur/LocalLur.java deleted file mode 100644 index 5980769..0000000 --- a/core/src/main/java/com/att/cadi/lur/LocalLur.java +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur; - -import java.io.IOException; -import java.security.Principal; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import com.att.cadi.AbsUserCache; -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CredVal; -import com.att.cadi.Hash; -import com.att.cadi.Permission; -import com.att.cadi.StrLur; -import com.att.cadi.User; -import com.att.cadi.config.Config; - - -/** - * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms. - * - * - */ -public final class LocalLur extends AbsUserCache implements StrLur, 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 supportingGroups; - private String supportedRealm; - - /** - * Construct by building structure, see "build" - * - * Reconstruct with "build" - * - * @param userProperty - * @param groupProperty - * @param decryptor - * @throws IOException - */ - public LocalLur(Access access, String userProperty, String groupProperty) throws IOException { - super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire - supportedRealm = access.getProperty(Config.BASIC_REALM, "localized"); - supportingGroups = new TreeSet(); - - if(userProperty!=null) { - // For each User name... - for(String user : userProperty.trim().split(SEMI)) { - String[] us = user.split(COLON,2); - String[] userpass = us[0].split(PERCENT,2); - String u; - User usr; - if(userpass.length>1) { - if(userpass.length>0 && userpass[0].indexOf('@')<0) { - userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()); - } - - u = userpass[0]; - byte[] pass = access.decrypt(userpass[1], true).getBytes(); - usr = new User(new ConfigPrincipal(u, pass)); - } else { - u = us[0]; - usr = new User(new ConfigPrincipal(u, (byte[])null)); - } - addUser(usr); - access.log(Level.INIT, "Local User:",usr.principal); - - if(us.length>1) { - Map newMap = usr.newMap(); - for(String group : us[1].split(COMMA)) { - supportingGroups.add(group); - usr.add(newMap,new LocalPermission(group)); - } - usr.setMap(newMap); - } - } - } - if(groupProperty!=null) { - // For each Group name... - for(String group : groupProperty.trim().split(SEMI)) { - String[] gs = group.split(COLON,2); - if(gs.length>1) { - supportingGroups.add(gs[0]); - LocalPermission p = new LocalPermission(gs[0]); - // Add all users (known by comma separators) - - for(String grpMem : gs[1].split(COMMA)) { - // look for password, if so, put in passMap - String[] userpass = grpMem.split(PERCENT,2); - if(userpass.length>0 && userpass[0].indexOf('@')<0) { - userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()); - } - User usr = getUser(userpass[0]); - if(userpass.length>1) { - byte[] pass = access.decrypt(userpass[1], true).getBytes(); - if(usr==null)addUser(usr=new User(new ConfigPrincipal(userpass[0],pass))); - else usr.principal=new ConfigPrincipal(userpass[0],pass); - } else { - if(usr==null)addUser(usr=new User(new ConfigPrincipal(userpass[0],(byte[])null))); - } - usr.add(p); - access.log(Level.INIT, "Local User:",usr.principal); - } - } - } - } - } - - public boolean validate(String user, CredVal.Type type, byte[] cred) { - User usr = getUser(user); - switch(type) { - case PASSWORD: - // covers null as well as bad pass - if(usr!=null && cred!=null && usr.principal instanceof ConfigPrincipal) { - return Hash.isEqual(cred,((ConfigPrincipal)usr.principal).getCred()); - } - break; - } - return false; - } - - // @Override - public boolean fish(Principal bait, Permission pond) { - if(supports(bait.getName()) && pond instanceof LocalPermission) { // local Users only have LocalPermissions - User user = getUser(bait); - return user==null?false:user.contains((LocalPermission)pond); - } - return false; - } - - public boolean fish(String bait, Permission pond) { - if(supports(bait) && pond instanceof LocalPermission) { // local Users only have LocalPermissions - User user = getUser(bait); - return user==null?false:user.contains((LocalPermission)pond); - } - return false; - } - - // We do not want to expose the actual Group, so make a copy. - public void fishAll(Principal bait, List perms) { - if(supports(bait.getName())) { - User user = getUser(bait); - if(user!=null) { - user.copyPermsTo(perms); - } - } - } - - public void fishAll(String bait, List perms) { - if(supports(bait)) { - User user = getUser(bait); - if(user!=null) { - user.copyPermsTo(perms); - } - } - } - - public boolean supports(String userName) { - return userName!=null && userName.endsWith(supportedRealm); - } - - public boolean handlesExclusively(Permission pond) { - return supportingGroups.contains(pond.getKey()); - } - - /* (non-Javadoc) - * @see com.att.cadi.Lur#createPerm(java.lang.String) - */ - @Override - public Permission createPerm(String p) { - return new LocalPermission(p); - } - -} diff --git a/core/src/main/java/com/att/cadi/lur/LocalPermission.java b/core/src/main/java/com/att/cadi/lur/LocalPermission.java deleted file mode 100644 index b44f840..0000000 --- a/core/src/main/java/com/att/cadi/lur/LocalPermission.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur; - -import com.att.cadi.Permission; - -public class LocalPermission implements Permission { - private String key; - - public LocalPermission(String role) { - this.key = role; - } - - public String getKey() { - return key; - } - - public String toString() { - return key; - } - - public boolean match(Permission p) { - return key.equals(p.getKey()); - } - - public String permType() { - return "LOCAL"; - } - - -} diff --git a/core/src/main/java/com/att/cadi/lur/NullLur.java b/core/src/main/java/com/att/cadi/lur/NullLur.java deleted file mode 100644 index 7b01f5a..0000000 --- a/core/src/main/java/com/att/cadi/lur/NullLur.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur; - -import java.security.Principal; -import java.util.List; - -import com.att.cadi.Lur; -import com.att.cadi.Permission; - -public class NullLur implements Lur { - private static final Permission NULL = new Permission() { - @Override - public String permType() { - return ""; - } - - @Override - public String getKey() { - return ""; - } - - @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 void fishAll(Principal bait, List permissions) { - } - - public void destroy() { - } - - public boolean handlesExclusively(Permission pond) { - return false; - } - - public boolean supports(String userName) { - return false; - } - - /* (non-Javadoc) - * @see com.att.cadi.Lur#createPerm(java.lang.String) - */ - @Override - public Permission createPerm(String p) { - return NULL; - } - - /* (non-Javadoc) - * @see com.att.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'; - } -} diff --git a/core/src/main/java/com/att/cadi/principal/BasicPrincipal.java b/core/src/main/java/com/att/cadi/principal/BasicPrincipal.java deleted file mode 100644 index 800628d..0000000 --- a/core/src/main/java/com/att/cadi/principal/BasicPrincipal.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; - -import com.att.cadi.BasicCred; -import com.att.cadi.GetCred; -import com.att.cadi.Symm; - -public class BasicPrincipal extends BearerPrincipal implements GetCred { - private static byte[] basic = "Basic ".getBytes(); - - private String name = null; - private String shortName = null; - private byte[] cred = null; - - private long created; - - public BasicPrincipal(String content,String domain) throws IOException { - created = System.currentTimeMillis(); - ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes()); - // Read past "Basic ", ensuring it starts with it. - for(int i=0;i0) { - domain=name.substring(at+1); - shortName=name.substring(0, at); - } else { - shortName = name; - name = name + '@' + domain; - } - } - - public BasicPrincipal(BasicCred bc, String domain) { - name = bc.getUser(); - cred = bc.getCred(); - } - - 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 byte[] getCred() { - return cred; - } - - public long created() { - return created; - } - - public String toString() { - return "Basic Authorization for " + name + " evaluated on " + new Date(created).toString(); - } -} diff --git a/core/src/main/java/com/att/cadi/principal/BearerPrincipal.java b/core/src/main/java/com/att/cadi/principal/BearerPrincipal.java deleted file mode 100644 index 0d215a5..0000000 --- a/core/src/main/java/com/att/cadi/principal/BearerPrincipal.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.security.Principal; - -public abstract class BearerPrincipal implements Principal { - private String bearer = null; - public BearerPrincipal setBearer(String bearer) { - this.bearer = bearer; - return this; - } - public String getBearer() { - return bearer; - } -} diff --git a/core/src/main/java/com/att/cadi/principal/CSPPrincipal_T.java b/core/src/main/java/com/att/cadi/principal/CSPPrincipal_T.java deleted file mode 100644 index e3ccb42..0000000 --- a/core/src/main/java/com/att/cadi/principal/CSPPrincipal_T.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.security.Principal; - -/** - * Indicate a CSP Principal that is trusted as a CSPPrincipal. - * - */ -public interface CSPPrincipal_T extends Principal { - -} diff --git a/core/src/main/java/com/att/cadi/principal/CachedBasicPrincipal.java b/core/src/main/java/com/att/cadi/principal/CachedBasicPrincipal.java deleted file mode 100644 index de1ebaf..0000000 --- a/core/src/main/java/com/att/cadi/principal/CachedBasicPrincipal.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.io.IOException; - -import com.att.cadi.BasicCred; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.taf.HttpTaf; - -/** - * Cached Principals need to be able to revalidate in the Background - * - * - */ -public class CachedBasicPrincipal extends BasicPrincipal implements CachedPrincipal { - 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 CachedPrincipal.Resp revalidate() { - Resp resp = creator.revalidate(this); - if(resp.equals(Resp.REVALIDATED))expires = System.currentTimeMillis()+timeToLive; - return resp; - } - - public long expires() { - return expires; - } - -} diff --git a/core/src/main/java/com/att/cadi/principal/TGuardPrincipal.java b/core/src/main/java/com/att/cadi/principal/TGuardPrincipal.java deleted file mode 100644 index e2a6400..0000000 --- a/core/src/main/java/com/att/cadi/principal/TGuardPrincipal.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -public class TGuardPrincipal extends BearerPrincipal { - - private String name, tresp; - - public TGuardPrincipal(String tresp) { - this.tresp=tresp; - } - - /** - * TODO Need to figure out what Organizations TGuard entities should be part of. - * - */ - public String getName() { - if(name==null) { - String temp = get("iv-user"); - if(temp==null)return null; - StringBuilder sb = new StringBuilder(); - int at = temp.indexOf('@'); - if(at<0) { - sb.append(temp); - } else { - sb.append(temp.substring(0, at)); - } - if(temp.endsWith("@uverse.com"))sb.append("@uverse.tguard.att.com"); - else if(temp.endsWith("@att.com"))sb.append("@com.tguard.att.com"); - else if(temp.endsWith("@att.net"))sb.append("@net.tguard.att.com"); - else sb.append("@tguard.att.com"); - name = sb.toString(); - } - return name; - } - - /** - * Get a value from a named TGuard Property - * - * TGuard response info is very dynamic. They can add new properties at any time, so we dare not code field names for these values. - * @param key - * @return - */ - public String get(String key) { - if(key==null)return null; - int idx=0,equal=0,amp=0; - while(idx>=0 && (equal = tresp.indexOf('=',idx))>=0) { - amp = tresp.indexOf('&',equal); - if(key.regionMatches(0, tresp, idx, equal-idx)) { - return amp>=0?tresp.substring(equal+1, amp):tresp.substring(equal+1); - } - idx=amp+(amp>0?1:0); - } - return null; - } - - public String info() { - return tresp; - } -} diff --git a/core/src/main/java/com/att/cadi/principal/TGuardPrincipal_T.java b/core/src/main/java/com/att/cadi/principal/TGuardPrincipal_T.java deleted file mode 100644 index cfd8564..0000000 --- a/core/src/main/java/com/att/cadi/principal/TGuardPrincipal_T.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.security.Principal; - -/** - * Indicate a TGuard Principal that is trusted as a TGuardPrincipal. - * - */ -public interface TGuardPrincipal_T extends Principal { - -} diff --git a/core/src/main/java/com/att/cadi/principal/TrustPrincipal.java b/core/src/main/java/com/att/cadi/principal/TrustPrincipal.java deleted file mode 100644 index 744560f..0000000 --- a/core/src/main/java/com/att/cadi/principal/TrustPrincipal.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.security.Principal; - -import com.att.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 X509Principal) { - userChain="x509"; - } else if(actual instanceof BasicPrincipal) { - userChain="BAth"; - } else { - userChain = actual.getClass().getSimpleName(); - } - } - - @Override - public String getName() { - return name; - } - - public String getOrigName() { - return original.getName() + '[' + userChain + ']'; - } - - @Override - public String userChain() { - return userChain; - } - - public Principal original() { - return original; - } - -} diff --git a/core/src/main/java/com/att/cadi/principal/X509Principal.java b/core/src/main/java/com/att/cadi/principal/X509Principal.java deleted file mode 100644 index 89a8dc2..0000000 --- a/core/src/main/java/com/att/cadi/principal/X509Principal.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.principal; - -import java.io.IOException; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.regex.Pattern; - -import com.att.cadi.GetCred; - -public class X509Principal extends BearerPrincipal implements GetCred { - private static final Pattern pattern = Pattern.compile("[a-zA-Z0-9]*\\@[a-zA-Z0-9.]*"); - private byte[] content; - private X509Certificate cert; - private String name; - - public X509Principal(String identity, X509Certificate cert, byte[] content) { - name = identity; - this.content = content; - this.cert = cert; - } - - public X509Principal(X509Certificate cert, byte[] content) throws IOException { - this.content=content; - this.cert = cert; - 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"); - - } - - - 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 String getName() { - return name; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/AbsTafResp.java b/core/src/main/java/com/att/cadi/taf/AbsTafResp.java deleted file mode 100644 index f57b975..0000000 --- a/core/src/main/java/com/att/cadi/taf/AbsTafResp.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.security.Principal; - -import com.att.cadi.Access; - -/** - * AbsTafResp - * - * Base class for TafResp (TAF Response Objects) - * - */ -public abstract class AbsTafResp implements TafResp { - - protected final String desc; - protected final Principal principal; - protected final Access access; - - /** - * 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 principal - * @param description - */ - public AbsTafResp(Access access, Principal principal, String description) { - this.access = access; - this.principal = principal; - this.desc = description; - } - - /** - * 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; - } - - /** - * 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 Principal getPrincipal() { - return principal; - } - - /** - * getAccess() - * - * Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated. - */ - public Access getAccess() { - return access; - } - - /* (non-Javadoc) - * @see com.att.cadi.taf.TafResp#isFailedAttempt() - */ - public boolean isFailedAttempt() { - return false; - } - -} diff --git a/core/src/main/java/com/att/cadi/taf/EpiTaf.java b/core/src/main/java/com/att/cadi/taf/EpiTaf.java deleted file mode 100644 index 613f317..0000000 --- a/core/src/main/java/com/att/cadi/taf/EpiTaf.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import com.att.cadi.CadiException; -import com.att.cadi.Taf; - -/** - * EpiTAF - * - * Short for "Epic TAF". Be able to run through a series of TAFs to obtain the validation needed. - * - * OK, the name could probably be better as "Tafs", like it was originally, but the pun was too - * irresistible for this author to pass up. - * - * - */ -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"); - } - - /** - * 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; - } - -} diff --git a/core/src/main/java/com/att/cadi/taf/HttpEpiTaf.java b/core/src/main/java/com/att/cadi/taf/HttpEpiTaf.java deleted file mode 100644 index 3036f07..0000000 --- a/core/src/main/java/com/att/cadi/taf/HttpEpiTaf.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.net.URI; -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.CadiException; -import com.att.cadi.Locator; -import com.att.cadi.Taf.LifeForm; -import com.att.cadi.TrustChecker; - -/** - * HttpEpiTaf - * - * An extension of the basic "EpiTAF" concept, check known HTTP Related TAFs for valid credentials - * - * - */ -public class HttpEpiTaf implements HttpTaf { - private HttpTaf[] tafs; - private Access access; - private Locator locator; - private TrustChecker trustChecker; - - /** - * HttpEpiTaf constructor - * - * Construct the HttpEpiTaf from variable Http specific TAF parameters - - * @param tafs - * @throws CadiException - */ - public HttpEpiTaf(Access access, Locator 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 -// trustChainProp = access.getProperty(Config.CADI_TRUST_PROP, Config.CADI_TRUST_PROP_DEFAULT); - - 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, firstTry = null; - List redirectables = null; - - for(HttpTaf taf : tafs) { - tresp = taf.validate(reading, req, resp); - 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; - } - } - - // 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. - - String auth = req.getParameter("Authentication"); - if(auth!=null) { - if("BasicAuth".equals(auth)) { - return LifeForm.SBLF; - } - } - // 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 - // 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) { - Resp resp; - for(HttpTaf taf : tafs) { - resp = taf.revalidate(prin); - switch(resp) { - case NOT_MINE: - break; - default: - return resp; - } - } - return Resp.NOT_MINE; - } - - /** - * 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/core/src/main/java/com/att/cadi/taf/HttpTaf.java b/core/src/main/java/com/att/cadi/taf/HttpTaf.java deleted file mode 100644 index ad22872..0000000 --- a/core/src/main/java/com/att/cadi/taf/HttpTaf.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.CachedPrincipal; -import com.att.cadi.Taf.LifeForm; - -/** - * A TAF which is in a specific HTTP environment in which the engine implements - * javax Servlet. - * - * Using the Http Request and Response interfaces takes the effort out of implementing in almost any kind of - * HTTP Container or Engine. - * - * - */ -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); -} diff --git a/core/src/main/java/com/att/cadi/taf/LoginPageTafResp.java b/core/src/main/java/com/att/cadi/taf/LoginPageTafResp.java deleted file mode 100644 index 8a6acad..0000000 --- a/core/src/main/java/com/att/cadi/taf/LoginPageTafResp.java +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.net.URI; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.Locator; -import com.att.cadi.Locator.Item; - -public class LoginPageTafResp extends AbsTafResp { - private final HttpServletResponse httpResp; - private final String loginPageURL; - - private LoginPageTafResp(Access access, final HttpServletResponse resp, String loginPageURL) { - super(access, 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 locator, final HttpServletResponse resp, List redir) { - if(locator!=null) { - try { - Item item = locator.best(); - URI uri = locator.get(item); - if(uri!=null) { - StringBuilder sb = new StringBuilder(uri.toString()); - String query = uri.getQuery(); - boolean first = query==null || query.length()==0; - int count=0; - for(Redirectable t : redir) { - if(first) { - sb.append('?'); - first=false; - } - else sb.append('&'); - sb.append(t.get()); - ++count; - } - if(count>0)return new LoginPageTafResp(access, resp, sb.toString()); - } - } catch (Exception e) { - access.log(e, "Error deriving Login Page location"); - } - } else if(!redir.isEmpty()) { - access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf"); - return redir.get(0); - } - return NullTafResp.singleton(); - } -} diff --git a/core/src/main/java/com/att/cadi/taf/NullTaf.java b/core/src/main/java/com/att/cadi/taf/NullTaf.java deleted file mode 100644 index 0a6f4bb..0000000 --- a/core/src/main/java/com/att/cadi/taf/NullTaf.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.Taf; - - -/** - * This TAF is set at the very beginning of Filters and Valves so that if any configuration issues hit while - * starting, the default behavior is to shut down traffic rather than leaving an open hole - * - * - */ -public class NullTaf implements Taf, HttpTaf { - // 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, HttpServletRequest req, HttpServletResponse resp) { - return NullTafResp.singleton(); - } - - public Resp revalidate(CachedPrincipal prin) { - return Resp.NOT_MINE; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/NullTafResp.java b/core/src/main/java/com/att/cadi/taf/NullTafResp.java deleted file mode 100644 index 8dcfc1e..0000000 --- a/core/src/main/java/com/att/cadi/taf/NullTafResp.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; - -/** - * A Null Pattern for setting responses to "Deny" before configuration is setup. - * - */ -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; - } - - public Principal getPrincipal() { - return null; - } - - public Access getAccess() { - return Access.NULL; - } - - /* (non-Javadoc) - * @see com.att.cadi.taf.TafResp#isFailedAttempt() - */ - public boolean isFailedAttempt() { - return true; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/PuntTafResp.java b/core/src/main/java/com/att/cadi/taf/PuntTafResp.java deleted file mode 100644 index 8951145..0000000 --- a/core/src/main/java/com/att/cadi/taf/PuntTafResp.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; - -/** - * A Punt Resp to make it fast and easy for a Taf to respond that it cannot handle a particular kind of - * request. It is always the same object, so there is no cost for memory, etc. - * - */ -public class PuntTafResp implements TafResp { - private PuntTafResp(){} - - private static TafResp singleton = new PuntTafResp(); - - public static TafResp singleton() { - return singleton; - } - - public boolean isValid() { - return false; - } - - public RESP isAuthenticated() { - return RESP.TRY_ANOTHER_TAF; - } - - public String desc() { - return "This Taf can or will not handle this authentication"; - } - - public RESP authenticate() throws IOException { - return RESP.TRY_ANOTHER_TAF; - } - - public Principal getPrincipal() { - return null; - } - - public Access getAccess() { - return NullTafResp.singleton().getAccess(); - } - - public boolean isFailedAttempt() { - return false; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/Redirectable.java b/core/src/main/java/com/att/cadi/taf/Redirectable.java deleted file mode 100644 index 4ef31bc..0000000 --- a/core/src/main/java/com/att/cadi/taf/Redirectable.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.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(); -} diff --git a/core/src/main/java/com/att/cadi/taf/TafResp.java b/core/src/main/java/com/att/cadi/taf/TafResp.java deleted file mode 100644 index 140ac13..0000000 --- a/core/src/main/java/com/att/cadi/taf/TafResp.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; -import com.att.cadi.CadiException; - -/** - * Response from Taf objects, which inform users what has happened and/or what should be done - * - * - */ -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. JG 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; - - /** - * Once authenticated, this object should hold a Principal created from the authorization - * @return - */ - public Principal 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(); -} diff --git a/core/src/main/java/com/att/cadi/taf/TrustNotTafResp.java b/core/src/main/java/com/att/cadi/taf/TrustNotTafResp.java deleted file mode 100644 index 29a299f..0000000 --- a/core/src/main/java/com/att/cadi/taf/TrustNotTafResp.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; - -public class TrustNotTafResp implements TafResp { - private final TafResp delegate; - private final String desc; - - 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 RESP isAuthenticated() { - return RESP.NO_FURTHER_PROCESSING; - } - - @Override - public RESP authenticate() throws IOException { - return RESP.NO_FURTHER_PROCESSING; - } - - @Override - public Principal getPrincipal() { - return delegate.getPrincipal(); - } - - @Override - public Access getAccess() { - return delegate.getAccess(); - } - - @Override - public boolean isFailedAttempt() { - return true; - } - - public String toString() { - return desc(); - } -} diff --git a/core/src/main/java/com/att/cadi/taf/TrustTafResp.java b/core/src/main/java/com/att/cadi/taf/TrustTafResp.java deleted file mode 100644 index 25c665b..0000000 --- a/core/src/main/java/com/att/cadi/taf/TrustTafResp.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; - -public class TrustTafResp implements TafResp { - private final TafResp delegate; - private final Principal principal; - private final String desc; - - public TrustTafResp(final TafResp delegate, final Principal 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 RESP isAuthenticated() { - return delegate.isAuthenticated(); - } - - @Override - public RESP authenticate() throws IOException { - return delegate.authenticate(); - } - - @Override - public Principal getPrincipal() { - return principal; - } - - @Override - public Access getAccess() { - return delegate.getAccess(); - } - - @Override - public boolean isFailedAttempt() { - return delegate.isFailedAttempt(); - } - - public String toString() { - return principal.getName() + " by trust of " + desc(); - } -} diff --git a/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTaf.java b/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTaf.java deleted file mode 100644 index f954a00..0000000 --- a/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTaf.java +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.basic; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.BasicCred; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.CredVal; -import com.att.cadi.CredVal.Type; -import com.att.cadi.Taf; -import com.att.cadi.principal.BasicPrincipal; -import com.att.cadi.principal.CachedBasicPrincipal; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TafResp.RESP; -import com.att.cadi.taf.dos.DenialOfServiceTaf; - -/** - * BasicHttpTaf - * - * This TAF implements the "Basic Auth" protocol. - * - * WARNING! It is true for any implementation of "Basic Auth" that the password is passed unencrypted. - * This is because the expectation, when designed years ago, was that it would only be used in - * conjunction with SSL (https). It is common, however, for users to ignore this on the assumption that - * their internal network is secure, or just ignorance. Therefore, a WARNING will be printed - * when the HTTP Channel is not encrypted (unless explicitly turned off). - * - * - */ -public class BasicHttpTaf implements HttpTaf { - private Access access; - private String realm; - private CredVal rbac; - 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; - } - - /** - * 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); - // ONLY FOR Last Ditch DEBUGGING... - // access.log(Level.WARN,bp.getName() + ":" + new String(bp.getCred())); - if(rbac.validate(bp.getName(),Type.PASSWORD,bp.getCred())) { - 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()), - 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()); - } - - // ONLY FOR Last Ditch DEBUGGING... - // access.log(Level.WARN,ba.getName() + ":" + new String(ba.getCred())); - if(rbac.validate(ba.getName(), Type.PASSWORD, ba.getCred())) { - 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(); - for(Object s : msg) { - sb.append(s.toString()); - } - if(pr!=null) { - sb.append(" for "); - sb.append(pr.getName()); - } - sb.append(" from "); - sb.append(req.getRemoteAddr()); - sb.append(':'); - sb.append(req.getRemotePort()); - return sb.toString(); - } - - @Override - public Resp revalidate(CachedPrincipal prin) { - 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())?Resp.REVALIDATED:Resp.UNVALIDATED; - } - return Resp.NOT_MINE; - } - - public String toString() { - return "Basic Auth enabled on realm: " + realm; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTafResp.java b/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTafResp.java deleted file mode 100644 index 1d43054..0000000 --- a/core/src/main/java/com/att/cadi/taf/basic/BasicHttpTafResp.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.basic; - -import java.io.IOException; -import java.security.Principal; - -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.taf.AbsTafResp; -import com.att.cadi.taf.TafResp; - -public class BasicHttpTafResp extends AbsTafResp implements TafResp { - private HttpServletResponse httpResp; - private String realm; - private RESP status; - private final boolean wasFailed; - - public BasicHttpTafResp(Access access, Principal principal, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) { - super(access,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/core/src/main/java/com/att/cadi/taf/cert/CertIdentity.java b/core/src/main/java/com/att/cadi/taf/cert/CertIdentity.java deleted file mode 100644 index 5d9624a..0000000 --- a/core/src/main/java/com/att/cadi/taf/cert/CertIdentity.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.cert; - -import java.security.Principal; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.servlet.http.HttpServletRequest; - -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 Principal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException; -} diff --git a/core/src/main/java/com/att/cadi/taf/cert/X509HttpTafResp.java b/core/src/main/java/com/att/cadi/taf/cert/X509HttpTafResp.java deleted file mode 100644 index 8148a4e..0000000 --- a/core/src/main/java/com/att/cadi/taf/cert/X509HttpTafResp.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.cert; - -import java.io.IOException; -import java.security.Principal; - -import com.att.cadi.Access; -import com.att.cadi.taf.AbsTafResp; -import com.att.cadi.taf.TafResp; - -public class X509HttpTafResp extends AbsTafResp implements TafResp { - private RESP status; - - public X509HttpTafResp(Access access, Principal principal, String description, RESP status) { - super(access, 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/core/src/main/java/com/att/cadi/taf/cert/X509Taf.java b/core/src/main/java/com/att/cadi/taf/cert/X509Taf.java deleted file mode 100644 index 6bef245..0000000 --- a/core/src/main/java/com/att/cadi/taf/cert/X509Taf.java +++ /dev/null @@ -1,257 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.cert; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.Principal; -import java.security.Signature; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.ArrayList; - -import javax.net.ssl.TrustManagerFactory; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.CadiException; -import com.att.cadi.Lur; -import com.att.cadi.Symm; -import com.att.cadi.Taf.LifeForm; -import com.att.cadi.config.Config; -import com.att.cadi.config.SecurityInfoC; -import com.att.cadi.config.SecurityInfo; -import com.att.cadi.lur.LocalPermission; -import com.att.cadi.principal.TGuardPrincipal; -import com.att.cadi.principal.X509Principal; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TafResp.RESP; -import com.att.cadi.util.Split; - -public class X509Taf implements HttpTaf { - - 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 cadiIssuers; - private String env; - private SecurityInfo si; - - static { - try { - certFactory = CertificateFactory.getInstance("X.509"); - messageDigest = MessageDigest.getInstance("SHA-256"); // use this to clone - tmf = TrustManagerFactory.getInstance(SecurityInfoC.SslKeyManagerFactoryAlgorithm); - } 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, "CN=ATT CADI Issuing CA 01, OU=CSO, O=ATT, C=US:CN=ATT CADI Issuing CA 02, OU=CSO, O=ATT, C=US").split(":")) { - cadiIssuers.add(ci); - } - try { - Class dci = access.classLoader().loadClass("com.att.authz.cadi.DirectCertIdentity"); - 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; - } - - try { - si = new SecurityInfo(access); - } catch (GeneralSecurityException | IOException e1) { - throw new CadiException(e1); - } - } - - 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 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 - if(cadiIssuers.contains(certarr[0].getIssuerDN().toString())) { - String x500 = certarr[0].getSubjectDN().getName(); - int ou=x500.indexOf("OU="); - if(ou>0) { - ou+=3; - int comma = x500.indexOf(',',ou); - if(comma>0) { - String id= x500.substring(ou,comma); - String idenv[] = id.split(":"); - if(idenv.length==1 || (idenv.length>1 && env.equals(idenv[1]))) { - return new X509HttpTafResp(access, - new X509Principal(idenv[0], certarr[0],null), - id + " validated by CADI x509", RESP.IS_AUTHENTICATED); - } - } - } - } - } - - 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 - return new X509HttpTafResp(access, null, "Certificate verified, but another Identity 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 && authHeader.startsWith("x509 ")) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(authHeader.length()); - try { - array = authHeader.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 " " -// 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 verified", 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 verified", RESP.TRY_ANOTHER_TAF); - } - - } else { - return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF); - } - } - - // A cert has been found, match Identify - Principal prin=null; - - for(int i=0;prin==null && i deniedIP=null, deniedID=null; - private Access access; - private static File dosIP, dosID; - - /** - * - * @param hostname - * @param prod - * @throws CadiException - */ - public DenialOfServiceTaf(Access access) throws CadiException { - this.access = access; - if(dosIP==null || dosID == null) { - String dirStr; - if((dirStr = access.getProperty("aaf_data_dir", null))!=null) { - dosIP = new File(dirStr+"/dosIP"); - readIP(); - dosID = new File(dirStr+"/dosID"); - readID(); - } - } - } - - 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 PuntTafResp.singleton(); - } - - public Resp revalidate(CachedPrincipal prin) { - // 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(deniedID!=null) { - return deniedID.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)); - if(deniedIP==null) { - deniedIP=new HashMap(); - } - - try { - 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 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 readID() { - if(dosID!=null && dosID.exists()) { - BufferedReader br; - try { - br = new BufferedReader(new FileReader(dosID)); - if(deniedID==null) { - deniedID=new HashMap(); - } - try { - 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 true; - } - return false; - } - - public List report() { - int initSize = 0; - if(deniedIP!=null)initSize+=deniedIP.size(); - if(deniedID!=null)initSize+=deniedID.size(); - ArrayList 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 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/core/src/main/java/com/att/cadi/taf/dos/DenialOfServiceTafResp.java b/core/src/main/java/com/att/cadi/taf/dos/DenialOfServiceTafResp.java deleted file mode 100644 index 1b4efed..0000000 --- a/core/src/main/java/com/att/cadi/taf/dos/DenialOfServiceTafResp.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.dos; - -import java.io.IOException; - -import com.att.cadi.Access; -import com.att.cadi.taf.AbsTafResp; - -public class DenialOfServiceTafResp extends AbsTafResp { - private RESP ect; // Homage to Arethra Franklin - - public DenialOfServiceTafResp(Access access, RESP resp, String description ) { - super(access, 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; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTaf.java b/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTaf.java deleted file mode 100644 index 67754a9..0000000 --- a/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTaf.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.localhost; - -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Enumeration; -import java.util.TreeSet; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.att.cadi.Access; -import com.att.cadi.Access.Level; -import com.att.cadi.CachedPrincipal; -import com.att.cadi.CachedPrincipal.Resp; -import com.att.cadi.Taf; -import com.att.cadi.taf.HttpTaf; -import com.att.cadi.taf.TafResp; -import com.att.cadi.taf.TafResp.RESP; - -/** - * Implement the ability to utilize LocalHost as a TAF. - * - * Configure with two properties, - * localhost.deny - * localhost.accept - * - * 1) If localhost.deny==true, then no localhost requests are allowed - * 2) If localhost.deny==false, but accept==false, return "Try Another TAF" (i.e. allow further checking of the - * chain, but don't treat localhost as an acceptable credential) - * 3) If localhost.deny=false and accept=true, then the processes coming from the same machine, given logins are needed, - * to run, are treated as validated. This is primarily for Developer purposes. - * - * - * - */ -public class LocalhostTaf implements HttpTaf { - private TafResp isLocalHost,isNotLocalHost; - private static final TreeSet addrSet; - - static { - addrSet = new TreeSet(); - try { - for(Enumeration en = NetworkInterface.getNetworkInterfaces();en.hasMoreElements();) { - NetworkInterface ni = en.nextElement(); - for(Enumeration eia = ni.getInetAddresses();eia.hasMoreElements();) { - InetAddress ia = eia.nextElement(); - addrSet.add(ia.getHostAddress()); - } - } - } catch (SocketException e) { - } - - } - - public LocalhostTaf(Access access, boolean accept, boolean isDenied) { - String hostname = access.getProperty("hostname",null); - if(hostname !=null) { - try { - addrSet.add(InetAddress.getByName(hostname).getHostAddress()); - } catch (UnknownHostException e) { - access.log(e,"Unknown Host"); - } - } - - if(isDenied) { - access.log(Level.INFO,"LocalhostTaf will deny all localhost traffic"); - } else { - access.log(Level.INFO,"LocalhostTaf will not deny localhost requests, ", - (accept?"and will treat them as authenticated":"but will require other authentication")); - } - // Set the appropriate behavior for when ID coming in is from localhost - isLocalHost = isDenied? - new LocalhostTafResp(access, RESP.NO_FURTHER_PROCESSING,"Localhost is denied"): - accept? - new LocalhostTafResp(access, RESP.IS_AUTHENTICATED,"Localhost is allowed"): - new LocalhostTafResp(access, RESP.TRY_ANOTHER_TAF,"Localhost is allowed"); - isNotLocalHost = new LocalhostTafResp(access, RESP.TRY_ANOTHER_TAF,"Address is not Localhost"); - } - -// @Override - public TafResp validate(Taf.LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { - String remote = req.getRemoteAddr(); - return addrSet.contains(remote) - ?isLocalHost - :isNotLocalHost; - } - - /** - * This function used for other TAFs (i.e. CSP, which can't work on localhost address) - * - * @param address - * @return - */ - public static boolean isLocalAddress(String address) { - return addrSet.contains(address); - } - - public String toString() { - return "Localhost TAF activated: " + isLocalHost.desc(); - } - - public Resp revalidate(CachedPrincipal prin) { - // shouldn't get here, since there's no need to Cache, but if so, LocalHost is always valid... - return Resp.REVALIDATED; - } -} diff --git a/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTafResp.java b/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTafResp.java deleted file mode 100644 index 2a074d1..0000000 --- a/core/src/main/java/com/att/cadi/taf/localhost/LocalhostTafResp.java +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.taf.localhost; - -import java.security.Principal; - -import com.att.cadi.Access; -import com.att.cadi.taf.TafResp; - -public class LocalhostTafResp implements TafResp { - private RESP action; - private String description; - private final static Principal principal = new Principal() { - private String name = System.getProperty("user.name")+"@localhost"; -// @Override - public String getName() { - return name; - } - }; - - private Access access; - - public LocalhostTafResp(Access access, RESP state, String desc) { - action = state; - description = desc; - this.access = access; - } - -// @Override - public boolean isValid() { - return action == RESP.IS_AUTHENTICATED; - } - -// @Override - public String desc() { - return description; - } - -// @Override - public RESP authenticate() { - return action; - } - - public RESP isAuthenticated() { - return action; - } - -// @Override - public Principal getPrincipal() { - return principal; - } - - public Access getAccess() { - return access; - } - - public boolean isFailedAttempt() { - return false; - } - -} diff --git a/core/src/main/java/com/att/cadi/util/Chmod.java b/core/src/main/java/com/att/cadi/util/Chmod.java deleted file mode 100644 index ddde50b..0000000 --- a/core/src/main/java/com/att/cadi/util/Chmod.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.util; - -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 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); - } - }; -} diff --git a/core/src/main/java/com/att/cadi/util/JsonOutputStream.java b/core/src/main/java/com/att/cadi/util/JsonOutputStream.java deleted file mode 100644 index 33deed0..0000000 --- a/core/src/main/java/com/att/cadi/util/JsonOutputStream.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.util; - -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; - - 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=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(prev255 || lbyte<0)) { - throw new MaskFormatException("Invalid Byte in IPV4 Address"); - } - rv|=lbyte<>bits; - } - return rv; - } - -} diff --git a/core/src/main/java/com/att/cadi/util/Split.java b/core/src/main/java/com/att/cadi/util/Split.java deleted file mode 100644 index 07332dd..0000000 --- a/core/src/main/java/com/att/cadi/util/Split.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.util; - -/** - * Split by Char, optional Trim - * - * Note: Copied from Inno to avoid linking issues. - * Note: I read the String split and Pattern split code, and we can do this more efficiently for a single Character - * - * 8/20/2015 - */ - -public class Split { - public static String[] split(char c, String value) { - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count,idx; - for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count); - String[] rv = new String[count]; - if(count==1) { - rv[0]=value; - } else { - int last=0; - count=-1; - for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) { - rv[++count]=value.substring(last,idx); - last = ++idx; - } - rv[++count]=value.substring(last); - } - return rv; - } - - public static String[] splitTrim(char c, String value) { - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count,idx; - for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count); - String[] rv = new String[count]; - if(count==1) { - rv[0]=value.trim(); - } else { - int last=0; - count=-1; - for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) { - rv[++count]=value.substring(last,idx).trim(); - last = ++idx; - } - rv[++count]=value.substring(last).trim(); - } - return rv; - } - - public static String[] splitTrim(char c, String value, int size) { - 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 && count0 && 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 void printf(String fmt, Object... args) { - System.console().printf(fmt, args); - } -} diff --git a/core/src/main/java/com/att/cadi/util/UserChainManip.java b/core/src/main/java/com/att/cadi/util/UserChainManip.java deleted file mode 100644 index 9f6eeec..0000000 --- a/core/src/main/java/com/att/cadi/util/UserChainManip.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.util; - -import com.att.cadi.UserChain; - -public class UserChainManip { - /** - Build an element in the correct format for UserChain. - Format:::[:AS][,::]* - @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 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(); - } - -} diff --git a/core/src/main/java/com/att/cadi/wsse/Action.java b/core/src/main/java/com/att/cadi/wsse/Action.java deleted file mode 100644 index 0ed99c0..0000000 --- a/core/src/main/java/com/att/cadi/wsse/Action.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.wsse; - -/** - * Interface to specify an action deep within a parsing tree on a local object - * - * We use a Generic so as to be flexible on create what that object actually is. This is passed in at the - * root "parse" call of Match. Similar to a "Visitor" Pattern, this object is passed upon reaching the right - * point in a parse tree. - * - * - * @param - */ -interface Action { - public boolean content(OUTPUT output, String text); -} diff --git a/core/src/main/java/com/att/cadi/wsse/Match.java b/core/src/main/java/com/att/cadi/wsse/Match.java deleted file mode 100644 index e1c1078..0000000 --- a/core/src/main/java/com/att/cadi/wsse/Match.java +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.wsse; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.XMLEvent; - -/** - * Match Class allows you to build an automatic Tree of StAX (or StAX like) - * Objects for frequent use. - * - * OBJECT is a type which you which to do some end Actions on, similar to a Visitor pattern, see Action - * - * Note: We have implemented with XReader and XEvent, rather than StAX for performance reasons. - * - * @see Action - * @see Match - * @see XEvent - * @see XReader - * - * - * @param - */ -//@SuppressWarnings("restriction") -public class Match { - private QName qname; - private Match[] next; - private Match prev; - private Action action = null; - private boolean stopAfter; - private boolean exclusive; - - - @SafeVarargs - public Match(String ns, String name, Match ... next) { - this.qname = new QName(ns,name); - this.next = next; - stopAfter = exclusive = false; - for(Match m : next) { // add the possible tags to look for - if(!m.stopAfter)m.prev = this; - } - } - - public Match 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 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 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 exclusive() { - exclusive = true; - return this; - } - - public Match set(Action action) { - this.action = action; - return this; - } -} diff --git a/core/src/main/java/com/att/cadi/wsse/WSSEParser.java b/core/src/main/java/com/att/cadi/wsse/WSSEParser.java deleted file mode 100644 index 4c7ba90..0000000 --- a/core/src/main/java/com/att/cadi/wsse/WSSEParser.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.wsse; - -import java.io.IOException; -import java.io.InputStream; - -import javax.xml.stream.XMLStreamException; - -import com.att.cadi.BasicCred; - - -/** - * WSSE Parser - * - * Read the User and Password from WSSE Formatted SOAP Messages - * - * This class uses StAX so that processing is stopped as soon as the Security User/Password are read into BasicCred, or the Header Ends - * - * This class is intended to be created once (or very few times) and reused as much as possible. - * - * It is as thread safe as StAX parsing is. - * - */ -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 parseTree; - //private XMLInputFactory inputFactory; - - public WSSEParser() { - // soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/[wsse:Password&wsse:Username] - parseTree = new Match(SOAP_NS,"root", // need a root level to start from... Doesn't matter what the tag is - new Match(SOAP_NS,"Envelope", - new Match(SOAP_NS,"Header", - new Match(WSSE_NS,"Security", - new Match(WSSE_NS,"UsernameToken", - new Match(WSSE_NS,"Password").set(new Action() { - public boolean content(BasicCred bc,String text) { - bc.setCred(text.getBytes()); - return true; - } - }), - new Match(WSSE_NS,"Username").set(new Action() { - 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 - //inputFactory = XMLInputFactory.newInstance(); - } - - public XMLStreamException parse(BasicCred bc, InputStream is) throws IOException { - try { - parseTree.onMatch(bc, new XReader(is)); - return null; - } catch (XMLStreamException e) { - return e; - } - } -} diff --git a/core/src/main/java/com/att/cadi/wsse/XEvent.java b/core/src/main/java/com/att/cadi/wsse/XEvent.java deleted file mode 100644 index 51a2734..0000000 --- a/core/src/main/java/com/att/cadi/wsse/XEvent.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.wsse; - -import javax.xml.namespace.QName; -import javax.xml.stream.events.XMLEvent; - -/** - * XEvent - * - * This mechanism mimics a minimal portion of StAX "XMLEvent", enough to work with minimal XReader. - * - * We implement the same interface, as much as minimally necessary, as XMLEvent for these small usages so as to - * be interchangeable in the future, if so desired - * - * - */ -// @SuppressWarnings("restriction") -public abstract class XEvent { - - public abstract int getEventType(); - - public StartElement asStartElement() { - return (StartElement)this; - } - - public Characters asCharacters() { - return (Characters)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; - } - } - 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/core/src/main/java/com/att/cadi/wsse/XReader.java b/core/src/main/java/com/att/cadi/wsse/XReader.java deleted file mode 100644 index 833eb60..0000000 --- a/core/src/main/java/com/att/cadi/wsse/XReader.java +++ /dev/null @@ -1,416 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.wsse; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import javax.xml.stream.XMLStreamException; - -/** - * XReader - * This class works similarly as StAX, except StAX has more behavior than is needed. That would be ok, but - * StAX also was Buffering in their code in such as way as to read most if not all the incoming stream into memory, - * defeating the purpose of pre-reading only the Header - * - * This Reader does no back-tracking, but is able to create events based on syntax and given state only, leaving the - * Read-ahead mode of the InputStream up to the other classes. - * - * At this time, we only implement the important events, though if this is good enough, it could be expanded, perhaps to - * replace the original XMLReader from StAX. - * - * - */ -// @SuppressWarnings("restriction") -public class XReader { - private XEvent curr,another; - private InputStream is; - private ByteArrayOutputStream baos; - private int state, count, last; - - private Stack> nsses; - - public XReader(InputStream is) { - this.is = is; - curr = another = null; - baos = new ByteArrayOutputStream(); - state = BEGIN_DOC; - count = 0; - nsses = new Stack>(); - } - - public boolean hasNext() throws XMLStreamException { - if(curr==null) { - curr = parse(); - } - return curr!=null; - } - - 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 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.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 - 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... - 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 , ,or both - 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; - } - 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 getNss(Map nss, Tag t) { - Map 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():nss):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. - * - * - */ - public class Tag { - public int state; - public String prefix,name,value; - public List attribs; - - 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); - - char quote = ((state&DOC_TYPE)==DOC_TYPE)?'\'':'"'; - if(value!=null) { - sb.append('='); - sb.append(quote); - sb.append(value); - sb.append(quote); - } - return sb.toString(); - } - } - -} diff --git a/core/src/main/java/org/onap/aaf/cadi/AES.java b/core/src/main/java/org/onap/aaf/cadi/AES.java new file mode 100644 index 0000000..515fc27 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/AES.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import org.onap.aaf.cadi.util.Chmod; + +public class AES { + public static final String AES = AES.class.getSimpleName(); + public static final int AES_KEY_SIZE = 128; // 256 isn't supported on all JDKs. + + private Cipher aesCipher; + private SecretKeySpec aeskeySpec; + + public AES() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { + aesCipher = Cipher.getInstance(AES); + aeskeySpec = new SecretKeySpec(newKey().getEncoded(), AES); + } + + public static SecretKey newKey() throws NoSuchAlgorithmException { + KeyGenerator kgen = KeyGenerator.getInstance(AES); + kgen.init(AES_KEY_SIZE); + return kgen.generateKey(); + } + + public AES(File keyfile) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { + aesCipher = Cipher.getInstance(AES); + byte[] aesKey = new byte[AES_KEY_SIZE/8]; + FileInputStream fis = new FileInputStream(keyfile); + try { + fis.read(aesKey); + } finally { + fis.close(); + } + aeskeySpec = new SecretKeySpec(aesKey,AES); + } + + public AES(byte[] aeskey, int offset, int len) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException { + aesCipher = Cipher.getInstance(AES); + aeskeySpec = new SecretKeySpec(aeskey,offset,len,AES); + } + + public byte[] encrypt(byte[] in) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); + return aesCipher.doFinal(in); + } + + public byte[] decrypt(byte[] in) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); + return aesCipher.doFinal(in); + } + + 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 { + if(encrypt) { + aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); + } else { + aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); + } + } catch (InvalidKeyException e) { + // KeySpec created earlier... no chance being wrong. + } + return new CipherOutputStream(os,aesCipher); + } + + public CipherInputStream inputStream(InputStream is, boolean encrypt) { + try { + if(encrypt) { + aesCipher.init(Cipher.ENCRYPT_MODE,aeskeySpec); + } else { + aesCipher.init(Cipher.DECRYPT_MODE,aeskeySpec); + } + } catch (InvalidKeyException e) { + // KeySpec created earlier... no chance being wrong. + } + + return new CipherInputStream(is,aesCipher); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/AbsCachedPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/AbsCachedPrincipal.java new file mode 100644 index 0000000..ceb6ca3 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/AbsCachedPrincipal.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +public abstract class AbsCachedPrincipal implements CachedPrincipal { + protected TAF taf; + + protected AbsCachedPrincipal(TAF taf) { + this.taf = taf; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java b/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java new file mode 100644 index 0000000..1846793 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/AbsUserCache.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; + +/** + * Implement Fast lookup and Cache for Local User Info + * + * Include ability to add and remove Users + * + * Also includes a Timer Thread (when necessary) to invoke cleanup on expiring Credentials + * + * + */ +public abstract class AbsUserCache { + static final int MIN_INTERVAL = 15000; + static final int MAX_INTERVAL = 1000*60*5; // 5 mins + private static Timer timer; + // Map of userName to User + private final Map> userMap; + private final Map missMap; + private Clean clean; + protected Access access; +// private final static Permission teaser = new LocalPermission("***NoPERM****"); + + protected AbsUserCache(Access access, long cleanInterval, int highCount, int usageCount) { + this.access = access; + userMap = new ConcurrentHashMap>(); + missMap = new TreeMap(); + 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 cache) { + this.access = cache.access; + userMap = cache.userMap; + missMap = cache.missMap; + synchronized(AbsUserCache.class) { + if(cache.clean!=null && cache.clean.lur==null && this instanceof CachingLur) { + cache.clean.lur=(CachingLur)this; + } + } + } + + protected void setLur(CachingLur lur) { + if(clean!=null)clean.lur = lur; + + } + + protected void addUser(User user) { + userMap.put(user.principal.getName(), user); + } + + // Useful for looking up by WebToken, etc. + protected void addUser(String key, User 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 + */ + protected boolean addMiss(String key, byte[] bs) { + Miss miss = missMap.get(key); + if(miss==null) { + synchronized(missMap) { + missMap.put(key, new Miss(bs,clean==null?MIN_INTERVAL:clean.timeInterval)); + } + return true; + } + return miss.add(bs); + } + + protected Miss missed(String key) { + return missMap.get(key); + } + + protected User getUser(String userName) { + User u = userMap.get(userName); + if(u!=null) { + u.incCount(); + } + return u; + } + + protected User getUser(Principal principal) { + return getUser(principal.getName()); + } + + /** + * Removes User from the Cache + * @param user + */ + protected void remove(User 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() { + List rv = new ArrayList(); + for(User 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(); + } + } + + + + // Simple map of Group name to a set of User Names + // private Map> 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 perms; + + public DumpInfo(User 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. + * + * + */ + private final class Clean extends TimerTask { + private final Access access; + private CachingLur 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> al = new ArrayList>(userMap.values().size()); + al.addAll(0, userMap.values()); + long now = System.currentTimeMillis() + advance; + for(User user : al) { + ++total; + if(user.count>usageTriggerCount) { + // access.log(Level.AUDIT, "Checking Thread", new Date(now)); + boolean touched = false, removed=false; + if(user.principal instanceof CachedPrincipal) { + CachedPrincipal cp = (CachedPrincipal)user.principal; + if(cp.expires() < now) { + switch(cp.revalidate()) { + case INACCESSIBLE: + access.log(Level.AUDIT, "AAF Inaccessible. Keeping credentials"); + break; + case REVALIDATED: + user.resetCount(); + // access.log(Level.AUDIT, "CACHE revalidated credentials"); + touched = true; + break; + default: + user.resetCount(); + remove(user); + ++count; + removed = true; + break; + } + } + } + + // access.log(Level.AUDIT, "User Perm Expires", new Date(user.permExpires)); + if(!removed && lur!=null && user.permExpires<= now ) { + // access.log(Level.AUDIT, "Reloading"); + 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 keys = new ArrayList(missTotal); + keys.addAll(missMap.keySet()); + for(String key : keys) { + Miss m = missMap.get(key); + if(m!=null && m.timestamp0) { + 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()); + } + } + } + + public static class Miss { + private static final int MAX_TRIES = 3; + + long timestamp; + byte[][] array; + + private long timetolive; + + private int tries; + + public Miss(byte[] first, long timeInterval) { + array = new byte[MAX_TRIES][]; + array[0]=first; + timestamp = System.currentTimeMillis() + timeInterval; + this.timetolive = timeInterval; + tries = 1; + } + + public boolean mayContinue(byte[] bs) { + if(++tries > MAX_TRIES) return false; + for(byte[] a : array) { + if(a==null)return true; + if(equals(a,bs)) { + return false; + } + } + return true; + } + + public synchronized boolean add(byte[] bc) { + if(++tries>MAX_TRIES)return false; + timestamp = System.currentTimeMillis()+timetolive; + for(int i=0;i=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; + } + + // @Override + public int read(byte[] b) throws IOException { + return read(b,0,b.length); + } + + + // @Override + 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); +// System.out.println("Capacitor read " + count); + if(count<=0) { + capacitor.done(); + capacitor=null; // all done with buffer + } + if(count0) { // watch for -1 + count+=temp; + } else { + if(count<=0)count = temp; // must account for Stream coming back -1 + } + } + break; + } + } +// System.out.println("read reports " + count); + return count; + } + + // @Override + public long skip(long n) throws IOException { + long skipped = capacitor.skip(n); + if(skipped extends Lur { + public abstract void remove(String user); + public abstract Resp reload(User user); + public abstract void setDebug(String commaDelimIDsOrNull); + public abstract void clear(Principal p, StringBuilder sb); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/CadiException.java b/core/src/main/java/org/onap/aaf/cadi/CadiException.java new file mode 100644 index 0000000..f8b06ce --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/CadiException.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +/** + * CADI Specific Exception + */ +public class CadiException extends Exception { + /** + * Generated ID + */ + private static final long serialVersionUID = -4180145363107742619L; + + public CadiException() { + super(); + } + + public CadiException(String message) { + super(message); + } + + public CadiException(Throwable cause) { + super(cause); + } + + public CadiException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java b/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java new file mode 100644 index 0000000..6cf5694 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/CadiWrap.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.filter.NullPermConverter; +import org.onap.aaf.cadi.filter.PermConverter; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.taf.TafResp; + + + +/** + * Inherit the HttpServletRequestWrapper, which calls methods of delegate it's created with, but + * overload the key security mechanisms with CADI mechanisms + * + * This works with mechanisms working strictly with HttpServletRequest (i.e. Servlet Filters) + * + * Specialty cases, i.e. Tomcat, which for their containers utilize their own mechanisms and Wrappers, you may + * need something similar. See AppServer specific code (i.e. tomcat) for these. + * + * + */ +public class CadiWrap extends HttpServletRequestWrapper implements HttpServletRequest, BasicCred { + private Principal 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,"(HttpRequest)",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 { + perm = pconv.convert(perm); + if(lur.fish(principal,lur.createPerm(perm))) { + access.log(Level.DEBUG,caller, principal.getName(), "has", perm); + return true; + } else { + access.log(Level.DEBUG,caller, principal.getName(), "does not have", perm); + 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 getPermissions(Principal p) { + List 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; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Capacitor.java b/core/src/main/java/org/onap/aaf/cadi/Capacitor.java new file mode 100644 index 0000000..a7aa4f6 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Capacitor.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.nio.ByteBuffer; +import java.util.ArrayList; + +/** + * Capacitor + * + * Storage mechanism for read data, specifically designed for InputStreams. + * + * The Standard BufferedInputStream requires a limit to be set for buffered reading, which is + * impractical for reading SOAP headers, which can be quite large. + * + */ +public class Capacitor { + private static final int DEFAULT_CHUNK = 256; + private ArrayList 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(idx0) { // 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(idx0) { + 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; + 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(idx15)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/core/src/main/java/org/onap/aaf/cadi/CmdLine.java b/core/src/main/java/org/onap/aaf/cadi/CmdLine.java new file mode 100644 index 0000000..b387c7a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/CmdLine.java @@ -0,0 +1,356 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; + +import org.onap.aaf.cadi.util.Chmod; +import org.onap.aaf.cadi.util.JsonOutputStream; + + + +/** + * A Class to run on command line to determine suitability of environment for certain TAFs. + * + * For instance, CSP supports services only in certain domains, and while dynamic host + * lookups on the machine work in most cases, sometimes, names and IPs are unexpected (and + * invalid) for CSP because of multiple NetworkInterfaces, etc + * + * + */ +public class CmdLine { + + /** + * @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]; + } 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() + '"'); + } +// . 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 reguritate 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 + && (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.encryptMD5asStringHex(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 salt = Integer.parseInt(args[2]); + 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.baseCrypt().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.baseCrypt().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,repeats; + do { + pass = Symm.randomGen(numDigits); + noLower=noUpper=noDigits=noSpecial=true; + repeats=false; + int c=-1,last; + for(int i=0;i=0x61 && c<=0x7A); + continue; + } + if(noUpper) { + noUpper=!(c>=0x41 && c<=0x5A); + continue; + } + if(noDigits) { + noDigits=!(c>=0x30 && c<=0x39); + continue; + } + if(noSpecial) { + noSpecial = "+!@#$%^&*(){}[]?:;,.".indexOf(c)<0; + continue; + } + + break; + } + } while(noLower || noUpper || noDigits || noSpecial || repeats); + 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 if("csptest".equalsIgnoreCase(args[0])) { + try { + System.out.println("CSP Compatibility test"); + + String hostName = InetAddress.getLocalHost().getCanonicalHostName(); + + System.out.println(" Your automatic hostname is reported as \"" + hostName + "\"\n"); + System.out.flush(); + return; + } catch (UnknownHostException e) { + e.printStackTrace(System.err); + } + } + } else { + System.out.println("Usage: java -jar ..."); + System.out.println(" keygen [] (Generates Key on file, or Std Out)"); + System.out.println(" digest (Encrypts to Key with \"keyfile\")"); + System.out.println(" passgen (Generate Password of given size)"); + System.out.println(" urlgen (Generate URL field of given size)"); + System.out.println(" csptest (Tests for CSP compatibility)"); + System.out.println(" encode64 (Encodes to Base64)"); + System.out.println(" decode64 (Decodes from Base64)"); + System.out.println(" encode64url (Encodes to Base64 URL charset)"); + System.out.println(" decode64url (Decodes from Base64 URL charset)"); + System.out.println(" sha256 (Digest String into SHA256 Hash)"); + System.out.println(" md5 (Digest String into MD5 Hash)"); + } + System.exit(1); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Connector.java b/core/src/main/java/org/onap/aaf/cadi/Connector.java new file mode 100644 index 0000000..0a55b0d --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Connector.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +public interface Connector { + public Lur newLur() throws CadiException; +} diff --git a/core/src/main/java/org/onap/aaf/cadi/CredVal.java b/core/src/main/java/org/onap/aaf/cadi/CredVal.java new file mode 100644 index 0000000..324746b --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/CredVal.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +/** + * UserPass + * + * The essential interface required by BasicAuth to determine if a given User/Password combination is + * valid. This is done as an interface. + * + */ +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); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/GetCred.java b/core/src/main/java/org/onap/aaf/cadi/GetCred.java new file mode 100644 index 0000000..c0917a5 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/GetCred.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +public interface GetCred { + byte[] getCred(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Hash.java b/core/src/main/java/org/onap/aaf/cadi/Hash.java new file mode 100644 index 0000000..9d8719a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Hash.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class Hash { + private static char hexDigit[] = "0123456789abcdef".toCharArray(); + +///////////////////////////////// +// MD5 +///////////////////////////////// + /** + * Encrypt MD5 from Byte Array to Byte Array + * @param input + * @return + * @throws NoSuchAlgorithmException + */ + public static byte[] encryptMD5 (byte[] input) throws NoSuchAlgorithmException { + 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[] encryptMD5 (byte[] input, int offset, int length) throws NoSuchAlgorithmException { + 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 encryptMD5asStringHex(String input) throws NoSuchAlgorithmException { + byte[] output = encryptMD5(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 { + 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 { + 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 { + byte[] output = hashSHA256(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: 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()); + byte[] output = Hash.hashSHA256(bb.array()); + StringBuilder sb = new StringBuilder("0x"); + for (byte b : output) { + sb.append(hexDigit[(b >> 4) & 0x0f]); + sb.append(hexDigit[b & 0x0f]); + } + return sb.toString(); + } + + /** + * 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> 4) & 0x0f]); + sb.append(hexDigit[b & 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=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; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Locator.java b/core/src/main/java/org/onap/aaf/cadi/Locator.java new file mode 100644 index 0000000..05b6442 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Locator.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +public interface Locator { + 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/core/src/main/java/org/onap/aaf/cadi/LocatorException.java b/core/src/main/java/org/onap/aaf/cadi/LocatorException.java new file mode 100644 index 0000000..43127ec --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/LocatorException.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +public class LocatorException extends Exception { + /** + * + */ + private static final long serialVersionUID = -4267929804321134469L; + + public LocatorException(String arg0) { + super(arg0); + } + + public LocatorException(Throwable arg0) { + super(arg0); + } + + public LocatorException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public LocatorException(CharSequence cs) { + super(cs.toString()); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Lur.java b/core/src/main/java/org/onap/aaf/cadi/Lur.java new file mode 100644 index 0000000..afbf2dd --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Lur.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.security.Principal; +import java.util.List; + + + +/** + * LUR: Local User Registry + * + * Concept by Robert Garskof, Implementation by Jonathan Gathman + * + * Where we can keep local copies of users and roles for faster Authorization when asked. + * + * Note: Author cannot resist the mental image of using a Fishing Lure to this LUR pattern + * + * + */ +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); + + /** + * 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 permissions); + + /** + * 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); + + /** + * What domain of User does this LUR support? (used to avoid asking when not possible) + * + * @param bait + * @return + */ + public boolean supports(String userName); + + /** + * Clear: Clear any Caching, if exists + */ + public void clear(Principal p, StringBuilder report); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Permission.java b/core/src/main/java/org/onap/aaf/cadi/Permission.java new file mode 100644 index 0000000..ac0ec46 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Permission.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +public interface Permission { + public String permType(); + public String getKey(); + public boolean match(Permission p); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/PropAccess.java b/core/src/main/java/org/onap/aaf/cadi/PropAccess.java new file mode 100644 index 0000000..d866e85 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/PropAccess.java @@ -0,0 +1,321 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map.Entry; + +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfo; + +import java.util.Properties; + +public class PropAccess implements Access { + private static final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + + public static Level DEFAULT = Level.AUDIT; + + private Symm symm; + private int level; + private Properties props; + private List recursionProtection = null; + private PrintStream out; + + private String name; + + public PropAccess() { + out=System.out; + init(null); + } + + /** + * This Constructor soley exists to instantiate Servlet Context Based Logging that will call "init" later. + * @param sc + */ + protected PropAccess(Object o) { + out=System.out; + props = new Properties(); + } + + public PropAccess(String ... args) { + this(System.out,args); + } + + public PropAccess(PrintStream ps, String[] args) { + out=ps==null?System.out:ps; + 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); + } + + public PropAccess(Properties p) { + this(System.out,p); + } + + public PropAccess(PrintStream ps, Properties p) { + out=ps==null?System.out:ps; + init(p); + } + + 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 es : System.getProperties().entrySet()) { + String key = es.getKey().toString(); + for(String start : new String[] {"cadi_","aaf_","cm_","csp_"}) { + 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) { + symm = Symm.obtain(this); + } + + name = props.getProperty(Config.CADI_LOGNAME, name); + + // 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); + } + } + + private void load(String cadi_prop_files) { + String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); + + if(cadi_prop_files!=null) { + int prev = 0, end = cadi_prop_files.length(); + int idx; + String filename; + while(prev(); + 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; + } + } + // Reset Symm if Keyfile Changes: + String newKeyFile = props.getProperty(Config.CADI_KEYFILE); + if((prevKeyFile==null && newKeyFile!=null) || (newKeyFile!=null && !newKeyFile.equals(prevKeyFile))) { + symm = Symm.obtain(this); + 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); + } + } + } + + @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)) { + StringBuilder sb = buildMsg(level, elements); + out.println(sb); + out.flush(); + } + } + + protected StringBuilder buildMsg(Level level, Object[] elements) { + StringBuilder sb = new StringBuilder(iso8601.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 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 boolean willLog(Level level) { + return level.inMask(this.level); + } + + @Override + public ClassLoader classLoader() { + return ClassLoader.getSystemClassLoader(); + } + + @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); + } + + ////////////////// + // Additional + ////////////////// + public String getProperty(String tag) { + return props.getProperty(tag); + } + + + 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 + symm = Symm.obtain(this); + } + } + } + + public Properties getDME2Properties() { + return Config.getDME2Props(this); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Revalidator.java b/core/src/main/java/org/onap/aaf/cadi/Revalidator.java new file mode 100644 index 0000000..68b2661 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Revalidator.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +public interface Revalidator { + /** + * Re-Validate Credential + * + * @param prin + * @return + */ + public CachedPrincipal.Resp revalidate(TRANS trans, CachedPrincipal prin); + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/SLF4JAccess.java b/core/src/main/java/org/onap/aaf/cadi/SLF4JAccess.java new file mode 100644 index 0000000..33b7050 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/SLF4JAccess.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SLF4JAccess extends PropAccess { + private static final Logger slf4j = LoggerFactory.getLogger("AAF"); + + public SLF4JAccess(final Properties initial) throws CadiException { + super(initial); + } + + public void log(Level level, Object... elements) { + switch(level) { + case AUDIT: + slf4j.info(msg(elements).toString()); + break; + case DEBUG: + slf4j.debug(msg(elements).toString()); + break; + case ERROR: + slf4j.error(msg(elements).toString()); + break; + case INFO: + slf4j.info(msg(elements).toString()); + break; + case INIT: + slf4j.info(msg(elements).toString()); + break; + case WARN: + slf4j.warn(msg(elements).toString()); + break; + default: + slf4j.info(msg(elements).toString()); + break; + } + } + + /* (non-Javadoc) + * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) + */ + @Override + public boolean willLog(Level level) { + switch(level) { + case DEBUG: + return slf4j.isDebugEnabled(); + case ERROR: + return slf4j.isErrorEnabled(); + case WARN: + return slf4j.isWarnEnabled(); +// case INFO: +// case INIT: +// case AUDIT: + default: + return slf4j.isInfoEnabled(); + } + } + + private StringBuilder msg(Object ... elements) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(Object o : elements) { + if(first) first = false; + else { + sb.append(' '); + } + sb.append(o.toString()); + } + return sb; + } + + public void log(Exception e, Object... elements) { + slf4j.error(msg(elements).toString(),e); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java b/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java new file mode 100644 index 0000000..88c45b0 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/SecuritySetter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +/** + * Apply any particular security mechanism + * + * This allows the definition of various mechanisms involved outside of DRcli jars + * + * + */ +public interface SecuritySetter { + 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/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java b/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java new file mode 100644 index 0000000..6c288d5 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/ServletContextAccess.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; +import java.util.Enumeration; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + +import org.onap.aaf.cadi.config.Config; + +public class ServletContextAccess extends PropAccess { + + private ServletContext context; + + public ServletContextAccess(FilterConfig filterConfig) { + super(filterConfig); // protected contstructor... 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()); + Config.getDME2Props(this); + } + + /* (non-Javadoc) + * @see com.att.cadi.PropAccess#log(com.att.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 com.att.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; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/StrLur.java b/core/src/main/java/org/onap/aaf/cadi/StrLur.java new file mode 100644 index 0000000..1a86c8e --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/StrLur.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.util.List; + + + +/** + * StrLUR: Implements fish with String, skipping the need to be a Principal where it doesn't make sense. + * + * + */ +public interface StrLur extends Lur { + /** + * 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(String 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(String bait, List permissions); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Symm.java b/core/src/main/java/org/onap/aaf/cadi/Symm.java new file mode 100644 index 0000000..beb0c40 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Symm.java @@ -0,0 +1,811 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Random; + +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; + +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; + +/** + * Key Conversion, primarily "Base64" + * + * Base64 is required for "Basic Authorization", which is an important part of the overall CADI Package. + * + * Note: This author found that there is not a "standard" library for Base64 conversion within Java. + * The source code implementations available elsewhere were surprisingly inefficient, requiring, for + * instance, multiple string creation, on a transaction pass. Integrating other packages that might be + * efficient enough would put undue Jar File Dependencies given this Framework should have none-but-Java + * dependencies. + * + * The essential algorithm is good for a symmetrical key system, as Base64 is really just + * a symmetrical key that everyone knows the values. + * + * This code is quite fast, taking about .016 ms for encrypting, decrypting and even .08 for key + * generation. The speed quality, especially of key generation makes this a candidate for a short term token + * used for identity. + * + * It may be used to easily avoid placing Clear-Text passwords in configurations, etc. and contains + * supporting functions such as 2048 keyfile generation (see keygen). This keyfile should, of course, + * be set to "400" (Unix) and protected as any other mechanism requires. + * + * However, this algorithm has not been tested against hackers. Until such a time, utilize more tested + * packages to protect Data, especially sensitive data at rest (long term). + * + */ +public class Symm { + private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; + public static final String ENC = "enc:"; + 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; + //Note: AES Encryption is not Thread Safe. It is Synchronized + private static 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); + + /** + * 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(); + + + + /** + * 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 la = new ArrayList(); + for(int i=0;icodeset.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; + } + + /* + * Note: AES Encryption is NOT thread-safe. Must surround entire use with synchronized + */ + private synchronized void exec(AESExec exec) throws IOException { + if(aes == null) { + try { + byte[] bytes = new byte[AES.AES_KEY_SIZE/8]; + int offset = (Math.abs(codeset[0])+47)%(codeset.length-bytes.length); + for(int i=0;i=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 { + is.skip(skip); + decode(is,os); + } + + /** + * 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(); + } + + /** + * Interface to allow this class to choose which algorithm to find index of character in Key + * + */ + private interface Convert { + public int convert(int read) throws IOException; + } + + /** + * Ordered uses a range of orders to compare against, rather than requiring the investigation + * of every character needed. + * + */ + private static final class Ordered implements Convert { + private int[][] range; + public Ordered(int[][] range) { + this.range = range; + } + public int convert(int read) throws IOException { + switch(read) { + case -1: + case '=': + case '\n': + return -1; + } + for(int i=0;i= range[i][0] && read<=range[i][1]) { + return read-range[i][2]; + } + } + throw new IOException("Unacceptable Character in Stream"); + } + } + + /** + * Unordered, i.e. the key is purposely randomized, simply has to investigate each character + * until we find a match. + * + */ + 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': + return -1; + } + for(int i=0;i=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=0;--j) { + if(seq[j]==0) { + seq[j]=codeset[filled]; + --filled; + break; + } + } + right = true; + } + } + return new Symm(seq,this); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Taf.java b/core/src/main/java/org/onap/aaf/cadi/Taf.java new file mode 100644 index 0000000..d4b2211 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Taf.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import org.onap.aaf.cadi.taf.TafResp; + + +/** + * TAF - Transmutative Assertion Framework. + * + * This main Interface embodies the essential of the assertion, where a number of different TAFs might be used to authenticate + * and that authentication to be recognized through other elements. + * + * Concept by Robert Garskof. Implemented by Jonathan Gathman + * + * + */ +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. JG 10/18/2012 + * + * @param lifeForm + * @param info + * @return + */ + public TafResp validate(LifeForm reading, String ... info); + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/Transmutate.java b/core/src/main/java/org/onap/aaf/cadi/Transmutate.java new file mode 100644 index 0000000..950f28f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/Transmutate.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.security.Principal; + +/** + * The unique element of TAF is that we establish the relationship/mechanism to mutate the Principal derived from + * one Authentication mechanism into a trustable Principal of another. The mechanism needs to be decided by system + * trusting. + * + * The Generic "T" is used so that the code used will be very specific for the implementation, enforced by Compiler + * + * This interface will allow differences of trusting Transmutation of Authentication + * + */ +public interface Transmutate { + /** + * 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/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java b/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java new file mode 100644 index 0000000..feade74 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/TrustChecker.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + + +import javax.servlet.http.HttpServletRequest; + +import org.onap.aaf.cadi.taf.TafResp; + +/** + * Change to another Principal based on Trust of caller and User Chain (if desired) + * + * + */ +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; + } + + @Override + public void setLur(Lur lur) { + } + }; + + public void setLur(Lur lur); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/User.java b/core/src/main/java/org/onap/aaf/cadi/User.java new file mode 100644 index 0000000..372e9bc --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/User.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +import java.security.Principal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.onap.aaf.cadi.lur.LocalPermission; + +/** + * Class to hold info from the User Perspective. + * + * + */ +public final class User { + private static Map NULL_MAP = new HashMap(); + public Principal principal; + Map 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; + 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; + perms = NULL_MAP; + expireInterval = Math.max(expireInterval, 0); // avoid < 1 + interval = Math.max(AbsUserCache.MIN_INTERVAL,Math.min(expireInterval,AbsUserCache.MAX_INTERVAL)); + permExpires = 0; + count = 0; + } + + 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.values().size()==0; + } + + public void setNoPerms() { + perms=NULL_MAP; + permExpires = System.currentTimeMillis() + interval; + } + + public boolean permsUnloaded() { + return perms==null; + } + + public synchronized void incCount() { + ++count; + } + + public synchronized void resetCount() { + count=0; + } + + public Map newMap() { + return new ConcurrentHashMap(); + } + + public void add(LocalPermission permission) { + if(perms==NULL_MAP)perms=newMap(); + perms.put(permission.getKey(),permission); + } + + public void add(Map newMap, PERM permission) { + newMap.put(permission.getKey(),permission); + } + + public void setMap(Map newMap) { + perms = newMap; + } + + public boolean contains(Permission perm) { + for (Permission p : perms.values()) { + if (p.match(perm)) return true; + } + return false; + } + + public void copyPermsTo(List 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(); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/UserChain.java b/core/src/main/java/org/onap/aaf/cadi/UserChain.java new file mode 100644 index 0000000..ac04792 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/UserChain.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi; + +/** + * Interface to add a User Chain String to Principal + * + * + * + * Where + * APP is name suitable for Logging (i.e. official App Acronym) + * ID is official User or MechID, best if includes Identity Source (i.e. ab1234@csp.att.com) + * Protocol is the Security protocol, + * + * Format:::[:AS][,::]* + * + * + * + */ +public interface UserChain { + public enum Protocol {BasicAuth,Cookie,Cert,OAuth}; + public String userChain(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/core/src/main/java/org/onap/aaf/cadi/config/Config.java new file mode 100644 index 0000000..4128665 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/Config.java @@ -0,0 +1,815 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.config; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CachingLur; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.lur.LocalLur; +import org.onap.aaf.cadi.lur.NullLur; +import org.onap.aaf.cadi.taf.HttpEpiTaf; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.basic.BasicHttpTaf; +import org.onap.aaf.cadi.taf.cert.X509Taf; +import org.onap.aaf.cadi.taf.dos.DenialOfServiceTaf; + +import java.util.Properties; +import java.util.TimerTask; + +/** + * Create a Consistent Configuration mechanism, even when configuration styles are as vastly different as + * Properties vs JavaBeans vs FilterConfigs... + * + * + */ +public class Config { + + private static final String HIDE_PASS = "***************"; + + 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_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_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 CSP_DOMAIN = "csp_domain"; + public static final String CSP_HOSTNAME = "csp_hostname"; + public static final String CSP_DEVL_LOCALHOST = "csp_devl_localhost"; + public static final String CSP_USER_HEADER = "CSP_USER"; + public static final String CSP_SYSTEMS_CONF = "CSPSystems.conf"; + public static final String CSP_SYSTEMS_CONF_FILE = "csp_systems_conf_file"; + + + public static final String TGUARD_ENV="tguard_env"; + public static final String TGUARD_DOMAIN = "tguard_domain"; + public static final String TGUARD_TIMEOUT = "tguard_timeout"; + public static final String TGUARD_TIMEOUT_DEF = "5000"; + public static final String TGUARD_CERTS = "tguard_certs"; // comma delimited SHA-256 finger prints +// public static final String TGUARD_DEVL_LOCALHOST = "tguard_devl_localhost"; +// public static final String TGUARD_USER_HEADER = "TGUARD_USER"; + + 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 AAF_ENV = "aaf_env"; + public static final String AAF_ROOT_NS = "aaf_root_ns"; + public static final String AAF_ROOT_COMPANY = "aaf_root_company"; + public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration + public static final String AAF_MECHID = "aaf_id"; + public static final String AAF_MECHPASS = "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_READ_TIMEOUT = "aaf_timeout"; + public static final String AAF_READ_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_DEPLOYED_VERSION = "DEPLOYED_VERSION"; + 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 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"; + + public static final String AFT_DME2_TRUSTSTORE_PASSWORD = "AFT_DME2_TRUSTSTORE_PASSWORD"; + public static final String AFT_DME2_TRUSTSTORE = "AFT_DME2_TRUSTSTORE"; + public static final String AFT_DME2_KEYSTORE_PASSWORD = "AFT_DME2_KEYSTORE_PASSWORD"; + public static final String AFT_DME2_KEY_PASSWORD = "AFT_DME2_KEY_PASSWORD"; + public static final String AFT_DME2_KEYSTORE = "AFT_DME2_KEYSTORE"; + public static final String AFT_DME2_SSL_TRUST_ALL = "AFT_DME2_SSL_TRUST_ALL"; + public static final String AFT_DME2_SSL_INCLUDE_PROTOCOLS = "AFT_DME2_SSL_INCLUDE_PROTOCOLS"; + + + // DME2 Client. First property must be set to "false", and the others set in order to use SSL Client + public static final String AFT_DME2_CLIENT_IGNORE_SSL_CONFIG="AFT_DME2_CLIENT_IGNORE_SSL_CONFIG"; + public static final String AFT_DME2_CLIENT_KEYSTORE = "AFT_DME2_CLIENT_KEYSTORE"; + public static final String AFT_DME2_CLIENT_KEYSTORE_PASSWORD = "AFT_DME2_CLIENT_KEYSTORE_PASSWORD"; + public static final String AFT_DME2_CLIENT_TRUSTSTORE = "AFT_DME2_CLIENT_TRUSTSTORE"; + public static final String AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD = "AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD"; + public static final String AFT_DME2_CLIENT_SSL_CERT_ALIAS = "AFT_DME2_CLIENT_SSL_CERT_ALIAS"; + public static final String AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS = "AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS"; + + + // 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"; + public static final String AAF_DOMAIN_SUPPORT_DEF = ".org"; + + + public static void setDefaultRealm(Access access) throws CadiException { + try { + boolean hasCSP; + try { + Class.forName("com.att.cadi.taf.csp.CSPTaf"); + hasCSP=true; + } catch(ClassNotFoundException e) { + hasCSP = logProp(access,Config.CSP_DOMAIN, null)!=null; + } + defaultRealm = logProp(access,Config.AAF_DEFAULT_REALM, + hasCSP?"csp.att.com": + logProp(access,Config.BASIC_REALM, + logProp(access,HOSTNAME,InetAddress.getLocalHost().getHostName()) + ) + ); + } catch (UnknownHostException e) { + //defaultRealm="none"; + } + } + + + public static HttpTaf configHttpTaf(Access access, TrustChecker tc, CredVal up, Lur lur, Object ... additionalTafLurs) throws CadiException { + ///////////////////////////////////////////////////// + // Setup AAFCon for any following + ///////////////////////////////////////////////////// + Object aafcon = null; + if(lur != null) { + Field f = null; + try { + f = lur.getClass().getField("aaf"); + aafcon = f.get(lur); + } catch (Exception nsfe) { + } + } + // IMPORTANT! Don't attempt to load AAF Connector if there is no AAF URL + String aafURL = access.getProperty(AAF_URL,null); + if(aafcon==null && aafURL!=null) { + aafcon = loadAAFConnector(access, 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 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 LocalHost + ///////////////////////////////////////////////////// + + String truststore = logProp(access, CADI_TRUSTSTORE, access.getProperty("AFT_DME2_TRUSTSTORE", null)); + if(truststore!=null) { + String truststore_pwd = access.getProperty(CADI_TRUSTSTORE_PASSWORD, access.getProperty("AFT_DME2_TRUSTSTORE_PASSWORD",null)); + if(truststore_pwd!=null) { + if(truststore_pwd.startsWith(Symm.ENC)) { + try { + truststore_pwd = access.decrypt(truststore_pwd,false); + } catch (IOException e) { + throw new CadiException(CADI_TRUSTSTORE_PASSWORD + " cannot be decrypted",e); + } + } + try { + htlist.add(new X509Taf(access,lur)); + access.log(Level.INIT,"Certificate Authorization enabled"); + } catch (SecurityException e) { + access.log(Level.INIT,"AAFListedCertIdentity cannot be instantiated. Certificate Authorization is now disabled",e); + } catch (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) + ///////////////////////////////////////////////////// + String basic_realm = logProp(access, BASIC_REALM,null); + boolean basic_warn = "TRUE".equals(access.getProperty(BASIC_WARN,"FALSE")); + if(basic_realm!=null && up!=null) { + access.log(Level.INIT,"Basic Authorization is enabled using realm",basic_realm); + // Allow warning about insecure channel to be turned off + if(!basic_warn)access.log(Level.INIT,"WARNING! The basic_warn property has been set to false.", + " There will be no additional warning if Basic Auth is used on an insecure channel" + ); + String aafCleanup = logProp(access, AAF_USER_EXPIRES,AAF_USER_EXPIRES_DEF); // Default is 10 mins + long userExp = Long.parseLong(aafCleanup); + + htlist.add(new BasicHttpTaf(access, up, basic_realm, userExp, basic_warn)); + } else { + access.log(Level.INIT,"Local Basic Authorization is disabled. Enable by setting basic_realm="); + } + + ///////////////////////////////////////////////////// + // Configure AAF Driven Basic Auth + ///////////////////////////////////////////////////// + boolean getRemoteAAF = true; + if(additionalTafLurs!=null) { + for(Object o : additionalTafLurs) { + if(o.getClass().getSimpleName().equals("DirectAAFLur")) { + getRemoteAAF = false; + break; + } + } + } + HttpTaf aaftaf=null; + if(getRemoteAAF) { + 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 defName = aafURL.contains("version=2.0")?"com.att.cadi.aaf.v2_0.AAFTaf":""; + String aafTafClassName = logProp(access, AAF_TAF_CLASS,defName); + // Only 2.0 available at this time + if("com.att.cadi.aaf.v2_0.AAFTaf".equals(aafTafClassName)) { + try { + Class aafTafClass = loadClass(access,aafTafClassName); + Class aafConClass = loadClass(access,"com.att.cadi.aaf.v2_0.AAFCon"); + + Constructor cstr = aafTafClass.getConstructor(aafConClass,boolean.class,AbsUserCache.class); + if(cstr!=null) { + aaftaf = (HttpTaf)cstr.newInstance(aafcon,basic_warn,lur); + 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 + } + } + } catch(Exception e) { + access.log(Level.INIT,"ERROR! AAF TAF Failed construction. NOT Configured"); + } + } + } + } + + + String alias = logProp(access, CADI_ALIAS,null); + + ///////////////////////////////////////////////////// + // Configure tGuard... (AT&T Client Repo) + ///////////////////////////////////////////////////// + // TGUARD Environment, translated to any other remote Environment validation mechanism... + String tGuard_domain = logProp(access, TGUARD_DOMAIN,null); + String tGuard_env = logProp(access, TGUARD_ENV, null); + + if(!("PROD".equals(tGuard_env) || "STAGE".equals(tGuard_env))) { + access.log(Level.INIT, "tGuard Authorization is disabled. Enable by setting", TGUARD_ENV, "to \"PROD\" or \"STAGE\""); + } else if(tGuard_domain==null) { + access.log(Level.INIT,TGUARD_DOMAIN + " must be set: tGuard Authorization is disabled."); + } else if(alias == null) { + access.log(Level.INIT,CADI_ALIAS + " must be set: tGuard Authorization is disabled."); + } else { + try { + Class tGuardClass = loadClass(access,"com.att.cadi.tguard.TGuardHttpTaf"); + if(aaftaf!=null) { + Constructor tGuardCnst = tGuardClass.getConstructor(new Class[]{Access.class, AbsUserCache.class}); + htlist.add((HttpTaf)tGuardCnst.newInstance(new Object[] {access,aaftaf})); + access.log(Level.INIT,"tGuard Authorization is enabled on",tGuard_env,"on the",tGuard_domain," tGuard Domain"); + } else { + Constructor tGuardCnst = tGuardClass.getConstructor(new Class[]{Access.class, int.class, int.class, int.class}); + htlist.add((HttpTaf)tGuardCnst.newInstance(new Object[] { + access, + Integer.parseInt(logProp(access, AAF_CLEAN_INTERVAL,AAF_CLEAN_INTERVAL_DEF)), + Integer.parseInt(logProp(access, AAF_HIGH_COUNT, AAF_HIGH_COUNT_DEF)), + Integer.parseInt(logProp(access, AAF_REFRESH_TRIGGER_COUNT, AAF_REFRESH_TRIGGER_COUNT_DEF)) + })); + access.log(Level.INIT,"tGuard Authorization is enabled on",tGuard_env,"on the",tGuard_domain," tGuard Domain"); + } + } catch(Exception e) { + access.log(e, Level.INIT,"tGuard Class cannot be loaded: tGuard Authorization is disabled."); + } + } + + ///////////////////////////////////////////////////// + // 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 HttpTaf) { + htlist.add((HttpTaf)additional); + access.log(Level.INIT,additional); + } + } + } + + ///////////////////////////////////////////////////// + // 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 locator = loadLocator(access, logProp(access, CADI_LOGINPAGE_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 set"); + } else { + access.log(Level.INIT,tag,"is set to",rv); + } + return rv; + } + + public static Lur configLur(Access access, Object ... additionalTafLurs) throws CadiException { + List 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; + lurs.add(ll = new LocalLur(access, users, groups)); // note b64==null is ok.. just means no encryption. + + 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 AAF Lur (if any) + ///////////////////////////////////////////////////// + String aafURL = logProp(access,AAF_URL,null); // Trigger Property + String aaf_env = access.getProperty(AAF_ENV,null); + if(aaf_env == 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) { + aaf_env = aafURL.substring(ec, slash); + ((PropAccess)access).setProperty(AAF_ENV, aaf_env); + access.printf(Level.INIT, "Setting aaf_env to %s from aaf_url value",aaf_env); + } + } + } + + 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,"com.att.cadi.aaf.v2_0.AAFLurPerm"); + ////////////AAF Lur 2.0 ///////////// + if(aafLurClassStr.startsWith("com.att.cadi.aaf.v2_0")) { + try { + Object aafcon = loadAAFConnector(access, aafURL); + if(aafcon==null) { + access.log(Level.INIT,"AAF LUR class,",aafLurClassStr,"cannot be constructed without valid AAFCon object."); + } else { + Class aafAbsAAFCon = loadClass(access, "com.att.cadi.aaf.v2_0.AAFCon"); + 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 final String COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2 = "com.att.cadi.aaf.v2_0.AAFConDME2"; + private static final String COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP = "com.att.cadi.aaf.v2_0.AAFConHttp"; + public static Object loadAAFConnector(Access access, String aafURL) { + Object aafcon = null; + Class aafConClass = null; + + try { + if(aafURL!=null) { + String aafConnector = access.getProperty(AAF_CONNECTOR_CLASS, COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP); + if(COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2.equals(aafConnector) || aafURL.contains("/service=")) { + aafConClass = loadClass(access, COM_ATT_CADI_AAF_V2_0_AAF_CON_DME2); + if(aafConClass!=null) { + Constructor cons = aafConClass.getConstructor(PropAccess.class); + aafcon = cons.newInstance(access); + } else { + access.log(Level.ERROR, "URL contains '/service=', which requires DME2"); + } + } else if(COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP.equals(aafConnector)) { + aafConClass = loadClass(access, COM_ATT_CADI_AAF_V2_0_AAF_CON_HTTP); + for(Constructor c : aafConClass.getConstructors()) { + List lo = new ArrayList(); + for(Class pc : c.getParameterTypes()) { + if(pc.equals(PropAccess.class)) { + lo.add(access); + } else if(pc.equals(Locator.class)) { + lo.add(loadLocator(access, aafURL)); + } else { + continue; + } + } + 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_MECHID, null); + String pass = access.getProperty(Config.AAF_MECHPASS, null); + if(mechid!=null && pass!=null) { + try { + Method basicAuth = aafConClass.getMethod("basicAuth", String.class, String.class); + basicAuth.invoke(aafcon, mechid,pass); + } catch (NoSuchMethodException 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) { + try { + cls = access.getClass().getClassLoader().loadClass(className); + } catch (ClassNotFoundException cnfe2) { + // just return null + } + } + return cls; + } + + @SuppressWarnings("unchecked") + public static Locator loadLocator(Access access, String url) { + Locator locator = null; + if(url==null) { + access.log(Level.INIT,"No URL for AAF Login Page. Disabled"); + } else { + if(url.contains("DME2RESOLVE")) { + try { + Class lcls = loadClass(access,"com.att.cadi.locator.DME2Locator"); + Class dmcls = loadClass(access,"com.att.aft.dme2.api.DME2Manager"); + Constructor cnst = lcls.getConstructor(new Class[] {Access.class,dmcls,String.class}); + locator = (Locator)cnst.newInstance(new Object[] {access,null,url}); + access.log(Level.INFO, "DME2Locator enabled with " + url); + } catch (Exception e) { + access.log(Level.INIT,"AAF Login Page accessed by " + url + " requires DME2. It is now disabled",e); + } + } else { + try { + Class cls = loadClass(access,"com.att.cadi.locator.PropertyLocator"); + Constructor cnst = cls.getConstructor(new Class[] {String.class}); + locator = (Locator)cnst.newInstance(new Object[] {url}); + access.log(Level.INFO, "PropertyLocator enabled with " + url); + } catch (Exception e) { + access.log(Level.INIT,"AAF Login Page accessed by " + url + " requires PropertyLocator. It is now disabled",e); + } + } + } + return locator; + } + + /* + * DME2 can only read Passwords as clear text properties. Leaving in "System Properties" un-encrypted exposes these passwords + */ + public static class PasswordRemoval extends TimerTask { + private Access access; + + private final List pws; + + public PasswordRemoval(Access access) { + this.access = access; + pws = new ArrayList(); + } + + @Override + public void run() { + for(String key:pws) { + access.log(Level.INIT, "Scrubbing " + key); + System.clearProperty(key); + } + } + public void add(String key) { + pws.add(key); + } + } + + private static final String Y = "Y"; + + private static String[][] CONVERTER_STRINGS=new String[][] { + {AFT_DME2_KEYSTORE,CADI_KEYSTORE,null}, + {AFT_DME2_KEYSTORE_PASSWORD,CADI_KEYSTORE_PASSWORD,null}, + {AFT_DME2_KEY_PASSWORD,CADI_KEY_PASSWORD,null}, + {AFT_DME2_TRUSTSTORE,CADI_TRUSTSTORE,null}, + {AFT_DME2_TRUSTSTORE_PASSWORD,CADI_TRUSTSTORE_PASSWORD,null}, + {AFT_DME2_CLIENT_KEYSTORE,CADI_KEYSTORE,null}, + {AFT_DME2_CLIENT_KEYSTORE_PASSWORD,CADI_KEYSTORE_PASSWORD,null}, + {AFT_DME2_CLIENT_TRUSTSTORE,CADI_TRUSTSTORE,null}, + {AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD,CADI_TRUSTSTORE_PASSWORD,null}, + {AFT_DME2_CLIENT_SSL_CERT_ALIAS,CADI_ALIAS,null}, + {AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS,CADI_PROTOCOLS,null}, + {"AFT_DME2_HOSTNAME",HOSTNAME,null}, + {"AFT_LATITUDE",null,Y}, + {"AFT_LONGITUDE",null,Y}, + {"AFT_ENVIRONMENT",null,Y}, + {"SCLD_PLATFORM",null,Y}, + {"DME2_EP_REGISTRY_CLASS",null,Y},// for Developer local access + {"AFT_DME2_EP_REGISTRY_FS_DIR",null,Y}, + {"DME2.DEBUG",null,null}, + {"AFT_DME2_HTTP_EXCHANGE_TRACE_ON",null,null}, + {"AFT_DME2_SSL_ENABLE",null,null}, + {"AFT_DME2_SSL_WANT_CLIENT_AUTH",null,null}, + {AFT_DME2_SSL_INCLUDE_PROTOCOLS,CADI_PROTOCOLS,null}, + {"AFT_DME2_SSL_VALIDATE_CERTS",null,null}, + {AFT_DME2_CLIENT_IGNORE_SSL_CONFIG,null,null}, + {"https.protocols",CADI_PROTOCOLS,Y}, + }; + + + + public static Properties getDME2Props(PropAccess access) { + Properties dprops = new Properties(); + String value = null; + boolean reqClientConfig = false; + for(String[] row : CONVERTER_STRINGS) { + value = access.getProperty(row[0],null); + if(value==null) { + value = System.getProperty(row[0]); + if(value==null && row[1]!=null) { + value = access.getProperty(row[1],null); + if(value == null) { + value = System.getProperty(row[1]); + } + } + } + if(value!=null) { + if(row[0].contains("_SSL_")) { + reqClientConfig = true; + } + if(row[0].startsWith("AFT") || row[0].startsWith("SCLD") || row[0].contains("DME2")) { + if(value.startsWith("enc:")) { + try { + value = access.decrypt(value, true); + } catch (IOException e) { + access.log(Level.ERROR, e); + } + System.setProperty(row[0], value); + } else if(Y.equals(row[2])) { + System.setProperty(row[0], value); + dprops.setProperty(row[0], value); + } else if(row[0].contains("PASSWORD") || row[0].contains("STORE")) { + System.setProperty(row[0], value); + } else { + dprops.setProperty(row[0], value); + } + } + + } + + } + + Properties sprops = System.getProperties(); + if(reqClientConfig && sprops.getProperty(AFT_DME2_CLIENT_IGNORE_SSL_CONFIG)==null) { + sprops.put(AFT_DME2_CLIENT_IGNORE_SSL_CONFIG, "false"); + replaceKeyWithTrust(sprops,AFT_DME2_KEYSTORE,AFT_DME2_TRUSTSTORE); + replaceKeyWithTrust(sprops,AFT_DME2_KEYSTORE_PASSWORD,AFT_DME2_TRUSTSTORE_PASSWORD); + replaceKeyWithTrust(sprops,AFT_DME2_CLIENT_KEYSTORE,AFT_DME2_CLIENT_TRUSTSTORE); + replaceKeyWithTrust(sprops,AFT_DME2_CLIENT_KEYSTORE_PASSWORD,AFT_DME2_CLIENT_TRUSTSTORE_PASSWORD); + } + + if(sprops.getProperty(AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS)==null) { + sprops.setProperty(AFT_DME2_CLIENT_SSL_INCLUDE_PROTOCOLS, access.getProperty(CADI_PROTOCOLS,SecurityInfo.HTTPS_PROTOCOLS_DEFAULT)); + } + + if(sprops.getProperty(AFT_DME2_SSL_INCLUDE_PROTOCOLS)==null) { + sprops.setProperty(AFT_DME2_SSL_INCLUDE_PROTOCOLS, access.getProperty(CADI_PROTOCOLS,SecurityInfo.HTTPS_PROTOCOLS_DEFAULT)); + } + + if(access.willLog(Level.DEBUG)) { + if(access instanceof PropAccess) { + access.log(Level.DEBUG,"Access Properties"); + for(Entry es : ((PropAccess)access).getProperties().entrySet()) { + access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),es.getValue().toString()); + } + } + access.log(Level.DEBUG,"DME2 Properties()"); + for(Entry es : dprops.entrySet()) { + value = es.getValue().toString(); + if(es.getKey().toString().contains("PASS")) { + if(value==null || !value.contains("enc:")) { + value = HIDE_PASS; + } + } + access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),value); + } + + access.log(Level.DEBUG,"System (AFT) Properties"); + for(Entry es : System.getProperties().entrySet()) { + if(es.getKey().toString().startsWith("AFT")) { + value = es.getValue().toString(); + if(es.getKey().toString().contains("PASS")) { + if(value==null || !value.contains("enc:")) { + value = HIDE_PASS; + } + } + access.printf(Level.DEBUG," %s=%s",es.getKey().toString(),value); + } + } + } + // Cover any not specific AFT props + String key; + for(Entry es : access.getProperties().entrySet()) { + if((key=es.getKey().toString()).startsWith("AFT_") && + !key.contains("PASSWORD") && + dprops.get(key)==null) { + dprops.put(key, es.getValue()); + } + } + return dprops; + } + + private static void replaceKeyWithTrust(Properties props, String ks, String ts) { + String value; + if(props.get(ks)==null && (value=props.getProperty(ts))!=null) { + props.put(ks,value); + props.remove(ts); + } + } + // Set by CSP, or is hostname. + public static String getDefaultRealm() { + return defaultRealm; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/config/Get.java b/core/src/main/java/org/onap/aaf/cadi/config/Get.java new file mode 100644 index 0000000..ea06c87 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/Get.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.config; + +import java.lang.reflect.Method; + +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 + * + */ + 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 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/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java b/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java new file mode 100644 index 0000000..dc5e4ef --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/GetAccess.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +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 com.att.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 com.att.cadi.PropAccess#getProperty(java.lang.String) + */ + @Override + public String getProperty(String tag) { + String rv; + rv = super.getProperty(tag, null); + if(rv==null && getter!=null) { + rv = getter.get(tag, null, true); + } + return rv; + } + + public Get get() { + return getter; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/config/MultiGet.java b/core/src/main/java/org/onap/aaf/cadi/config/MultiGet.java new file mode 100644 index 0000000..551018c --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/MultiGet.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.config; + +public class MultiGet implements Get { + private Get[] getters; + + public MultiGet(Get ... getters) { + this.getters = getters; + } + + @Override + public String get(String name, String def, boolean print) { + String str; + for(Get getter : getters) { + str = getter.get(name, null, print); + if(str!=null) + return str; + } + return def; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java b/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java new file mode 100644 index 0000000..4301d53 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.rmi.AccessException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509KeyManager; +import javax.net.ssl.X509TrustManager; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +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"; + + public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; + public static final String REGEX_COMMA = "\\s*,\\s*"; + public static final String SslKeyManagerFactoryAlgorithm; + + private SSLSocketFactory scf; + private X509KeyManager[] km; + private X509TrustManager[] tm; + public final String default_alias; + private NetMask[] trustMasks; + private SSLContext ctx; + private HostnameVerifier maskHV; + + // Change Key Algorithms for IBM's VM. Could put in others, if needed. + static { + if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) { + SslKeyManagerFactoryAlgorithm = "IbmX509"; + } else { + SslKeyManagerFactoryAlgorithm = "SunX509"; + } + } + + + public SecurityInfo(final Access access) throws GeneralSecurityException, IOException { + // reuse DME2 Properties for convenience if specific Properties don't exist + String keyStore = access.getProperty(Config.CADI_KEYSTORE, + access.getProperty(Config.AFT_DME2_KEYSTORE,null)); + String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, + access.getProperty(Config.AFT_DME2_KEYSTORE_PASSWORD, null)); + keyStorePasswd = keyStorePasswd==null?null:access.decrypt(keyStorePasswd,false); + String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, + access.getProperty(Config.AFT_DME2_TRUSTSTORE, null)); + String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, + access.getProperty(Config.AFT_DME2_TRUSTSTORE_PASSWORD,null)); + trustStorePasswd = trustStorePasswd==null?null:access.decrypt(trustStorePasswd,false); + default_alias = access.getProperty(Config.CADI_ALIAS, + access.getProperty(Config.AFT_DME2_CLIENT_SSL_CERT_ALIAS,null)); + + String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD,null); + keyPasswd = keyPasswd==null?keyStorePasswd:access.decrypt(keyPasswd,false); + String tips=access.getProperty(Config.CADI_TRUST_MASKS, null); + if(tips!=null) { + 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 kmal = new ArrayList(); + for(String ksname : keyStore.split(REGEX_COMMA)) { + file = new File(ksname); + String keystoreFormat; + if(ksname.endsWith("pkcs12")) { + keystoreFormat = "PKCS12"; + } else { + keystoreFormat = "JKS"; + } + if(file.exists()) { + FileInputStream fis = new FileInputStream(file); + try { + KeyStore ks = KeyStore.getInstance(keystoreFormat); + ks.load(fis, keyStorePasswd.toCharArray()); + kmf.init(ks, keyPasswd.toCharArray()); + } finally { + fis.close(); + } + } + } + for(KeyManager km : kmf.getKeyManagers()) { + if(km instanceof X509KeyManager) { + kmal.add((X509KeyManager)km); + } + } + km = new X509KeyManager[kmal.size()]; + kmal.toArray(km); + } + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm); + if(trustStore!=null) { + for(String tsname : trustStore.split(REGEX_COMMA)) { + file = new File(tsname); + if(file.exists()) { + FileInputStream fis = new FileInputStream(file); + try { + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(fis, trustStorePasswd.toCharArray()); + tmf.init(ts); + } finally { + fis.close(); + } + } + } + TrustManager tms[] = tmf.getTrustManagers(); + tm = new X509TrustManager[tms==null?0:tms.length]; + for(int i=0;i extends SecurityInfo { + public SecuritySetter defSS; + + public SecurityInfoC(Access access) throws GeneralSecurityException, IOException { + super(access); + } + + public SecurityInfoC set(SecuritySetter defSS) { + this.defSS = defSS; + return this; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java b/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java new file mode 100644 index 0000000..e0893e6 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/config/UsersDump.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.config; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Date; +import java.util.HashSet; + +import org.onap.aaf.cadi.AbsUserCache; +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(""); + ps.println(""); + ps.println(""); + + // We loop through Users, but want to write Groups first... therefore, save off print + StringBuilder sb = new StringBuilder(); + + // Obtain all unique role names + HashSet groups = new HashSet(); + for(AbsUserCache.DumpInfo di : lur.dumpInfo()) { + sb.append("\n "); + + } + + // Print roles + for(String group : groups) { + ps.print(" "); + } + + ps.println(sb); + + ps.println(""); + ps.flush(); + } catch (Throwable 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()]; + try { + fis.read(orig); + } finally { + fis.close(); + } + // Starting at third "<" ( line) + int startA=0, startB=0; + for(int i=0;startA value(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java new file mode 100644 index 0000000..871dee3 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/AUTHZServlet.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; + +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * + */ +public class AUTHZServlet implements Servlet { + private String[] roles; + private Servlet delegate; + + protected AUTHZServlet(Class 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 void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException { + if(roles==null) { + delegate.service(req,resp); + } else { // Validate + try { + HttpServletRequest hreq = (HttpServletRequest)req; + boolean proceed = false; + for(String role : roles) { + if(hreq.isUserInRole(role)) { + proceed = true; + break; + } + } + if(proceed) { + delegate.service(req,resp); + } else { + //baseRequest.getServletContext().log(hreq.getUserPrincipal().getName()+" Refused " + roles); + ((HttpServletResponse)resp).sendError(403); // forbidden + } + } catch(ClassCastException e) { + throw new ServletException("JASPIServlet only supports HTTPServletRequest/HttpServletResponse"); + } + } + } + + public void destroy() { + delegate.destroy(); + } + + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java b/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java new file mode 100644 index 0000000..596afd2 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/AccessGetter.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +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); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java new file mode 100644 index 0000000..2ccd29a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiAccess.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import javax.servlet.ServletContext; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.Get; + +public class CadiAccess implements Access { + // constants for a couple of very commonly used strings. + protected static final String FROM = "from"; + protected static final String FOR = "for"; + + // Properties derived from sources (could be property files, Valve Configurations, Filter + // configs, etc. + protected Properties props; + + // Will we write Logs? + protected Level willWrite = Level.INFO; + + protected ServletContext context; + protected Get getter = Get.NULL; // replace with Derived Class getter + private Symm symm; + + public CadiAccess(Map map) { + if(map!=null && !map.isEmpty()) { + props = new Properties(); + for(Entry es : map.entrySet()) { + Object v = es.getValue(); + if(v!=null) { + props.put(es.getKey(), v.toString()); + } + } + Object keyfile = props.get(Config.CADI_KEYFILE); + if(keyfile!=null) { + try { + FileInputStream fis = new FileInputStream(keyfile.toString()); + symm = Symm.obtain(fis); + } catch (Exception e) { + } + } + + } + } + + public Level willWrite() { + return willWrite; + } + + /* (non-Javadoc) + * @see com.att.cadi.Access#willLog(com.att.cadi.Access.Level) + */ + @Override + public boolean willLog(Level level) { + return willWrite.compareTo(level)<=0; + } + + /** + * Add the "Level" to the Buildline for Logging types that don't specify, or straight Streams, etc. Then buildline + * + * Build a line of code onto a StringBuilder based on Objects. Analyze whether + * spaces need including. + * + * @param level + * @param sb + * @param elements + * @return + */ + public final static StringBuilder buildLine(Level level, StringBuilder sb, Object[] elements) { + sb.append(level.name()); + return buildLine(sb,elements); + } + + /* + * Build a line of code onto a StringBuilder based on Objects. Analyze whether + * spaces need including. + * + * @param sb + * @param elements + * @return + */ + public final static StringBuilder buildLine(StringBuilder sb, Object[] elements) { + sb.append(' '); + String str; + boolean notFirst = false; + for(Object o : elements) { + if(o!=null) { + str = o.toString(); + + if(str.length()>0) { + if(notFirst && shouldAddSpace(str,true) && shouldAddSpace(sb,false)) { + sb.append(' '); + } else { + notFirst=true; + } + sb.append(str); + } + } + } + return sb; + } + + private static boolean shouldAddSpace(CharSequence c,boolean start) { + if(c.length()>0) + switch(c.charAt(start?0:c.length()-1)) { + case ' ': + case '\t': + case '\n': + case '\'': + case '"': + case '|': + return false; + } + return true; + } + + /** + * Standard mechanism for logging, given being within a Servlet Context + * + * Here, we treat + * + * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup + * scenarios) + * + */ + public void log(Level level, Object... elements) { + if(willWrite.compareTo(level)<=0) { + StringBuilder sb = buildLine(level, new StringBuilder(),elements); + if(context==null) { + System.out.println(sb.toString()); + } else { + context.log(sb.toString()); + } + } + } + + /** + * Standard mechanism for logging an Exception, given being within a Servlet Context, etc + * + * if context exists, log to it, otherwise log to Std Out (The latter is usually for startup + * scenarios) + * + */ + public void log(Exception e, Object... elements) { + if(willWrite.compareTo(Level.ERROR)<=0) { + StringBuilder sb = buildLine(Level.ERROR, new StringBuilder(),elements); + + if(context==null) { + sb.append(e.toString()); + System.out.println(sb.toString()); + } else { + context.log(sb.toString(),e); + } + } + } + + public void setLogLevel(Level level) { + willWrite = level; + } + + /** + * Pass back the classloader of the Servlet Context, if it exists. Otherwise, get the classloader + * of this object. + */ + public ClassLoader classLoader() { // Use the Classloader that Context was created with + return (context==null?this:context).getClass().getClassLoader(); + } + + /** + * Get the Property from Context + */ + public String getProperty(String string, String def) { + String rv = null; + + if ( props != null ) + rv = props.getProperty( string, def ); + + if(rv==null) { + rv = context.getInitParameter(string); + } + return rv==null?def:rv; + + } + + public void load(InputStream is) throws IOException { + if(this.props==null) { + this.props = new Properties(); + } + this.props.load(is); + symm = Symm.obtain(this); + } + + public String decrypt(String encrypted, boolean anytext) throws IOException { + if(symm==null) { + String keyfile = getter.get(Config.CADI_KEYFILE, null, true); + if(keyfile!=null) { + FileInputStream fis = new FileInputStream(keyfile); + symm=Symm.obtain(fis); + fis.close(); + } + } + return (symm!=null && encrypted!=null && (anytext || encrypted.startsWith(Symm.ENC))) + ? symm.depass(encrypted) + : encrypted; + } + + @Override + public void printf(Level level, String fmt, Object[] elements) { + // TODO Auto-generated method stub + + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java new file mode 100644 index 0000000..0b8bb8f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiFilter.java @@ -0,0 +1,305 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.PropAccess; +import org.onap.aaf.cadi.ServletContextAccess; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.Get; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; + +/** + * CadiFilter + * + * This class implements Servlet Filter, and ties together CADI implementations + * + * This class can be used in a standard J2EE Servlet manner. Optimal usage is for POJO operations, where + * one can enforce this Filter being first and primary. Depending on the Container, it + * may be more effective, in some cases, to utilize features that allow earlier determination of + * AUTHN (Authorization). An example would be "Tomcat Valve". These implementations, however, should + * be modeled after the "init" and "doFilter" functions, and be kept up to date as this class changes. + * + * + * + */ +public class CadiFilter implements Filter { + private static CadiHTTPManip httpChecker; + private static String[] pathExceptions; + private static List mapPairs; + private Access access; + private Object[] additionalTafLurs; + 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)); + } + + + /** + * 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; + if(init) { + init(new AccessGetter(access)); + } + additionalTafLurs = moreTafLurs; + } + + /** + * 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)); + } + + + private void init(Get getter) throws ServletException { + // Start with the assumption of "Don't trust anyone". + TrustChecker tc = TrustChecker.NOTRUST; // default position + try { + @SuppressWarnings("unchecked") + Class ctc = (Class) Class.forName("com.att.cadi.aaf.v2_0.AAFTrustChecker"); + if(ctc!=null) { + Constructor 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()); + } + + + // 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 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"); + } + } + } + } + } + } + } + } + + // 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; + } + } + } + + /** + * 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 { + try { + HttpServletRequest hreq = (HttpServletRequest)request; + if(noAuthn(hreq)) { + chain.doFilter(request, response); + } else { + HttpServletResponse hresp = (HttpServletResponse)response; + TafResp tresp = httpChecker.validate(hreq, hresp); + if(tresp.isAuthenticated()==RESP.IS_AUTHENTICATED) { + CadiWrap cw = new CadiWrap(hreq, tresp, httpChecker.getLur(),getConverter(hreq)); + if(httpChecker.notCadi(cw, hresp)) { + chain.doFilter(cw,response); + } + } + } + } catch (ClassCastException e) { + throw new ServletException("CadiFilter expects Servlet to be an HTTP Servlet",e); + } + } + + + /** + * 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 + * + */ + private class Pair { + public Pair(String key, PermConverter pc) { + name = key; + this.pc = pc; + } + public String name; + public PermConverter pc; + } + +} + diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java b/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java new file mode 100644 index 0000000..a3df1c0 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/CadiHTTPManip.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Connector; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Taf; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.lur.EpiLur; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.util.UserChainManip; + +/** + * Encapsulate common HTTP Manipulation Behavior. It will appropriately set + * HTTPServletResponse for Redirect or Forbidden, as needed. + * + * Further, this is useful, because it avoids multiple creates of Connections, where some Filters + * are created and destroyed regularly. + * + * + * + */ +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 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 { + synchronized(CADI) { + this.access = access; +// Get getter = new AccessGetter(access); + Config.setDefaultRealm(access); + + aaf_id = access.getProperty(Config.CADI_ALIAS,access.getProperty(Config.AAF_MECHID, null)); + if(aaf_id==null) { + access.printf(Level.INIT, "%s is not set. %s can be used instead",Config.AAF_MECHID,Config.CADI_ALIAS); + } else { + access.printf(Level.INIT, "%s is set to %s",Config.AAF_MECHID,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; + } + + if(con!=null) { // try to reutilize connector + List ll = null; + for(Object tl : additionalTafLurs) { + if(tl instanceof Lur) { + if(ll==null) { + ll = new ArrayList(); + ll.add(con.newLur()); + } + ll.add((Lur)tl); + } + } + if(ll==null) { + lur = con.newLur(); + } else { + lur = new EpiLur((Lur[])ll.toArray()); + } + } else { + lur = Config.configLur(access, 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(access, tc, up, lur, additionalTafLurs); + } + } + + public TafResp validate(HttpServletRequest hreq, HttpServletResponse hresp) 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; + } + + 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; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java b/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java new file mode 100644 index 0000000..e6912e7 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/FCGet.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Get; + +/* + * A private method to query the Filter config and if not exists, return the default. This + * cleans up the initialization code. + */ +class FCGet implements Get { + /** + * + */ + 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 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/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java new file mode 100644 index 0000000..933e6f9 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/MapPermConverter.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.util.HashMap; +import java.util.Map; + +public class MapPermConverter implements PermConverter { + private HashMap map; + + /** + * 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 map() { + return map; + } + + public String convert(String minimal) { + String rv = map.get(minimal); + return rv==null?minimal:rv; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java new file mode 100644 index 0000000..223e1a4 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/NullPermConverter.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + + +/** + * A NullPermConverter + * + * Obey the PermConverter Interface, but passed in "minimal" String is not converted. + * + * + */ +public class NullPermConverter implements PermConverter { + + private NullPermConverter() {} + private static final NullPermConverter singleton = new NullPermConverter(); + public static NullPermConverter singleton() {return singleton;} + + public String convert(String minimal) { + return minimal; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java b/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java new file mode 100644 index 0000000..87e3c78 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/PathFilter.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; + +/** + * PathFilter + * + * This class implements Servlet Filter, and uses AAF to validate access to a Path. + * + * This class can be used in a standard J2EE Servlet manner. + * + * + */ +public class PathFilter implements Filter { + private ServletContext context; + private String aaf_type; + private String not_authorized_msg; + private final Log log; + + /** + * 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('|'); + + aaf_type = sb.toString(); + + attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG); + if(attr==null) { + not_authorized_msg = "Forbidden - Not Authorized to access this Path"; + } else { + not_authorized_msg = 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 = aaf_type+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,not_authorized_msg); + } + } + + /** + * Containers call "destroy" when time to cleanup + */ + public void destroy() { + log.info("PathFilter destroyed."); + } + + + +} + diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java b/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java new file mode 100644 index 0000000..8f71e29 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/PermConverter.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.filter; + +/** + * Convert a simplistic, single string Permission into an Enterprise Scoped Perm + * + * + */ +public interface PermConverter { + public String convert(String minimal); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java b/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java new file mode 100644 index 0000000..0a5873e --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/RolesAllowed.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +/** + * RolesAllowed + * + * + * Similar to Java EE's Spec from Annotations 1.1, 2.8 + * + * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined + * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in + * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation + * + */ +package org.onap.aaf.cadi.filter; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * JASPI Style Annotation of RolesAllowed when the coding style is desired but actually including all + * JEE jars is not. If using actual JASPI, use official @interface classes, not this one... + * + */ +@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(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java b/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java new file mode 100644 index 0000000..f581c5f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/filter/ServletImpl.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +/** + * RolesAllowed + * + * + * Similar to Java EE's Spec from Annotations 1.1, 2.8 + * + * That Spec, however, was geared towards being able to route calls to Methods on Objects, and thus needed a more refined + * sense of permissions hierarchy. The same mechanism, however, can easily be achieved on single Servlet/Handlers in + * POJOs like Jetty by simply adding the Roles Allowed in a similar Annotation + * + */ +package org.onap.aaf.cadi.filter; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +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 value(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java new file mode 100644 index 0000000..32e4816 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/lur/ConfigPrincipal.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur; + +import java.io.IOException; +import java.security.Principal; + +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; + + 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 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; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java b/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java new file mode 100644 index 0000000..0e612e9 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/lur/EpiLur.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur; + +import java.security.Principal; +import java.util.List; + +import org.onap.aaf.cadi.CachingLur; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Permission; + +/** + * EpiLUR + * + * Short for "Epic LUR". Be able to run through a series of LURs to obtain the validation needed. + * + * The pun is better for the other pattern... "TAF" (aka EpiTaf), but it's still the larger picture of + * LURs that will be accomplished. + * + * FYI, the reason we separate LURs, rather than combine, is that Various User Repository Resources have + * different Caching requirements. For instance, the Local User Repo (with stand alone names), never expire, but might be + * refreshed with a change in Configuration File, while the Remote Service based LURs will need to expire at prescribed intervals + * + * + */ +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"); + } + + public boolean fish(Principal bait, Permission pond) { + if(pond==null) { + return false; + } + boolean rv = false; + Lur lur; + for(int i=0;!rv && i permissions) { + for(Lur lur : lurs) { + lur.fishAll(bait, permissions); + } + } + + 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; + } + + // 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)l).remove(id); + } + } + } + + public Lur subLur(Class cls ) { + for(Lur l : lurs) { + if(l.getClass().isAssignableFrom(cls)) { + return l; + } + } + return null; + } + + @Override + public Permission createPerm(String p) { + return new LocalPermission(p); + } + + /* (non-Javadoc) + * @see com.att.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/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java b/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java new file mode 100644 index 0000000..4086b51 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/lur/LocalLur.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur; + +import java.io.IOException; +import java.security.Principal; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.onap.aaf.cadi.AbsUserCache; +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Hash; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.StrLur; +import org.onap.aaf.cadi.User; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.config.Config; + + +/** + * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms. + * + * + */ +public final class LocalLur extends AbsUserCache implements StrLur, 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 supportingGroups; + private String supportedRealm; + + /** + * Construct by building structure, see "build" + * + * Reconstruct with "build" + * + * @param userProperty + * @param groupProperty + * @param decryptor + * @throws IOException + */ + public LocalLur(Access access, String userProperty, String groupProperty) throws IOException { + super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire + supportedRealm = access.getProperty(Config.BASIC_REALM, "localized"); + supportingGroups = new TreeSet(); + + if(userProperty!=null) { + // For each User name... + for(String user : userProperty.trim().split(SEMI)) { + String[] us = user.split(COLON,2); + String[] userpass = us[0].split(PERCENT,2); + String u; + User usr; + if(userpass.length>1) { + if(userpass.length>0 && userpass[0].indexOf('@')<0) { + userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()); + } + + u = userpass[0]; + byte[] pass = access.decrypt(userpass[1], true).getBytes(); + usr = new User(new ConfigPrincipal(u, pass)); + } else { + u = us[0]; + usr = new User(new ConfigPrincipal(u, (byte[])null)); + } + addUser(usr); + access.log(Level.INIT, "Local User:",usr.principal); + + if(us.length>1) { + Map newMap = usr.newMap(); + for(String group : us[1].split(COMMA)) { + supportingGroups.add(group); + usr.add(newMap,new LocalPermission(group)); + } + usr.setMap(newMap); + } + } + } + if(groupProperty!=null) { + // For each Group name... + for(String group : groupProperty.trim().split(SEMI)) { + String[] gs = group.split(COLON,2); + if(gs.length>1) { + supportingGroups.add(gs[0]); + LocalPermission p = new LocalPermission(gs[0]); + // Add all users (known by comma separators) + + for(String grpMem : gs[1].split(COMMA)) { + // look for password, if so, put in passMap + String[] userpass = grpMem.split(PERCENT,2); + if(userpass.length>0 && userpass[0].indexOf('@')<0) { + userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()); + } + User usr = getUser(userpass[0]); + if(userpass.length>1) { + byte[] pass = access.decrypt(userpass[1], true).getBytes(); + if(usr==null)addUser(usr=new User(new ConfigPrincipal(userpass[0],pass))); + else usr.principal=new ConfigPrincipal(userpass[0],pass); + } else { + if(usr==null)addUser(usr=new User(new ConfigPrincipal(userpass[0],(byte[])null))); + } + usr.add(p); + access.log(Level.INIT, "Local User:",usr.principal); + } + } + } + } + } + + public boolean validate(String user, CredVal.Type type, byte[] cred) { + User usr = getUser(user); + switch(type) { + case PASSWORD: + // covers null as well as bad pass + if(usr!=null && cred!=null && usr.principal instanceof ConfigPrincipal) { + return Hash.isEqual(cred,((ConfigPrincipal)usr.principal).getCred()); + } + break; + } + return false; + } + + // @Override + public boolean fish(Principal bait, Permission pond) { + if(supports(bait.getName()) && pond instanceof LocalPermission) { // local Users only have LocalPermissions + User user = getUser(bait); + return user==null?false:user.contains((LocalPermission)pond); + } + return false; + } + + public boolean fish(String bait, Permission pond) { + if(supports(bait) && pond instanceof LocalPermission) { // local Users only have LocalPermissions + User user = getUser(bait); + return user==null?false:user.contains((LocalPermission)pond); + } + return false; + } + + // We do not want to expose the actual Group, so make a copy. + public void fishAll(Principal bait, List perms) { + if(supports(bait.getName())) { + User user = getUser(bait); + if(user!=null) { + user.copyPermsTo(perms); + } + } + } + + public void fishAll(String bait, List perms) { + if(supports(bait)) { + User user = getUser(bait); + if(user!=null) { + user.copyPermsTo(perms); + } + } + } + + public boolean supports(String userName) { + return userName!=null && userName.endsWith(supportedRealm); + } + + public boolean handlesExclusively(Permission pond) { + return supportingGroups.contains(pond.getKey()); + } + + /* (non-Javadoc) + * @see com.att.cadi.Lur#createPerm(java.lang.String) + */ + @Override + public Permission createPerm(String p) { + return new LocalPermission(p); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java b/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java new file mode 100644 index 0000000..cccb74c --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/lur/LocalPermission.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +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; + } + + public String toString() { + return key; + } + + public boolean match(Permission p) { + return key.equals(p.getKey()); + } + + public String permType() { + return "LOCAL"; + } + + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java b/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java new file mode 100644 index 0000000..94080df --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/lur/NullLur.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur; + +import java.security.Principal; +import java.util.List; + +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 ""; + } + + @Override + public String getKey() { + return ""; + } + + @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 void fishAll(Principal bait, List permissions) { + } + + public void destroy() { + } + + public boolean handlesExclusively(Permission pond) { + return false; + } + + public boolean supports(String userName) { + return false; + } + + /* (non-Javadoc) + * @see com.att.cadi.Lur#createPerm(java.lang.String) + */ + @Override + public Permission createPerm(String p) { + return NULL; + } + + /* (non-Javadoc) + * @see com.att.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'; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java new file mode 100644 index 0000000..e84caeb --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/BasicPrincipal.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Date; + +import org.onap.aaf.cadi.BasicCred; +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 String name = null; + private String shortName = null; + private byte[] cred = null; + + private long created; + + public BasicPrincipal(String content,String domain) throws IOException { + created = System.currentTimeMillis(); + ByteArrayInputStream bis = new ByteArrayInputStream(content.getBytes()); + // Read past "Basic ", ensuring it starts with it. + for(int i=0;i0) { + domain=name.substring(at+1); + shortName=name.substring(0, at); + } else { + shortName = name; + name = name + '@' + domain; + } + } + + public BasicPrincipal(BasicCred bc, String domain) { + name = bc.getUser(); + cred = bc.getCred(); + } + + 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 byte[] getCred() { + return cred; + } + + public long created() { + return created; + } + + public String toString() { + return "Basic Authorization for " + name + " evaluated on " + new Date(created).toString(); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java new file mode 100644 index 0000000..08793c5 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/BearerPrincipal.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.security.Principal; + +public abstract class BearerPrincipal implements Principal { + private String bearer = null; + public BearerPrincipal setBearer(String bearer) { + this.bearer = bearer; + return this; + } + public String getBearer() { + return bearer; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/CSPPrincipal_T.java b/core/src/main/java/org/onap/aaf/cadi/principal/CSPPrincipal_T.java new file mode 100644 index 0000000..3694584 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/CSPPrincipal_T.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.security.Principal; + +/** + * Indicate a CSP Principal that is trusted as a CSPPrincipal. + * + */ +public interface CSPPrincipal_T extends Principal { + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java new file mode 100644 index 0000000..9a33dc6 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/CachedBasicPrincipal.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.io.IOException; + +import org.onap.aaf.cadi.BasicCred; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.taf.HttpTaf; + +/** + * Cached Principals need to be able to revalidate in the Background + * + * + */ +public class CachedBasicPrincipal extends BasicPrincipal implements CachedPrincipal { + 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 CachedPrincipal.Resp revalidate() { + Resp resp = creator.revalidate(this); + if(resp.equals(Resp.REVALIDATED))expires = System.currentTimeMillis()+timeToLive; + return resp; + } + + public long expires() { + return expires; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal.java new file mode 100644 index 0000000..b55f86a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +public class TGuardPrincipal extends BearerPrincipal { + + private String name, tresp; + + public TGuardPrincipal(String tresp) { + this.tresp=tresp; + } + + /** + * TODO Need to figure out what Organizations TGuard entities should be part of. + * + */ + public String getName() { + if(name==null) { + String temp = get("iv-user"); + if(temp==null)return null; + StringBuilder sb = new StringBuilder(); + int at = temp.indexOf('@'); + if(at<0) { + sb.append(temp); + } else { + sb.append(temp.substring(0, at)); + } + if(temp.endsWith("@uverse.com"))sb.append("@uverse.tguard.att.com"); + else if(temp.endsWith("@att.com"))sb.append("@com.tguard.att.com"); + else if(temp.endsWith("@att.net"))sb.append("@net.tguard.att.com"); + else sb.append("@tguard.att.com"); + name = sb.toString(); + } + return name; + } + + /** + * Get a value from a named TGuard Property + * + * TGuard response info is very dynamic. They can add new properties at any time, so we dare not code field names for these values. + * @param key + * @return + */ + public String get(String key) { + if(key==null)return null; + int idx=0,equal=0,amp=0; + while(idx>=0 && (equal = tresp.indexOf('=',idx))>=0) { + amp = tresp.indexOf('&',equal); + if(key.regionMatches(0, tresp, idx, equal-idx)) { + return amp>=0?tresp.substring(equal+1, amp):tresp.substring(equal+1); + } + idx=amp+(amp>0?1:0); + } + return null; + } + + public String info() { + return tresp; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal_T.java b/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal_T.java new file mode 100644 index 0000000..235c74c --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/TGuardPrincipal_T.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.security.Principal; + +/** + * Indicate a TGuard Principal that is trusted as a TGuardPrincipal. + * + */ +public interface TGuardPrincipal_T extends Principal { + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java b/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java new file mode 100644 index 0000000..4add242 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/TrustPrincipal.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +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 X509Principal) { + userChain="x509"; + } else if(actual instanceof BasicPrincipal) { + userChain="BAth"; + } else { + userChain = actual.getClass().getSimpleName(); + } + } + + @Override + public String getName() { + return name; + } + + public String getOrigName() { + return original.getName() + '[' + userChain + ']'; + } + + @Override + public String userChain() { + return userChain; + } + + public Principal original() { + return original; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java b/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java new file mode 100644 index 0000000..2f3fd28 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/principal/X509Principal.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.principal; + +import java.io.IOException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.regex.Pattern; + +import org.onap.aaf.cadi.GetCred; + +public class X509Principal extends BearerPrincipal implements GetCred { + private static final Pattern pattern = Pattern.compile("[a-zA-Z0-9]*\\@[a-zA-Z0-9.]*"); + private byte[] content; + private X509Certificate cert; + private String name; + + public X509Principal(String identity, X509Certificate cert, byte[] content) { + name = identity; + this.content = content; + this.cert = cert; + } + + public X509Principal(X509Certificate cert, byte[] content) throws IOException { + this.content=content; + this.cert = cert; + 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"); + + } + + + 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 String getName() { + return name; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java new file mode 100644 index 0000000..6a7f15e --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/AbsTafResp.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.security.Principal; + +import org.onap.aaf.cadi.Access; + +/** + * AbsTafResp + * + * Base class for TafResp (TAF Response Objects) + * + */ +public abstract class AbsTafResp implements TafResp { + + protected final String desc; + protected final Principal principal; + protected final Access access; + + /** + * 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 principal + * @param description + */ + public AbsTafResp(Access access, Principal principal, String description) { + this.access = access; + this.principal = principal; + this.desc = description; + } + + /** + * 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; + } + + /** + * 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 Principal getPrincipal() { + return principal; + } + + /** + * getAccess() + * + * Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated. + */ + public Access getAccess() { + return access; + } + + /* (non-Javadoc) + * @see com.att.cadi.taf.TafResp#isFailedAttempt() + */ + public boolean isFailedAttempt() { + return false; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java new file mode 100644 index 0000000..7cb40ed --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/EpiTaf.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Taf; + +/** + * EpiTAF + * + * Short for "Epic TAF". Be able to run through a series of TAFs to obtain the validation needed. + * + * OK, the name could probably be better as "Tafs", like it was originally, but the pun was too + * irresistible for this author to pass up. + * + * + */ +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"); + } + + /** + * 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; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java new file mode 100644 index 0000000..05832f7 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.net.URI; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Locator; +import org.onap.aaf.cadi.TrustChecker; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.Taf.LifeForm; + +/** + * HttpEpiTaf + * + * An extension of the basic "EpiTAF" concept, check known HTTP Related TAFs for valid credentials + * + * + */ +public class HttpEpiTaf implements HttpTaf { + private HttpTaf[] tafs; + private Access access; + private Locator locator; + private TrustChecker trustChecker; + + /** + * HttpEpiTaf constructor + * + * Construct the HttpEpiTaf from variable Http specific TAF parameters + + * @param tafs + * @throws CadiException + */ + public HttpEpiTaf(Access access, Locator 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 +// trustChainProp = access.getProperty(Config.CADI_TRUST_PROP, Config.CADI_TRUST_PROP_DEFAULT); + + 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, firstTry = null; + List redirectables = null; + + for(HttpTaf taf : tafs) { + tresp = taf.validate(reading, req, resp); + 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; + } + } + + // 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. + + String auth = req.getParameter("Authentication"); + if(auth!=null) { + if("BasicAuth".equals(auth)) { + return LifeForm.SBLF; + } + } + // 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 + // 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) { + Resp resp; + for(HttpTaf taf : tafs) { + resp = taf.revalidate(prin); + switch(resp) { + case NOT_MINE: + break; + default: + return resp; + } + } + return Resp.NOT_MINE; + } + + /** + * 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/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java new file mode 100644 index 0000000..325de6a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/HttpTaf.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.Taf.LifeForm; + +/** + * A TAF which is in a specific HTTP environment in which the engine implements + * javax Servlet. + * + * Using the Http Request and Response interfaces takes the effort out of implementing in almost any kind of + * HTTP Container or Engine. + * + * + */ +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); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java new file mode 100644 index 0000000..b6bb385 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.net.URI; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Locator; +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 LoginPageTafResp(Access access, final HttpServletResponse resp, String loginPageURL) { + super(access, 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 locator, final HttpServletResponse resp, List redir) { + if(locator!=null) { + try { + Item item = locator.best(); + URI uri = locator.get(item); + if(uri!=null) { + StringBuilder sb = new StringBuilder(uri.toString()); + String query = uri.getQuery(); + boolean first = query==null || query.length()==0; + int count=0; + for(Redirectable t : redir) { + if(first) { + sb.append('?'); + first=false; + } + else sb.append('&'); + sb.append(t.get()); + ++count; + } + if(count>0)return new LoginPageTafResp(access, resp, sb.toString()); + } + } catch (Exception e) { + access.log(e, "Error deriving Login Page location"); + } + } else if(!redir.isEmpty()) { + access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf"); + return redir.get(0); + } + return NullTafResp.singleton(); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java new file mode 100644 index 0000000..fb1b930 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/NullTaf.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.Taf; +import org.onap.aaf.cadi.CachedPrincipal.Resp; + + +/** + * This TAF is set at the very beginning of Filters and Valves so that if any configuration issues hit while + * starting, the default behavior is to shut down traffic rather than leaving an open hole + * + * + */ +public class NullTaf implements Taf, HttpTaf { + // 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, HttpServletRequest req, HttpServletResponse resp) { + return NullTafResp.singleton(); + } + + public Resp revalidate(CachedPrincipal prin) { + return Resp.NOT_MINE; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java new file mode 100644 index 0000000..97e49e0 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/NullTafResp.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; + +/** + * A Null Pattern for setting responses to "Deny" before configuration is setup. + * + */ +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; + } + + public Principal getPrincipal() { + return null; + } + + public Access getAccess() { + return Access.NULL; + } + + /* (non-Javadoc) + * @see com.att.cadi.taf.TafResp#isFailedAttempt() + */ + public boolean isFailedAttempt() { + return true; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java new file mode 100644 index 0000000..10c401a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/PuntTafResp.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; + +/** + * A Punt Resp to make it fast and easy for a Taf to respond that it cannot handle a particular kind of + * request. It is always the same object, so there is no cost for memory, etc. + * + */ +public class PuntTafResp implements TafResp { + private PuntTafResp(){} + + private static TafResp singleton = new PuntTafResp(); + + public static TafResp singleton() { + return singleton; + } + + public boolean isValid() { + return false; + } + + public RESP isAuthenticated() { + return RESP.TRY_ANOTHER_TAF; + } + + public String desc() { + return "This Taf can or will not handle this authentication"; + } + + public RESP authenticate() throws IOException { + return RESP.TRY_ANOTHER_TAF; + } + + public Principal getPrincipal() { + return null; + } + + public Access getAccess() { + return NullTafResp.singleton().getAccess(); + } + + public boolean isFailedAttempt() { + return false; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java b/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java new file mode 100644 index 0000000..6e20bab --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/Redirectable.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +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(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java new file mode 100644 index 0000000..cb0915a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/TafResp.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CadiException; + +/** + * Response from Taf objects, which inform users what has happened and/or what should be done + * + * + */ +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. JG 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; + + /** + * Once authenticated, this object should hold a Principal created from the authorization + * @return + */ + public Principal 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(); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java new file mode 100644 index 0000000..2ab4a62 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/TrustNotTafResp.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; + +public class TrustNotTafResp implements TafResp { + private final TafResp delegate; + private final String desc; + + 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 RESP isAuthenticated() { + return RESP.NO_FURTHER_PROCESSING; + } + + @Override + public RESP authenticate() throws IOException { + return RESP.NO_FURTHER_PROCESSING; + } + + @Override + public Principal getPrincipal() { + return delegate.getPrincipal(); + } + + @Override + public Access getAccess() { + return delegate.getAccess(); + } + + @Override + public boolean isFailedAttempt() { + return true; + } + + public String toString() { + return desc(); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java new file mode 100644 index 0000000..cd4c92f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/TrustTafResp.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; + +public class TrustTafResp implements TafResp { + private final TafResp delegate; + private final Principal principal; + private final String desc; + + public TrustTafResp(final TafResp delegate, final Principal 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 RESP isAuthenticated() { + return delegate.isAuthenticated(); + } + + @Override + public RESP authenticate() throws IOException { + return delegate.authenticate(); + } + + @Override + public Principal getPrincipal() { + return principal; + } + + @Override + public Access getAccess() { + return delegate.getAccess(); + } + + @Override + public boolean isFailedAttempt() { + return delegate.isFailedAttempt(); + } + + public String toString() { + return principal.getName() + " by trust of " + desc(); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java new file mode 100644 index 0000000..f6cc3a7 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.basic; + +import java.io.IOException; +import java.security.Principal; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.BasicCred; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.CredVal; +import org.onap.aaf.cadi.Taf; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.CredVal.Type; +import org.onap.aaf.cadi.principal.BasicPrincipal; +import org.onap.aaf.cadi.principal.CachedBasicPrincipal; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; +import org.onap.aaf.cadi.taf.dos.DenialOfServiceTaf; + +/** + * BasicHttpTaf + * + * This TAF implements the "Basic Auth" protocol. + * + * WARNING! It is true for any implementation of "Basic Auth" that the password is passed unencrypted. + * This is because the expectation, when designed years ago, was that it would only be used in + * conjunction with SSL (https). It is common, however, for users to ignore this on the assumption that + * their internal network is secure, or just ignorance. Therefore, a WARNING will be printed + * when the HTTP Channel is not encrypted (unless explicitly turned off). + * + * + */ +public class BasicHttpTaf implements HttpTaf { + private Access access; + private String realm; + private CredVal rbac; + 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; + } + + /** + * 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); + // ONLY FOR Last Ditch DEBUGGING... + // access.log(Level.WARN,bp.getName() + ":" + new String(bp.getCred())); + if(rbac.validate(bp.getName(),Type.PASSWORD,bp.getCred())) { + 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()), + 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()); + } + + // ONLY FOR Last Ditch DEBUGGING... + // access.log(Level.WARN,ba.getName() + ":" + new String(ba.getCred())); + if(rbac.validate(ba.getName(), Type.PASSWORD, ba.getCred())) { + 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(); + for(Object s : msg) { + sb.append(s.toString()); + } + if(pr!=null) { + sb.append(" for "); + sb.append(pr.getName()); + } + sb.append(" from "); + sb.append(req.getRemoteAddr()); + sb.append(':'); + sb.append(req.getRemotePort()); + return sb.toString(); + } + + @Override + public Resp revalidate(CachedPrincipal prin) { + 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())?Resp.REVALIDATED:Resp.UNVALIDATED; + } + return Resp.NOT_MINE; + } + + public String toString() { + return "Basic Auth enabled on realm: " + realm; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java new file mode 100644 index 0000000..45eab48 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTafResp.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.basic; + +import java.io.IOException; +import java.security.Principal; + +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.taf.AbsTafResp; +import org.onap.aaf.cadi.taf.TafResp; + +public class BasicHttpTafResp extends AbsTafResp implements TafResp { + private HttpServletResponse httpResp; + private String realm; + private RESP status; + private final boolean wasFailed; + + public BasicHttpTafResp(Access access, Principal principal, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) { + super(access,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/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java b/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java new file mode 100644 index 0000000..1d84d67 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/cert/CertIdentity.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.cert; + +import java.security.Principal; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.servlet.http.HttpServletRequest; + +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 Principal identity(HttpServletRequest req, X509Certificate cert, byte[] certBytes) throws CertificateException; +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java new file mode 100644 index 0000000..f301fc2 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509HttpTafResp.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.cert; + +import java.io.IOException; +import java.security.Principal; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.taf.AbsTafResp; +import org.onap.aaf.cadi.taf.TafResp; + +public class X509HttpTafResp extends AbsTafResp implements TafResp { + private RESP status; + + public X509HttpTafResp(Access access, Principal principal, String description, RESP status) { + super(access, 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/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java b/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java new file mode 100644 index 0000000..36217cc --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/cert/X509Taf.java @@ -0,0 +1,257 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.cert; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Principal; +import java.security.Signature; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; + +import javax.net.ssl.TrustManagerFactory; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.Taf.LifeForm; +import org.onap.aaf.cadi.config.Config; +import org.onap.aaf.cadi.config.SecurityInfo; +import org.onap.aaf.cadi.config.SecurityInfoC; +import org.onap.aaf.cadi.lur.LocalPermission; +import org.onap.aaf.cadi.principal.TGuardPrincipal; +import org.onap.aaf.cadi.principal.X509Principal; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; +import org.onap.aaf.cadi.util.Split; + +public class X509Taf implements HttpTaf { + + 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 cadiIssuers; + private String env; + private SecurityInfo si; + + static { + try { + certFactory = CertificateFactory.getInstance("X.509"); + messageDigest = MessageDigest.getInstance("SHA-256"); // use this to clone + tmf = TrustManagerFactory.getInstance(SecurityInfoC.SslKeyManagerFactoryAlgorithm); + } 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, "CN=ATT CADI Issuing CA 01, OU=CSO, O=ATT, C=US:CN=ATT CADI Issuing CA 02, OU=CSO, O=ATT, C=US").split(":")) { + cadiIssuers.add(ci); + } + try { + Class dci = access.classLoader().loadClass("com.att.authz.cadi.DirectCertIdentity"); + 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; + } + + try { + si = new SecurityInfo(access); + } catch (GeneralSecurityException | IOException e1) { + throw new CadiException(e1); + } + } + + 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 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 + if(cadiIssuers.contains(certarr[0].getIssuerDN().toString())) { + String x500 = certarr[0].getSubjectDN().getName(); + int ou=x500.indexOf("OU="); + if(ou>0) { + ou+=3; + int comma = x500.indexOf(',',ou); + if(comma>0) { + String id= x500.substring(ou,comma); + String idenv[] = id.split(":"); + if(idenv.length==1 || (idenv.length>1 && env.equals(idenv[1]))) { + return new X509HttpTafResp(access, + new X509Principal(idenv[0], certarr[0],null), + id + " validated by CADI x509", RESP.IS_AUTHENTICATED); + } + } + } + } + } + + 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 + return new X509HttpTafResp(access, null, "Certificate verified, but another Identity 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 && authHeader.startsWith("x509 ")) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(authHeader.length()); + try { + array = authHeader.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 " " +// 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 verified", 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 verified", RESP.TRY_ANOTHER_TAF); + } + + } else { + return new X509HttpTafResp(access, null, "No Certificate Info on Transaction", RESP.TRY_ANOTHER_TAF); + } + } + + // A cert has been found, match Identify + Principal prin=null; + + for(int i=0;prin==null && i deniedIP=null, deniedID=null; + private Access access; + private static File dosIP, dosID; + + /** + * + * @param hostname + * @param prod + * @throws CadiException + */ + public DenialOfServiceTaf(Access access) throws CadiException { + this.access = access; + if(dosIP==null || dosID == null) { + String dirStr; + if((dirStr = access.getProperty("aaf_data_dir", null))!=null) { + dosIP = new File(dirStr+"/dosIP"); + readIP(); + dosID = new File(dirStr+"/dosID"); + readID(); + } + } + } + + 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 PuntTafResp.singleton(); + } + + public Resp revalidate(CachedPrincipal prin) { + // 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(deniedID!=null) { + return deniedID.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)); + if(deniedIP==null) { + deniedIP=new HashMap(); + } + + try { + 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 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 readID() { + if(dosID!=null && dosID.exists()) { + BufferedReader br; + try { + br = new BufferedReader(new FileReader(dosID)); + if(deniedID==null) { + deniedID=new HashMap(); + } + try { + 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 true; + } + return false; + } + + public List report() { + int initSize = 0; + if(deniedIP!=null)initSize+=deniedIP.size(); + if(deniedID!=null)initSize+=deniedID.size(); + ArrayList 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 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/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java new file mode 100644 index 0000000..ac6c01a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/dos/DenialOfServiceTafResp.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.dos; + +import java.io.IOException; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.taf.AbsTafResp; + +public class DenialOfServiceTafResp extends AbsTafResp { + private RESP ect; // Homage to Arethra Franklin + + public DenialOfServiceTafResp(Access access, RESP resp, String description ) { + super(access, 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; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTaf.java b/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTaf.java new file mode 100644 index 0000000..af9554f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTaf.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.localhost; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.CachedPrincipal; +import org.onap.aaf.cadi.Taf; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CachedPrincipal.Resp; +import org.onap.aaf.cadi.taf.HttpTaf; +import org.onap.aaf.cadi.taf.TafResp; +import org.onap.aaf.cadi.taf.TafResp.RESP; + +/** + * Implement the ability to utilize LocalHost as a TAF. + * + * Configure with two properties, + * localhost.deny + * localhost.accept + * + * 1) If localhost.deny==true, then no localhost requests are allowed + * 2) If localhost.deny==false, but accept==false, return "Try Another TAF" (i.e. allow further checking of the + * chain, but don't treat localhost as an acceptable credential) + * 3) If localhost.deny=false and accept=true, then the processes coming from the same machine, given logins are needed, + * to run, are treated as validated. This is primarily for Developer purposes. + * + * + * + */ +public class LocalhostTaf implements HttpTaf { + private TafResp isLocalHost,isNotLocalHost; + private static final TreeSet addrSet; + + static { + addrSet = new TreeSet(); + try { + for(Enumeration en = NetworkInterface.getNetworkInterfaces();en.hasMoreElements();) { + NetworkInterface ni = en.nextElement(); + for(Enumeration eia = ni.getInetAddresses();eia.hasMoreElements();) { + InetAddress ia = eia.nextElement(); + addrSet.add(ia.getHostAddress()); + } + } + } catch (SocketException e) { + } + + } + + public LocalhostTaf(Access access, boolean accept, boolean isDenied) { + String hostname = access.getProperty("hostname",null); + if(hostname !=null) { + try { + addrSet.add(InetAddress.getByName(hostname).getHostAddress()); + } catch (UnknownHostException e) { + access.log(e,"Unknown Host"); + } + } + + if(isDenied) { + access.log(Level.INFO,"LocalhostTaf will deny all localhost traffic"); + } else { + access.log(Level.INFO,"LocalhostTaf will not deny localhost requests, ", + (accept?"and will treat them as authenticated":"but will require other authentication")); + } + // Set the appropriate behavior for when ID coming in is from localhost + isLocalHost = isDenied? + new LocalhostTafResp(access, RESP.NO_FURTHER_PROCESSING,"Localhost is denied"): + accept? + new LocalhostTafResp(access, RESP.IS_AUTHENTICATED,"Localhost is allowed"): + new LocalhostTafResp(access, RESP.TRY_ANOTHER_TAF,"Localhost is allowed"); + isNotLocalHost = new LocalhostTafResp(access, RESP.TRY_ANOTHER_TAF,"Address is not Localhost"); + } + +// @Override + public TafResp validate(Taf.LifeForm reading, HttpServletRequest req, HttpServletResponse resp) { + String remote = req.getRemoteAddr(); + return addrSet.contains(remote) + ?isLocalHost + :isNotLocalHost; + } + + /** + * This function used for other TAFs (i.e. CSP, which can't work on localhost address) + * + * @param address + * @return + */ + public static boolean isLocalAddress(String address) { + return addrSet.contains(address); + } + + public String toString() { + return "Localhost TAF activated: " + isLocalHost.desc(); + } + + public Resp revalidate(CachedPrincipal prin) { + // shouldn't get here, since there's no need to Cache, but if so, LocalHost is always valid... + return Resp.REVALIDATED; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTafResp.java b/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTafResp.java new file mode 100644 index 0000000..bda5484 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/taf/localhost/LocalhostTafResp.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.taf.localhost; + +import java.security.Principal; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.taf.TafResp; + +public class LocalhostTafResp implements TafResp { + private RESP action; + private String description; + private final static Principal principal = new Principal() { + private String name = System.getProperty("user.name")+"@localhost"; +// @Override + public String getName() { + return name; + } + }; + + private Access access; + + public LocalhostTafResp(Access access, RESP state, String desc) { + action = state; + description = desc; + this.access = access; + } + +// @Override + public boolean isValid() { + return action == RESP.IS_AUTHENTICATED; + } + +// @Override + public String desc() { + return description; + } + +// @Override + public RESP authenticate() { + return action; + } + + public RESP isAuthenticated() { + return action; + } + +// @Override + public Principal getPrincipal() { + return principal; + } + + public Access getAccess() { + return access; + } + + public boolean isFailedAttempt() { + return false; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java b/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java new file mode 100644 index 0000000..f999a11 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/util/Chmod.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.util; + +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 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); + } + }; +} diff --git a/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java b/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java new file mode 100644 index 0000000..546292e --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/util/JsonOutputStream.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.util; + +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; + + 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=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(prev255 || lbyte<0)) { + throw new MaskFormatException("Invalid Byte in IPV4 Address"); + } + rv|=lbyte<>bits; + } + return rv; + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/util/Split.java b/core/src/main/java/org/onap/aaf/cadi/util/Split.java new file mode 100644 index 0000000..c3b37dc --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/util/Split.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.util; + +/** + * Split by Char, optional Trim + * + * Note: Copied from Inno to avoid linking issues. + * Note: I read the String split and Pattern split code, and we can do this more efficiently for a single Character + * + * 8/20/2015 + */ + +public class Split { + public static String[] split(char c, String value) { + // Count items to preallocate Array (memory alloc is more expensive than counting twice) + int count,idx; + for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count); + String[] rv = new String[count]; + if(count==1) { + rv[0]=value; + } else { + int last=0; + count=-1; + for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) { + rv[++count]=value.substring(last,idx); + last = ++idx; + } + rv[++count]=value.substring(last); + } + return rv; + } + + public static String[] splitTrim(char c, String value) { + // Count items to preallocate Array (memory alloc is more expensive than counting twice) + int count,idx; + for(count=1,idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,++idx),++count); + String[] rv = new String[count]; + if(count==1) { + rv[0]=value.trim(); + } else { + int last=0; + count=-1; + for(idx=value.indexOf(c);idx>=0;idx=value.indexOf(c,idx)) { + rv[++count]=value.substring(last,idx).trim(); + last = ++idx; + } + rv[++count]=value.substring(last).trim(); + } + return rv; + } + + public static String[] splitTrim(char c, String value, int size) { + 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 && count0 && 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 void printf(String fmt, Object... args) { + System.console().printf(fmt, args); + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java b/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java new file mode 100644 index 0000000..5f945f3 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/util/UserChainManip.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +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:::[:AS][,::]* + @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 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(); + } + +} diff --git a/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java b/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java new file mode 100644 index 0000000..e95337f --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/wsse/Action.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.wsse; + +/** + * Interface to specify an action deep within a parsing tree on a local object + * + * We use a Generic so as to be flexible on create what that object actually is. This is passed in at the + * root "parse" call of Match. Similar to a "Visitor" Pattern, this object is passed upon reaching the right + * point in a parse tree. + * + * + * @param + */ +interface Action { + public boolean content(OUTPUT output, String text); +} diff --git a/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java b/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java new file mode 100644 index 0000000..bffe447 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/wsse/Match.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.wsse; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; + +/** + * Match Class allows you to build an automatic Tree of StAX (or StAX like) + * Objects for frequent use. + * + * OBJECT is a type which you which to do some end Actions on, similar to a Visitor pattern, see Action + * + * Note: We have implemented with XReader and XEvent, rather than StAX for performance reasons. + * + * @see Action + * @see Match + * @see XEvent + * @see XReader + * + * + * @param + */ +//@SuppressWarnings("restriction") +public class Match { + private QName qname; + private Match[] next; + private Match prev; + private Action action = null; + private boolean stopAfter; + private boolean exclusive; + + + @SafeVarargs + public Match(String ns, String name, Match ... next) { + this.qname = new QName(ns,name); + this.next = next; + stopAfter = exclusive = false; + for(Match m : next) { // add the possible tags to look for + if(!m.stopAfter)m.prev = this; + } + } + + public Match 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 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 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 exclusive() { + exclusive = true; + return this; + } + + public Match set(Action action) { + this.action = action; + return this; + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java b/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java new file mode 100644 index 0000000..760020a --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/wsse/WSSEParser.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.wsse; + +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.stream.XMLStreamException; + +import org.onap.aaf.cadi.BasicCred; + + +/** + * WSSE Parser + * + * Read the User and Password from WSSE Formatted SOAP Messages + * + * This class uses StAX so that processing is stopped as soon as the Security User/Password are read into BasicCred, or the Header Ends + * + * This class is intended to be created once (or very few times) and reused as much as possible. + * + * It is as thread safe as StAX parsing is. + * + */ +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 parseTree; + //private XMLInputFactory inputFactory; + + public WSSEParser() { + // soap:Envelope/soap:Header/wsse:Security/wsse:UsernameToken/[wsse:Password&wsse:Username] + parseTree = new Match(SOAP_NS,"root", // need a root level to start from... Doesn't matter what the tag is + new Match(SOAP_NS,"Envelope", + new Match(SOAP_NS,"Header", + new Match(WSSE_NS,"Security", + new Match(WSSE_NS,"UsernameToken", + new Match(WSSE_NS,"Password").set(new Action() { + public boolean content(BasicCred bc,String text) { + bc.setCred(text.getBytes()); + return true; + } + }), + new Match(WSSE_NS,"Username").set(new Action() { + 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 + //inputFactory = XMLInputFactory.newInstance(); + } + + public XMLStreamException parse(BasicCred bc, InputStream is) throws IOException { + try { + parseTree.onMatch(bc, new XReader(is)); + return null; + } catch (XMLStreamException e) { + return e; + } + } +} diff --git a/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java b/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java new file mode 100644 index 0000000..e5af256 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/wsse/XEvent.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.wsse; + +import javax.xml.namespace.QName; +import javax.xml.stream.events.XMLEvent; + +/** + * XEvent + * + * This mechanism mimics a minimal portion of StAX "XMLEvent", enough to work with minimal XReader. + * + * We implement the same interface, as much as minimally necessary, as XMLEvent for these small usages so as to + * be interchangeable in the future, if so desired + * + * + */ +// @SuppressWarnings("restriction") +public abstract class XEvent { + + public abstract int getEventType(); + + public StartElement asStartElement() { + return (StartElement)this; + } + + public Characters asCharacters() { + return (Characters)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; + } + } + 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/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java b/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java new file mode 100644 index 0000000..8fa8113 --- /dev/null +++ b/core/src/main/java/org/onap/aaf/cadi/wsse/XReader.java @@ -0,0 +1,416 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.wsse; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import javax.xml.stream.XMLStreamException; + +/** + * XReader + * This class works similarly as StAX, except StAX has more behavior than is needed. That would be ok, but + * StAX also was Buffering in their code in such as way as to read most if not all the incoming stream into memory, + * defeating the purpose of pre-reading only the Header + * + * This Reader does no back-tracking, but is able to create events based on syntax and given state only, leaving the + * Read-ahead mode of the InputStream up to the other classes. + * + * At this time, we only implement the important events, though if this is good enough, it could be expanded, perhaps to + * replace the original XMLReader from StAX. + * + * + */ +// @SuppressWarnings("restriction") +public class XReader { + private XEvent curr,another; + private InputStream is; + private ByteArrayOutputStream baos; + private int state, count, last; + + private Stack> nsses; + + public XReader(InputStream is) { + this.is = is; + curr = another = null; + baos = new ByteArrayOutputStream(); + state = BEGIN_DOC; + count = 0; + nsses = new Stack>(); + } + + public boolean hasNext() throws XMLStreamException { + if(curr==null) { + curr = parse(); + } + return curr!=null; + } + + 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 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.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 + 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... + 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 , ,or both + 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; + } + 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 getNss(Map nss, Tag t) { + Map 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():nss):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. + * + * + */ + public class Tag { + public int state; + public String prefix,name,value; + public List attribs; + + 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); + + char quote = ((state&DOC_TYPE)==DOC_TYPE)?'\'':'"'; + if(value!=null) { + sb.append('='); + sb.append(quote); + sb.append(value); + sb.append(quote); + } + return sb.toString(); + } + } + +} diff --git a/core/src/test/java/com/att/cadi/JU_AES.java b/core/src/test/java/com/att/cadi/JU_AES.java deleted file mode 100644 index fb2482a..0000000 --- a/core/src/test/java/com/att/cadi/JU_AES.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; - -import org.junit.Test; - -import junit.framework.Assert; - -public class JU_AES { - - @Test - public void test() throws Exception { - AES aes = new AES(); - String orig = "I'm a password, really"; - byte[] passin = orig.getBytes(); - byte[] encrypted = aes.encrypt(passin); - byte[] b64enc = Symm.base64.encode(encrypted); - System.out.println(new String(b64enc)); - - encrypted = Symm.base64.decode(b64enc); - passin = aes.decrypt(encrypted); - Assert.assertEquals(orig, new String(passin)); - } - - @Test - public void testInputStream() throws Exception { - AES aes = new AES(); - String orig = "I'm a password, really"; - ByteArrayInputStream bais = new ByteArrayInputStream(orig.getBytes()); - CipherInputStream cis = aes.inputStream(bais, true); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Symm.base64.encode(cis, baos); - cis.close(); - - byte[] b64encrypted; - System.out.println(new String(b64encrypted=baos.toByteArray())); - - - baos.reset(); - CipherOutputStream cos = aes.outputStream(baos, false); - Symm.base64.decode(new ByteArrayInputStream(b64encrypted),cos); - cos.close(); - Assert.assertEquals(orig, new String(baos.toByteArray())); - } - - @Test - public void testObtain() throws Exception { - byte[] keygen = Symm.baseCrypt().keygen(); - - Symm symm = Symm.obtain(new ByteArrayInputStream(keygen)); - - String orig ="Another Password, please"; - String encrypted = symm.enpass(orig); - System.out.println(encrypted); - String decrypted = symm.depass(encrypted); - System.out.println(decrypted); - Assert.assertEquals(orig, decrypted); - } - -} diff --git a/core/src/test/java/com/att/cadi/lur/test/JU_LocalLur.java b/core/src/test/java/com/att/cadi/lur/test/JU_LocalLur.java deleted file mode 100644 index f11c74d..0000000 --- a/core/src/test/java/com/att/cadi/lur/test/JU_LocalLur.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.test; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import org.junit.Test; - -import com.att.cadi.CredVal.Type; -import com.att.cadi.Lur; -import com.att.cadi.Permission; -import com.att.cadi.PropAccess; -import com.att.cadi.Symm; -import com.att.cadi.config.UsersDump; -import com.att.cadi.lur.LocalLur; -import com.att.cadi.lur.LocalPermission; - -public class JU_LocalLur { - - @Test - public void test() throws IOException { - Symm symmetric = Symm.baseCrypt().obtain(); - LocalLur up; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - baos.write(Symm.ENC.getBytes()); - symmetric.enpass("", baos); - PropAccess ta = new PropAccess(); - Lur ml = up = new LocalLur(ta,"myname:groupA,groupB","admin:myname,yourname;suser:hisname,hername,m1234%"+baos.toString()); - - Permission admin = new LocalPermission("admin"); - Permission suser = new LocalPermission("suser"); - - // Check User fish - assertTrue(ml.fish(new JUPrincipal("myname"),admin)); - assertTrue(ml.fish(new JUPrincipal("hisname"),admin)); - assertFalse(ml.fish(new JUPrincipal("noname"),admin)); - assertTrue(ml.fish(new JUPrincipal("itsname"),suser)); - assertTrue(ml.fish(new JUPrincipal("hername"),suser)); - assertFalse(ml.fish(new JUPrincipal("myname"),suser)); - - - // Check validate password - assertTrue(up.validate("m1234",Type.PASSWORD, "".getBytes())); - assertFalse(up.validate("m1234",Type.PASSWORD, "badPass".getBytes())); - - // Check fishAll - Set set = new TreeSet(); - List perms = new ArrayList(); - ml.fishAll(new JUPrincipal("myname"), perms); - for(Permission p : perms) { - set.add(p.getKey()); - } - assertEquals("[admin, groupA, groupB]",set.toString()); - UsersDump.write(System.out, up); - System.out.flush(); - - } - - // Simplistic Principal for testing purposes - private static class JUPrincipal implements Principal { - private String name; - public JUPrincipal(String name) { - this.name = name; - } -// @Override - public String getName() { - return name; - } - } - -} diff --git a/core/src/test/java/com/att/cadi/lur/test/TestAccess.java b/core/src/test/java/com/att/cadi/lur/test/TestAccess.java deleted file mode 100644 index 81d5092..0000000 --- a/core/src/test/java/com/att/cadi/lur/test/TestAccess.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.lur.test; - -import java.io.IOException; -import java.io.InputStream; - -import com.att.cadi.Access; -import com.att.cadi.Symm; - -public class TestAccess implements Access { - private Symm symm; - - public TestAccess() { - symm = Symm.obtain(this); - } - - public TestAccess(Symm symmetric) { - symm = symmetric; - } - - public void log(Level level, Object... elements) { - boolean first = true; - for(int i=0;i=0) { - aa[i]=(byte)c; - } - } - System.out.println(new String(aa)); - - bsis.reset(); - - byte bb[] = new byte[400]; - for(int i=0;i=0) { - bb[i]=(byte)c; - } - } - System.out.println(new String(bb)); - - } finally { - bsis.close(); - fis.close(); - } - } - - @Test - public void testByteArray() throws Exception { - FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); - BufferedServletInputStream bsis = new BufferedServletInputStream(fis); - try { - bsis.mark(0); - byte aa[] = new byte[260]; - bsis.read(aa); - System.out.println(new String(aa)); - - bsis.reset(); - - byte bb[] = new byte[400]; - bsis.read(bb); - System.out.println(new String(bb)); - - } finally { - bsis.close(); - fis.close(); - } - } - - @Test - public void testDoubleRead() throws Exception { - FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); - BufferedServletInputStream bsis = new BufferedServletInputStream(fis); - try { - bsis.mark(0); - byte aa[] = new byte[260]; - bsis.read(aa); - System.out.println(new String(aa)); - - bsis.reset(); - - byte bb[] = new byte[400]; - bsis.read(bb); - System.out.println(new String(bb)); - - } finally { - bsis.close(); - fis.close(); - } - } - - @Test - public void testByteArray2() throws Exception { - FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); - try { - BufferedServletInputStream bsis = new BufferedServletInputStream(fis); - byte[] content = null; - byte aa[] = new byte[500]; - for(int i=0;i<2000;++i) { - bsis.mark(0); - bsis.read(aa,0,260); - if(i==0)System.out.println(new String(aa)); - - bsis.reset(); - - bsis.read(aa,0,aa.length); - if(i==0) { - System.out.println(new String(aa)); - content = aa; - aa = new byte[400]; - } - bsis = new BufferedServletInputStream(new ByteArrayInputStream(content)); - - } - - System.out.println(new String(aa)); - - } finally { - fis.close(); - } - } - - // "Bug" 4/22/2013 - // Some XML code expects Buffered InputStream can never return 0... This isn't actually true, but we'll accommodate as far - // as we can. - // Here, we make sure we set and read the Buffered data, making sure the buffer is empty on the last test... - @Test - public void issue04_22_2013() throws IOException { - String testString = "We want to read in and get out with a Buffered Stream seamlessly."; - ByteArrayInputStream bais = new ByteArrayInputStream(testString.getBytes()); - BufferedServletInputStream bsis = new BufferedServletInputStream(bais); - try { - bsis.mark(0); - byte aa[] = new byte[testString.length()]; // 65 count... important for our test (divisible by 5); - - int read; - for(int i=0;i=0;i+=read) { - read = bsis.read(bb,i,5); - switch(i) { - case 65: - assertEquals(read,-1); - break; - default: - assertEquals(read,5); - } - } - System.out.println(new String(bb)); - assertEquals(testString,new String(aa)); - assertEquals(testString,new String(bb)); - - } finally { - bsis.close(); - bais.close(); - } - - } - - -} diff --git a/core/src/test/java/com/att/cadi/test/JU_Capacitor.java b/core/src/test/java/com/att/cadi/test/JU_Capacitor.java deleted file mode 100644 index 5584911..0000000 --- a/core/src/test/java/com/att/cadi/test/JU_Capacitor.java +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * ============LICENSE_START==================================================== - * * org.onap.aaf - * * =========================================================================== - * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * * =========================================================================== - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * * ============LICENSE_END==================================================== - * * - * * ECOMP is a trademark and service mark of AT&T Intellectual Property. - * * - ******************************************************************************/ -package com.att.cadi.test; - -import static junit.framework.Assert.assertEquals; - -import org.junit.Test; - -import com.att.cadi.Capacitor; - -public class JU_Capacitor { - @Test - public void testA() { - Capacitor cap = new Capacitor(); - - for(int iter=0;iter<200;++iter) { - for(int i=0;i<20;++i) { - cap.put((byte)('a'+i)); - } - cap.setForRead(); - byte[] array = new byte[20]; - for(int i=0;i<20;++i) { - array[i]=(byte)cap.read(); - } - assertEquals("abcdefghijklmnopqrst",new String(array)); - assertEquals(-1,cap.read()); - cap.done(); - } - } - - public final static String TEST_DATA = - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - @Test - public void testB() { - Capacitor cap = new Capacitor(); - byte[] arrayA = TEST_DATA.getBytes(); - System.out.println(arrayA.length); - for(int iter=0;iter<200;++iter) { - for(int i=0;i=0); - } finally { - fis.close(); - } - - for(int i=0;i", baos); + PropAccess ta = new PropAccess(); + Lur ml = up = new LocalLur(ta,"myname:groupA,groupB","admin:myname,yourname;suser:hisname,hername,m1234%"+baos.toString()); + + Permission admin = new LocalPermission("admin"); + Permission suser = new LocalPermission("suser"); + + // Check User fish + assertTrue(ml.fish(new JUPrincipal("myname"),admin)); + assertTrue(ml.fish(new JUPrincipal("hisname"),admin)); + assertFalse(ml.fish(new JUPrincipal("noname"),admin)); + assertTrue(ml.fish(new JUPrincipal("itsname"),suser)); + assertTrue(ml.fish(new JUPrincipal("hername"),suser)); + assertFalse(ml.fish(new JUPrincipal("myname"),suser)); + + + // Check validate password + assertTrue(up.validate("m1234",Type.PASSWORD, "".getBytes())); + assertFalse(up.validate("m1234",Type.PASSWORD, "badPass".getBytes())); + + // Check fishAll + Set set = new TreeSet(); + List perms = new ArrayList(); + ml.fishAll(new JUPrincipal("myname"), perms); + for(Permission p : perms) { + set.add(p.getKey()); + } + assertEquals("[admin, groupA, groupB]",set.toString()); + UsersDump.write(System.out, up); + System.out.flush(); + + } + + // Simplistic Principal for testing purposes + private static class JUPrincipal implements Principal { + private String name; + public JUPrincipal(String name) { + this.name = name; + } +// @Override + public String getName() { + return name; + } + } + +} diff --git a/core/src/test/java/org/onap/aaf/cadi/lur/test/TestAccess.java b/core/src/test/java/org/onap/aaf/cadi/lur/test/TestAccess.java new file mode 100644 index 0000000..8b1bab6 --- /dev/null +++ b/core/src/test/java/org/onap/aaf/cadi/lur/test/TestAccess.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.lur.test; + +import java.io.IOException; +import java.io.InputStream; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Symm; + +public class TestAccess implements Access { + private Symm symm; + + public TestAccess() { + symm = Symm.obtain(this); + } + + public TestAccess(Symm symmetric) { + symm = symmetric; + } + + public void log(Level level, Object... elements) { + boolean first = true; + for(int i=0;i=0) { + aa[i]=(byte)c; + } + } + System.out.println(new String(aa)); + + bsis.reset(); + + byte bb[] = new byte[400]; + for(int i=0;i=0) { + bb[i]=(byte)c; + } + } + System.out.println(new String(bb)); + + } finally { + bsis.close(); + fis.close(); + } + } + + @Test + public void testByteArray() throws Exception { + FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); + BufferedServletInputStream bsis = new BufferedServletInputStream(fis); + try { + bsis.mark(0); + byte aa[] = new byte[260]; + bsis.read(aa); + System.out.println(new String(aa)); + + bsis.reset(); + + byte bb[] = new byte[400]; + bsis.read(bb); + System.out.println(new String(bb)); + + } finally { + bsis.close(); + fis.close(); + } + } + + @Test + public void testDoubleRead() throws Exception { + FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); + BufferedServletInputStream bsis = new BufferedServletInputStream(fis); + try { + bsis.mark(0); + byte aa[] = new byte[260]; + bsis.read(aa); + System.out.println(new String(aa)); + + bsis.reset(); + + byte bb[] = new byte[400]; + bsis.read(bb); + System.out.println(new String(bb)); + + } finally { + bsis.close(); + fis.close(); + } + } + + @Test + public void testByteArray2() throws Exception { + FileInputStream fis = new FileInputStream("test/CBUSevent.xml"); + try { + BufferedServletInputStream bsis = new BufferedServletInputStream(fis); + byte[] content = null; + byte aa[] = new byte[500]; + for(int i=0;i<2000;++i) { + bsis.mark(0); + bsis.read(aa,0,260); + if(i==0)System.out.println(new String(aa)); + + bsis.reset(); + + bsis.read(aa,0,aa.length); + if(i==0) { + System.out.println(new String(aa)); + content = aa; + aa = new byte[400]; + } + bsis = new BufferedServletInputStream(new ByteArrayInputStream(content)); + + } + + System.out.println(new String(aa)); + + } finally { + fis.close(); + } + } + + // "Bug" 4/22/2013 + // Some XML code expects Buffered InputStream can never return 0... This isn't actually true, but we'll accommodate as far + // as we can. + // Here, we make sure we set and read the Buffered data, making sure the buffer is empty on the last test... + @Test + public void issue04_22_2013() throws IOException { + String testString = "We want to read in and get out with a Buffered Stream seamlessly."; + ByteArrayInputStream bais = new ByteArrayInputStream(testString.getBytes()); + BufferedServletInputStream bsis = new BufferedServletInputStream(bais); + try { + bsis.mark(0); + byte aa[] = new byte[testString.length()]; // 65 count... important for our test (divisible by 5); + + int read; + for(int i=0;i=0;i+=read) { + read = bsis.read(bb,i,5); + switch(i) { + case 65: + assertEquals(read,-1); + break; + default: + assertEquals(read,5); + } + } + System.out.println(new String(bb)); + assertEquals(testString,new String(aa)); + assertEquals(testString,new String(bb)); + + } finally { + bsis.close(); + bais.close(); + } + + } + + +} diff --git a/core/src/test/java/org/onap/aaf/cadi/test/JU_Capacitor.java b/core/src/test/java/org/onap/aaf/cadi/test/JU_Capacitor.java new file mode 100644 index 0000000..9d11fe4 --- /dev/null +++ b/core/src/test/java/org/onap/aaf/cadi/test/JU_Capacitor.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * ============LICENSE_START==================================================== + * * org.onap.aaf + * * =========================================================================== + * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * * =========================================================================== + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * ============LICENSE_END==================================================== + * * + * * ECOMP is a trademark and service mark of AT&T Intellectual Property. + * * + ******************************************************************************/ +package org.onap.aaf.cadi.test; + +import static junit.framework.Assert.assertEquals; + +import org.junit.Test; +import org.onap.aaf.cadi.Capacitor; + +public class JU_Capacitor { + @Test + public void testA() { + Capacitor cap = new Capacitor(); + + for(int iter=0;iter<200;++iter) { + for(int i=0;i<20;++i) { + cap.put((byte)('a'+i)); + } + cap.setForRead(); + byte[] array = new byte[20]; + for(int i=0;i<20;++i) { + array[i]=(byte)cap.read(); + } + assertEquals("abcdefghijklmnopqrst",new String(array)); + assertEquals(-1,cap.read()); + cap.done(); + } + } + + public final static String TEST_DATA = + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + + "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + + "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + + "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + @Test + public void testB() { + Capacitor cap = new Capacitor(); + byte[] arrayA = TEST_DATA.getBytes(); + System.out.println(arrayA.length); + for(int iter=0;iter<200;++iter) { + for(int i=0;i=0); + } finally { + fis.close(); + } + + for(int i=0;i 4.0.0 - com.att.cadi + org.onap.aaf.cadi parent CADI Parent POM (Code, Access, Data, Identity) 1.0.0-SNAPSHOT @@ -49,7 +48,7 @@ true UTF-8 1.0.0-SNAPSHOT - 2.6 + 1.0.0-SNAPSHOT 3.1.200 @@ -59,8 +58,13 @@ + 1.0.0-SNAPSHOT + https://nexus.onap.org + /content/repositories/snapshots/ + /content/repositories/releases/ + /content/repositories/staging/ + /content/sites/site/org/onap/aaf/cadi/${project.artifactId}/${project.version} - @@ -101,69 +105,69 @@ - com.att.authz + org.onap.aaf.authz authz-client ${project.authClientVersion} - com.att.cadi + org.onap.aaf.cadi cadi-core ${project.version} - com.att.cadi + org.onap.aaf.cadi cadi-core ${project.version} tests - com.att.cadi + org.onap.aaf.cadi cadi-cass ${project.version} - com.att.cadi + org.onap.aaf.cadi cadi-aaf ${project.version} - com.att.cadi + org.onap.aaf.cadi cadi-aaf ${project.version} full - com.att.cadi + org.onap.aaf.cadi cadi-client ${project.version} - com.att.cadi + org.onap.aaf.cadi cadi-tomcat ${project.version} - com.att.cadi + org.onap.aaf.cadi cadi-tguard ${project.version} - com.att.inno + org.onap.aaf.inno env ${project.innoVersion} - com.att.inno + org.onap.aaf.inno rosetta ${project.innoVersion} @@ -389,17 +393,6 @@ - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - ossrhdme - https://oss.sonatype.org/ - true - - org.codehaus.mojo @@ -412,15 +405,7 @@ - - - - maven-surefire-plugin - 2.17 - - - - + @@ -453,28 +438,61 @@ - + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ${nexusproxy} + 176c31dfe190a + ecomp-staging + + - - - - - - - - https://github.com/att/AAF.git - ${project.scm.connection} - http://github.com/att/AAF/tree/master - - - - ossrhdme - https://oss.sonatype.org/content/repositories/snapshots - - - ossrhdme - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - + + + ecomp-releases + AAF Release Repository + ${nexusproxy}${releaseNexusPath} + + + ecomp-snapshots + AAF Snapshot Repository + ${nexusproxy}${snapshotNexusPath} + + + ecomp-site + dav:${nexusproxy}${sitePath} + + + + onap-plugin-snapshots + https://nexus.onap.org/content/repositories/snapshots/ + + + + + + central + Maven 2 repository 2 + http://repo2.maven.org/maven2/ + + + onap-jar-snapshots + https://nexus.onap.org/content/repositories/snapshots + + + spring-repo + Spring repo + https://artifacts.alfresco.com/nexus/content/repositories/public/ + + + repository.jboss.org-public + JBoss.org Maven repository + https://repository.jboss.org/nexus/content/groups/public + + -- cgit 1.2.3-korg