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