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