1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\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
11 * * http://www.apache.org/licenses/LICENSE-2.0
\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
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.sso;
\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
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
46 public class AAFSSO {
\r
47 public static final MyConsole cons = TheConsole.implemented()?new TheConsole():new SubStandardConsole();
\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
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
59 private PrintStream os, stdout=null,stderr=null;
\r
61 private Method close;
\r
63 public AAFSSO(String[] args) throws IOException, CadiException {
\r
64 List<String> larg = new ArrayList<String>(args.length);
\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
73 if("-logout".equalsIgnoreCase(args[i])) {
\r
75 } else if("-login".equalsIgnoreCase(args[i])) {
\r
82 String[] nargs = new String[larg.size()];
\r
83 larg.toArray(nargs);
\r
85 dot_aaf = new File(System.getProperty("user.home")+"/.aaf");
\r
86 if(!dot_aaf.exists()) {
\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
96 access = new PropAccess(os,nargs);
\r
97 Config.setDefaultRealm(access);
\r
99 user = access.getProperty(Config.AAF_MECHID);
\r
100 encrypted_pass = access.getProperty(Config.AAF_MECHPASS);
\r
102 File dot_aaf_kf = new File(dot_aaf,"keyfile");
\r
104 sso = new File(dot_aaf,"sso.props");
\r
106 if(dot_aaf_kf.exists()) {
\r
107 dot_aaf_kf.setWritable(true,true);
\r
108 dot_aaf_kf.delete();
\r
113 System.out.println("AAF SSO information removed");
\r
117 if(!dot_aaf_kf.exists()) {
\r
118 FileOutputStream fos = new FileOutputStream(dot_aaf_kf);
\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
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
135 String alias = access.getProperty(Config.CADI_ALIAS);
\r
136 if(user==null && alias!=null && access.getProperty(Config.CADI_KEYSTORE_PASSWORD)!=null) {
\r
138 access.setProperty(Config.AAF_MECHID, user);
\r
142 Symm decryptor = Symm.obtain(dot_aaf_kf);
\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
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
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
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
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
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
184 if (user == null) {
\r
185 err = new StringBuilder("Add -D" + Config.AAF_MECHID + "=<id> ");
\r
188 if (encrypted_pass == null && alias==null) {
\r
190 err = new StringBuilder();
\r
192 err.append("and ");
\r
194 err.append("-D" + Config.AAF_MECHPASS + "=<passwd> ");
\r
198 public void setLogDefault() {
\r
199 access.setLogLevel(PropAccess.DEFAULT);
\r
201 System.setOut(stdout);
\r
205 public void setStdErrDefault() {
\r
206 access.setLogLevel(PropAccess.DEFAULT);
\r
208 System.setErr(stderr);
\r
212 public void setLogDefault(Level level) {
\r
213 access.setLogLevel(level);
\r
215 System.setOut(stdout);
\r
219 public boolean loginOnly() {
\r
223 public void addProp(String key, String value) {
\r
224 if(diskprops!=null) {
\r
225 diskprops.setProperty(key, value);
\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
235 FileOutputStream fos = new FileOutputStream(sso);
\r
237 diskprops.store(fos, "AAF Single Signon");
\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
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
255 public PropAccess access() {
\r
259 public StringBuilder err() {
\r
263 public String user() {
\r
267 public String enc_pass() {
\r
268 return encrypted_pass;
\r
271 public boolean useX509() {
\r
275 public void close() {
\r
278 close.invoke(null);
\r
279 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
\r
280 // nothing to do here.
\r