d553ceb10ab47fa1043704c4d96af2770d71fb11
[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 }