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