001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.converter.bea; 018 019 import java.util.regex.Pattern; 020 import java.util.regex.Matcher; 021 import java.util.Properties; 022 import java.util.Iterator; 023 import java.lang.reflect.Method; 024 import java.lang.reflect.InvocationTargetException; 025 import java.io.File; 026 import java.io.FileInputStream; 027 import java.io.FileNotFoundException; 028 import java.io.BufferedReader; 029 import java.io.FileReader; 030 import java.io.StringWriter; 031 import java.io.PrintWriter; 032 import java.io.IOException; 033 import java.io.InputStream; 034 import java.net.URLClassLoader; 035 import java.net.URL; 036 037 /** 038 * Reads information out of the WebLogic domain directory. 039 * Needs access to the WebLogic JARs in the weblogic81/server/lib directory. 040 * 041 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 042 */ 043 public class Weblogic81Utils { 044 private final static Pattern ENCRYPTED_STRING = Pattern.compile("\\\"\\{\\S+\\}\\S+?\\\""); 045 private Object decoder; 046 private Method decode; 047 private Object decrypter; 048 private Method decrypt; 049 private File domainDir; 050 051 public Weblogic81Utils(String libDirPath, String domainDirPath) { 052 File libDir = new File(libDirPath); 053 if(!libDir.exists() || !libDir.canRead() || !libDir.isDirectory()) throw new IllegalArgumentException("Bad weblogic lib dir"); 054 File weblogicJar = new File(libDir, "weblogic.jar"); 055 File securityJar = new File(libDir, "jsafeFIPS.jar"); 056 if(!weblogicJar.canRead()) throw new IllegalArgumentException("Cannot find JARs in provided lib dir"); 057 domainDir = new File(domainDirPath); 058 if(!domainDir.exists() || !domainDir.canRead() || !domainDir.isDirectory()) throw new IllegalArgumentException("Bad domain directory"); 059 File state = new File(domainDir, "SerializedSystemIni.dat"); 060 if(!state.canRead()) throw new IllegalArgumentException("Cannot find serialized state in domain directory"); 061 try { 062 ClassLoader loader = new URLClassLoader(securityJar.exists() ? new URL[]{weblogicJar.toURL(), securityJar.toURL()} : new URL[]{weblogicJar.toURL()}, Weblogic81Utils.class.getClassLoader()); 063 initialize(loader, state); 064 } catch (Exception e) { 065 throw (RuntimeException)new IllegalArgumentException("Unable to initialize encryption routines from provided arguments").initCause(e); 066 } 067 } 068 069 public Properties getBootProperties() { 070 File boot = new File(domainDir, "boot.properties"); 071 FileInputStream bootIn = null; 072 try { 073 bootIn = new FileInputStream(boot); 074 } catch (FileNotFoundException e) { 075 return null; 076 } 077 try { 078 Properties props = new Properties(); 079 props.load(bootIn); 080 bootIn.close(); 081 for (Iterator it = props.keySet().iterator(); it.hasNext();) { 082 String key = (String) it.next(); 083 String value = props.getProperty(key); 084 if(value != null && value.startsWith("{")) props.setProperty(key, decryptString(value)); 085 } 086 return props; 087 } catch (Exception e) { 088 return null; 089 } 090 } 091 092 public String getConfigXML() throws FileNotFoundException { 093 File config = new File(domainDir, "config.xml"); 094 BufferedReader in = new BufferedReader(new FileReader(config)); 095 StringWriter string = new StringWriter(); 096 PrintWriter out = new PrintWriter(string); 097 String line; 098 Matcher m = ENCRYPTED_STRING.matcher(""); 099 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 }