0
|
1 // Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC.
|
|
2 // All rights reserved.
|
|
3 //
|
|
4 //-------------------------------------------------------------------------
|
|
5 // This file is part of the TightVNC software. Please visit our Web site:
|
|
6 //
|
|
7 // http://www.tightvnc.com/
|
|
8 //
|
|
9 // This program is free software; you can redistribute it and/or modify
|
|
10 // it under the terms of the GNU General Public License as published by
|
|
11 // the Free Software Foundation; either version 2 of the License, or
|
|
12 // (at your option) any later version.
|
|
13 //
|
|
14 // This program is distributed in the hope that it will be useful,
|
|
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 // GNU General Public License for more details.
|
|
18 //
|
|
19 // You should have received a copy of the GNU General Public License along
|
|
20 // with this program; if not, write to the Free Software Foundation, Inc.,
|
|
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
22 //-------------------------------------------------------------------------
|
|
23 //
|
|
24
|
|
25 package com.glavsoft.viewer.swing.ssh;
|
|
26
|
|
27 import com.glavsoft.utils.Strings;
|
|
28 import com.glavsoft.viewer.CancelConnectionException;
|
|
29 import com.glavsoft.viewer.swing.ConnectionParams;
|
|
30 import com.glavsoft.viewer.swing.Utils;
|
|
31 import com.jcraft.jsch.*;
|
|
32
|
|
33 import javax.swing.*;
|
|
34 import java.io.ByteArrayInputStream;
|
|
35 import java.io.ByteArrayOutputStream;
|
|
36 import java.io.IOException;
|
|
37 import java.io.InputStream;
|
|
38 import java.lang.reflect.InvocationTargetException;
|
|
39 import java.util.logging.Logger;
|
|
40 import java.util.prefs.Preferences;
|
|
41
|
|
42 public class SshConnectionManager implements SshKnownHostsManager {
|
|
43
|
|
44 public static final String SSH_NODE = "com/glavsoft/viewer/ssh";
|
|
45 public static final String KNOWN_HOSTS = "known_hosts";
|
|
46 private Session session;
|
|
47 private String errorMessage = "";
|
|
48 private final JFrame parentWindow;
|
|
49 private JSch jsch;
|
|
50
|
|
51 public SshConnectionManager(JFrame parentWindow) {
|
|
52 this.parentWindow = parentWindow;
|
|
53 }
|
|
54
|
|
55 public int connect(ConnectionParams connectionParams) throws CancelConnectionException {
|
|
56 if (Strings.isTrimmedEmpty(connectionParams.sshUserName)) {
|
|
57 connectionParams.sshUserName = getInteractivelySshUserName();
|
|
58 }
|
|
59
|
|
60 if (session != null && session.isConnected()) {
|
|
61 session.disconnect();
|
|
62 }
|
|
63 jsch = new JSch();
|
|
64 try {
|
|
65 jsch.setKnownHosts(getKnownHostsStream());
|
|
66 } catch (JSchException e) {
|
|
67 Logger.getLogger(this.getClass().getName()).severe("Cannot set JSCH known hosts: " + e.getMessage());
|
|
68 }
|
|
69 int port = 0;
|
|
70 try {
|
|
71 session = jsch.getSession(
|
|
72 connectionParams.sshUserName, connectionParams.sshHostName, connectionParams.getSshPortNumber());
|
|
73 UserInfo ui = new SwingSshUserInfo(parentWindow);
|
|
74 session.setUserInfo(ui);
|
|
75 session.connect();
|
|
76 sync();
|
|
77 port = session.setPortForwardingL(0, connectionParams.hostName, connectionParams.getPortNumber());
|
|
78 } catch (JSchException e) {
|
|
79 session.disconnect();
|
|
80 errorMessage = e.getMessage();
|
|
81 }
|
|
82 return port;
|
|
83 }
|
|
84
|
|
85 private String getInteractivelySshUserName() throws CancelConnectionException {
|
|
86 class Pair {
|
|
87 int intRes;
|
|
88 String stringRes;
|
|
89 }
|
|
90 final Pair result = new Pair();
|
|
91 try {
|
|
92 SwingUtilities.invokeAndWait(new Runnable() {
|
|
93 @Override
|
|
94 public void run() {
|
|
95 final JOptionPane pane = new JOptionPane("Please enter the user name for SSH connection:",
|
|
96 JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
|
|
97 pane.setWantsInput(true);
|
|
98 final JDialog dialog = pane.createDialog(parentWindow, "SSH User Name");
|
|
99 Utils.decorateDialog(dialog);
|
|
100 dialog.setVisible(true);
|
|
101 result.stringRes = pane.getInputValue() != null ? (String) pane.getInputValue() : "";
|
|
102 result.intRes = pane.getValue() != null ? (Integer) pane.getValue() : JOptionPane.OK_CANCEL_OPTION;
|
|
103 dialog.dispose();
|
|
104 }
|
|
105 });
|
|
106 } catch (InterruptedException e) {
|
|
107 Logger.getLogger(getClass().getName()).severe(e.getMessage());
|
|
108 } catch (InvocationTargetException e) {
|
|
109 Logger.getLogger(getClass().getName()).severe(e.getMessage());
|
|
110 }
|
|
111 if (result.intRes != JOptionPane.OK_OPTION) {
|
|
112 throw new CancelConnectionException("No Ssh User Name entered");
|
|
113 }
|
|
114 return result.stringRes;
|
|
115 }
|
|
116
|
|
117 public boolean isConnected() {
|
|
118 return session.isConnected();
|
|
119 }
|
|
120
|
|
121 public String getErrorMessage() {
|
|
122 return errorMessage;
|
|
123 }
|
|
124
|
|
125 private InputStream getKnownHostsStream() {
|
|
126 Preferences sshNode = Preferences.userRoot().node(SSH_NODE);
|
|
127 return new ByteArrayInputStream(sshNode.getByteArray(KNOWN_HOSTS, new byte[0]));
|
|
128 }
|
|
129
|
|
130 @Override
|
|
131 public void sync() {
|
|
132 ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
133 HostKeyRepository repository = jsch.getHostKeyRepository();
|
|
134 try {
|
|
135 HostKey[] hostKey = repository.getHostKey();
|
|
136 if (null == hostKey) return;
|
|
137 for (HostKey hk : hostKey) {
|
|
138 String host = hk.getHost();
|
|
139 String type = hk.getType();
|
|
140 if (type.equals("UNKNOWN")) {
|
|
141 write(out, host);
|
|
142 write(out, "\n");
|
|
143 continue;
|
|
144 }
|
|
145 write(out, host);
|
|
146 write(out, " ");
|
|
147 write(out, type);
|
|
148 write(out, " ");
|
|
149 write(out, hk.getKey());
|
|
150 write(out, "\n");
|
|
151 }
|
|
152 } catch (IOException e) {
|
|
153 Logger.getLogger(this.getClass().getName()).severe("Cannot sync JSCH known hosts: " + e.getMessage());
|
|
154 }
|
|
155 Preferences sshNode = Preferences.userRoot().node(SSH_NODE);
|
|
156 sshNode.putByteArray(KNOWN_HOSTS, out.toByteArray());
|
|
157 }
|
|
158
|
|
159 private void write(ByteArrayOutputStream out, String str) throws IOException {
|
|
160 try {
|
|
161 out.write(str.getBytes("UTF-8"));
|
|
162 } catch (java.io.UnsupportedEncodingException e) {
|
|
163 out.write(str.getBytes());
|
|
164 }
|
|
165 }
|
|
166
|
|
167 } |