| 1 23 package com.sun.appserv.management.client.prefs; 24 import java.io.BufferedReader ; 25 import java.io.FileReader ; 26 import java.io.FileWriter ; 27 import java.io.BufferedWriter ; 28 import java.io.File ; 29 import java.io.IOException ; 30 import java.net.URI ; 31 import java.net.URISyntaxException ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.ArrayList ; 36 import java.util.Map ; 37 import java.util.Collection ; 38 import java.util.Collections ; 39 import sun.misc.BASE64Decoder; 41 import sun.misc.BASE64Encoder; 42 43 49 public class MemoryHashLoginInfoStore implements LoginInfoStore { 50 51 public static final String DEFAULT_STORE_NAME = ".asadminpass"; 52 53 private static final BASE64Encoder encoder = new BASE64Encoder(); 54 private static final BASE64Decoder decoder = new BASE64Decoder(); 55 56 private Map <HostPortKey, LoginInfo> state; 57 private final File store; 58 63 public MemoryHashLoginInfoStore() throws StoreException { 64 BufferedReader br = null; 65 BufferedWriter bw = null; 66 try { 67 final File dir = new File (System.getProperty("user.home")); 68 store = new File (dir, DEFAULT_STORE_NAME); 69 if (!store.exists()) { 70 store.createNewFile(); 71 bw = new BufferedWriter (new FileWriter (store)); 72 FileMapTransform.writePreamble(bw); 73 state = new HashMap <HostPortKey, LoginInfo> (); 74 } 75 else { 76 br = new BufferedReader (new FileReader (store)); 77 state = FileMapTransform.readAll(br); 78 } 79 } 80 catch(final Exception e) { 81 throw new StoreException(e); 82 } 83 finally { 84 try { 85 if (br != null) 86 br.close(); 87 } 88 catch(final Exception ee) {}; try { 90 if (bw != null) 91 bw.close(); 92 } 93 catch(final Exception ee) {}; } 95 } 96 97 public void store(final LoginInfo login) throws StoreException { 98 this.store(login, false); 99 } 100 101 public void store(final LoginInfo login, boolean overwrite) throws StoreException { 102 if (login == null) 103 throw new IllegalArgumentException ("null_arg"); 104 final String host = login.getHost(); 105 final int port = login.getPort(); 106 if (!overwrite && this.exists(host, port)) { 107 throw new StoreException("Login exists for host: " + host + " port: " + port); 108 } 109 final HostPortKey key = new HostPortKey(host, port); 110 final LoginInfo old = state.get(key); 111 state.put(key, login); 112 commit(key, old); 114 protect(); 115 } 116 117 public void remove(final String host, final int port) { 118 final HostPortKey key = new HostPortKey(host, port); 119 final LoginInfo gone = state.remove(key); 120 commit(key, gone); 121 } 122 123 public LoginInfo read(String host, int port) { 124 final HostPortKey key = new HostPortKey(host, port); 125 final LoginInfo login = state.get(key); return ( login ); 127 } 128 129 public boolean exists(String host, int port) { 130 final HostPortKey key = new HostPortKey(host, port); 131 final boolean exists = state.containsKey(key); return ( exists ); 133 } 134 135 public int size() { 136 return ( state.size() ); } 138 139 public Collection <LoginInfo> list() { 140 final Collection <LoginInfo> logins = state.values(); return (Collections.unmodifiableCollection(logins) ); 142 } 143 144 public String getName() { 145 return ( store.getAbsoluteFile().getAbsolutePath() ); 146 } 147 148 private void commit(final HostPortKey key, LoginInfo old) { 150 BufferedWriter writer = null; 151 try { 152 writer = new BufferedWriter (new FileWriter (store)); 154 FileMapTransform.writeAll(state.values(), writer); 155 } 156 catch(final Exception e) { 157 state.put(key, old); try { if (old != null) { 160 writer = new BufferedWriter (new FileWriter (store)); 161 FileMapTransform.writeAll(state.values(), writer); 162 } 163 } 164 catch(final Exception ae) { 165 throw new RuntimeException ("catastrophe, can't write it to file"); 166 } } 168 finally { 169 try { 170 writer.close(); 171 } catch(final Exception ee) {} } 173 } 174 175 private void protect() 176 { 177 184 try 185 { 186 if(store == null || !store.exists()) 187 return; 188 189 ProcessBuilder pb = new ProcessBuilder ("chmod", "0600", store.getAbsolutePath()); 190 pb.start(); 191 } 192 catch(Exception e) 193 { 194 } 196 } 197 198 private static class FileMapTransform { 199 private FileMapTransform() {} static Map <HostPortKey, LoginInfo> readAll(final BufferedReader reader) throws IOException , URISyntaxException { 201 String line = null; 202 final Map <HostPortKey, LoginInfo> map = new HashMap <HostPortKey, LoginInfo> (); 203 while ((line = reader.readLine()) != null) { 204 if (line.startsWith("#")) 205 continue; final int si = line.indexOf(' '); if (si == -1) 208 throw new IOException ("Error: invalid record: " + line); 209 final URI uri = new URI (line.substring(0, si)); 210 final String encp = line.substring(si+1, line.length()); 211 final HostPortKey key = uri2Key(uri); 212 final LoginInfo value = line2LoginInfo(uri, encp); 213 map.put(key, value); 214 } 215 return ( map ); 216 } 217 static void writeAll(final Collection <LoginInfo> logins, final BufferedWriter writer) throws IOException , URISyntaxException { 218 writePreamble(writer); 219 final List <LoginInfo> list = new ArrayList <LoginInfo>(logins); 221 Collections.sort(list); 222 final Iterator <LoginInfo> it = list.iterator(); 223 while (it.hasNext()) { 224 final LoginInfo login = it.next(); 225 writeOne(login, writer); 227 } 228 } 229 private static void writeOne(final LoginInfo login, final BufferedWriter writer) throws IOException , URISyntaxException { 230 writer.write(login2Line(login)); 231 writer.newLine(); 232 } 233 static final HostPortKey uri2Key(final URI uri) { 234 final String host = uri.getHost(); 235 final int port = uri.getPort(); 236 final HostPortKey key = new HostPortKey(host, port); 237 return ( key ); 238 } 239 static final LoginInfo line2LoginInfo(final URI uri, final String encp) throws IOException { 240 final String host = uri.getHost(); 241 final int port = uri.getPort(); 242 final String user = uri.getUserInfo(); 243 final String password = new String (decoder.decodeBuffer(encp)); 244 return ( new LoginInfo(host, port, user, password) ); 245 } 246 static final String login2Line(final LoginInfo login) throws IOException , URISyntaxException { 247 final String scheme = "asadmin"; 248 final String host = login.getHost(); 249 final int port = login.getPort(); 250 final String user = login.getUser(); 251 final String path = null; 252 final String query = null; 253 final String frag = null; 254 final URI uri = new URI (scheme, user, host, port, path, query, frag); 255 final String password = login.getPassword(); 256 final String encp = encoder.encode(password.getBytes()); 257 final String line = uri.toString() + ' ' + encp; 258 259 return ( line ); 260 } 261 static void writePreamble(final BufferedWriter bw) throws IOException { 262 final String preamble = "# Do not edit this file by hand. Use login interface instead."; 263 bw.write(preamble); 264 bw.newLine(); 265 } 266 } 267 268 private static class HostPortKey { 269 private final String host; 270 private final int port; 271 HostPortKey(final String host, final int port) { 272 this.host = host; 273 this.port = port; 274 } 275 public boolean equals(final Object other) { 276 boolean same = false; 277 if (other instanceof HostPortKey) { 278 final HostPortKey that = (HostPortKey)other; 279 same = this.host.equals(that.host) && this.port == that.port; 280 } 281 return ( same ); 282 } 283 public int hashCode() { 284 return ( (int) (53 * host.hashCode() + 31 * port) ); 285 } 286 } 287 } | Popular Tags |