/*
* SSHTools - Java SSH2 API
*
* Copyright (C) 2002-2003 Lee David Painter and Contributors.
*
* Contributions made by:
*
* Brett Smith
* Richard Pernavas
* Erwin Bolwidt
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sshtools.j2ssh.authentication;
import com.sshtools.j2ssh.io.ByteArrayWriter;
import com.sshtools.j2ssh.transport.SshMessage;
import com.sshtools.j2ssh.transport.publickey.SshPrivateKey;
import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.util.Properties;
/**
*
*
* @author $author$
* @version $Revision: 1.21 $
*/
public class PublicKeyAuthenticationClient extends SshAuthenticationClient {
private static Log log = LogFactory.getLog(PublicKeyAuthenticationClient.class);
/** */
protected SshPrivateKey key;
private String privateKeyFile = null;
private String passphrase = null;
/**
* Creates a new PublicKeyAuthenticationClient object.
*/
public PublicKeyAuthenticationClient() {
}
/**
*
*
* @param key
*/
public void setKey(SshPrivateKey key) {
this.key = key;
}
public void setKeyfile(String privateKeyFile) {
this.privateKeyFile = privateKeyFile;
}
public String getKeyfile() {
return privateKeyFile;
}
/**
*
*/
public void reset() {
privateKeyFile = null;
passphrase = null;
}
/**
*
*
* @return
*/
public String getMethodName() {
return "publickey";
}
/**
*
*
* @param authentication
* @param username
* @param serviceToStart
* @param key
*
* @return
*
* @throws IOException
*/
public boolean acceptsKey(AuthenticationProtocolClient authentication,
String username, String serviceToStart, SshPublicKey key)
throws IOException {
authentication.registerMessage(SshMsgUserAuthPKOK.class,
SshMsgUserAuthPKOK.SSH_MSG_USERAUTH_PK_OK);
log.info(
"Determining if server can accept public key for authentication");
ByteArrayWriter baw = new ByteArrayWriter();
// Now prepare and send the message
baw.write(0);
baw.writeString(key.getAlgorithmName());
baw.writeBinaryString(key.getEncoded());
SshMessage msg = new SshMsgUserAuthRequest(username, serviceToStart,
getMethodName(), baw.toByteArray());
authentication.sendMessage(msg);
try {
msg = authentication.readMessage(SshMsgUserAuthPKOK.SSH_MSG_USERAUTH_PK_OK);
if (msg instanceof SshMsgUserAuthPKOK) {
return true;
} else {
throw new IOException(
"Unexpected message returned from readMessage");
}
} catch (TerminatedStateException ex) {
return false;
}
}
/**
*
*
* @param authentication
* @param serviceToStart
*
* @throws IOException
* @throws TerminatedStateException
* @throws AuthenticationProtocolException
*/
public void authenticate(AuthenticationProtocolClient authentication,
String serviceToStart) throws IOException, TerminatedStateException {
if ((getUsername() == null) || (key == null)) {
throw new AuthenticationProtocolException(
"You must supply a username and a key");
}
ByteArrayWriter baw = new ByteArrayWriter();
log.info("Generating data to sign");
SshPublicKey pub = key.getPublicKey();
log.info("Preparing public key authentication request");
// Now prepare and send the message
baw.write(1);
baw.writeString(pub.getAlgorithmName());
baw.writeBinaryString(pub.getEncoded());
// Create the signature data
ByteArrayWriter data = new ByteArrayWriter();
data.writeBinaryString(authentication.getSessionIdentifier());
data.write(SshMsgUserAuthRequest.SSH_MSG_USERAUTH_REQUEST);
data.writeString(getUsername());
data.writeString(serviceToStart);
data.writeString(getMethodName());
data.write(1);
data.writeString(pub.getAlgorithmName());
data.writeBinaryString(pub.getEncoded());
// Generate the signature
baw.writeBinaryString(key.generateSignature(data.toByteArray()));
SshMsgUserAuthRequest msg = new SshMsgUserAuthRequest(getUsername(),
serviceToStart, getMethodName(), baw.toByteArray());
authentication.sendMessage(msg);
}
/*public boolean showAuthenticationDialog(Component parent) {
SshPrivateKeyFile pkf = null;
if (privateKeyFile == null) {
JFileChooser chooser = new JFileChooser();
chooser.setFileHidingEnabled(false);
chooser.setDialogTitle("Select Private Key File For Authentication");
if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
privateKeyFile = chooser.getSelectedFile().getAbsolutePath();
} else {
return false;
}
}
FileInputStream in = null;
try {
pkf = SshPrivateKeyFile.parse(new File(privateKeyFile));
} catch (InvalidSshKeyException iske) {
JOptionPane.showMessageDialog(parent, iske.getMessage());
return false;
} catch (IOException ioe) {
JOptionPane.showMessageDialog(parent, ioe.getMessage());
}
// Now see if its passphrase protected
if (pkf.isPassphraseProtected()) {
if (passphrase == null) {
// Show the passphrase dialog
Window w = (Window) SwingUtilities.getAncestorOfClass(Window.class,
parent);
PassphraseDialog dialog = null;
if (w instanceof Frame) {
dialog = new PassphraseDialog((Frame) w);
} else if (w instanceof Dialog) {
dialog = new PassphraseDialog((Dialog) w);
} else {
dialog = new PassphraseDialog();
}
do {
dialog.setVisible(true);
if (dialog.isCancelled()) {
return false;
}
passphrase = new String(dialog.getPassphrase());
try {
key = pkf.toPrivateKey(passphrase);
break;
} catch (InvalidSshKeyException ihke) {
dialog.setMessage("Passphrase Invalid! Try again");
dialog.setMessageForeground(Color.red);
}
} while (true);
} else {
try {
key = pkf.toPrivateKey(passphrase);
} catch (InvalidSshKeyException ihke) {
return false;
}
}
} else {
try {
key = pkf.toPrivateKey(null);
} catch (InvalidSshKeyException ihke) {
JOptionPane.showMessageDialog(parent, ihke.getMessage());
return false;
}
}
return true;
}*/
public Properties getPersistableProperties() {
Properties properties = new Properties();
if (getUsername() != null) {
properties.setProperty("Username", getUsername());
}
if (privateKeyFile != null) {
properties.setProperty("PrivateKey", privateKeyFile);
}
return properties;
}
/**
*
*
* @param properties
*/
public void setPersistableProperties(Properties properties) {
setUsername(properties.getProperty("Username"));
if (properties.getProperty("PrivateKey") != null) {
privateKeyFile = properties.getProperty("PrivateKey");
}
if (properties.getProperty("Passphrase") != null) {
passphrase = properties.getProperty("Passphrase");
}
}
/**
*
*
* @return
*/
public boolean canAuthenticate() {
return ((getUsername() != null) && (key != null));
}
}