// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.utils.crypt; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Properties; import javax.ejb.Local; import org.apache.log4j.Logger; import org.jasypt.encryption.pbe.StandardPBEStringEncryptor; import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.SystemIntegrityChecker; import com.cloud.utils.exception.CloudRuntimeException; @Local(value = {SystemIntegrityChecker.class}) public class EncryptionSecretKeyChecker implements SystemIntegrityChecker { private static final Logger s_logger = Logger.getLogger(EncryptionSecretKeyChecker.class); private static final String s_keyFile = "/etc/cloud/management/key"; private static final String s_envKey = "CLOUD_SECRET_KEY"; private static StandardPBEStringEncryptor s_encryptor = new StandardPBEStringEncryptor(); private static boolean s_useEncryption = false; @Override public void check() { //Get encryption type from db.properties final File dbPropsFile = PropertiesUtil.findConfigFile("db.properties"); final Properties dbProps = new Properties(); try { dbProps.load(new FileInputStream(dbPropsFile)); final String encryptionType = dbProps.getProperty("db.cloud.encryption.type"); s_logger.debug("Encryption Type: "+ encryptionType); if(encryptionType == null || encryptionType.equals("none")){ return; } s_encryptor.setAlgorithm("PBEWithMD5AndDES"); String secretKey = null; SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig(); if(encryptionType.equals("file")){ try { BufferedReader in = new BufferedReader(new FileReader(s_keyFile)); secretKey = in.readLine(); //Check for null or empty secret key } catch (FileNotFoundException e) { throw new CloudRuntimeException("File containing secret key not found: "+s_keyFile, e); } catch (IOException e) { throw new CloudRuntimeException("Error while reading secret key from: "+s_keyFile, e); } if(secretKey == null || secretKey.isEmpty()){ throw new CloudRuntimeException("Secret key is null or empty in file "+s_keyFile); } } else if(encryptionType.equals("env")){ secretKey = System.getenv(s_envKey); if(secretKey == null || secretKey.isEmpty()){ throw new CloudRuntimeException("Environment variable "+s_envKey+" is not set or empty"); } } else if(encryptionType.equals("web")){ ServerSocket serverSocket = null; int port = 8097; try { serverSocket = new ServerSocket(port); } catch (IOException ioex) { throw new CloudRuntimeException("Error initializing secret key reciever", ioex); } s_logger.info("Waiting for admin to send secret key on port "+port); Socket clientSocket = null; try { clientSocket = serverSocket.accept(); } catch (IOException e) { throw new CloudRuntimeException("Accept failed on "+port); } PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine, outputLine; if ((inputLine = in.readLine()) != null) { secretKey = inputLine; } out.close(); in.close(); clientSocket.close(); serverSocket.close(); } else { throw new CloudRuntimeException("Invalid encryption type: "+encryptionType); } stringConfig.setPassword(secretKey); s_encryptor.setConfig(stringConfig); s_useEncryption = true; } catch (FileNotFoundException e) { throw new CloudRuntimeException("File db.properties not found", e); } catch (IOException e) { throw new CloudRuntimeException("Error while reading db.properties", e); } } public static StandardPBEStringEncryptor getEncryptor() { return s_encryptor; } public static boolean useEncryption(){ return s_useEncryption; } //Initialize encryptor for migration during secret key change public static void initEncryptorForMigration(String secretKey){ s_encryptor.setAlgorithm("PBEWithMD5AndDES"); SimpleStringPBEConfig stringConfig = new SimpleStringPBEConfig(); stringConfig.setPassword(secretKey); s_encryptor.setConfig(stringConfig); s_useEncryption = true; } }