001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2023 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.q2.ssh; 020 021import org.apache.sshd.common.Factory; 022import org.apache.sshd.common.SshConstants; 023import org.apache.sshd.server.*; 024import org.apache.sshd.server.channel.ChannelSession; 025import org.apache.sshd.server.command.Command; 026import org.apache.sshd.server.command.CommandFactory; 027import org.apache.sshd.server.session.ServerSession; 028import org.apache.sshd.server.session.ServerSessionAware; 029import org.apache.sshd.server.shell.ShellFactory; 030import org.jpos.q2.CLI; 031import org.jpos.q2.Q2; 032import org.jpos.util.Log; 033 034import java.io.IOException; 035import java.io.InputStream; 036import java.io.OutputStream; 037 038public class CliShellFactory implements Factory<Command>, CommandFactory, ShellFactory { 039 Q2 q2; 040 String[] prefixes; 041 042 public CliShellFactory(Q2 q2, String[] prefixes) { 043 this.q2 = q2; 044 this.prefixes = prefixes; 045 } 046 047 public Command create() { 048 return new JPosCLIShell(null); 049 } 050 051 @Override 052 public Command createCommand(ChannelSession channel, String command) { 053 return new JPosCLIShell(command); 054 } 055 056 @Override 057 public Command createShell(ChannelSession channel) { return new JPosCLIShell(null); } 058 059 public class JPosCLIShell implements Command, ServerSessionAware { 060 InputStream in; 061 OutputStream out; 062 OutputStream err; 063 SshCLI cli = null; 064 ServerSession serverSession; 065 String args; 066 067 public void setInputStream(InputStream in) { 068 this.in = in; 069 } 070 071 public void setOutputStream(OutputStream out) { 072 this.out = out; 073 } 074 075 public void setErrorStream(OutputStream err) { 076 this.err = err; 077 } 078 079 public void setExitCallback(ExitCallback exitCallback) { 080 } 081 082 public JPosCLIShell(String args) { 083 this.args = args; 084 } 085 086 public void setSession(ServerSession serverSession) { 087 this.serverSession = serverSession; 088 } 089 090 public void start(ChannelSession channel, Environment env) throws IOException { 091 cli = new SshCLI(q2, args != null ? null : in, out, args, args == null); 092 try { 093 cli.setServerSession(serverSession); 094 cli.start(); 095 } catch (Exception e) { 096 throw new IOException("Could not start", e); 097 } 098 } 099 100 public void destroy(ChannelSession channel) { 101 if (cli != null) { 102 cli.stop(); 103 } 104 } 105 } 106 107 public class SshCLI extends CLI { 108 ServerSession serverSession = null; 109 110 public SshCLI(Q2 q2, InputStream in, OutputStream out, String line, boolean keepRunning) throws IOException { 111 super(q2, in, out, line, keepRunning, true); 112 } 113 114 protected boolean running() { 115 return !ctx.isStopped(); 116 } 117 118 protected void markStopped() { 119 ctx.setStopped(true); 120 } 121 122 protected void markStarted() { 123 ctx.setStopped(false); 124 } 125 126 protected String[] getCompletionPrefixes() { 127 return prefixes; 128 } 129 130 protected void handleExit() { 131 if (serverSession != null) { 132 try { 133 serverSession.disconnect(SshConstants.SSH2_DISCONNECT_BY_APPLICATION, ""); 134 } catch (IOException e) { 135 Log.getLog(Q2.LOGGER_NAME, "sshd").error(e); 136 } 137 } 138 } 139 140 public void setServerSession(ServerSession serverSession) { 141 this.serverSession = serverSession; 142 } 143 } 144}