Mass removal of all Tabs (Style Warnings)
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / configure / ArtifactDir.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.configure;
23
24 import java.io.File;
25 import java.io.FileOutputStream;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.PrintStream;
29 import java.io.PrintWriter;
30 import java.security.KeyStore;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import org.onap.aaf.cadi.CadiException;
37 import org.onap.aaf.cadi.Symm;
38 import org.onap.aaf.cadi.config.Config;
39 import org.onap.aaf.cadi.util.Chmod;
40 import org.onap.aaf.misc.env.Trans;
41 import org.onap.aaf.misc.env.util.Chrono;
42
43 import certman.v1_0.Artifacts.Artifact;
44 import certman.v1_0.CertInfo;
45
46 public abstract class ArtifactDir implements PlaceArtifact {
47
48     protected static final String C_R = "\n";
49     protected File dir;
50     private List<String> encodeds = new ArrayList<>();
51     
52     private Symm symm;
53     // This checks for multiple passes of Dir on the same objects.  Run clear after done.
54     protected static Map<String,Object> processed = new HashMap<>();
55
56
57     /**
58      * Note:  Derived Classes should ALWAYS call "super.place(cert,arti)" first, and 
59      * then "placeProperties(arti)" just after they implement
60      */
61     @Override
62     public final boolean place(Trans trans, CertInfo certInfo, Artifact arti, String machine) throws CadiException {
63         validate(arti);
64         
65         try {
66             // Obtain/setup directory as required
67             dir = new File(arti.getDir());
68             if(processed.get("dir")==null) {
69                 if(!dir.exists()) {
70                     Chmod.to755.chmod(dir);
71                     if(!dir.mkdirs()) {
72                         throw new CadiException("Could not create " + dir);
73                     }
74                 }
75                 
76                 // Also place cm_url and Host Name
77                 addProperty(Config.CM_URL,trans.getProperty(Config.CM_URL));
78 //                addProperty(Config.HOSTNAME,machine);
79 //                addProperty(Config.AAF_ENV,certInfo.getEnv());
80                 // Obtain Issuers
81                 boolean first = true;
82                 StringBuilder issuers = new StringBuilder();
83                 for(String dn : certInfo.getCaIssuerDNs()) {
84                     if(first) {
85                         first=false;
86                     } else {
87                         issuers.append(':');
88                     }
89                     issuers.append(dn);
90                 }
91                 addProperty(Config.CADI_X509_ISSUERS,issuers.toString());
92             }
93             symm = (Symm)processed.get("symm");
94             if(symm==null) {
95                 // CADI Key Gen
96                 File f = new File(dir,arti.getNs() + ".keyfile");
97                 if(!f.exists()) {
98                     write(f,Chmod.to400,Symm.keygen());
99                 }
100                 symm = Symm.obtain(f); 
101
102                 addEncProperty("ChallengePassword", certInfo.getChallenge());
103                 
104                 processed.put("symm",symm);
105             }
106
107             _place(trans, certInfo,arti);
108             
109             placeProperties(arti);
110             
111             processed.put("dir",dir);
112
113         } catch (Exception e) {
114             throw new CadiException(e);
115         }
116         return true;
117     }
118
119     /**
120      * Derived Classes implement this instead, so Dir can process first, and write any Properties last
121      * @param cert
122      * @param arti
123      * @return
124      * @throws CadiException
125      */
126     protected abstract boolean _place(Trans trans, CertInfo certInfo, Artifact arti) throws CadiException;
127
128     protected void addProperty(String tag, String value) throws IOException {
129         StringBuilder sb = new StringBuilder();
130         sb.append(tag);
131         sb.append('=');
132         sb.append(value);
133         encodeds.add(sb.toString());
134     }
135
136     protected void addEncProperty(String tag, String value) throws IOException {
137         StringBuilder sb = new StringBuilder();
138         sb.append(tag);
139         sb.append('=');
140         sb.append("enc:");
141         sb.append(symm.enpass(value));
142         encodeds.add(sb.toString());
143     }
144
145     public static void write(File f, Chmod c, String ... data) throws IOException {
146         f.setWritable(true,true);
147         
148         FileOutputStream fos = new FileOutputStream(f);
149         PrintStream ps = new PrintStream(fos);
150         try {
151             for(String s : data) {
152                 ps.print(s);
153             }
154         } finally {
155             ps.close();
156             c.chmod(f);
157         }
158     }
159
160     public static void write(File f, Chmod c, byte[] bytes) throws IOException {
161         f.setWritable(true,true);
162         
163         FileOutputStream fos = new FileOutputStream(f);
164         try {
165             fos.write(bytes);
166         } finally {
167             fos.close();
168             c.chmod(f);
169         }
170     }
171     
172     public static void write(File f, Chmod c, KeyStore ks, char[] pass ) throws IOException, CadiException {
173         f.setWritable(true,true);
174         
175         FileOutputStream fos = new FileOutputStream(f);
176         try {
177             ks.store(fos, pass);
178         } catch (Exception e) {
179             throw new CadiException(e);
180         } finally {
181             fos.close();
182             c.chmod(f);
183         }
184     }
185
186
187     private void validate(Artifact a) throws CadiException {
188         StringBuilder sb = new StringBuilder();
189         if(a.getDir()==null) {
190             sb.append("File Artifacts require a path");
191         }
192
193         if(a.getNs()==null) {
194             if(sb.length()>0) {
195                 sb.append('\n');
196             }
197             sb.append("File Artifacts require an AAF Namespace");
198         }
199         
200         if(sb.length()>0) {
201             throw new CadiException(sb.toString());
202         }
203     }
204
205     private boolean placeProperties(Artifact arti) throws CadiException {
206         if(encodeds.size()==0) {
207             return true;
208         }
209         boolean first=processed.get("dir")==null;
210         try {
211             File f = new File(dir,arti.getNs()+".cred.props");
212             if(f.exists()) {
213                 if(first) {
214                     File backup = File.createTempFile(f.getName()+'.', ".backup",dir);
215                     f.renameTo(backup);
216                 } else {
217                     f.setWritable(true);
218                 }
219             }
220             
221             // Append if not first
222             PrintWriter pw = new PrintWriter(new FileWriter(f,!first));
223             try {
224                 // Write a Header
225                 if(first) {
226                     for(int i=0;i<60;++i) {
227                         pw.print('#');
228                     }
229                     pw.println();
230                     pw.println("# Properties Generated by AT&T Certificate Manager");
231                     pw.print("#   by ");
232                     pw.println(System.getProperty("user.name"));
233                     pw.print("#   on ");
234                     pw.println(Chrono.dateStamp());
235                     pw.println("# @copyright 2016, AT&T");
236                     for(int i=0;i<60;++i) {
237                         pw.print('#');
238                     }
239                     pw.println();
240                     for(String prop : encodeds) {
241                         if(    prop.startsWith("cm_") 
242                             || prop.startsWith(Config.HOSTNAME)
243                             || prop.startsWith(Config.AAF_ENV)) {
244                             pw.println(prop);
245                         }
246                     }
247                 }
248             
249                 for(String prop : encodeds) {
250                     if(prop.startsWith("cadi")) {
251                         pw.println(prop);
252                     }
253                 }
254             } finally {
255                 pw.close();
256             }
257             Chmod.to644.chmod(f);
258             
259             if(first) {
260                 // Challenge
261                 f = new File(dir,arti.getNs()+".chal");
262                 if(f.exists()) {
263                     f.delete();
264                 }
265                 pw = new PrintWriter(new FileWriter(f));
266                 try {
267                     for(String prop : encodeds) {
268                         if(prop.startsWith("Challenge")) {
269                             pw.println(prop);
270                         }
271                     }
272                 } finally {
273                     pw.close();
274                 }
275                 Chmod.to400.chmod(f);
276             }
277         } catch(Exception e) {
278             throw new CadiException(e);
279         }
280         return true;
281     }
282     
283     public static void clear() {
284         processed.clear();
285     }
286
287 }