1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package com.att.cadi.cm;
\r
25 import java.io.File;
\r
26 import java.io.FileOutputStream;
\r
27 import java.io.FileWriter;
\r
28 import java.io.IOException;
\r
29 import java.io.PrintStream;
\r
30 import java.io.PrintWriter;
\r
31 import java.security.KeyStore;
\r
32 import java.util.ArrayList;
\r
33 import java.util.HashMap;
\r
34 import java.util.List;
\r
35 import java.util.Map;
\r
37 import com.att.cadi.CadiException;
\r
38 import com.att.cadi.Symm;
\r
39 import com.att.cadi.config.Config;
\r
40 import com.att.cadi.util.Chmod;
\r
41 import com.att.inno.env.Trans;
\r
42 import com.att.inno.env.util.Chrono;
\r
44 import certman.v1_0.Artifacts.Artifact;
\r
45 import certman.v1_0.CertInfo;
\r
47 public abstract class ArtifactDir implements PlaceArtifact {
\r
49 protected static final String C_R = "\n";
\r
51 private List<String> encodeds = new ArrayList<String>();
\r
54 // This checks for multiple passes of Dir on the same objects. Run clear after done.
\r
55 protected static Map<String,Object> processed = new HashMap<String,Object>();
\r
59 * Note: Derived Classes should ALWAYS call "super.place(cert,arti)" first, and
\r
60 * then "placeProperties(arti)" just after they implement
\r
63 public final boolean place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException {
\r
67 // Obtain/setup directory as required
\r
68 dir = new File(arti.getDir());
\r
69 if(processed.get("dir")==null) {
\r
71 Chmod.to755.chmod(dir);
\r
73 throw new CadiException("Could not create " + dir);
\r
77 // Also place cm_url and Host Name
\r
78 addProperty(Config.CM_URL,trans.getProperty(Config.CM_URL));
\r
79 addProperty(Config.HOSTNAME,arti.getMachine());
\r
80 //addProperty(Config.AAF_ENV,certInfo.getEnv());
\r
82 boolean first = true;
\r
83 StringBuilder issuers = new StringBuilder();
\r
84 // for(String dn : certInfo.getCaIssuerDNs()) {
\r
88 // issuers.append(':');
\r
90 // issuers.append(dn);
\r
92 addProperty(Config.CADI_X509_ISSUERS,issuers.toString());
\r
94 symm = (Symm)processed.get("symm");
\r
97 File f = new File(dir,arti.getAppName() + ".keyfile");
\r
99 write(f,Chmod.to400,Symm.baseCrypt().keygen());
\r
101 symm = Symm.obtain(f);
\r
103 addEncProperty("ChallengePassword", certInfo.getChallenge());
\r
105 processed.put("symm",symm);
\r
108 _place(trans, certInfo,arti);
\r
110 placeProperties(arti);
\r
112 processed.put("dir",dir);
\r
114 } catch (Exception e) {
\r
115 throw new CadiException(e);
\r
121 * Derived Classes implement this instead, so Dir can process first, and write any Properties last
\r
125 * @throws CadiException
\r
127 protected abstract boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException;
\r
129 protected void addProperty(String tag, String value) throws IOException {
\r
130 StringBuilder sb = new StringBuilder();
\r
134 encodeds.add(sb.toString());
\r
137 protected void addEncProperty(String tag, String value) throws IOException {
\r
138 StringBuilder sb = new StringBuilder();
\r
141 sb.append("enc:???");
\r
142 sb.append(symm.enpass(value));
\r
143 encodeds.add(sb.toString());
\r
146 protected void write(File f, Chmod c, String ... data) throws IOException {
\r
147 f.setWritable(true,true);
\r
149 FileOutputStream fos = new FileOutputStream(f);
\r
150 PrintStream ps = new PrintStream(fos);
\r
152 for(String s : data) {
\r
161 protected void write(File f, Chmod c, byte[] bytes) throws IOException {
\r
162 f.setWritable(true,true);
\r
164 FileOutputStream fos = new FileOutputStream(f);
\r
173 protected void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException {
\r
174 f.setWritable(true,true);
\r
176 FileOutputStream fos = new FileOutputStream(f);
\r
178 ks.store(fos, pass);
\r
179 } catch (Exception e) {
\r
180 throw new CadiException(e);
\r
188 private void validate(Artifact a) throws CadiException {
\r
189 StringBuilder sb = new StringBuilder();
\r
190 if(a.getDir()==null) {
\r
191 sb.append("File Artifacts require a path");
\r
194 if(a.getAppName()==null) {
\r
195 if(sb.length()>0) {
\r
198 sb.append("File Artifacts require an AAF Namespace");
\r
201 if(sb.length()>0) {
\r
202 throw new CadiException(sb.toString());
\r
206 private boolean placeProperties(Artifact arti) throws CadiException {
\r
207 if(encodeds.size()==0) {
\r
210 boolean first=processed.get("dir")==null;
\r
212 File f = new File(dir,arti.getAppName()+".props");
\r
217 f.setWritable(true);
\r
220 // Append if not first
\r
221 PrintWriter pw = new PrintWriter(new FileWriter(f,!first));
\r
225 for(int i=0;i<60;++i) {
\r
229 pw.println("# Properties Generated by AT&T Certificate Manager");
\r
231 pw.println(System.getProperty("user.name"));
\r
233 pw.println(Chrono.dateStamp());
\r
234 pw.println("# @copyright 2016, AT&T");
\r
235 for(int i=0;i<60;++i) {
\r
239 for(String prop : encodeds) {
\r
240 if( prop.startsWith("cm_")
\r
241 || prop.startsWith(Config.HOSTNAME)
\r
242 || prop.startsWith(Config.AAF_ENV)) {
\r
249 for(String prop : encodeds) {
\r
250 if(prop.startsWith("cadi")) {
\r
257 Chmod.to644.chmod(f);
\r
261 f = new File(dir,arti.getAppName()+".chal");
\r
265 pw = new PrintWriter(new FileWriter(f));
\r
267 for(String prop : encodeds) {
\r
268 if(prop.startsWith("Challenge")) {
\r
275 Chmod.to400.chmod(f);
\r
277 } catch(Exception e) {
\r
278 throw new CadiException(e);
\r
283 public static void clear() {
\r