001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.common.util.encrypt.provider; 017 018import static com.google.common.base.Optional.absent; 019import static com.google.common.base.Optional.fromNullable; 020import static com.google.common.base.Preconditions.checkState; 021import static java.lang.String.format; 022import static org.apache.commons.lang3.StringUtils.isBlank; 023import static org.apache.commons.lang3.StringUtils.trimToNull; 024import static org.kuali.common.util.base.Exceptions.illegalState; 025import static org.kuali.common.util.base.Precondition.checkNotBlank; 026import static org.kuali.common.util.encrypt.EncryptionStrength.DEFAULT_ENCRYPTION_STRENGTH; 027import static org.kuali.common.util.encrypt.provider.DefaultEncryptionContextProviderChain.toEnvKey; 028import static org.kuali.common.util.log.Loggers.newLogger; 029 030import java.io.File; 031import java.io.IOException; 032import java.util.List; 033 034import org.apache.commons.io.FileUtils; 035import org.kuali.common.util.encrypt.EncryptionContext; 036import org.kuali.common.util.encrypt.EncryptionStrength; 037import org.kuali.common.util.file.CanonicalFile; 038import org.slf4j.Logger; 039 040import com.google.common.base.Optional; 041import com.google.common.collect.ImmutableList; 042 043public final class FileEncryptionContextProvider implements EncryptionContextProvider { 044 045 private static final Logger logger = newLogger(); 046 047 private static final String ENC_PASSWORD_FILE_SYS_KEY = "enc.password.file"; 048 private static final String ENC_PASSWORD_FILE_ENV_KEY = toEnvKey(ENC_PASSWORD_FILE_SYS_KEY); 049 private static final File DEFAULT_ENC_PASSWORD_FILE = new CanonicalFile(System.getProperty("user.home") + "/.enc/password"); 050 051 @Override 052 public Optional<EncryptionContext> getEncryptionContext() { 053 File file = getEncPasswordFile(); 054 if (!file.exists()) { 055 logger.debug(format("[%s] does not exist", file)); 056 return absent(); 057 } 058 List<String> lines = readLines(file); 059 String password = getPassword(lines); 060 EncryptionStrength strength = getStrength(lines); 061 logger.debug(format("[%s, %s] encryption password located", file, strength)); 062 return Optional.of(new EncryptionContext(password, strength)); 063 } 064 065 protected EncryptionStrength getStrength(List<String> lines) { 066 if (lines.size() < 2) { 067 return DEFAULT_ENCRYPTION_STRENGTH; 068 } 069 String value = lines.get(1); 070 if (isBlank(value)) { 071 return DEFAULT_ENCRYPTION_STRENGTH; 072 } 073 return EncryptionStrength.valueOf(value.toUpperCase().trim()); 074 } 075 076 protected String getPassword(List<String> lines) { 077 checkState(lines.size() > 0, "[%s] must contain at least one line"); 078 String password = trimToNull(lines.get(0)); 079 checkNotBlank(password, "password"); 080 return password; 081 } 082 083 protected static List<String> readLines(File file) { 084 try { 085 return ImmutableList.copyOf(FileUtils.readLines(file)); 086 } catch (IOException e) { 087 throw illegalState(e); 088 } 089 } 090 091 protected static File getEncPasswordFile() { 092 Optional<String> sys = getOptional(System.getProperty(ENC_PASSWORD_FILE_SYS_KEY)); 093 if (sys.isPresent()) { 094 File file = new CanonicalFile(sys.get()); 095 logger.debug(format("encryption system property: %s=[%s]", ENC_PASSWORD_FILE_SYS_KEY, file.getPath())); 096 return file; 097 } 098 Optional<String> env = getOptional(System.getenv(ENC_PASSWORD_FILE_ENV_KEY)); 099 if (env.isPresent()) { 100 File file = new CanonicalFile(env.get()); 101 logger.debug(format("encryption environment variable: %s=[%s]", ENC_PASSWORD_FILE_ENV_KEY, file.getPath())); 102 return file; 103 } 104 return DEFAULT_ENC_PASSWORD_FILE; 105 } 106 107 protected static Optional<String> getOptional(String value) { 108 return fromNullable(trimToNull(value)); 109 } 110 111}