/** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with 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. */ package org.apache.airavata.credential.store.store.impl.db; import org.apache.airavata.common.utils.DBUtil; import org.apache.airavata.common.utils.KeyStorePasswordCallback; import org.apache.airavata.common.utils.SecurityUtil; import org.apache.airavata.credential.store.credential.Credential; import org.apache.airavata.credential.store.credential.CredentialOwnerType; import org.apache.airavata.credential.store.store.CredentialStoreException; import java.io.*; import java.security.GeneralSecurityException; import java.sql.*; import java.util.ArrayList; import java.util.List; /** * Data access class for credential store. */ public class CredentialsDAO extends ParentDAO { private String keyStorePath = null; private String secretKeyAlias = null; private KeyStorePasswordCallback keyStorePasswordCallback = null; public CredentialsDAO() { } public CredentialsDAO(String keyStore, String alias, KeyStorePasswordCallback passwordCallback) { this.keyStorePath = keyStore; this.secretKeyAlias = alias; this.keyStorePasswordCallback = passwordCallback; } public String getKeyStorePath() { return keyStorePath; } public void setKeyStorePath(String keyStorePath) { this.keyStorePath = keyStorePath; } public String getSecretKeyAlias() { return secretKeyAlias; } public void setSecretKeyAlias(String secretKeyAlias) { this.secretKeyAlias = secretKeyAlias; } public KeyStorePasswordCallback getKeyStorePasswordCallback() { return keyStorePasswordCallback; } public void setKeyStorePasswordCallback(KeyStorePasswordCallback keyStorePasswordCallback) { this.keyStorePasswordCallback = keyStorePasswordCallback; } /** * String createTable = "CREATE TABLE CREDENTIALS\n" + "(\n" + " GATEWAY_ID VARCHAR(256) NOT NULL,\n" + * " TOKEN_ID VARCHAR(256) NOT NULL,\n" + // Actual token used to identify the credential * " CREDENTIAL BLOB NOT NULL,\n" + " PORTAL_USER_ID VARCHAR(256) NOT NULL,\n" + * " TIME_PERSISTED TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n" + " PRIMARY KEY (GATEWAY_ID, TOKEN_ID)\n" * + ")"; */ public void addCredentials(String gatewayId, Credential credential, Connection connection) throws CredentialStoreException { String sql = "INSERT INTO CREDENTIALS (GATEWAY_ID, TOKEN_ID, CREDENTIAL, PORTAL_USER_ID, TIME_PERSISTED, DESCRIPTION, CREDENTIAL_OWNER_TYPE) VALUES (?, ?, ?, ?, ?, ?, ?)"; PreparedStatement preparedStatement = null; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, gatewayId); preparedStatement.setString(2, credential.getToken()); InputStream isCert = new ByteArrayInputStream(convertObjectToByteArray(credential)); preparedStatement.setBinaryStream(3, isCert); preparedStatement.setString(4, credential.getPortalUserName()); java.util.Date date = new java.util.Date(); Timestamp timestamp = new Timestamp(date.getTime()); preparedStatement.setTimestamp(5, timestamp); preparedStatement.setString(6,credential.getDescription()); preparedStatement.setString(7, credential.getCredentialOwnerType().toString()); preparedStatement.executeUpdate(); } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error persisting credentials."); stringBuilder.append(" gateway - ").append(gatewayId); stringBuilder.append(" token id - ").append(credential.getToken()); log.error(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement); } } public void deleteCredentials(String gatewayName, String tokenId, Connection connection) throws CredentialStoreException { String sql = "DELETE FROM CREDENTIALS WHERE GATEWAY_ID=? AND TOKEN_ID=?"; PreparedStatement preparedStatement = null; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, gatewayName); preparedStatement.setString(2, tokenId); preparedStatement.executeUpdate(); connection.commit(); } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error deleting credentials for ."); stringBuilder.append("gateway - ").append(gatewayName); stringBuilder.append("token id - ").append(tokenId); log.error(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement); } } /** * String createTable = "CREATE TABLE CREDENTIALS\n" + "(\n" + " GATEWAY_ID VARCHAR(256) NOT NULL,\n" + * " TOKEN_ID VARCHAR(256) NOT NULL,\n" + // Actual token used to identify the credential * " CREDENTIAL BLOB NOT NULL,\n" + " PORTAL_USER_ID VARCHAR(256) NOT NULL,\n" + * " TIME_PERSISTED TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n" + " PRIMARY KEY (GATEWAY_ID, TOKEN_ID)\n" * + ")"; */ public void updateCredentials(String gatewayId, Credential credential, Connection connection) throws CredentialStoreException { String sql = "UPDATE CREDENTIALS set CREDENTIAL = ?, PORTAL_USER_ID = ?, TIME_PERSISTED = ?, DESCRIPTION = ?, CREDENTIAL_OWNER_TYPE = ? where GATEWAY_ID = ? and TOKEN_ID = ?"; PreparedStatement preparedStatement = null; try { preparedStatement = connection.prepareStatement(sql); InputStream isCert = new ByteArrayInputStream(convertObjectToByteArray(credential)); preparedStatement.setBinaryStream(1, isCert); preparedStatement.setString(2, credential.getPortalUserName()); preparedStatement.setTimestamp(3, new Timestamp(new java.util.Date().getTime())); preparedStatement.setString(4, credential.getDescription()); preparedStatement.setString(5, credential.getCredentialOwnerType().toString()); preparedStatement.setString(6, gatewayId); preparedStatement.setString(7, credential.getToken()); preparedStatement.executeUpdate(); } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error updating credentials."); stringBuilder.append(" gateway - ").append(gatewayId); stringBuilder.append(" token id - ").append(credential.getToken()); log.error(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement); } } /** * String createTable = "CREATE TABLE CREDENTIALS\n" + "(\n" + " GATEWAY_ID VARCHAR(256) NOT NULL,\n" + * " TOKEN_ID VARCHAR(256) NOT NULL,\n" + // Actual token used to identify the credential * " CREDENTIAL BLOB NOT NULL,\n" + " PORTAL_USER_ID VARCHAR(256) NOT NULL,\n" + * " TIME_PERSISTED TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n" + " PRIMARY KEY (GATEWAY_ID, TOKEN_ID)\n" * + ")"; */ public Credential getCredential(String gatewayName, String tokenId, Connection connection) throws CredentialStoreException { String sql = "SELECT * FROM CREDENTIALS WHERE GATEWAY_ID=? AND TOKEN_ID=?"; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, gatewayName); preparedStatement.setString(2, tokenId); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { // CertificateCredential certificateCredential = new CertificateCredential(); Blob blobCredentials = resultSet.getBlob("CREDENTIAL"); byte[] certificate = blobCredentials.getBytes(1, (int) blobCredentials.length()); Credential certificateCredential = (Credential) convertByteArrayToObject(certificate); certificateCredential.setPortalUserName(resultSet.getString("PORTAL_USER_ID")); certificateCredential.setCertificateRequestedTime(resultSet.getTimestamp("TIME_PERSISTED")); certificateCredential.setDescription(resultSet.getString("DESCRIPTION")); certificateCredential.setCredentialOwnerType(CredentialOwnerType.valueOf(resultSet.getString("CREDENTIAL_OWNER_TYPE"))); return certificateCredential; } } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error retrieving credentials for user."); stringBuilder.append("gateway - ").append(gatewayName); stringBuilder.append("token id - ").append(tokenId); log.debug(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement, resultSet); } return null; } /** * */ public String getGatewayID(String tokenId, Connection connection) throws CredentialStoreException { String sql = "SELECT GATEWAY_ID FROM CREDENTIALS WHERE TOKEN_ID=?"; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, tokenId); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { return resultSet.getString("GATEWAY_ID"); } } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error retrieving credentials for user."); stringBuilder.append("token id - ").append(tokenId); log.debug(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement, resultSet); } return null; } /** * String createTable = "CREATE TABLE CREDENTIALS\n" + "(\n" + " GATEWAY_ID VARCHAR(256) NOT NULL,\n" + * " TOKEN_ID VARCHAR(256) NOT NULL,\n" + // Actual token used to identify the credential * " CREDENTIAL BLOB NOT NULL,\n" + " PORTAL_USER_ID VARCHAR(256) NOT NULL,\n" + * " TIME_PERSISTED TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n" + " PRIMARY KEY (GATEWAY_ID, TOKEN_ID)\n" * + ")"; */ public List<Credential> getCredentials(String gatewayName, Connection connection) throws CredentialStoreException { List<Credential> credentialList = new ArrayList<Credential>(); String sql = "SELECT * FROM CREDENTIALS WHERE GATEWAY_ID=?"; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, gatewayName); resultSet = preparedStatement.executeQuery(); Credential certificateCredential; while (resultSet.next()) { Blob blobCredentials = resultSet.getBlob("CREDENTIAL"); byte[] certificate = blobCredentials.getBytes(1, (int) blobCredentials.length()); certificateCredential = (Credential) convertByteArrayToObject(certificate); certificateCredential.setToken(resultSet.getString("TOKEN_ID")); certificateCredential.setPortalUserName(resultSet.getString("PORTAL_USER_ID")); certificateCredential.setCertificateRequestedTime(resultSet.getTimestamp("TIME_PERSISTED")); certificateCredential.setDescription(resultSet.getString("DESCRIPTION")); certificateCredential.setCredentialOwnerType(CredentialOwnerType.valueOf(resultSet.getString("CREDENTIAL_OWNER_TYPE"))); credentialList.add(certificateCredential); } } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error retrieving credential list for "); stringBuilder.append("gateway - ").append(gatewayName); log.debug(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement, resultSet); } return credentialList; } /** * Gets all credentials. * @param connection The database connection * @return All credentials as a list * @throws CredentialStoreException If an error occurred while rerieving credentials. */ public List<Credential> getCredentials(Connection connection) throws CredentialStoreException { List<Credential> credentialList = new ArrayList<Credential>(); String sql = "SELECT * FROM CREDENTIALS"; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); Credential certificateCredential; while (resultSet.next()) { Blob blobCredentials = resultSet.getBlob("CREDENTIAL"); byte[] certificate = blobCredentials.getBytes(1, (int) blobCredentials.length()); certificateCredential = (Credential) convertByteArrayToObject(certificate); certificateCredential.setToken(resultSet.getString("TOKEN_ID")); certificateCredential.setPortalUserName(resultSet.getString("PORTAL_USER_ID")); certificateCredential.setCertificateRequestedTime(resultSet.getTimestamp("TIME_PERSISTED")); certificateCredential.setDescription(resultSet.getString("DESCRIPTION")); certificateCredential.setCredentialOwnerType(CredentialOwnerType.valueOf(resultSet.getString("CREDENTIAL_OWNER_TYPE"))); credentialList.add(certificateCredential); } } catch (SQLException e) { StringBuilder stringBuilder = new StringBuilder("Error retrieving all credentials"); log.debug(stringBuilder.toString(), e); throw new CredentialStoreException(stringBuilder.toString(), e); } finally { DBUtil.cleanup(preparedStatement, resultSet); } return credentialList; } public Object convertByteArrayToObject(byte[] data) throws CredentialStoreException { ObjectInputStream objectInputStream = null; Object o = null; try { try { //decrypt the data first if (encrypt()) { data = SecurityUtil.decrypt(this.keyStorePath, this.secretKeyAlias, this.keyStorePasswordCallback, data); } objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data)); o = objectInputStream.readObject(); } catch (IOException e) { throw new CredentialStoreException("Error de-serializing object.", e); } catch (ClassNotFoundException e) { throw new CredentialStoreException("Error de-serializing object.", e); } catch (GeneralSecurityException e) { throw new CredentialStoreException("Error decrypting data.", e); } } finally { if (objectInputStream != null) { try { objectInputStream.close(); } catch (IOException e) { log.error("Error occurred while closing the stream", e); } } } return o; } public byte[] convertObjectToByteArray(Serializable o) throws CredentialStoreException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = null; try { objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(o); objectOutputStream.flush(); } catch (IOException e) { throw new CredentialStoreException("Error serializing object.", e); } finally { if (objectOutputStream != null) { try { objectOutputStream.close(); } catch (IOException e) { log.error("Error occurred while closing object output stream", e); } } } // encrypt the byte array if (encrypt()) { byte[] array = byteArrayOutputStream.toByteArray(); try { return SecurityUtil.encrypt(this.keyStorePath, this.secretKeyAlias, this.keyStorePasswordCallback, array); } catch (GeneralSecurityException e) { throw new CredentialStoreException("Error encrypting data", e); } catch (IOException e) { throw new CredentialStoreException("Error encrypting data. IO exception.", e); } } else { return byteArrayOutputStream.toByteArray(); } } /** * Says whether to encrypt data or not. if alias, keystore is set * we treat encryption true. * @return true if data should encrypt else false. */ private boolean encrypt() { return this.keyStorePath != null; } }