AT&T 2.0.19 Code drop, stage 2
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / sso / AAFSSO.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.sso;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.PrintStream;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Properties;
34
35 import org.onap.aaf.cadi.CadiException;
36 import org.onap.aaf.cadi.PropAccess;
37 import org.onap.aaf.cadi.Symm;
38 import org.onap.aaf.cadi.Access.Level;
39 import org.onap.aaf.cadi.config.Config;
40 import org.onap.aaf.cadi.util.MyConsole;
41 import org.onap.aaf.cadi.util.SubStandardConsole;
42 import org.onap.aaf.cadi.util.TheConsole;
43
44
45 public class AAFSSO {
46         public static final MyConsole  cons = TheConsole.implemented()?new TheConsole():new SubStandardConsole();
47         
48         private Properties diskprops = null; // use for temp storing User/Password on disk
49         private File dot_aaf = null, sso=null; // instantiated, if ever, with diskprops
50         
51         boolean removeSSO=false;
52         boolean loginOnly = false;
53         private PropAccess access;
54         private StringBuilder err;
55         private String user,encrypted_pass;
56         private boolean use_X509;
57
58         private PrintStream os, stdout=null,stderr=null;
59
60         private Method close;
61
62         public AAFSSO(String[] args) throws IOException, CadiException {
63                 List<String> larg = new ArrayList<String>(args.length);
64
65                 // Cover for bash's need to escape *.. (\\*)
66                 // also, remove SSO if required
67                 for (int i = 0; i < args.length; ++i) {
68                         if ("\\*".equals(args[i])) {
69                                 args[i] = "*";
70                         }
71                         
72                         if("-logout".equalsIgnoreCase(args[i])) {
73                                 removeSSO=true;
74                         } else if("-login".equalsIgnoreCase(args[i])) {
75                                 loginOnly = true;
76                         } else {
77                                 larg.add(args[i]);
78                         }
79                 }
80                 
81                 String[] nargs = new String[larg.size()];
82                 larg.toArray(nargs);
83
84                 dot_aaf = new File(System.getProperty("user.home")+"/.aaf");
85                 if(!dot_aaf.exists()) {
86                         dot_aaf.mkdirs();
87                 }
88                 File f = new File(dot_aaf,"sso.out");
89                 os = new PrintStream(new FileOutputStream(f,true));
90                 stdout = System.out;
91                 stderr = System.err;
92                 System.setOut(os);
93                 System.setErr(os);
94
95                 access = new PropAccess(os,nargs);
96                 Config.setDefaultRealm(access);
97
98                 user = access.getProperty(Config.AAF_APPID);
99                 encrypted_pass = access.getProperty(Config.AAF_APPPASS);
100                 
101                 File dot_aaf_kf = new File(dot_aaf,"keyfile");
102                 
103                 sso = new File(dot_aaf,"sso.props");
104                 if(removeSSO) {
105                         if(dot_aaf_kf.exists()) {
106                                 dot_aaf_kf.setWritable(true,true);
107                                 dot_aaf_kf.delete();
108                         }
109                         if(sso.exists()) {
110                                 sso.delete();
111                         }
112                         System.out.println("AAF SSO information removed");
113                         System.exit(0);
114                 }
115                 
116                 if(!dot_aaf_kf.exists()) {
117                         FileOutputStream fos = new FileOutputStream(dot_aaf_kf);
118                         try {
119                                 fos.write(Symm.keygen());
120                                 dot_aaf_kf.setExecutable(false,false);
121                                 dot_aaf_kf.setWritable(false,false);
122                                 dot_aaf_kf.setReadable(false,false);
123                                 dot_aaf_kf.setReadable(true, true);
124                         } finally {
125                                 fos.close();
126                         }
127                 }
128
129                 String keyfile = access.getProperty(Config.CADI_KEYFILE); // in case it's CertificateMan props
130                 if(keyfile==null) {
131                         access.setProperty(Config.CADI_KEYFILE, dot_aaf_kf.getAbsolutePath());
132                 }
133                 
134                 String alias = access.getProperty(Config.CADI_ALIAS);
135                 if(user==null && alias!=null && access.getProperty(Config.CADI_KEYSTORE_PASSWORD)!=null) {
136                         user = alias;
137                         access.setProperty(Config.AAF_APPID, user);
138                         use_X509 = true;
139                 } else {
140                         use_X509 = false;
141                         Symm decryptor = Symm.obtain(dot_aaf_kf);
142                         if (user==null) {
143                                 if(sso.exists() && sso.lastModified()>System.currentTimeMillis()-(8*60*60*1000 /* 8 hours */)) {
144                                         String cm_url = access.getProperty(Config.CM_URL); // SSO might overwrite...
145                                         FileInputStream fos = new FileInputStream(sso);
146                                         try {
147                                                 access.load(fos);
148                                                 user = access.getProperty(Config.AAF_APPID);
149                                                 encrypted_pass = access.getProperty(Config.AAF_APPPASS);
150                                                 // decrypt with .aaf, and re-encrypt with regular Keyfile
151                                                 access.setProperty(Config.AAF_APPPASS, 
152                                                                 access.encrypt(decryptor.depass(encrypted_pass)));
153                                                 if(cm_url!=null) { //Command line CM_URL Overwrites ssofile.
154                                                         access.setProperty(Config.CM_URL, cm_url);
155                                                 }
156                                         } finally {
157                                                 fos.close();
158                                         }
159                                 } else {
160                                         diskprops = new Properties();
161                                         String realm = Config.getDefaultRealm();
162                                         // Turn on Console Sysout
163                                         System.setOut(stdout);
164                                         user=cons.readLine("aaf_id(%s@%s): ",System.getProperty("user.name"),realm);
165                                         if(user==null) {
166                                                 user = System.getProperty("user.name")+'@'+realm;
167                                         } else if(user.length()==0) { // 
168                                                 user = System.getProperty("user.name")+'@' + realm;
169                                         } else if(user.indexOf('@')<0 && realm!=null) {
170                                                 user = user+'@'+realm;
171                                         }
172                                         access.setProperty(Config.AAF_APPID,user);
173                                         diskprops.setProperty(Config.AAF_APPID,user);
174                                         encrypted_pass = new String(cons.readPassword("aaf_password: "));
175                                         System.setOut(os);
176                                         encrypted_pass = Symm.ENC+decryptor.enpass(encrypted_pass);
177                                         access.setProperty(Config.AAF_APPPASS,encrypted_pass);
178                                         diskprops.setProperty(Config.AAF_APPPASS,encrypted_pass);
179                                         diskprops.setProperty(Config.CADI_KEYFILE, access.getProperty(Config.CADI_KEYFILE));
180                                 }
181                         }
182                 }
183                 if (user == null) {
184                         err = new StringBuilder("Add -D" + Config.AAF_APPID + "=<id> ");
185                 }
186         
187                 if (encrypted_pass == null && alias==null) {
188                         if (err == null) {
189                                 err = new StringBuilder();
190                         } else {
191                                 err.append("and ");
192                         }
193                         err.append("-D" + Config.AAF_APPPASS + "=<passwd> ");
194                 }
195         }
196         
197         public void setLogDefault() {
198                 access.setLogLevel(PropAccess.DEFAULT);
199                 if(stdout!=null) {
200                         System.setOut(stdout);
201                 }
202         }
203
204         public void setStdErrDefault() {
205                 access.setLogLevel(PropAccess.DEFAULT);
206                 if(stderr!=null) {
207                         System.setErr(stderr);
208                 }
209         }
210
211         public void setLogDefault(Level level) {
212                 access.setLogLevel(level);
213                 if(stdout!=null) {
214                         System.setOut(stdout);
215                 }
216         }
217         
218         public boolean loginOnly() {
219                 return loginOnly;
220         }
221
222         public void addProp(String key, String value) {
223                 if(diskprops!=null) {
224                         diskprops.setProperty(key, value);
225                 }
226         }
227         
228         public void writeFiles() throws IOException {
229                 // Store Creds, if they work 
230                 if(diskprops!=null) {
231                         if(!dot_aaf.exists()) {
232                                 dot_aaf.mkdirs();
233                         }
234                         FileOutputStream fos = new FileOutputStream(sso);
235                         try {
236                                 diskprops.store(fos, "AAF Single Signon");
237                         } finally {
238                                 fos.close();
239                                 sso.setWritable(false,false);
240                                 sso.setExecutable(false,false);
241                                 sso.setReadable(false,false);
242                                 sso.setReadable(true,true);
243                         }
244                 }
245                 if(sso!=null) {
246                         sso.setReadable(false,false);
247                         sso.setWritable(false,false);
248                         sso.setExecutable(false,false);
249                         sso.setReadable(true,true);
250                         sso.setWritable(true,true);
251                 }
252         }
253
254         public PropAccess access() {
255                 return access;
256         }
257
258         public StringBuilder err() {
259                 return err;
260         }
261         
262         public String user() {
263                 return user;
264         }
265         
266         public String enc_pass() {
267                 return encrypted_pass;
268         }
269         
270         public boolean useX509() {
271                 return use_X509;
272         }
273         
274         public void close() {
275                 if(close!=null) {
276                         try {
277                                 close.invoke(null);
278                         } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
279                                 // nothing to do here.
280                         }
281                         close = null;
282                 }
283         }
284 }