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