1 /** 2 * 3 * Copyright 2003-2004 The Apache Software Foundation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.geronimo.converter.bea; 18 19 import java.util.regex.Pattern; 20 import java.util.regex.Matcher; 21 import java.util.Properties; 22 import java.util.Iterator; 23 import java.lang.reflect.Method; 24 import java.lang.reflect.InvocationTargetException; 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.FileNotFoundException; 28 import java.io.BufferedReader; 29 import java.io.FileReader; 30 import java.io.StringWriter; 31 import java.io.PrintWriter; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.net.URLClassLoader; 35 import java.net.URL; 36 37 /** 38 * Reads information out of the WebLogic domain directory. 39 * Needs access to the WebLogic JARs in the weblogic81/server/lib directory. 40 * 41 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $ 42 */ 43 public class Weblogic81Utils { 44 private final static Pattern ENCRYPTED_STRING = Pattern.compile("\\\"\\{\\S+\\}\\S+?\\\""); 45 private Object decoder; 46 private Method decode; 47 private Object decrypter; 48 private Method decrypt; 49 private File domainDir; 50 51 public Weblogic81Utils(String libDirPath, String domainDirPath) { 52 File libDir = new File(libDirPath); 53 if(!libDir.exists() || !libDir.canRead() || !libDir.isDirectory()) throw new IllegalArgumentException("Bad weblogic lib dir"); 54 File weblogicJar = new File(libDir, "weblogic.jar"); 55 File securityJar = new File(libDir, "jsafeFIPS.jar"); 56 if(!weblogicJar.canRead()) throw new IllegalArgumentException("Cannot find JARs in provided lib dir"); 57 domainDir = new File(domainDirPath); 58 if(!domainDir.exists() || !domainDir.canRead() || !domainDir.isDirectory()) throw new IllegalArgumentException("Bad domain directory"); 59 File state = new File(domainDir, "SerializedSystemIni.dat"); 60 if(!state.canRead()) throw new IllegalArgumentException("Cannot find serialized state in domain directory"); 61 try { 62 ClassLoader loader = new URLClassLoader(securityJar.exists() ? new URL[]{weblogicJar.toURL(), securityJar.toURL()} : new URL[]{weblogicJar.toURL()}, Weblogic81Utils.class.getClassLoader()); 63 initialize(loader, state); 64 } catch (Exception e) { 65 throw (RuntimeException)new IllegalArgumentException("Unable to initialize encryption routines from provided arguments").initCause(e); 66 } 67 } 68 69 public Properties getBootProperties() { 70 File boot = new File(domainDir, "boot.properties"); 71 FileInputStream bootIn = null; 72 try { 73 bootIn = new FileInputStream(boot); 74 } catch (FileNotFoundException e) { 75 return null; 76 } 77 try { 78 Properties props = new Properties(); 79 props.load(bootIn); 80 bootIn.close(); 81 for (Iterator it = props.keySet().iterator(); it.hasNext();) { 82 String key = (String) it.next(); 83 String value = props.getProperty(key); 84 if(value != null && value.startsWith("{")) props.setProperty(key, decryptString(value)); 85 } 86 return props; 87 } catch (Exception e) { 88 return null; 89 } 90 } 91 92 public String getConfigXML() throws FileNotFoundException { 93 File config = new File(domainDir, "config.xml"); 94 BufferedReader in = new BufferedReader(new FileReader(config)); 95 StringWriter string = new StringWriter(); 96 PrintWriter out = new PrintWriter(string); 97 String line; 98 Matcher m = ENCRYPTED_STRING.matcher(""); 99 try { 100 while((line = in.readLine()) != null) { 101 m.reset(line); 102 int last = -1; 103 while(m.find()) { 104 out.print(line.substring(last+1, m.start())); 105 String s = line.substring(m.start(), m.end()); 106 out.print("\""); 107 out.print(decryptString(s.substring(1, s.length()-1))); 108 out.print("\""); 109 last = m.end()-1; 110 } 111 if(last == -1) { 112 out.println(line); 113 } else { 114 if(line.length() > last+1) { 115 out.print(line.substring(last+1)); 116 } 117 out.println(); 118 } 119 out.flush(); 120 } 121 in.close(); 122 out.close(); 123 } catch (Exception e) { 124 return null; 125 } 126 return string.getBuffer().toString(); 127 } 128 129 private void initialize(ClassLoader loader, File state) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException, InstantiationException { 130 byte[] salt = null, key = null; 131 FileInputStream in = new FileInputStream(state); 132 salt = readBytes(in); 133 int i = in.read(); 134 if(i != -1) { 135 if(i != 1) throw new IllegalStateException(); 136 key = readBytes(in); 137 } 138 in.close(); 139 decrypter = getEncryptionService(loader, salt, key); 140 decoder = loader.loadClass("weblogic.utils.encoders.BASE64Decoder").newInstance(); 141 decode = decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}); 142 decrypt = decrypter.getClass().getMethod("decryptString", new Class[]{byte[].class}); 143 } 144 145 private static byte[] readBytes(InputStream in) throws IOException { 146 int len = in.read(); 147 if(len < 0) 148 throw new IOException("stream is empty"); 149 byte result[] = new byte[len]; 150 int index = 0; 151 while(true) { 152 if(index >= len) { 153 break; 154 } 155 int count = in.read(result, index, len - index); 156 if(count == -1) 157 break; 158 index += count; 159 } 160 return result; 161 } 162 163 private String decryptString(String string) throws IllegalAccessException, InvocationTargetException { 164 if(string.indexOf('}') > -1) { 165 string = string.substring(string.indexOf("}")+1); 166 } 167 return (String) decrypt.invoke(decrypter, new Object[]{decode.invoke(decoder, new Object[]{string})}); 168 } 169 170 static Object getEncryptionService(ClassLoader loader, byte salt[], byte key[]) throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException { 171 String magic = "0xccb97558940b82637c8bec3c770f86fa3a391a56"; 172 Object factory = loader.loadClass("weblogic.security.internal.encryption.JSafeEncryptionServiceImpl").getMethod("getFactory", new Class[0]).invoke(null, null); 173 Method getter = factory.getClass().getMethod("getEncryptionService", new Class[]{byte[].class, String.class, byte[].class}); 174 return getter.invoke(factory, new Object[]{salt, magic, key}); 175 } 176 }