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