001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.j2ssh.authentication;
027:
028: import com.sshtools.j2ssh.io.ByteArrayWriter;
029: import com.sshtools.j2ssh.transport.SshMessage;
030: import com.sshtools.j2ssh.transport.publickey.SshPrivateKey;
031: import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
036: import java.io.IOException;
037:
038: import java.util.Properties;
039:
040: /**
041: *
042: *
043: * @author $author$
044: * @version $Revision: 1.21 $
045: */
046: public class PublicKeyAuthenticationClient extends
047: SshAuthenticationClient {
048: private static Log log = LogFactory
049: .getLog(PublicKeyAuthenticationClient.class);
050:
051: /** */
052: protected SshPrivateKey key;
053: private String privateKeyFile = null;
054: private String passphrase = null;
055:
056: /**
057: * Creates a new PublicKeyAuthenticationClient object.
058: */
059: public PublicKeyAuthenticationClient() {
060: }
061:
062: /**
063: *
064: *
065: * @param key
066: */
067: public void setKey(SshPrivateKey key) {
068: this .key = key;
069: }
070:
071: public void setKeyfile(String privateKeyFile) {
072: this .privateKeyFile = privateKeyFile;
073: }
074:
075: public String getKeyfile() {
076: return privateKeyFile;
077: }
078:
079: /**
080: *
081: */
082: public void reset() {
083: privateKeyFile = null;
084: passphrase = null;
085: }
086:
087: /**
088: *
089: *
090: * @return
091: */
092: public String getMethodName() {
093: return "publickey";
094: }
095:
096: /**
097: *
098: *
099: * @param authentication
100: * @param username
101: * @param serviceToStart
102: * @param key
103: *
104: * @return
105: *
106: * @throws IOException
107: */
108: public boolean acceptsKey(
109: AuthenticationProtocolClient authentication,
110: String username, String serviceToStart, SshPublicKey key)
111: throws IOException {
112: authentication.registerMessage(SshMsgUserAuthPKOK.class,
113: SshMsgUserAuthPKOK.SSH_MSG_USERAUTH_PK_OK);
114: log
115: .info("Determining if server can accept public key for authentication");
116:
117: ByteArrayWriter baw = new ByteArrayWriter();
118:
119: // Now prepare and send the message
120: baw.write(0);
121: baw.writeString(key.getAlgorithmName());
122: baw.writeBinaryString(key.getEncoded());
123:
124: SshMessage msg = new SshMsgUserAuthRequest(username,
125: serviceToStart, getMethodName(), baw.toByteArray());
126: authentication.sendMessage(msg);
127:
128: try {
129: msg = authentication
130: .readMessage(SshMsgUserAuthPKOK.SSH_MSG_USERAUTH_PK_OK);
131:
132: if (msg instanceof SshMsgUserAuthPKOK) {
133: return true;
134: } else {
135: throw new IOException(
136: "Unexpected message returned from readMessage");
137: }
138: } catch (TerminatedStateException ex) {
139: return false;
140: }
141: }
142:
143: /**
144: *
145: *
146: * @param authentication
147: * @param serviceToStart
148: *
149: * @throws IOException
150: * @throws TerminatedStateException
151: * @throws AuthenticationProtocolException
152: */
153: public void authenticate(
154: AuthenticationProtocolClient authentication,
155: String serviceToStart) throws IOException,
156: TerminatedStateException {
157: if ((getUsername() == null) || (key == null)) {
158: throw new AuthenticationProtocolException(
159: "You must supply a username and a key");
160: }
161:
162: ByteArrayWriter baw = new ByteArrayWriter();
163: log.info("Generating data to sign");
164:
165: SshPublicKey pub = key.getPublicKey();
166: log.info("Preparing public key authentication request");
167:
168: // Now prepare and send the message
169: baw.write(1);
170: baw.writeString(pub.getAlgorithmName());
171: baw.writeBinaryString(pub.getEncoded());
172:
173: // Create the signature data
174: ByteArrayWriter data = new ByteArrayWriter();
175: data.writeBinaryString(authentication.getSessionIdentifier());
176: data.write(SshMsgUserAuthRequest.SSH_MSG_USERAUTH_REQUEST);
177: data.writeString(getUsername());
178: data.writeString(serviceToStart);
179: data.writeString(getMethodName());
180: data.write(1);
181: data.writeString(pub.getAlgorithmName());
182: data.writeBinaryString(pub.getEncoded());
183:
184: // Generate the signature
185: baw
186: .writeBinaryString(key.generateSignature(data
187: .toByteArray()));
188:
189: SshMsgUserAuthRequest msg = new SshMsgUserAuthRequest(
190: getUsername(), serviceToStart, getMethodName(), baw
191: .toByteArray());
192: authentication.sendMessage(msg);
193: }
194:
195: /*public boolean showAuthenticationDialog(Component parent) {
196: SshPrivateKeyFile pkf = null;
197: if (privateKeyFile == null) {
198: JFileChooser chooser = new JFileChooser();
199: chooser.setFileHidingEnabled(false);
200: chooser.setDialogTitle("Select Private Key File For Authentication");
201: if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
202: privateKeyFile = chooser.getSelectedFile().getAbsolutePath();
203: } else {
204: return false;
205: }
206: }
207: FileInputStream in = null;
208: try {
209: pkf = SshPrivateKeyFile.parse(new File(privateKeyFile));
210: } catch (InvalidSshKeyException iske) {
211: JOptionPane.showMessageDialog(parent, iske.getMessage());
212: return false;
213: } catch (IOException ioe) {
214: JOptionPane.showMessageDialog(parent, ioe.getMessage());
215: }
216: // Now see if its passphrase protected
217: if (pkf.isPassphraseProtected()) {
218: if (passphrase == null) {
219: // Show the passphrase dialog
220: Window w = (Window) SwingUtilities.getAncestorOfClass(Window.class,
221: parent);
222: PassphraseDialog dialog = null;
223: if (w instanceof Frame) {
224: dialog = new PassphraseDialog((Frame) w);
225: } else if (w instanceof Dialog) {
226: dialog = new PassphraseDialog((Dialog) w);
227: } else {
228: dialog = new PassphraseDialog();
229: }
230: do {
231: dialog.setVisible(true);
232: if (dialog.isCancelled()) {
233: return false;
234: }
235: passphrase = new String(dialog.getPassphrase());
236: try {
237: key = pkf.toPrivateKey(passphrase);
238: break;
239: } catch (InvalidSshKeyException ihke) {
240: dialog.setMessage("Passphrase Invalid! Try again");
241: dialog.setMessageForeground(Color.red);
242: }
243: } while (true);
244: } else {
245: try {
246: key = pkf.toPrivateKey(passphrase);
247: } catch (InvalidSshKeyException ihke) {
248: return false;
249: }
250: }
251: } else {
252: try {
253: key = pkf.toPrivateKey(null);
254: } catch (InvalidSshKeyException ihke) {
255: JOptionPane.showMessageDialog(parent, ihke.getMessage());
256: return false;
257: }
258: }
259: return true;
260: }*/
261: public Properties getPersistableProperties() {
262: Properties properties = new Properties();
263:
264: if (getUsername() != null) {
265: properties.setProperty("Username", getUsername());
266: }
267:
268: if (privateKeyFile != null) {
269: properties.setProperty("PrivateKey", privateKeyFile);
270: }
271:
272: return properties;
273: }
274:
275: /**
276: *
277: *
278: * @param properties
279: */
280: public void setPersistableProperties(Properties properties) {
281: setUsername(properties.getProperty("Username"));
282:
283: if (properties.getProperty("PrivateKey") != null) {
284: privateKeyFile = properties.getProperty("PrivateKey");
285: }
286:
287: if (properties.getProperty("Passphrase") != null) {
288: passphrase = properties.getProperty("Passphrase");
289: }
290: }
291:
292: /**
293: *
294: *
295: * @return
296: */
297: public boolean canAuthenticate() {
298: return ((getUsername() != null) && (key != null));
299: }
300: }
|