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