View Javadoc

1   /*
2    * $HeadURL: $
3    * $Date: $
4    * $Revision: $
5    * $Author: $
6    * 
7    * Copyright (c) 2005 MindTree Consulting Ltd. 
8    * 
9    * This file is part of Insight.
10   * 
11   * Insight is free software: you can redistribute it and/or modify it under the 
12   * terms of the GNU General Public License as published by the Free Software 
13   * Foundation, either version 3 of the License, or (at your option) any later 
14   * version.
15   * 
16   * Insight is distributed in the hope that it will be useful, but 
17   * WITHOUT ANY WARRANTY; without even the implied warranty of 
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
19   * Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public License along with 
22   * Insight.  If not, see <http://www.gnu.org/licenses/>.
23   */
24  
25  package com.mindtree.techworks.insight.download;
26  
27  import java.awt.Component;
28  import java.io.File;
29  import java.text.MessageFormat;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.Map;
33  
34  import javax.swing.JOptionPane;
35  
36  import com.mindtree.techworks.insight.InsightConstants;
37  import com.mindtree.techworks.insight.gui.widgets.StatusBar;
38  import com.sshtools.j2ssh.transport.AbstractKnownHostsKeyVerification;
39  import com.sshtools.j2ssh.transport.InvalidHostFileException;
40  import com.sshtools.j2ssh.transport.TransportProtocolException;
41  import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
42  
43  
44  /**
45   * Tries to verify the remote host using the $HOME/.ssh/known_hosts file, else
46   * prompts the user for action.
47   * 
48   * @see com.sshtools.j2ssh.transport.AbstractKnownHostsKeyVerification
49   *      AbstractKnownHostsKeyVerification
50   * @author Bindul Bhowmik
51   * @version $Revision: 27 $ $Date: 2007-12-16 04:58:03 -0700 (Sun, 16 Dec 2007) $
52   */
53  public class SshKnownHostKeyVerification extends
54  		AbstractKnownHostsKeyVerification {
55  
56  	//
57  	// Instance variables
58  	//
59  
60  	/**
61  	 * The component to use as parent for the JOptions pane
62  	 */
63  	Component parentComponent;
64  
65  	//
66  	// Store of private keys for the session!
67  	//
68  
69  	/**
70  	 * This map stores all the hosts and their keys which are allowed for a
71  	 * particular session only. See Bugzilla Bug # 2971
72  	 */
73  	private static Map sessionAllowedHostStore = new HashMap();
74  
75  	//
76  	// Constructors
77  	//
78  
79  	/**
80  	 * Creates an instance of <code>SshKnownHostKeyVerification</code>
81  	 * 
82  	 * @throws InvalidHostFileException If the host file is invalid.
83  	 */
84  	public SshKnownHostKeyVerification () throws InvalidHostFileException {
85  
86  		super(new File(System.getProperty("user.home"), ".ssh" + File.separator
87  				+ "known_hosts").getAbsolutePath());
88  
89  		// Init - get the allowed hosts
90  		// Bugzilla Bug#2971 Storing the allowed hosts for the session. This
91  		// will prevent the permission dialog to pop up everytime a connection
92  		// is tried to a host which has been temporarily accepted.
93  		if (!sessionAllowedHostStore.isEmpty()) {
94  			synchronized (sessionAllowedHostStore) {
95  				for (Iterator hosts = sessionAllowedHostStore.keySet()
96  						.iterator(); hosts.hasNext();) {
97  					String host = (String) hosts.next();
98  					allowHost(host, (SshPublicKey) sessionAllowedHostStore
99  							.get(host), false);
100 				}
101 			}
102 		}
103 	}
104 
105 	/**
106 	 * Creates an instance of <code>SshKnownHostKeyVerification</code>
107 	 * 
108 	 * @param parentComponent The component to use as parent for the JOptions
109 	 *            pane
110 	 * @throws InvalidHostFileException If the host file is invalid.
111 	 */
112 	public SshKnownHostKeyVerification (Component parentComponent)
113 			throws InvalidHostFileException {
114 
115 		this();
116 		this.parentComponent = parentComponent;
117 	}
118 
119 	/**
120 	 * @see com.sshtools.j2ssh.transport.AbstractKnownHostsKeyVerification#onHostKeyMismatch(java.lang.String,
121 	 *      com.sshtools.j2ssh.transport.publickey.SshPublicKey,
122 	 *      com.sshtools.j2ssh.transport.publickey.SshPublicKey)
123 	 */
124 	public void onHostKeyMismatch (String host, SshPublicKey allowedHostKey,
125 			SshPublicKey actualHostKey) throws TransportProtocolException {
126 
127 		// Bugzilla Bug#2972, Externalized strings
128 		StringBuffer message = new StringBuffer();
129 		message.append(MessageFormat.format(InsightConstants
130 				.getLiteral("SSH_KEY_MISMATCH_MSG_FORMAT"), new String [] {
131 				host, actualHostKey.getFingerprint(),
132 				allowedHostKey.getFingerprint() }));
133 		getResponse(host, allowedHostKey, message);
134 
135 	}
136 
137 	/**
138 	 * @see com.sshtools.j2ssh.transport.AbstractKnownHostsKeyVerification#onUnknownHost(java.lang.String,
139 	 *      com.sshtools.j2ssh.transport.publickey.SshPublicKey)
140 	 */
141 	public void onUnknownHost (String host, SshPublicKey key)
142 			throws TransportProtocolException {
143 
144 		// Bugzilla Bug#2972, Externalized strings
145 		StringBuffer message = new StringBuffer();
146 		message.append(MessageFormat.format(InsightConstants
147 				.getLiteral("SSH_KEY_UNKNOWN_HOST_MSG_FORMAT"), new String [] {
148 				host, key.getFingerprint() }));
149 		getResponse(host, key, message);
150 	}
151 
152 	//
153 	// Util methods
154 	//
155 
156 	/**
157 	 * @param host
158 	 * @param pk
159 	 * @param message
160 	 * @throws TransportProtocolException
161 	 * @throws InvalidHostFileException
162 	 */
163 	private void getResponse (String host, SshPublicKey pk, StringBuffer message)
164 			throws TransportProtocolException {
165 
166 		// Bugzilla Bug#2972: Externalized all strings
167 		String permYes = InsightConstants.getLiteral("SSH_KEY_ALLOW_YES");
168 		String permNo = InsightConstants.getLiteral("SSH_KEY_ALLOW_NO");
169 		String permAlways = InsightConstants.getLiteral("SSH_KEY_ALLOW_ALWAYS");
170 
171 		Object [] options = (isHostFileWriteable() ? new String [] { permYes,
172 				permNo, permAlways } : new String [] { permYes, permNo });
173 
174 		if (!isHostFileWriteable()) {
175 			message.append("\n");
176 			message.append(InsightConstants
177 					.getLiteral("SSH_KEY_HOST_FILE_NOT_WRITABLE"));
178 		}
179 
180 		message.append("\n\n");
181 		message.append(InsightConstants
182 				.getLiteral("SSH_KEY_ALLOW_HOST_QUESTION"));
183 
184 		// Changed the default option of the dialog box to : No.
185 		// Done with fix for Bugzilla Issue # 2971
186 		String response = (String) JOptionPane.showInputDialog(parentComponent,
187 				message.toString(), InsightConstants
188 						.getLiteral("SSH_KEY_DIALOG_TITLE"),
189 				JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
190 
191 		if (null == response || response.equalsIgnoreCase(permNo)) {
192 			// Clear the status bar for "Connecting to remote host" message.
193 			// Not needed for a response "YES" because it gets cleared when
194 			// the JFileChooser gets successfully created.
195 			StatusBar.getInstance().clearDisplay(1);
196 			JOptionPane.showMessageDialog(parentComponent, InsightConstants
197 					.getLiteral("SSH_KEY_CANNOT_CONTINUE"), InsightConstants
198 					.getLiteral("ERROR"), JOptionPane.ERROR_MESSAGE);
199 			throw new TransportProtocolException("Host not allowed!");
200 		} else if (response.equalsIgnoreCase(permYes)) {
201 			allowHost(host, pk, false);
202 			// Bugzilla Bug#2971 Storing the allowed hosts for the session. This
203 			// will prevent the permission dialog to pop up everytime a
204 			// connection
205 			// is tried to a host which has been temporarily accepted.
206 			synchronized (sessionAllowedHostStore) {
207 				sessionAllowedHostStore.put(host, pk);
208 			}
209 		} else if (response.equalsIgnoreCase(permAlways)) {
210 			if (isHostFileWriteable()) {
211 				allowHost(host, pk, true);
212 			} else {
213 				allowHost(host, pk, false);
214 			}
215 
216 		}
217 	}
218 
219 }