/** * 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.ChannelShell; import com.keybox.common.util.AuthUtil; import com.keybox.manage.db.*; import com.keybox.manage.model.*; import com.keybox.manage.model.SortedSet; import com.keybox.manage.util.SSHUtil; import com.opensymphony.xwork2.ActionSupport; 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.BufferedReader; import java.io.StringReader; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This action will create composite ssh terminals to be used */ @InterceptorRef("keyboxStack") public class SecureShellAction extends ActionSupport implements ServletRequestAware, ServletResponseAware { private static Logger log = LoggerFactory.getLogger(SecureShellAction.class); List<SessionOutput> outputList; String command; HttpServletResponse servletResponse; HttpServletRequest servletRequest; List<Long> systemSelectId; HostSystem currentSystemStatus; HostSystem pendingSystemStatus; String password; String passphrase; Integer id; List<HostSystem> systemList = new ArrayList<>(); List<HostSystem> allocatedSystemList = new ArrayList<>(); UserSettings userSettings; static Map<Long, UserSchSessions> userSchSessionMap = new ConcurrentHashMap<>(); Script script = new Script(); /** * creates composite terminals if there are errors or authentication issues. */ @Action(value = "/admin/createTerms", results = { @Result(name = "success", location = "/admin/secure_shell.jsp") } ) public String createTerms() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); Long sessionId = AuthUtil.getSessionId(servletRequest.getSession()); if (pendingSystemStatus != null && pendingSystemStatus.getId() != null) { //get status currentSystemStatus = SystemStatusDB.getSystemStatus(pendingSystemStatus.getId(), userId); //if initial status run script if (currentSystemStatus != null && (HostSystem.INITIAL_STATUS.equals(currentSystemStatus.getStatusCd()) || HostSystem.AUTH_FAIL_STATUS.equals(currentSystemStatus.getStatusCd()) || HostSystem.PUBLIC_KEY_FAIL_STATUS.equals(currentSystemStatus.getStatusCd())) ) { //set current session currentSystemStatus = SSHUtil.openSSHTermOnSystem(passphrase, password, userId, sessionId, currentSystemStatus, userSchSessionMap); } if (currentSystemStatus != null && (HostSystem.AUTH_FAIL_STATUS.equals(currentSystemStatus.getStatusCd()) || HostSystem.PUBLIC_KEY_FAIL_STATUS.equals(currentSystemStatus.getStatusCd()))) { pendingSystemStatus = currentSystemStatus; } else { pendingSystemStatus = SystemStatusDB.getNextPendingSystem(userId); //if success loop through systems until finished or need password while (pendingSystemStatus != null && currentSystemStatus != null && HostSystem.SUCCESS_STATUS.equals(currentSystemStatus.getStatusCd())) { currentSystemStatus = SSHUtil.openSSHTermOnSystem(passphrase, password, userId, sessionId, pendingSystemStatus, userSchSessionMap); pendingSystemStatus = SystemStatusDB.getNextPendingSystem(userId); } } } //set system list if no pending systems if (SystemStatusDB.getNextPendingSystem(userId) == null) { setSystemList(userId, sessionId); //set allocated systems for connect to SortedSet sortedSet=new SortedSet(); sortedSet.setOrderByField(SystemDB.SORT_BY_NAME); if (Auth.MANAGER.equals(AuthUtil.getUserType(servletRequest.getSession()))) { sortedSet=SystemDB.getSystemSet(sortedSet); } else { sortedSet=SystemDB.getUserSystemSet(sortedSet, userId); } if(sortedSet!=null && sortedSet.getItemList()!=null) { allocatedSystemList = (List<HostSystem>) sortedSet.getItemList(); } //set theme this.userSettings =UserThemeDB.getTheme(userId); } return SUCCESS; } @Action(value = "/admin/getNextPendingSystemForTerms", results = { @Result(name = "success", location = "/admin/secure_shell.jsp") } ) public String getNextPendingSystemForTerms() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); currentSystemStatus = SystemStatusDB.getSystemStatus(pendingSystemStatus.getId(), userId); currentSystemStatus.setErrorMsg("Auth fail"); currentSystemStatus.setStatusCd(HostSystem.GENERIC_FAIL_STATUS); SystemStatusDB.updateSystemStatus(currentSystemStatus, userId); SystemDB.updateSystem(currentSystemStatus); pendingSystemStatus = SystemStatusDB.getNextPendingSystem(userId); //set system list if no pending systems if (pendingSystemStatus == null) { setSystemList(userId, AuthUtil.getSessionId(servletRequest.getSession())); } return SUCCESS; } @Action(value = "/admin/selectSystemsForCompositeTerms", results = { @Result(name = "success", location = "/admin/secure_shell.jsp") } ) public String selectSystemsForCompositeTerms() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); if (systemSelectId != null && !systemSelectId.isEmpty()) { SystemStatusDB.setInitialSystemStatus(systemSelectId, userId, AuthUtil.getUserType(servletRequest.getSession())); pendingSystemStatus = SystemStatusDB.getNextPendingSystem(userId); User user = UserDB.getUser(userId); user.setIpAddress(AuthUtil.getClientIPAddress(servletRequest)); AuthUtil.setSessionId(servletRequest.getSession(), SessionAuditDB.createSessionLog(user)); } return SUCCESS; } @Action(value = "/admin/exitTerms", results = { @Result(name = "success", location = "/admin/menu.action", type = "redirect") } ) public String exitTerms() { return SUCCESS; } @Action(value = "/admin/disconnectTerm") public String disconnectTerm() { Long sessionId = AuthUtil.getSessionId(servletRequest.getSession()); if (SecureShellAction.getUserSchSessionMap() != null) { UserSchSessions userSchSessions = SecureShellAction.getUserSchSessionMap().get(sessionId); if (userSchSessions != null) { try { SchSession schSession = userSchSessions.getSchSessionMap().get(id); //disconnect ssh session if(schSession!=null) { if (schSession.getChannel() != null) schSession.getChannel().disconnect(); if (schSession.getSession() != null) schSession.getSession().disconnect(); schSession.setChannel(null); schSession.setSession(null); schSession.setInputToChannel(null); schSession.setCommander(null); schSession.setOutFromChannel(null); } //remove from map userSchSessions.getSchSessionMap().remove(id); } catch (Exception ex) { log.error(ex.toString(), ex); } } } return null; } @Action(value = "/admin/createSession") public String createSession() { Long userId = AuthUtil.getUserId(servletRequest.getSession()); if (systemSelectId != null && !systemSelectId.isEmpty()) { SystemStatusDB.setInitialSystemStatus(systemSelectId, userId, AuthUtil.getUserType(servletRequest.getSession())); pendingSystemStatus = SystemStatusDB.getNextPendingSystem(userId); createTerms(); } return null; } @Action(value = "/admin/setPtyType") public String setPtyType() { Long sessionId = AuthUtil.getSessionId(servletRequest.getSession()); if (SecureShellAction.getUserSchSessionMap() != null) { UserSchSessions userSchSessions = SecureShellAction.getUserSchSessionMap().get(sessionId); if (userSchSessions != null && userSchSessions.getSchSessionMap() != null) { SchSession schSession = userSchSessions.getSchSessionMap().get(id); ChannelShell channel = (ChannelShell) schSession.getChannel(); channel.setPtySize((int) Math.floor(userSettings.getPtyWidth() / 7.2981), (int) Math.floor(userSettings.getPtyHeight() / 14.4166), userSettings.getPtyWidth(), userSettings.getPtyHeight()); schSession.setChannel(channel); } } return null; } /** * set system list once all connections have been attempted * * @param userId user id * @param sessionId session id */ private void setSystemList(Long userId, Long sessionId) { //check user map if (userSchSessionMap != null && !userSchSessionMap.isEmpty() && userSchSessionMap.get(sessionId) != null) { //get user sessions Map<Integer, SchSession> schSessionMap = userSchSessionMap.get(sessionId).getSchSessionMap(); for (SchSession schSession : schSessionMap.values()) { //add to host system list systemList.add(schSession.getHostSystem()); //run script it exists if (script != null && script.getId() != null && script.getId() > 0) { script = ScriptDB.getScript(script.getId(), userId); BufferedReader reader = new BufferedReader(new StringReader(script.getScript())); String line; try { while ((line = reader.readLine()) != null) { schSession.getCommander().println(line); } } catch (Exception e) { log.error(e.toString(), e); } } } } } public List<SessionOutput> getOutputList() { return outputList; } public void setOutputList(List<SessionOutput> outputList) { this.outputList = outputList; } public String getCommand() { return command; } public void setCommand(String command) { this.command = command; } public HttpServletResponse getServletResponse() { return servletResponse; } public void setServletResponse(HttpServletResponse servletResponse) { this.servletResponse = servletResponse; } public List<Long> getSystemSelectId() { return systemSelectId; } public void setSystemSelectId(List<Long> systemSelectId) { this.systemSelectId = systemSelectId; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public HostSystem getCurrentSystemStatus() { return currentSystemStatus; } public void setCurrentSystemStatus(HostSystem currentSystemStatus) { this.currentSystemStatus = currentSystemStatus; } public HostSystem getPendingSystemStatus() { return pendingSystemStatus; } public void setPendingSystemStatus(HostSystem pendingSystemStatus) { this.pendingSystemStatus = pendingSystemStatus; } public Script getScript() { return script; } public void setScript(Script script) { this.script = script; } public String getPassphrase() { return passphrase; } public void setPassphrase(String passphrase) { this.passphrase = passphrase; } public HttpServletRequest getServletRequest() { return servletRequest; } public void setServletRequest(HttpServletRequest servletRequest) { this.servletRequest = servletRequest; } public List<HostSystem> getSystemList() { return systemList; } public void setSystemList(List<HostSystem> systemList) { this.systemList = systemList; } public static Map<Long, UserSchSessions> getUserSchSessionMap() { return userSchSessionMap; } public static void setUserSchSessionMap(Map<Long, UserSchSessions> userSchSessionMap) { SecureShellAction.userSchSessionMap = userSchSessionMap; } public List<HostSystem> getAllocatedSystemList() { return allocatedSystemList; } public void setAllocatedSystemList(List<HostSystem> allocatedSystemList) { this.allocatedSystemList = allocatedSystemList; } public UserSettings getUserSettings() { return userSettings; } public void setUserSettings(UserSettings userSettings) { this.userSettings = userSettings; } }