Java tutorial
/** * 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.ec2box.manage.util; import com.ec2box.common.util.AppConfig; import com.ec2box.manage.db.SystemDB; import com.ec2box.manage.model.*; import com.ec2box.manage.task.SecureShellTask; import com.jcraft.jsch.*; import com.ec2box.manage.db.EC2KeyDB; import com.ec2box.manage.db.SystemStatusDB; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.util.Map; /** * SSH utility class used to create public/private key for system and distribute authorized key files */ public class SSHUtil { //system path to public/private key public static String KEY_PATH = DBUtils.class.getClassLoader().getResource("ec2db").getPath(); public static final int SESSION_TIMEOUT = 60000; public static final int CHANNEL_TIMEOUT = 60000; public static final int SERVER_ALIVE_INTERVAL = StringUtils .isNumeric(AppConfig.getProperty("serverAliveInterval")) ? Integer.parseInt(AppConfig.getProperty("serverAliveInterval")) * 1000 : 60 * 1000; private SSHUtil() { } /** * distributes uploaded item to system defined * * @param hostSystem object contains host system information * @param session an established SSH session * @param source source file * @param destination destination file * @return status uploaded file */ public static HostSystem pushUpload(HostSystem hostSystem, Session session, String source, String destination) { hostSystem.setStatusCd(HostSystem.SUCCESS_STATUS); Channel channel = null; ChannelSftp c = null; try { channel = session.openChannel("sftp"); channel.setInputStream(System.in); channel.setOutputStream(System.out); channel.connect(CHANNEL_TIMEOUT); c = (ChannelSftp) channel; destination = destination.replaceAll("~\\/|~", ""); //get file input stream FileInputStream file = new FileInputStream(source); c.put(file, destination); } catch (Exception e) { hostSystem.setErrorMsg(e.getMessage()); hostSystem.setStatusCd(HostSystem.GENERIC_FAIL_STATUS); } //exit if (c != null) { c.exit(); } //disconnect if (channel != null) { channel.disconnect(); } return hostSystem; } /** * return the next instance id based on ids defined in the session map * * @param sessionId session id * @param userSessionMap user session map * @return */ private static int getNextInstanceId(Long sessionId, Map<Long, UserSchSessions> userSessionMap) { Integer instanceId = 1; if (userSessionMap.get(sessionId) != null) { for (Integer id : userSessionMap.get(sessionId).getSchSessionMap().keySet()) { if (!id.equals(instanceId) && userSessionMap.get(sessionId).getSchSessionMap().get(instanceId) == null) { return instanceId; } instanceId = instanceId + 1; } } return instanceId; } /** * open new ssh session on host system * * @param passphrase key passphrase for instance * @param password password for instance * @param userId user id * @param sessionId session id * @param hostSystem host system * @param userSessionMap user session map * @return status of systems */ public static HostSystem openSSHTermOnSystem(String passphrase, String password, Long userId, Long sessionId, HostSystem hostSystem, Map<Long, UserSchSessions> userSessionMap) { JSch jsch = new JSch(); int instanceId = getNextInstanceId(sessionId, userSessionMap); hostSystem.setStatusCd(HostSystem.SUCCESS_STATUS); hostSystem.setInstanceId(instanceId); SchSession schSession = null; try { EC2Key ec2Key = EC2KeyDB.getEC2Key(hostSystem.getKeyId()); //add private key if (ec2Key != null && ec2Key.getId() != null) { if (passphrase != null && !passphrase.trim().equals("")) { jsch.addIdentity(ec2Key.getId().toString(), ec2Key.getPrivateKey().trim().getBytes(), null, passphrase.getBytes()); } else { jsch.addIdentity(ec2Key.getId().toString(), ec2Key.getPrivateKey().trim().getBytes(), null, null); } } //create session Session session = jsch.getSession(hostSystem.getUser(), hostSystem.getHost(), hostSystem.getPort()); //set password if it exists if (password != null && !password.trim().equals("")) { session.setPassword(password); } session.setConfig("StrictHostKeyChecking", "no"); session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password"); session.setServerAliveInterval(SERVER_ALIVE_INTERVAL); session.connect(SESSION_TIMEOUT); Channel channel = session.openChannel("shell"); if ("true".equals(AppConfig.getProperty("agentForwarding"))) { ((ChannelShell) channel).setAgentForwarding(true); } ((ChannelShell) channel).setPtyType("xterm"); InputStream outFromChannel = channel.getInputStream(); //new session output //new session output SessionOutput sessionOutput = new SessionOutput(sessionId, hostSystem); Runnable run = new SecureShellTask(sessionOutput, outFromChannel); Thread thread = new Thread(run); thread.start(); OutputStream inputToChannel = channel.getOutputStream(); PrintStream commander = new PrintStream(inputToChannel, true); channel.connect(); schSession = new SchSession(); schSession.setUserId(userId); schSession.setSession(session); schSession.setChannel(channel); schSession.setCommander(commander); schSession.setInputToChannel(inputToChannel); schSession.setOutFromChannel(outFromChannel); schSession.setHostSystem(hostSystem); } catch (Exception e) { hostSystem.setErrorMsg(e.getMessage()); if (e.getMessage().toLowerCase().contains("userauth fail")) { hostSystem.setStatusCd(HostSystem.PUBLIC_KEY_FAIL_STATUS); } else if (e.getMessage().toLowerCase().contains("auth fail") || e.getMessage().toLowerCase().contains("auth cancel")) { hostSystem.setStatusCd(HostSystem.AUTH_FAIL_STATUS); } else if (e.getMessage().toLowerCase().contains("unknownhostexception")) { hostSystem.setErrorMsg("DNS Lookup Failed"); hostSystem.setStatusCd(HostSystem.HOST_FAIL_STATUS); } else { hostSystem.setStatusCd(HostSystem.GENERIC_FAIL_STATUS); } } //add session to map if (hostSystem.getStatusCd().equals(HostSystem.SUCCESS_STATUS)) { //get the server maps for user UserSchSessions userSchSessions = userSessionMap.get(sessionId); //if no user session create a new one if (userSchSessions == null) { userSchSessions = new UserSchSessions(); } Map<Integer, SchSession> schSessionMap = userSchSessions.getSchSessionMap(); //add server information schSessionMap.put(instanceId, schSession); userSchSessions.setSchSessionMap(schSessionMap); //add back to map userSessionMap.put(sessionId, userSchSessions); } SystemStatusDB.updateSystemStatus(hostSystem, userId); SystemDB.updateSystem(hostSystem); return hostSystem; } }