Update AAF Version 1.0.0
[aaf/cadi.git] / aaf / src / main / java / org / onap / aaf / cadi / cm / CmAgent.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\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
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \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
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.onap.aaf.cadi.cm;\r
24 \r
25 import java.io.File;\r
26 import java.io.FileInputStream;\r
27 import java.io.FileOutputStream;\r
28 import java.net.InetAddress;\r
29 import java.net.UnknownHostException;\r
30 import java.security.KeyStore;\r
31 import java.security.cert.X509Certificate;\r
32 import java.util.ArrayDeque;\r
33 import java.util.Deque;\r
34 import java.util.GregorianCalendar;\r
35 import java.util.HashMap;\r
36 import java.util.Iterator;\r
37 import java.util.Map;\r
38 import java.util.Map.Entry;\r
39 \r
40 import org.onap.aaf.cadi.PropAccess;\r
41 import org.onap.aaf.cadi.Symm;\r
42 import org.onap.aaf.cadi.aaf.client.ErrMessage;\r
43 import org.onap.aaf.cadi.aaf.v2_0.AAFCon;\r
44 import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;\r
45 import org.onap.aaf.cadi.client.Future;\r
46 import org.onap.aaf.cadi.config.Config;\r
47 import org.onap.aaf.cadi.http.HBasicAuthSS;\r
48 import org.onap.aaf.cadi.sso.AAFSSO;\r
49 \r
50 import java.util.Properties;\r
51 \r
52 import org.onap.aaf.inno.env.Data.TYPE;\r
53 import org.onap.aaf.inno.env.Env;\r
54 import org.onap.aaf.inno.env.TimeTaken;\r
55 import org.onap.aaf.inno.env.Trans;\r
56 import org.onap.aaf.inno.env.util.Chrono;\r
57 import org.onap.aaf.inno.env.util.Split;\r
58 import org.onap.aaf.rosetta.env.RosettaDF;\r
59 import org.onap.aaf.rosetta.env.RosettaEnv;\r
60 \r
61 import certman.v1_0.Artifacts;\r
62 import certman.v1_0.Artifacts.Artifact;\r
63 import certman.v1_0.CertInfo;\r
64 import certman.v1_0.CertificateRequest;\r
65 \r
66 public class CmAgent {\r
67         private static final String PRINT = "print";\r
68         private static final String FILE = "file";\r
69         private static final String PKCS12 = "pkcs12";\r
70         private static final String JKS = "jks";\r
71         private static final String SCRIPT="script";\r
72         \r
73         private static final String CM_VER = "1.0";\r
74         public static final int PASS_SIZE = 24;\r
75         private static int TIMEOUT;\r
76         \r
77         private static RosettaDF<CertificateRequest> reqDF;\r
78         private static RosettaDF<CertInfo> certDF;\r
79         private static RosettaDF<Artifacts> artifactsDF;\r
80         private static ErrMessage errMsg;\r
81         private static Map<String,PlaceArtifact> placeArtifact;\r
82         private static RosettaEnv env;\r
83 \r
84         public static void main(String[] args) {\r
85                 int exitCode = 0;\r
86                 try {\r
87                         AAFSSO aafsso = new AAFSSO(args);\r
88                         if(aafsso.loginOnly()) {\r
89                                 aafsso.setLogDefault();\r
90                                 aafsso.writeFiles();\r
91                                 System.out.println("AAF SSO information created in ~/.aaf");\r
92                         } else {\r
93                                 PropAccess access = aafsso.access();\r
94                                 env = new RosettaEnv(access.getProperties());\r
95                                 Deque<String> cmds = new ArrayDeque<String>();\r
96                                 for(String p : args) {\r
97                                         if(p.indexOf('=')<0) {\r
98                                                 cmds.add(p);\r
99                                         }\r
100                                 }\r
101                                 \r
102                                 if(cmds.size()==0) {\r
103                                         aafsso.setLogDefault();\r
104                                         System.out.println("Usage: java -jar <cadi-aaf-*-full.jar> cmd [<tag=value>]*");\r
105                                         System.out.println("   create   <mechID> [<machine>]");\r
106                                         System.out.println("   read     <mechID> [<machine>]");\r
107                                         System.out.println("   update   <mechID> [<machine>]");\r
108                                         System.out.println("   delete   <mechID> [<machine>]");\r
109                                         System.out.println("   copy     <mechID> <machine> <newmachine>[,<newmachine>]*");\r
110                                         System.out.println("   place    <mechID> [<machine>]");\r
111                                         System.out.println("   showpass <mechID> [<machine>]");\r
112                                         System.out.println("   check    <mechID> [<machine>]");\r
113                                         System.exit(1);\r
114                                 }\r
115                                 \r
116                                 TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, "5000"));\r
117                         \r
118                                 reqDF = env.newDataFactory(CertificateRequest.class);\r
119                                 artifactsDF = env.newDataFactory(Artifacts.class);\r
120                                 certDF = env.newDataFactory(CertInfo.class);\r
121                                 errMsg = new ErrMessage(env);\r
122         \r
123                                 placeArtifact = new HashMap<String,PlaceArtifact>();\r
124                                 placeArtifact.put(JKS, new PlaceArtifactInKeystore(JKS));\r
125                                 placeArtifact.put(PKCS12, new PlaceArtifactInKeystore(PKCS12));\r
126                                 placeArtifact.put(FILE, new PlaceArtifactInFiles());\r
127                                 placeArtifact.put(PRINT, new PlaceArtifactOnStream(System.out));\r
128                                 placeArtifact.put(SCRIPT, new PlaceArtifactScripts());\r
129                                 \r
130                                 Trans trans = env.newTrans();\r
131                                 try {\r
132                                         // show Std out again\r
133                                         aafsso.setLogDefault();\r
134                                         aafsso.setStdErrDefault();\r
135                                         \r
136                                         // if CM_URL can be obtained, add to sso.props, if written\r
137                                         String cm_url = getProperty(access,env,false, Config.CM_URL,Config.CM_URL+": ");\r
138                                         if(cm_url!=null) {\r
139                                                 aafsso.addProp(Config.CM_URL, cm_url);\r
140                                         }\r
141                                         aafsso.writeFiles();\r
142 \r
143                                         AAFCon<?> aafcon = new AAFConHttp(access,Config.CM_URL);\r
144 \r
145                                         String cmd = cmds.removeFirst();\r
146                                         if("place".equals(cmd)) {\r
147                                                 placeCerts(trans,aafcon,cmds);\r
148                                         } else if("create".equals(cmd)) {\r
149                                                 createArtifact(trans, aafcon,cmds);\r
150                                         } else if("read".equals(cmd)) {\r
151                                                 readArtifact(trans, aafcon, cmds);\r
152                                         } else if("copy".equals(cmd)) {\r
153                                                 copyArtifact(trans, aafcon, cmds);\r
154                                         } else if("update".equals(cmd)) {\r
155                                                 updateArtifact(trans, aafcon, cmds);\r
156                                         } else if("delete".equals(cmd)) {\r
157                                                 deleteArtifact(trans, aafcon, cmds);\r
158                                         } else if("showpass".equals(cmd)) {\r
159                                                 showPass(trans,aafcon,cmds);\r
160                                         } else if("check".equals(cmd)) {\r
161                                                 try {\r
162                                                         exitCode = check(trans,aafcon,cmds);\r
163                                                 } catch (Exception e) {\r
164                                                         exitCode = 1;\r
165                                                         throw e;\r
166                                                 }\r
167                                         } else {\r
168                                                 AAFSSO.cons.printf("Unknown command \"%s\"\n", cmd);\r
169                                         }\r
170                                 } finally {\r
171                                         StringBuilder sb = new StringBuilder();\r
172                         trans.auditTrail(4, sb, Trans.REMOTE);\r
173                         if(sb.length()>0) {\r
174                                 trans.info().log("Trans Info\n",sb);\r
175                         }\r
176                                 }\r
177                                 aafsso.close();\r
178                         }\r
179                 } catch (Exception e) {\r
180                         e.printStackTrace();\r
181                 }\r
182                 if(exitCode!=0) {\r
183                         System.exit(exitCode);\r
184                 }\r
185         }\r
186 \r
187         private static String getProperty(PropAccess pa, Env env, boolean secure, String tag, String prompt, Object ... def) {\r
188                 String value;\r
189                 if((value=pa.getProperty(tag))==null) {\r
190                         if(secure) {\r
191                                 value = new String(AAFSSO.cons.readPassword(prompt, def));\r
192                         } else {\r
193                                 value = AAFSSO.cons.readLine(prompt,def).trim();\r
194                         }\r
195                         if(value!=null) {\r
196                                 if(value.length()>0) {\r
197                                         pa.setProperty(tag,value);\r
198                                         env.setProperty(tag,value);\r
199                                 } else if(def.length==1) {\r
200                                         value=def[0].toString();\r
201                                         pa.setProperty(tag,value);\r
202                                         env.setProperty(tag,value);\r
203                                 }\r
204                         }\r
205                 }\r
206                 return value;\r
207         }\r
208 \r
209         private static String mechID(Deque<String> cmds) {\r
210                 if(cmds.size()<1) {\r
211                         String alias = env.getProperty(Config.CADI_ALIAS);\r
212                         return alias!=null?alias:AAFSSO.cons.readLine("MechID: ");\r
213                 }\r
214                 return cmds.removeFirst();      \r
215         }\r
216 \r
217         private static String machine(Deque<String> cmds) throws UnknownHostException {\r
218                 if(cmds.size()>0) {\r
219                         return cmds.removeFirst();\r
220                 } else {\r
221                         String mach = env.getProperty(Config.HOSTNAME);\r
222                         return mach!=null?mach:InetAddress.getLocalHost().getHostName();\r
223                 }\r
224         }\r
225 \r
226         private static String[] machines(Deque<String> cmds)  {\r
227                 String machines;\r
228                 if(cmds.size()>0) {\r
229                         machines = cmds.removeFirst();\r
230                 } else {\r
231                         machines = AAFSSO.cons.readLine("Machines (sep by ','): ");\r
232                 }\r
233                 return Split.split(',', machines);\r
234         }\r
235 \r
236         private static void createArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
237                 String mechID = mechID(cmds);\r
238                 String machine = machine(cmds);\r
239 \r
240                 Artifacts artifacts = new Artifacts();\r
241                 Artifact arti = new Artifact();\r
242                 artifacts.getArtifact().add(arti);\r
243                 arti.setMechid(mechID!=null?mechID:AAFSSO.cons.readLine("MechID: "));\r
244                 arti.setMachine(machine!=null?machine:AAFSSO.cons.readLine("Machine (%s): ",InetAddress.getLocalHost().getHostName()));\r
245                 arti.setCa(AAFSSO.cons.readLine("CA: (%s): ","aaf"));\r
246                 \r
247                 String resp = AAFSSO.cons.readLine("Types [file,jks,script] (%s): ", "jks");\r
248                 for(String s : Split.splitTrim(',', resp)) {\r
249                         arti.getType().add(s);\r
250                 }\r
251                 // Always do Script\r
252                 if(!resp.contains(SCRIPT)) {\r
253                         arti.getType().add(SCRIPT);\r
254                 }\r
255 \r
256                 // Note: Sponsor is set on Creation by CM\r
257                 String configRootName = AAFCon.reverseDomain(arti.getMechid());\r
258                 arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",configRootName));\r
259                 arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", System.getProperty("user.dir")));\r
260                 arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", System.getProperty("user.name")));\r
261                 arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renewal Days (%s):", "30")));\r
262                 arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (mailto owner):", "")));\r
263                 \r
264                 TimeTaken tt = trans.start("Create Artifact", Env.REMOTE);\r
265                 try {\r
266                         Future<Artifacts> future = aafcon.client(CM_VER).create("/cert/artifacts", artifactsDF, artifacts);\r
267                         if(future.get(TIMEOUT)) {\r
268                                 trans.info().printf("Call to AAF Certman successful %s, %s",arti.getMechid(), arti.getMachine());\r
269                         } else {\r
270                                 trans.error().printf("Call to AAF Certman failed, %s",\r
271                                         errMsg.toMsg(future));\r
272                         }\r
273                 } finally {\r
274                         tt.done();\r
275                 }\r
276         }\r
277 \r
278         private static String toNotification(String notification) {\r
279                 if(notification==null) {\r
280                         notification="";\r
281                 } else if(notification.length()>0) {\r
282                         if(notification.indexOf(':')<0) {\r
283                                 notification = "mailto:" + notification;\r
284                         }\r
285                 }\r
286                 return notification;\r
287         }\r
288         \r
289 \r
290         private static void readArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
291                 String mechID = mechID(cmds);\r
292                 String machine = machine(cmds);\r
293 \r
294                 TimeTaken tt = trans.start("Read Artifact", Env.SUB);\r
295                 try {\r
296                         Future<Artifacts> future = aafcon.client(CM_VER)\r
297                                         .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
298         \r
299                         if(future.get(TIMEOUT)) {\r
300                                 boolean printed = false;\r
301                                 for(Artifact a : future.value.getArtifact()) {\r
302                                         AAFSSO.cons.printf("MechID:          %s\n",a.getMechid()); \r
303                                         AAFSSO.cons.printf("  Sponsor:       %s\n",a.getSponsor()); \r
304                                         AAFSSO.cons.printf("Machine:         %s\n",a.getMachine()); \r
305                                         AAFSSO.cons.printf("CA:              %s\n",a.getCa()); \r
306                                         StringBuilder sb = new StringBuilder();\r
307                                         boolean first = true;\r
308                                         for(String t : a.getType()) {\r
309                                                 if(first) {first=false;}\r
310                                                 else{sb.append(',');}\r
311                                                 sb.append(t);\r
312                                         }\r
313                                         AAFSSO.cons.printf("Types:           %s\n",sb);\r
314                                         AAFSSO.cons.printf("Namespace:       %s\n",a.getAppName()); \r
315                                         AAFSSO.cons.printf("Directory:       %s\n",a.getDir());\r
316                                         AAFSSO.cons.printf("O/S User:        %s\n",a.getOsUser());\r
317                                         AAFSSO.cons.printf("Renew Days:      %d\n",a.getRenewDays());\r
318                                         AAFSSO.cons.printf("Notification     %s\n",a.getNotification());\r
319                                         printed = true;\r
320                                 }\r
321                                 if(!printed) {\r
322                                         AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine);\r
323                                 }\r
324                         } else {\r
325                                 trans.error().log(errMsg.toMsg(future));\r
326                         }\r
327                 } finally {\r
328                         tt.done();\r
329                 }\r
330         }\r
331         \r
332         private static void copyArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
333                 String mechID = mechID(cmds);\r
334                 String machine = machine(cmds);\r
335                 String[] newmachs = machines(cmds);\r
336                 if(newmachs==null || newmachs == null) {\r
337                         trans.error().log("No machines listed to copy to");\r
338                 } else {\r
339                         TimeTaken tt = trans.start("Copy Artifact", Env.REMOTE);\r
340                         try {\r
341                                 Future<Artifacts> future = aafcon.client(CM_VER)\r
342                                                 .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
343                         \r
344                                 if(future.get(TIMEOUT)) {\r
345                                         boolean printed = false;\r
346                                         for(Artifact a : future.value.getArtifact()) {\r
347                                                 for(String m : newmachs) {\r
348                                                         a.setMachine(m);\r
349                                                         Future<Artifacts> fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, future.value);\r
350                                                         if(fup.get(TIMEOUT)) {\r
351                                                                 trans.info().printf("Copy of %s %s successful to %s",mechID,machine,m);\r
352                                                         } else {\r
353                                                                 trans.error().printf("Call to AAF Certman failed, %s",\r
354                                                                         errMsg.toMsg(fup));\r
355                                                         }\r
356         \r
357                                                         printed = true;\r
358                                                 }\r
359                                         }\r
360                                         if(!printed) {\r
361                                                 AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine);\r
362                                         }\r
363                                 } else {\r
364                                         trans.error().log(errMsg.toMsg(future));\r
365                                 }\r
366                         } finally {\r
367                                 tt.done();\r
368                         }\r
369                 }\r
370         }\r
371 \r
372         private static void updateArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
373                 String mechID = mechID(cmds);\r
374                 String machine = machine(cmds);\r
375 \r
376                 TimeTaken tt = trans.start("Update Artifact", Env.REMOTE);\r
377                 try {\r
378                         Future<Artifacts> fread = aafcon.client(CM_VER)\r
379                                         .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
380         \r
381                         if(fread.get(TIMEOUT)) {\r
382                                 Artifacts artifacts = new Artifacts();\r
383                                 for(Artifact a : fread.value.getArtifact()) {\r
384                                         Artifact arti = new Artifact();\r
385                                         artifacts.getArtifact().add(arti);\r
386                                         \r
387                                         AAFSSO.cons.printf("For %s on %s\n", a.getMechid(),a.getMachine());\r
388                                         arti.setMechid(a.getMechid());\r
389                                         arti.setMachine(a.getMachine());\r
390                                         arti.setCa(AAFSSO.cons.readLine("CA: (%s): ",a.getCa()));\r
391                                         StringBuilder sb = new StringBuilder();\r
392                                         boolean first = true;\r
393                                         for(String t : a.getType()) {\r
394                                                 if(first) {first=false;}\r
395                                                 else{sb.append(',');}\r
396                                                 sb.append(t);\r
397                                         }\r
398         \r
399                                         String resp = AAFSSO.cons.readLine("Types [file,jks,pkcs12] (%s): ", sb);\r
400                                         for(String s : Split.splitTrim(',', resp)) {\r
401                                                 arti.getType().add(s);\r
402                                         }\r
403                                         // Always do Script\r
404                                         if(!resp.contains(SCRIPT)) {\r
405                                                 arti.getType().add(SCRIPT);\r
406                                         }\r
407 \r
408                                         // Note: Sponsor is set on Creation by CM\r
409                                         arti.setAppName(AAFSSO.cons.readLine("Namespace (%s): ",a.getAppName()));\r
410                                         arti.setDir(AAFSSO.cons.readLine("Directory (%s): ", a.getDir()));\r
411                                         arti.setOsUser(AAFSSO.cons.readLine("OS User (%s): ", a.getOsUser()));\r
412                                         arti.setRenewDays(Integer.parseInt(AAFSSO.cons.readLine("Renew Days (%s):", a.getRenewDays())));\r
413                                         arti.setNotification(toNotification(AAFSSO.cons.readLine("Notification (%s):", a.getNotification())));\r
414         \r
415                                 }\r
416                                 if(artifacts.getArtifact().size()==0) {\r
417                                         AAFSSO.cons.printf("Artifact for %s %s does not exist", mechID, machine);\r
418                                 } else {\r
419                                         Future<Artifacts> fup = aafcon.client(CM_VER).update("/cert/artifacts", artifactsDF, artifacts);\r
420                                         if(fup.get(TIMEOUT)) {\r
421                                                 trans.info().printf("Call to AAF Certman successful %s, %s",mechID,machine);\r
422                                         } else {\r
423                                                 trans.error().printf("Call to AAF Certman failed, %s",\r
424                                                         errMsg.toMsg(fup));\r
425                                         }\r
426                                 }\r
427                         } else {\r
428                                 trans.error().printf("Call to AAF Certman failed, %s %s, %s",\r
429                                                 errMsg.toMsg(fread),mechID,machine);\r
430                         }\r
431                 } finally {\r
432                         tt.done();\r
433                 }\r
434         }\r
435         \r
436         private static void deleteArtifact(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
437                 String mechid = mechID(cmds);\r
438                 String machine = machine(cmds);\r
439                 \r
440                 TimeTaken tt = trans.start("Delete Artifact", Env.REMOTE);\r
441                 try {\r
442                         Future<Void> future = aafcon.client(CM_VER)\r
443                                         .delete("/cert/artifacts/"+mechid+"/"+machine,"application/json" );\r
444         \r
445                         if(future.get(TIMEOUT)) {\r
446                                 trans.info().printf("Call to AAF Certman successful %s, %s",mechid,machine);\r
447                         } else {\r
448                                 trans.error().printf("Call to AAF Certman failed, %s %s, %s",\r
449                                         errMsg.toMsg(future),mechid,machine);\r
450                         }\r
451                 } finally {\r
452                         tt.done();\r
453                 }\r
454         }\r
455 \r
456         \r
457 \r
458         private static boolean placeCerts(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
459                 boolean rv = false;\r
460                 String mechID = mechID(cmds);\r
461                 String machine = machine(cmds);\r
462                 \r
463                 TimeTaken tt = trans.start("Place Artifact", Env.REMOTE);\r
464                 try {\r
465                         Future<Artifacts> acf = aafcon.client(CM_VER)\r
466                                         .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
467                         if(acf.get(TIMEOUT)) {\r
468                                 // Have to wait for JDK 1.7 source...\r
469                                 //switch(artifact.getType()) {\r
470                                 if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) {\r
471                                         AAFSSO.cons.printf("===> There are no artifacts for %s %s", mechID, machine);\r
472                                 } else {\r
473                                         for(Artifact a : acf.value.getArtifact()) {\r
474                                                 String osID = System.getProperty("user.name");\r
475                                                 if(a.getOsUser().equals(osID)) {\r
476                                                         CertificateRequest cr = new CertificateRequest();\r
477                                                         cr.setMechid(a.getMechid());\r
478                                                         cr.setSponsor(a.getSponsor());\r
479                                                         cr.getFqdns().add(a.getMachine());\r
480                                                         Future<String> f = aafcon.client(CM_VER)\r
481                                                                         .setQueryParams("withTrust")\r
482                                                                         .updateRespondString("/cert/" + a.getCa(),reqDF, cr);\r
483                                                         if(f.get(TIMEOUT)) {\r
484                                                                 CertInfo capi = certDF.newData().in(TYPE.JSON).load(f.body()).asObject();\r
485                                                                 for(String type : a.getType()) {\r
486                                                                         PlaceArtifact pa = placeArtifact.get(type);\r
487                                                                         if(pa!=null) {\r
488                                                                                 if(rv = pa.place(trans, capi, a)) {\r
489                                                                                         notifyPlaced(a,rv);\r
490                                                                                 }\r
491                                                                         }\r
492                                                                 }\r
493                                                                 // Cover for the above multiple pass possibilities with some static Data, then clear per Artifact\r
494                                                         } else {\r
495                                                                 trans.error().log(errMsg.toMsg(f));\r
496                                                         }\r
497                                                 } else {\r
498                                                         trans.error().log("You must be OS User \"" + a.getOsUser() +"\" to place Certificates on this box");\r
499                                                 }\r
500                                         }\r
501                                 }\r
502                         } else {\r
503                                 trans.error().log(errMsg.toMsg(acf));\r
504                         }\r
505                 } finally {\r
506                         tt.done();\r
507                 }\r
508                 return rv;\r
509         }\r
510         \r
511         private static void notifyPlaced(Artifact a, boolean rv) {\r
512                 \r
513                 \r
514         }\r
515 \r
516         private static void showPass(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
517                 String mechID = mechID(cmds);\r
518                 String machine = machine(cmds);\r
519 \r
520                 TimeTaken tt = trans.start("Show Password", Env.REMOTE);\r
521                 try {\r
522                         Future<Artifacts> acf = aafcon.client(CM_VER)\r
523                                         .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
524                         if(acf.get(TIMEOUT)) {\r
525                                 // Have to wait for JDK 1.7 source...\r
526                                 //switch(artifact.getType()) {\r
527                                 if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) {\r
528                                         AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine);\r
529                                 } else {\r
530                                         String id = aafcon.defID();\r
531                                         boolean allowed;\r
532                                         for(Artifact a : acf.value.getArtifact()) {\r
533                                                 allowed = id!=null && (id.equals(a.getSponsor()) ||\r
534                                                                 (id.equals(a.getMechid()) \r
535                                                                                 && aafcon.securityInfo().defSS.getClass().isAssignableFrom(HBasicAuthSS.class)));\r
536                                                 if(!allowed) {\r
537                                                         Future<String> pf = aafcon.client(CM_VER).read("/cert/may/" + \r
538                                                                         a.getAppName() + ".certman|"+a.getCa()+"|showpass","*/*");\r
539                                                         if(pf.get(TIMEOUT)) {\r
540                                                                 allowed = true;\r
541                                                         } else {\r
542                                                                 trans.error().log(errMsg.toMsg(pf));\r
543                                                         }\r
544                                                 }\r
545                                                 if(allowed) {\r
546                                                         File dir = new File(a.getDir());\r
547                                                         Properties props = new Properties();\r
548                                                         FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props"));\r
549                                                         try {\r
550                                                                 props.load(fis);\r
551                                                                 fis.close();\r
552                                                                 fis = new FileInputStream(new File(dir,a.getAppName()+".chal"));\r
553                                                                 props.load(fis);\r
554                                                         } finally {\r
555                                                                 fis.close();\r
556                                                         }\r
557                                                         \r
558                                                         File f = new File(dir,a.getAppName()+".keyfile");\r
559                                                         if(f.exists()) {\r
560                                                                 Symm symm = Symm.obtain(f);\r
561                                                                 \r
562                                                                 for(Iterator<Entry<Object,Object>> iter = props.entrySet().iterator(); iter.hasNext();) {\r
563                                                                         Entry<Object,Object> en = iter.next();\r
564                                                                         if(en.getValue().toString().startsWith("enc:???")) {\r
565                                                                                 System.out.printf("%s=%s\n", en.getKey(), symm.depass(en.getValue().toString()));\r
566                                                                         }\r
567                                                                 }\r
568                                                         } else {\r
569                                                                 trans.error().printf("%s.keyfile must exist to read passwords for %s on %s",\r
570                                                                                 f.getAbsolutePath(),a.getMechid(), a.getMachine());\r
571                                                         }\r
572                                                 }\r
573                                         }\r
574                                 }\r
575                         } else {\r
576                                 trans.error().log(errMsg.toMsg(acf));\r
577                         }\r
578                 } finally {\r
579                         tt.done();\r
580                 }\r
581 \r
582         }\r
583         \r
584 \r
585         /**\r
586          * Check returns Error Codes, so that Scripts can know what to do\r
587          * \r
588          *   0 - Check Complete, nothing to do\r
589          *   1 - General Error\r
590          *   2 - Error for specific Artifact - read check.msg\r
591          *   10 - Certificate Updated - check.msg is email content\r
592          *   \r
593          * @param trans\r
594          * @param aafcon\r
595          * @param cmds\r
596          * @return\r
597          * @throws Exception\r
598          */\r
599         private static int check(Trans trans, AAFCon<?> aafcon, Deque<String> cmds) throws Exception {\r
600                 int exitCode=1;\r
601                 String mechID = mechID(cmds);\r
602                 String machine = machine(cmds);\r
603                 \r
604                 TimeTaken tt = trans.start("Check Certificate", Env.REMOTE);\r
605                 try {\r
606                 \r
607                         Future<Artifacts> acf = aafcon.client(CM_VER)\r
608                                         .read("/cert/artifacts/"+mechID+'/'+machine, artifactsDF);\r
609                         if(acf.get(TIMEOUT)) {\r
610                                 // Have to wait for JDK 1.7 source...\r
611                                 //switch(artifact.getType()) {\r
612                                 if(acf.value.getArtifact()==null || acf.value.getArtifact().isEmpty()) {\r
613                                         AAFSSO.cons.printf("No Artifacts found for %s on %s", mechID, machine);\r
614                                 } else {\r
615                                         String id = aafcon.defID();\r
616                                         GregorianCalendar now = new GregorianCalendar();\r
617                                         for(Artifact a : acf.value.getArtifact()) {\r
618                                                 if(id.equals(a.getMechid())) {\r
619                                                         File dir = new File(a.getDir());\r
620                                                         Properties props = new Properties();\r
621                                                         FileInputStream fis = new FileInputStream(new File(dir,a.getAppName()+".props"));\r
622                                                         try {\r
623                                                                 props.load(fis);\r
624                                                         } finally {\r
625                                                                 fis.close();\r
626                                                         }\r
627                                                         \r
628                                                         String prop;                                            \r
629                                                         File f;\r
630         \r
631                                                         if((prop=props.getProperty(Config.CADI_KEYFILE))==null ||\r
632                                                                 !(f=new File(prop)).exists()) {\r
633                                                                         trans.error().printf("Keyfile must exist to check Certificates for %s on %s",\r
634                                                                                 a.getMechid(), a.getMachine());\r
635                                                         } else {\r
636                                                                 String ksf = props.getProperty(Config.CADI_KEYSTORE);\r
637                                                                 String ksps = props.getProperty(Config.CADI_KEYSTORE_PASSWORD);\r
638                                                                 if(ksf==null || ksps == null) {\r
639                                                                         trans.error().printf("Properties %s and %s must exist to check Certificates for %s on %s",\r
640                                                                                         Config.CADI_KEYSTORE, Config.CADI_KEYSTORE_PASSWORD,a.getMechid(), a.getMachine());\r
641                                                                 } else {\r
642                                                                         KeyStore ks = KeyStore.getInstance("JKS");\r
643                                                                         Symm symm = Symm.obtain(f);\r
644                                                                         \r
645                                                                         fis = new FileInputStream(ksf);\r
646                                                                         try {\r
647                                                                                 ks.load(fis,symm.depass(ksps).toCharArray());\r
648                                                                         } finally {\r
649                                                                                 fis.close();\r
650                                                                         }\r
651                                                                         X509Certificate cert = (X509Certificate)ks.getCertificate(mechID);\r
652                                                                         String msg = null;\r
653 \r
654                                                                         if(cert==null) {\r
655                                                                                 msg = String.format("X509Certificate does not exist for %s on %s in %s",\r
656                                                                                                 a.getMechid(), a.getMachine(), ksf);\r
657                                                                                 trans.error().log(msg);\r
658                                                                                 exitCode = 2;\r
659                                                                         } else {\r
660                                                                                 GregorianCalendar renew = new GregorianCalendar();\r
661                                                                                 renew.setTime(cert.getNotAfter());\r
662                                                                                 renew.add(GregorianCalendar.DAY_OF_MONTH,-1*a.getRenewDays());\r
663                                                                                 if(renew.after(now)) {\r
664                                                                                         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", \r
665                                                                                                         a.getMechid(), a.getMachine(),Chrono.dateOnlyStamp(now),cert.getNotAfter(),Chrono.dateOnlyStamp(renew));\r
666                                                                                         trans.info().log(msg);\r
667                                                                                         exitCode = 0; // OK\r
668                                                                                 } else {\r
669                                                                                         trans.info().printf("X509Certificate for %s on %s expiration, %s, needs Renewal.\n", \r
670                                                                                                         a.getMechid(), a.getMachine(),cert.getNotAfter());\r
671                                                                                         cmds.offerLast(mechID);\r
672                                                                                         cmds.offerLast(machine);\r
673                                                                                         if(placeCerts(trans,aafcon,cmds)) {\r
674                                                                                                 msg = String.format("X509Certificate for %s on %s has been renewed. Ensure services using are refreshed.\n", \r
675                                                                                                                 a.getMechid(), a.getMachine());\r
676                                                                                                 exitCode = 10; // Refreshed\r
677                                                                                         } else {\r
678                                                                                                 msg = String.format("X509Certificate for %s on %s attempted renewal, but failed. Immediate Investigation is required!\n", \r
679                                                                                                                 a.getMechid(), a.getMachine());\r
680                                                                                                 exitCode = 1; // Error Renewing\r
681                                                                                         }\r
682                                                                                 }\r
683                                                                         }\r
684                                                                         if(msg!=null) {\r
685                                                                                 FileOutputStream fos = new FileOutputStream(a.getDir()+'/'+a.getAppName()+".msg");\r
686                                                                                 try {\r
687                                                                                         fos.write(msg.getBytes());\r
688                                                                                 } finally {\r
689                                                                                         fos.close();\r
690                                                                                 }\r
691                                                                         }\r
692                                                                 }\r
693                                                                 \r
694                                                         }\r
695                                                 }\r
696                                         }\r
697                                 }\r
698                         } else {\r
699                                 trans.error().log(errMsg.toMsg(acf));\r
700                                 exitCode=1;\r
701                         }\r
702                 } finally {\r
703                         tt.done();\r
704                 }\r
705                 return exitCode;\r
706         }\r
707 \r
708 }\r
709                         \r
710                 \r
711 \r
712 \r