/** * * 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.server; import org.apache.airavata.common.exception.ApplicationSettingsException; import org.apache.airavata.common.utils.DBUtil; import org.apache.airavata.common.utils.ServerSettings; import org.apache.airavata.credential.store.cpi.CredentialStoreService; import org.apache.airavata.credential.store.cpi.credential_store_cpiConstants; import org.apache.airavata.credential.store.credential.CommunityUser; import org.apache.airavata.credential.store.credential.Credential; import org.apache.airavata.credential.store.credential.CredentialOwnerType; import org.apache.airavata.model.credential.store.*; import org.apache.airavata.credential.store.store.CredentialStoreException; import org.apache.airavata.credential.store.store.impl.CertificateCredentialWriter; import org.apache.airavata.credential.store.store.impl.CredentialReaderImpl; import org.apache.airavata.credential.store.store.impl.SSHCredentialWriter; import org.apache.airavata.credential.store.store.impl.util.CredentialStoreInitUtil; import org.apache.airavata.credential.store.util.TokenGenerator; import org.apache.airavata.credential.store.util.Utility; import org.apache.commons.codec.binary.Base64; import org.apache.thrift.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.security.provider.X509Factory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.sql.SQLException; import java.util.*; public class CredentialStoreServerHandler implements CredentialStoreService.Iface { protected static Logger log = LoggerFactory.getLogger(CredentialStoreServerHandler.class); private DBUtil dbUtil; private SSHCredentialWriter sshCredentialWriter; private CertificateCredentialWriter certificateCredentialWriter; private CredentialReaderImpl credentialReader; public CredentialStoreServerHandler() throws ApplicationSettingsException, IllegalAccessException, ClassNotFoundException, InstantiationException, SQLException, IOException { String jdbcUrl = ServerSettings.getCredentialStoreDBURL(); String userName = ServerSettings.getCredentialStoreDBUser(); String password = ServerSettings.getCredentialStoreDBPassword(); String driverName = ServerSettings.getCredentialStoreDBDriver(); log.debug("Starting credential store, connecting to database - " + jdbcUrl + " DB user - " + userName + " driver name - " + driverName); CredentialStoreInitUtil.initializeDB(); dbUtil = new DBUtil(jdbcUrl, userName, password, driverName); sshCredentialWriter = new SSHCredentialWriter(dbUtil); certificateCredentialWriter = new CertificateCredentialWriter(dbUtil); credentialReader = new CredentialReaderImpl(dbUtil); } @Override public String getCSServiceVersion() throws TException { return credential_store_cpiConstants.CS_CPI_VERSION; } @Override public String addSSHCredential(SSHCredential sshCredential) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential = new org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential(); credential.setGateway(sshCredential.getGatewayId()); credential.setPortalUserName(sshCredential.getUsername()); // only username and gateway id will be sent by client. String token = TokenGenerator.generateToken(sshCredential.getGatewayId(), null); credential.setToken(token); credential.setPassphrase(String.valueOf(UUID.randomUUID())); if (sshCredential.getPrivateKey() != null) { credential.setPrivateKey(sshCredential.getPrivateKey().getBytes()); } if(sshCredential.getDescription() != null){ credential.setDescription(sshCredential.getDescription()); } if (sshCredential.getPublicKey() != null) { credential.setPublicKey(sshCredential.getPublicKey().getBytes()); } if (sshCredential.getPublicKey() == null || sshCredential.getPrivateKey() == null) { credential = Utility.generateKeyPair(credential); } credential.setCredentialOwnerType(CredentialOwnerType.findByDataModelType(sshCredential.getCredentialOwnerType())); sshCredentialWriter.writeCredentials(credential); return token; } catch (CredentialStoreException e) { log.error("Error occurred while saving SSH Credentials.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while saving SSH Credentials."); } catch (Exception e) { log.error("Error occurred while generating key pair.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while generating key pair.."); } } @Override public String addCertificateCredential(CertificateCredential certificateCredential) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential credential = new org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential(); credential.setPortalUserName(certificateCredential.getCommunityUser().getUsername()); credential.setCommunityUser(new CommunityUser(certificateCredential.getCommunityUser().getGatewayName(), certificateCredential.getCommunityUser().getUsername(), certificateCredential.getCommunityUser().getUserEmail())); String token = TokenGenerator.generateToken(certificateCredential.getCommunityUser().getGatewayName(), null); credential.setToken(token); Base64 encoder = new Base64(64); byte [] decoded = encoder.decode(certificateCredential.getX509Cert().replaceAll(X509Factory.BEGIN_CERT, "").replaceAll(X509Factory.END_CERT, "")); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate certificate = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(decoded)); X509Certificate[] certificates = new X509Certificate[1]; certificates[0] = certificate; credential.setCertificates(certificates); certificateCredentialWriter.writeCredentials(credential); return token; } catch (CredentialStoreException e) { log.error("Error occurred while saving Certificate Credentials.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while saving Certificate Credentials."); } catch (Exception e) { log.error("Error occurred while converting to X509 certificate.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while converting to X509 certificate.."); } } @Override public String addPasswordCredential(PasswordCredential passwordCredential) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { org.apache.airavata.credential.store.credential.impl.password.PasswordCredential credential = new org.apache.airavata.credential.store.credential.impl.password.PasswordCredential(); credential.setGateway(passwordCredential.getGatewayId()); credential.setPortalUserName(passwordCredential.getPortalUserName()); credential.setUserName(passwordCredential.getLoginUserName()); credential.setPassword(passwordCredential.getPassword()); credential.setDescription(passwordCredential.getDescription()); String token = TokenGenerator.generateToken(passwordCredential.getGatewayId(), null); credential.setToken(token); sshCredentialWriter.writeCredentials(credential); return token; } catch (CredentialStoreException e) { log.error("Error occurred while saving PWD Credentials.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while saving PWD Credentials."); } catch (Exception e) { log.error("Error occurred while registering PWD Credentials.", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while registering PWD Credentials.."); } } @Override public SSHCredential getSSHCredential(String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { Credential credential = credentialReader.getCredential(gatewayId, tokenId); if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential1 = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; SSHCredential sshCredential = new SSHCredential(); sshCredential.setUsername(credential1.getPortalUserName()); sshCredential.setGatewayId(credential1.getGateway()); sshCredential.setPublicKey(new String(credential1.getPublicKey())); sshCredential.setPrivateKey(new String(credential1.getPrivateKey())); sshCredential.setPassphrase(credential1.getPassphrase()); sshCredential.setToken(credential1.getToken()); sshCredential.setPersistedTime(credential1.getCertificateRequestedTime().getTime()); sshCredential.setDescription(credential1.getDescription()); sshCredential.setCredentialOwnerType(credential1.getCredentialOwnerType().getDatamodelType()); return sshCredential; } else { log.info("Could not find SSH credentials for token - " + tokenId + " and " + "gateway id - " + gatewayId); return null; } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving SSH credentialfor token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving SSH credential for token - " + tokenId + " and gateway id - " + gatewayId); } } @Override public CredentialSummary getCredentialSummary(SummaryType type, String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { if(type.equals(SummaryType.SSH)){ Credential credential = credentialReader.getCredential(gatewayId, tokenId); if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential credential1 = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; CredentialSummary sshCredentialSummary = new CredentialSummary(); sshCredentialSummary.setType(SummaryType.SSH); sshCredentialSummary.setUsername(credential1.getPortalUserName()); sshCredentialSummary.setGatewayId(credential1.getGateway()); sshCredentialSummary.setPublicKey(new String(credential1.getPublicKey())); sshCredentialSummary.setToken(credential1.getToken()); sshCredentialSummary.setPersistedTime(credential1.getCertificateRequestedTime().getTime()); sshCredentialSummary.setDescription(credential1.getDescription()); return sshCredentialSummary; } else { log.info("Could not find SSH credential for token - " + tokenId + " and " + "gateway id - " + gatewayId); return null; } }else{ log.info("Summay Type"+ type.toString() + " not supported for - " + tokenId + " and " + "gateway id - " + gatewayId); return null; } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving SSH credential Summary for token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving SSH credential Summary for token - " + tokenId + " and gateway id - " + gatewayId); } } @Override public CertificateCredential getCertificateCredential(String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { Credential credential = credentialReader.getCredential(gatewayId, tokenId); if (credential instanceof org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential) { org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential credential1 = (org.apache.airavata.credential.store.credential.impl.certificate.CertificateCredential) credential; CertificateCredential certificateCredential = new CertificateCredential(); org.apache.airavata.model.credential.store.CommunityUser communityUser = new org.apache.airavata.model.credential.store.CommunityUser(); communityUser.setGatewayName(credential1.getCommunityUser().getGatewayName()); communityUser.setUsername(credential1.getCommunityUser().getUserName()); communityUser.setUserEmail(credential1.getCommunityUser().getUserEmail()); certificateCredential.setCommunityUser(communityUser); certificateCredential.setToken(credential1.getToken()); certificateCredential.setLifeTime(credential1.getLifeTime()); certificateCredential.setNotAfter(credential1.getNotAfter()); certificateCredential.setNotBefore(credential1.getNotBefore()); certificateCredential.setPersistedTime(credential1.getCertificateRequestedTime().getTime()); if (credential1.getPrivateKey() != null){ certificateCredential.setPrivateKey(credential1.getPrivateKey().toString()); } certificateCredential.setX509Cert(credential1.getCertificates()[0].toString()); return certificateCredential; } else { log.info("Could not find Certificate credentials for token - " + tokenId + " and " + "gateway id - " + gatewayId); return null; } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving Certificate credential for token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving Certificate credential for token - " + tokenId + " and gateway id - " + gatewayId); } } @Override public PasswordCredential getPasswordCredential(String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { Credential credential = credentialReader.getCredential(gatewayId, tokenId); if (credential instanceof org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) { org.apache.airavata.credential.store.credential.impl.password.PasswordCredential credential1 = (org.apache.airavata.credential .store.credential.impl.password.PasswordCredential) credential; PasswordCredential pwdCredential = new PasswordCredential(); pwdCredential.setGatewayId(credential1.getGateway()); pwdCredential.setPortalUserName(credential1.getPortalUserName()); pwdCredential.setLoginUserName(credential1.getUserName()); pwdCredential.setPassword(credential1.getPassword()); pwdCredential.setDescription(credential1.getDescription()); pwdCredential.setToken(credential1.getToken()); pwdCredential.setPersistedTime(credential1.getCertificateRequestedTime().getTime()); return pwdCredential; } else { log.info("Could not find PWD credentials for token - " + tokenId + " and " + "gateway id - " + gatewayId); return null; } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving PWD credentialfor token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving PWD credential for token - " + tokenId + " and gateway id - " + gatewayId); } } @Override public Map<String, String> getAllSSHKeysForUser(String username) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { Map<String, String> sshKeyMap = new HashMap<>(); try { List<Credential> allCredentials = credentialReader.getAllCredentials(); if (allCredentials != null && !allCredentials.isEmpty()){ for (Credential credential : allCredentials) { if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; String portalUserName = sshCredential.getPortalUserName(); if (portalUserName != null && sshCredential.getCredentialOwnerType() == CredentialOwnerType.USER){ if (portalUserName.equals(username)) { byte[] publicKey = sshCredential.getPublicKey(); if (publicKey != null) { sshKeyMap.put(sshCredential.getToken(), new String(publicKey)); } } } } } } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving credentials", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving credentials"); } return sshKeyMap; } @Override public Map<String, String> getAllSSHKeysForGateway(String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { Map<String, String> sshKeyMap = new HashMap<>(); try { List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId); if (allCredentials != null && !allCredentials.isEmpty()){ for (Credential credential : allCredentials) { if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; byte[] publicKey = sshCredential.getPublicKey(); if (publicKey != null && sshCredential.getCredentialOwnerType() == CredentialOwnerType.GATEWAY) { sshKeyMap.put(sshCredential.getToken(), new String(publicKey)); } } } } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving credentials", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving credentials"); } return sshKeyMap; } @Override public List<CredentialSummary> getAllCredentialSummaryForGateway(SummaryType type, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { if(type.equals(SummaryType.SSH)){ Map<String, String> sshKeyMap = new HashMap<>(); List<CredentialSummary> summaryList = new ArrayList<>(); try { List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId); if (allCredentials != null && !allCredentials.isEmpty()){ for (Credential credential : allCredentials) { if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential && credential.getCredentialOwnerType() == CredentialOwnerType.GATEWAY) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; CredentialSummary sshCredentialSummary = new CredentialSummary(); sshCredentialSummary.setType(SummaryType.SSH); sshCredentialSummary.setToken(sshCredential.getToken()); sshCredentialSummary.setUsername(sshCredential.getPortalUserName()); sshCredentialSummary.setGatewayId(sshCredential.getGateway()); sshCredentialSummary.setDescription(sshCredential.getDescription()); sshCredentialSummary.setPublicKey(new String(sshCredential.getPublicKey())); summaryList.add(sshCredentialSummary); } } } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving credential Summary", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving credential Summary"); } return summaryList; }else{ log.info("Summay Type"+ type.toString() + " not supported for gateway id - " + gatewayId); return null; } } @Override public List<CredentialSummary> getAllCredentialSummaryForUserInGateway(SummaryType type, String gatewayId, String userId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { if(type.equals(SummaryType.SSH)){ Map<String, String> sshKeyMap = new HashMap<>(); List<CredentialSummary> summaryList = new ArrayList<>(); try { List<Credential> allCredentials = credentialReader.getAllCredentials(); if (allCredentials != null && !allCredentials.isEmpty()){ for (Credential credential : allCredentials) { if (credential instanceof org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredential = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; String portalUserName = sshCredential.getPortalUserName(); String gateway = sshCredential.getGateway(); if (portalUserName != null && gateway != null){ if (portalUserName.equals(userId) && gateway.equals(gatewayId) && sshCredential.getCredentialOwnerType() == CredentialOwnerType.USER) { org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential sshCredentialKey = (org.apache.airavata.credential.store.credential.impl.ssh.SSHCredential) credential; CredentialSummary sshCredentialSummary = new CredentialSummary(); sshCredentialSummary.setType(SummaryType.SSH); sshCredentialSummary.setToken(sshCredentialKey.getToken()); sshCredentialSummary.setUsername(sshCredentialKey.getPortalUserName()); sshCredentialSummary.setGatewayId(sshCredentialKey.getGateway()); sshCredentialSummary.setDescription(sshCredentialKey.getDescription()); sshCredentialSummary.setPublicKey(new String(sshCredentialKey.getPublicKey())); summaryList.add(sshCredentialSummary); } } } } } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving credential Summary", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving credential Summary"); } return summaryList; }else{ log.info("Summay Type"+ type.toString() + " not supported for user Id - " + userId + " and " + "gateway id - " + gatewayId); return null; } } @Override public Map<String, String> getAllPWDCredentialsForGateway(String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { Map<String, String> pwdCredMap = new HashMap<>(); try { List<Credential> allCredentials = credentialReader.getAllCredentialsPerGateway(gatewayId); if (allCredentials != null && !allCredentials.isEmpty()){ for (Credential credential : allCredentials) { if (credential instanceof org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) { org.apache.airavata.credential.store.credential.impl.password.PasswordCredential pwdCredential = (org.apache.airavata.credential.store.credential.impl.password.PasswordCredential) credential; pwdCredMap.put(pwdCredential.getToken(),pwdCredential.getDescription() == null ? "" : pwdCredential.getDescription()); } } } } catch (CredentialStoreException e) { log.error("Error occurred while retrieving credentials", e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while retrieving credentials"); } return pwdCredMap; } @Override public boolean deleteSSHCredential(String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { credentialReader.removeCredentials(gatewayId, tokenId); return true; } catch (CredentialStoreException e) { log.error("Error occurred while deleting SSH credential for token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while deleting SSH credential for token - " + tokenId + " and gateway id - " + gatewayId); } } @Override public boolean deletePWDCredential(String tokenId, String gatewayId) throws org.apache.airavata.credential.store.exception.CredentialStoreException, TException { try { credentialReader.removeCredentials(gatewayId, tokenId); return true; } catch (CredentialStoreException e) { log.error("Error occurred while deleting PWD credential for token - " + tokenId + " and gateway id - " + gatewayId, e); throw new org.apache.airavata.credential.store.exception.CredentialStoreException("Error occurred while deleting PWD credential for token - " + tokenId + " and gateway id - " + gatewayId); } } }