001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 021 package org.apache.geronimo.system.util; 022 023 import java.io.File; 024 import java.io.FileInputStream; 025 import java.io.FileOutputStream; 026 import java.io.IOException; 027 import java.io.ObjectInputStream; 028 import java.io.ObjectOutputStream; 029 import java.security.SecureRandom; 030 031 import javax.crypto.spec.SecretKeySpec; 032 033 import org.apache.geronimo.gbean.GBeanInfo; 034 import org.apache.geronimo.gbean.GBeanInfoBuilder; 035 import org.apache.geronimo.gbean.GBeanLifecycle; 036 import org.apache.geronimo.system.serverinfo.ServerInfo; 037 import org.apache.geronimo.crypto.AbstractEncryption; 038 import org.apache.geronimo.crypto.EncryptionManager; 039 040 /** 041 * Like SimpleEncryption except it uses a stored secret key. If the key file is missing, it makes up a new one. 042 * 043 * WARNING: NOT RECOMMENDED. If you lose the secret key file your encrypted passwords will be unavailable. Instead, secure 044 * your operationg environment and use something like ldap or a database to store passwords in. 045 * 046 * To use, include something like this in the rmi-naming module of var/config/config.xml: 047 * 048 * <gbean name="org.apache.geronimo.framework/rmi-naming/2.1-SNAPSHOT/car?name=ConfiguredEncryption,j2eeType=GBean" gbeanInfo="org.apache.geronimo.system.util.ConfiguredEncryption"> 049 * <attribute name="path">var/security/ConfiguredSecretKey.ser</attribute> 050 * <reference name="ServerInfo"><pattern><name>ServerInfo</name></pattern></reference> 051 * </gbean> 052 * 053 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 054 */ 055 public class ConfiguredEncryption extends AbstractEncryption implements GBeanLifecycle { 056 057 private final SecretKeySpec spec; 058 059 060 public ConfiguredEncryption(String path, ServerInfo serverInfo) throws IOException, ClassNotFoundException { 061 File location = serverInfo.resolve(path); 062 if (location.exists()) { 063 FileInputStream in = new FileInputStream(location); 064 try { 065 ObjectInputStream oin = new ObjectInputStream(in); 066 try { 067 spec = (SecretKeySpec) oin.readObject(); 068 } finally { 069 oin.close(); 070 } 071 } finally { 072 in.close(); 073 } 074 } else { 075 SecureRandom random = new SecureRandom(); 076 random.setSeed(System.currentTimeMillis()); 077 byte[] bytes = new byte[16]; 078 random.nextBytes(bytes); 079 spec = new SecretKeySpec(bytes, "AES"); 080 File dir = location.getParentFile(); 081 if (!dir.exists()) { 082 dir.mkdirs(); 083 } 084 if (!dir.exists() || !dir.isDirectory()) { 085 throw new IllegalStateException("Could not create directory for secret key spec: " + dir); 086 } 087 FileOutputStream out = new FileOutputStream(location); 088 try { 089 ObjectOutputStream oout = new ObjectOutputStream(out); 090 try { 091 oout.writeObject(spec); 092 oout.flush(); 093 } finally { 094 oout.close(); 095 } 096 } finally { 097 out.close(); 098 } 099 } 100 } 101 102 public void doStart() throws Exception { 103 EncryptionManager.setEncryptionPrefix("{Configured}", this); 104 } 105 106 public void doStop() throws Exception { 107 } 108 109 public void doFail() { 110 } 111 112 protected SecretKeySpec getSecretKeySpec() { 113 return spec; 114 } 115 116 public static final GBeanInfo GBEAN_INFO; 117 118 static { 119 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(ConfiguredEncryption.class, "GBean"); 120 infoBuilder.addAttribute("path", String.class, true, true); 121 infoBuilder.addReference("ServerInfo", ServerInfo.class, "GBean"); 122 infoBuilder.setConstructor(new String[]{"path", "ServerInfo"}); 123 GBEAN_INFO = infoBuilder.getBeanInfo(); 124 } 125 126 public static GBeanInfo getGBeanInfo() { 127 return GBEAN_INFO; 128 } 129 130 }