/** * Copyright 2013 Sean Kavanagh - sean.p.kavanagh6@gmail.com * * Licensed 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 com.keybox.manage.action; import com.jcraft.jsch.JSch; import com.jcraft.jsch.KeyPair; import com.keybox.common.util.AppConfig; import com.keybox.common.util.AuthUtil; import com.keybox.manage.db.*; import com.keybox.manage.model.*; import com.keybox.manage.util.EncryptionUtil; import com.keybox.manage.util.PasswordUtil; import com.keybox.manage.util.RefreshAuthKeyUtil; import com.keybox.manage.util.SSHUtil; import com.opensymphony.xwork2.ActionSupport; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Action to generate and distribute auth keys for systems or users */ @SuppressWarnings("unchecked") @InterceptorRef("keyboxStack") public class AuthKeysAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { public static final String REQUIRED = "Required"; public static final String INVALID = "Invalid"; public static final String PUBLIC_KEY_PUBLIC_KEY = "publicKey.publicKey"; private static Logger log = LoggerFactory.getLogger(AuthKeysAction.class); HttpServletRequest servletRequest; HttpServletResponse servletResponse; List<Profile> profileList; List<User> userList; PublicKey publicKey; SortedSet sortedSet = new SortedSet(); List<Long> systemSelectId; boolean forceUserKeyGenEnabled="true".equals(AppConfig.getProperty("forceUserKeyGeneration")); HostSystem pendingSystem = null; HostSystem hostSystem = new HostSystem(); List<PublicKey> userPublicKeyList; Long existingKeyId; @Action(value = "/manage/enablePublicKey", results = { @Result(name = "success", location = "/manage/view_keys.jsp") } ) public String enablePublicKey() { publicKey= PublicKeyDB.getPublicKey(publicKey.getId()); PublicKeyDB.enableKey(publicKey.getId()); profileList = ProfileDB.getAllProfiles(); userList= UserDB.getUserSet(new SortedSet(SessionAuditDB.SORT_BY_USERNAME)).getItemList(); sortedSet = PublicKeyDB.getPublicKeySet(sortedSet); distributePublicKeys(publicKey); return SUCCESS; } @Action(value = "/manage/disablePublicKey", results = { @Result(name = "success", location = "/manage/view_keys.jsp") } ) public String disablePublicKey() { publicKey= PublicKeyDB.getPublicKey(publicKey.getId()); PublicKeyDB.disableKey(publicKey.getId()); profileList = ProfileDB.getAllProfiles(); userList= UserDB.getUserSet(new SortedSet(SessionAuditDB.SORT_BY_USERNAME)).getItemList(); sortedSet = PublicKeyDB.getPublicKeySet(sortedSet); distributePublicKeys(publicKey); return SUCCESS; } @Action(value = "/manage/viewKeys", results = { @Result(name = "success", location = "/manage/view_keys.jsp") } ) public String manageViewKeys() { profileList = ProfileDB.getAllProfiles(); userList= UserDB.getUserSet(new SortedSet(SessionAuditDB.SORT_BY_USERNAME)).getItemList(); sortedSet = PublicKeyDB.getPublicKeySet(sortedSet); return SUCCESS; } @Action(value = "/admin/viewKeys", results = { @Result(name = "success", location = "/admin/view_keys.jsp") } ) public String adminViewKeys() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); String userType = AuthUtil.getUserType(servletRequest.getSession()); if (Auth.MANAGER.equals(userType)) { profileList = ProfileDB.getAllProfiles(); } else { profileList = UserProfileDB.getProfilesByUser(userId); } sortedSet = PublicKeyDB.getPublicKeySet(sortedSet, userId); userPublicKeyList = PublicKeyDB.getUniquePublicKeysForUser(userId); return SUCCESS; } @Action(value = "/admin/savePublicKey", results = { @Result(name = "input", location = "/admin/view_keys.jsp"), @Result(name = "success", location = "/admin/viewKeys.action?sortedSet.orderByDirection=${sortedSet.orderByDirection}&sortedSet.orderByField=${sortedSet.orderByField}&keyNm=${publicKey.keyNm}", type = "redirect") } ) public String savePublicKeys() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); String userType = AuthUtil.getUserType(servletRequest.getSession()); publicKey.setUserId(userId); if (Auth.MANAGER.equals(userType) || UserProfileDB.checkIsUsersProfile(userId, publicKey.getProfile().getId())) { if (publicKey.getId() != null) { PublicKeyDB.updatePublicKey(publicKey); } else { PublicKeyDB.insertPublicKey(publicKey); } distributePublicKeys(publicKey); } return SUCCESS; } @Action(value = "/admin/deletePublicKey", results = { @Result(name = "input", location = "/admin/view_keys.jsp"), @Result(name = "success", location = "/admin/viewKeys.action?sortedSet.orderByDirection=${sortedSet.orderByDirection}&sortedSet.orderByField=${sortedSet.orderByField}", type = "redirect") } ) public String deletePublicKey() { if (publicKey.getId() != null) { //get public key then delete publicKey = PublicKeyDB.getPublicKey(publicKey.getId()); PublicKeyDB.deletePublicKey(publicKey.getId(), AuthUtil.getUserId(servletRequest.getSession())); } distributePublicKeys(publicKey); return SUCCESS; } public static final String PVT_KEY="privateKey"; @Action(value = "/admin/downloadPvtKey") public String downloadPvtKey() { String privateKey=EncryptionUtil.decrypt((String)servletRequest.getSession().getAttribute(PVT_KEY)); if(StringUtils.isNotEmpty(publicKey.getKeyNm()) && StringUtils.isNotEmpty(privateKey)) { try { servletResponse.setContentType("application/octet-stream"); servletResponse.setHeader("Content-Disposition", "attachment;filename=" + publicKey.getKeyNm() + ".key"); servletResponse.getOutputStream().write(privateKey.getBytes()); servletResponse.getOutputStream().flush(); servletResponse.getOutputStream().close(); } catch (Exception ex) { log.error(ex.toString(), ex); } } //remove pvt key servletRequest.getSession().setAttribute(PVT_KEY, null); servletRequest.getSession().removeAttribute(PVT_KEY); return null; } /** * generates public private key from passphrase * * @param username username to set in public key comment * @param keyname keyname to set in public key comment * @return public key */ public String generateUserKey(String username, String keyname) { //set key type int type = KeyPair.RSA; if("dsa".equals(SSHUtil.KEY_TYPE)) { type = KeyPair.DSA; } else if("ecdsa".equals(SSHUtil.KEY_TYPE)) { type = KeyPair.ECDSA; } JSch jsch = new JSch(); String pubKey=null; try { KeyPair keyPair = KeyPair.genKeyPair(jsch, type, SSHUtil.KEY_LENGTH); OutputStream os = new ByteArrayOutputStream(); keyPair.writePrivateKey(os, publicKey.getPassphrase().getBytes()); //set private key servletRequest.getSession().setAttribute(PVT_KEY, EncryptionUtil.encrypt(os.toString())); os = new ByteArrayOutputStream(); keyPair.writePublicKey(os, username + "@" + keyname); pubKey = os.toString(); keyPair.dispose(); } catch (Exception ex) { log.error(ex.toString(), ex); } return pubKey; } /** * Validates all fields for adding a public key */ public void validateSavePublicKeys() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); if (publicKey == null || publicKey.getKeyNm() == null || publicKey.getKeyNm().trim().equals("")) { addFieldError("publicKey.keyNm", REQUIRED); } if(publicKey!=null) { if(existingKeyId!=null){ publicKey.setPublicKey(PublicKeyDB.getPublicKey(existingKeyId).getPublicKey()); } else if("true".equals(AppConfig.getProperty("forceUserKeyGeneration"))){ if (publicKey.getPassphrase() == null || publicKey.getPassphrase().trim().equals("")) { addFieldError("publicKey.passphrase", REQUIRED); } else if (publicKey.getPassphraseConfirm() == null || publicKey.getPassphraseConfirm().trim().equals("")) { addFieldError("publicKey.passphraseConfirm", REQUIRED); } else if(!publicKey.getPassphrase().equals(publicKey.getPassphraseConfirm())) { addActionError("Passphrases do not match"); } else if(!PasswordUtil.isValid(publicKey.getPassphrase())){ addActionError(PasswordUtil.PASSWORD_REQ_ERROR_MSG); } else { publicKey.setPublicKey(generateUserKey(UserDB.getUser(userId).getUsername(), publicKey.getKeyNm())); } } if( publicKey.getPublicKey() == null || publicKey.getPublicKey().trim().equals("")) { addFieldError(PUBLIC_KEY_PUBLIC_KEY, REQUIRED); } else if (SSHUtil.getFingerprint(publicKey.getPublicKey()) == null || SSHUtil.getKeyType(publicKey.getPublicKey()) == null) { addFieldError(PUBLIC_KEY_PUBLIC_KEY, INVALID); } else if (PublicKeyDB.isKeyDisabled(SSHUtil.getFingerprint(publicKey.getPublicKey()))) { addActionError("This key has been disabled. Please generate and set a new public key."); addFieldError(PUBLIC_KEY_PUBLIC_KEY, INVALID); } else if (PublicKeyDB.isKeyRegistered(userId, publicKey)) { addActionError("This key has already been registered under selected profile."); addFieldError(PUBLIC_KEY_PUBLIC_KEY, INVALID); } } if (!this.getFieldErrors().isEmpty()) { String userType = AuthUtil.getUserType(servletRequest.getSession()); if (Auth.MANAGER.equals(userType)) { profileList = ProfileDB.getAllProfiles(); } else { profileList = UserProfileDB.getProfilesByUser(userId); } sortedSet = PublicKeyDB.getPublicKeySet(sortedSet, userId); userPublicKeyList = PublicKeyDB.getUniquePublicKeysForUser(userId); } } /** * distribute public keys to all systems or to profile * * @param publicKey public key to distribute */ private void distributePublicKeys(PublicKey publicKey){ if (publicKey.getProfile() != null && publicKey.getProfile().getId() != null) { RefreshAuthKeyUtil.refreshProfileSystems(publicKey.getProfile().getId()); } else { RefreshAuthKeyUtil.refreshAllSystems(); } } public HttpServletRequest getServletRequest() { return servletRequest; } public void setServletRequest(HttpServletRequest servletRequest) { this.servletRequest = servletRequest; } public List<Profile> getProfileList() { return profileList; } public void setProfileList(List<Profile> profileList) { this.profileList = profileList; } public PublicKey getPublicKey() { return publicKey; } public void setPublicKey(PublicKey publicKey) { this.publicKey = publicKey; } public SortedSet getSortedSet() { return sortedSet; } public void setSortedSet(SortedSet sortedSet) { this.sortedSet = sortedSet; } public List<Long> getSystemSelectId() { return systemSelectId; } public void setSystemSelectId(List<Long> systemSelectId) { this.systemSelectId = systemSelectId; } public HostSystem getPendingSystem() { return pendingSystem; } public void setPendingSystem(HostSystem pendingSystem) { this.pendingSystem = pendingSystem; } public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; } public HostSystem getHostSystem() { return hostSystem; } public void setHostSystem(HostSystem hostSystem) { this.hostSystem = hostSystem; } public HttpServletResponse getServletResponse() { return servletResponse; } public void setServletResponse(HttpServletResponse servletResponse) { this.servletResponse = servletResponse; } public boolean getForceUserKeyGenEnabled() { return forceUserKeyGenEnabled; } public void setForceUserKeyGenEnabled(boolean forceUserKeyGenEnabled) { this.forceUserKeyGenEnabled = forceUserKeyGenEnabled; } public List<PublicKey> getUserPublicKeyList() { return userPublicKeyList; } public void setUserPublicKeyList(List<PublicKey> userPublicKeyList) { this.userPublicKeyList = userPublicKeyList; } public Long getExistingKeyId() { return existingKeyId; } public void setExistingKeyId(Long existingKeyId) { this.existingKeyId = existingKeyId; } }