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