/*
* 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.common.configuration;
import com.sshtools.common.util.PropertyUtil;
import com.sshtools.j2ssh.authentication.SshAuthenticationClient;
import com.sshtools.j2ssh.authentication.SshAuthenticationClientFactory;
import com.sshtools.j2ssh.configuration.SshConnectionProperties;
import com.sshtools.j2ssh.forwarding.ForwardingConfiguration;
import com.sshtools.j2ssh.io.IOUtil;
import com.sshtools.j2ssh.transport.AlgorithmNotSupportedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
*
*
* @author $author$
* @version $Revision: 1.22 $
*/
public class SshToolsConnectionProfile extends SshConnectionProperties {
private static Log log = LogFactory.getLog(SshToolsConnectionProfile.class);
/** */
public static final int DO_NOTHING = 1;
/** */
public static final int START_SHELL = 2;
/** */
public static final int EXECUTE_COMMANDS = 3;
private Map applicationProperties = new HashMap();
private Map sftpFavorites = new HashMap();
private Map authMethods = new HashMap();
private boolean requestPseudoTerminal = true;
private boolean disconnectOnSessionClose = true;
private int onceAuthenticated = START_SHELL;
private String executeCommands = "";
private boolean allowAgentForwarding = false;
// SAX Processing variables
private String currentElement = null;
private String currentAuthentication = null;
private Properties currentProperties = null;
private String connectionFile;
/**
* Creates a new SshToolsConnectionProfile object.
*/
public SshToolsConnectionProfile() {
}
/**
*
*
* @return
*/
public Map getAuthenticationMethods() {
return authMethods;
}
/**
*
*
* @return
*/
public boolean requiresPseudoTerminal() {
return requestPseudoTerminal;
}
/**
*
*
* @return
*/
public boolean disconnectOnSessionClose() {
return disconnectOnSessionClose;
}
/**
*
*
* @param requiresPseudoTerminal
*/
public void setRequiresPseudoTerminal(boolean requiresPseudoTerminal) {
this.requestPseudoTerminal = requiresPseudoTerminal;
}
/**
*
*
* @param disconnectOnSessionClose
*/
public void setDisconnectOnSessionClose(boolean disconnectOnSessionClose) {
this.disconnectOnSessionClose = disconnectOnSessionClose;
}
/**
*
*/
public void clearAuthenticationCache() {
SshAuthenticationClient auth;
Properties properties;
for (Iterator it = authMethods.values().iterator(); it.hasNext();) {
auth = (SshAuthenticationClient) it.next();
properties = auth.getPersistableProperties();
auth.reset();
auth.setPersistableProperties(properties);
}
}
/**
*
*
* @param onceAuthenticated
*/
public void setOnceAuthenticatedCommand(int onceAuthenticated) {
this.onceAuthenticated = onceAuthenticated;
}
/**
*
*
* @return
*/
public int getOnceAuthenticatedCommand() {
return onceAuthenticated;
}
/**
*
*
* @param executeCommands
*/
public void setCommandsToExecute(String executeCommands) {
this.executeCommands = executeCommands;
}
/**
*
*
* @return
*/
public String getCommandsToExecute() {
return executeCommands;
}
/**
*
*
* @param name
* @param defaultValue
*
* @return
*/
public String getApplicationProperty(String name, String defaultValue) {
String value = (String) applicationProperties.get(name);
if (value == null) {
return defaultValue;
} else {
return value;
}
}
/**
*
*
* @param name
* @param defaultValue
*
* @return
*/
public Map getSftpFavorites() {
return sftpFavorites;
}
/**
*
*
* @param name
* @param defaultValue
*
* @return
*/
public void setSftpFavorite(String name, String value) {
sftpFavorites.put(name, value);
}
/**
*
*
* @param name
* @param defaultValue
*
* @return
*/
public int getApplicationPropertyInt(String name, int defaultValue) {
try {
return Integer.parseInt(getApplicationProperty(name,
String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
/**
*
*
* @param name
* @param defaultValue
*
* @return
*/
public boolean getApplicationPropertyBoolean(String name,
boolean defaultValue) {
try {
return new Boolean(getApplicationProperty(name,
String.valueOf(defaultValue))).booleanValue();
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
/**
*
*
* @param name
* @param defaultColor
*
* @return
*/
public Color getApplicationPropertyColor(String name, Color defaultColor) {
return PropertyUtil.stringToColor(getApplicationProperty(name,
PropertyUtil.colorToString(defaultColor)));
}
/**
*
*
* @param name
* @param value
*/
public void setApplicationProperty(String name, String value) {
applicationProperties.put(name, value);
}
/**
*
*
* @param name
* @param value
*/
public void setApplicationProperty(String name, int value) {
applicationProperties.put(name, String.valueOf(value));
}
/**
*
*
* @param name
* @param value
*/
public void setApplicationProperty(String name, boolean value) {
applicationProperties.put(name, String.valueOf(value));
}
/**
*
*
* @param name
* @param value
*/
public void setApplicationProperty(String name, Color value) {
applicationProperties.put(name, PropertyUtil.colorToString(value));
}
/**
*
*
* @param method
*/
public void addAuthenticationMethod(SshAuthenticationClient method) {
if (method != null) {
if (!authMethods.containsKey(method.getMethodName())) {
authMethods.put(method.getMethodName(), method);
}
}
}
/**
*
*
* @param config
*/
public void addLocalForwarding(ForwardingConfiguration config) {
if (config != null) {
localForwardings.put(config.getName(), config);
}
}
/**
*
*
* @param config
*/
public void addRemoteForwarding(ForwardingConfiguration config) {
if (config != null) {
remoteForwardings.put(config.getName(), config);
}
}
/**
*
*
* @return
*/
public boolean getAllowAgentForwarding() {
return allowAgentForwarding;
}
/**
*
*
* @param allowAgentForwarding
*/
public void setAllowAgentForwarding(boolean allowAgentForwarding) {
this.allowAgentForwarding = allowAgentForwarding;
}
/**
*
*
* @param name
*/
public void removeLocalForwarding(String name) {
localForwardings.remove(name);
}
/**
*
*
* @param name
*/
public void removeRemoteForwarding(String name) {
remoteForwardings.remove(name);
}
/**
*
*
* @param file
*
* @throws InvalidProfileFileException
*/
public void open(String file) throws InvalidProfileFileException {
connectionFile = file;
open(new File(file));
}
/**
*
*
* @param file
*
* @throws InvalidProfileFileException
*/
public void open(File file) throws InvalidProfileFileException {
InputStream in = null;
try {
in = new FileInputStream(file);
open(in);
} catch (FileNotFoundException fnfe) {
throw new InvalidProfileFileException(file + " was not found!");
} finally {
IOUtil.closeStream(in);
}
}
/**
*
*
* @param in
*
* @throws InvalidProfileFileException
*/
public void open(InputStream in) throws InvalidProfileFileException {
try {
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxFactory.newSAXParser();
XMLHandler handler = new XMLHandler();
saxParser.parse(in, handler);
handler = null;
// in.close();
} catch (IOException ioe) {
throw new InvalidProfileFileException("IO error. " +
ioe.getMessage());
} catch (SAXException sax) {
throw new InvalidProfileFileException("SAX Error: " +
sax.getMessage());
} catch (ParserConfigurationException pce) {
throw new InvalidProfileFileException("SAX Parser Error: " +
pce.getMessage());
} finally {
}
}
/**
*
*
* @param method
*/
public void removeAuthenticaitonMethod(String method) {
authMethods.remove(method);
}
public void removeAuthenticationMethods() {
authMethods.clear();
}
/**
*
*
* @param file
*
* @throws InvalidProfileFileException
*/
public void save(String file) throws InvalidProfileFileException {
try {
File f = new File(file);
FileOutputStream out = new FileOutputStream(f);
out.write(toString().getBytes());
out.close();
} catch (FileNotFoundException fnfe) {
throw new InvalidProfileFileException(file + " was not found!");
} catch (IOException ioe) {
throw new InvalidProfileFileException("io error on " + file);
} finally {
}
}
public void save() throws InvalidProfileFileException {
save(connectionFile);
}
/**
*
*
* @return
*/
public String toString() {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
xml += ("<SshToolsConnectionProfile Hostname=\"" + host + "\" Port=\"" +
String.valueOf(port) + "\" Username=\"" + username + "\"" +
" Provider=\"" + getTransportProviderString() + "\">");
xml += (" <PreferedCipher Client2Server=\"" + prefEncryption +
"\" Server2Client=\"" + prefDecryption + "\"/>\n");
xml += (" <PreferedMac Client2Server=\"" + prefRecvMac +
"\" Server2Client=\"" + prefSendMac + "\"/>\n");
xml += (" <PreferedCompression Client2Server=\"" + prefRecvComp +
"\" Server2Client=\"" + prefSendComp + "\"/>\n");
xml += (" <PreferedPublicKey Name=\"" + prefPK + "\"/>\n");
xml += (" <PreferedKeyExchange Name=\"" + prefKex + "\"/>\n");
xml += (" <OnceAuthenticated value=\"" +
String.valueOf(onceAuthenticated) + "\"/>\n");
if (onceAuthenticated == EXECUTE_COMMANDS) {
xml += (" <ExecuteCommands>" + executeCommands +
"</ExecuteCommands>\n");
}
Iterator it = authMethods.entrySet().iterator();
Map.Entry entry;
Properties properties;
while (it.hasNext()) {
entry = (Map.Entry) it.next();
xml += (" <AuthenticationMethod Name=\"" + entry.getKey() +
"\">\n");
SshAuthenticationClient auth = (SshAuthenticationClient) entry.getValue();
properties = auth.getPersistableProperties();
Iterator it2 = properties.entrySet().iterator();
while (it2.hasNext()) {
entry = (Map.Entry) it2.next();
xml += (" <AuthenticationProperty Name=\"" +
entry.getKey() + "\" Value=\"" + entry.getValue() + "\"/>\n");
}
xml += " </AuthenticationMethod>\n";
}
it = applicationProperties.entrySet().iterator();
while (it.hasNext()) {
entry = (Map.Entry) it.next();
xml += (" <ApplicationProperty Name=\"" + entry.getKey() +
"\" Value=\"" + entry.getValue() + "\"/>\n");
}
// Write the SFTP Favorite entries to file
it = sftpFavorites.entrySet().iterator();
while (it.hasNext()) {
entry = (Map.Entry) it.next();
xml += (" <SftpFavorite Name=\"" + entry.getKey() +
"\" Value=\"" + entry.getValue() + "\"/>\n");
}
it = localForwardings.values().iterator();
xml += (" <ForwardingAutoStart value=\"" +
String.valueOf(forwardingAutoStart) + "\"/>\n");
while (it.hasNext()) {
ForwardingConfiguration config = (ForwardingConfiguration) it.next();
xml += (" <LocalPortForwarding Name=\"" + config.getName() +
"\" AddressToBind=\"" + config.getAddressToBind() +
"\" PortToBind=\"" + String.valueOf(config.getPortToBind()) +
"\" AddressToConnect=\"" + config.getHostToConnect() +
"\" PortToConnect=\"" + String.valueOf(config.getPortToConnect()) +
"\"/>\n");
}
it = remoteForwardings.values().iterator();
while (it.hasNext()) {
ForwardingConfiguration config = (ForwardingConfiguration) it.next();
xml += (" <RemotePortForwarding Name=\"" + config.getName() +
"\" AddressToBind=\"" + config.getAddressToBind() +
"\" PortToBind=\"" + String.valueOf(config.getPortToBind()) +
"\" AddressToConnect=\"" + config.getHostToConnect() +
"\" PortToConnect=\"" + String.valueOf(config.getPortToConnect()) +
"\"/>\n");
}
xml += "</SshToolsConnectionProfile>";
return xml;
}
private class XMLHandler extends DefaultHandler {
boolean commandsToExecute = false;
public void startElement(String uri, String localName, String qname,
Attributes attrs) throws SAXException {
if (currentElement == null) {
if (!qname.equals("SshToolsConnectionProfile")) {
throw new SAXException("Unexpected root element " + qname);
}
host = attrs.getValue("Hostname");
username = attrs.getValue("Username");
String p = attrs.getValue("Port");
if (p == null) {
port = 22;
} else {
port = Integer.parseInt(p);
}
setTransportProviderString(attrs.getValue("Provider"));
if ((host == null) || (username == null)) {
throw new SAXException(
"Required attribute for element <SshToolsConnectionProfile> missing");
}
} else {
String c2s;
String s2c;
if (currentElement.equals("SshToolsConnectionProfile")) {
if (qname.equals("PreferedCipher")) {
c2s = attrs.getValue("Client2Server");
s2c = attrs.getValue("Server2Client");
if ((c2s == null) || (s2c == null)) {
throw new SAXException(
"Required attribute missing for <PreferedCipher> element");
}
prefEncryption = c2s;
prefDecryption = s2c;
} else if (qname.equals("OnceAuthenticated")) {
if (attrs.getValue("value") != null) {
try {
onceAuthenticated = Integer.parseInt(attrs.getValue(
"value"));
} catch (NumberFormatException ex) {
onceAuthenticated = START_SHELL;
}
}
} else if (qname.equals("ExecuteCommands")) {
commandsToExecute = true;
executeCommands = "";
} else if (qname.equals("PreferedCompression")) {
c2s = attrs.getValue("Client2Server");
s2c = attrs.getValue("Server2Client");
if ((c2s == null) || (s2c == null)) {
throw new SAXException(
"Required attribute missing for <PreferedCompression> element");
}
prefRecvComp = c2s;
prefSendComp = s2c;
} else if (qname.equals("PreferedMac")) {
c2s = attrs.getValue("Client2Server");
s2c = attrs.getValue("Server2Client");
if ((c2s == null) || (s2c == null)) {
throw new SAXException(
"Required attribute missing for <PreferedMac> element");
}
prefRecvMac = c2s;
prefSendMac = s2c;
} else if (qname.equals("PreferedPublicKey")) {
String name = attrs.getValue("Name");
if (name == null) {
throw new SAXException(
"Required attribute missing for <PreferedPublickey> element");
}
prefPK = name;
} else if (qname.equals("PreferedKeyExchange")) {
String name = attrs.getValue("Name");
if (name == null) {
throw new SAXException(
"Required attribute missing for <PreferedKeyExchange> element");
}
prefPK = name;
} else if (qname.equals("ApplicationProperty")) {
String name = attrs.getValue("Name");
String value = attrs.getValue("Value");
if ((name == null) || (value == null)) {
throw new SAXException(
"Required attributes missing for <ApplicationProperty> element");
}
applicationProperties.put(name, value);
} else if (qname.equals("SftpFavorite")) {
String name = attrs.getValue("Name");
String value = attrs.getValue("Value");
if ((name == null) || (value == null)) {
throw new SAXException(
"Required attributes missing for <SftpFavorite> element");
}
sftpFavorites.put(name, value);
} else if (qname.equals("AuthenticationMethod")) {
currentAuthentication = attrs.getValue("Name");
currentProperties = new Properties();
if (currentAuthentication == null) {
throw new SAXException(
"Required attribute missing for <AuthenticationMethod> element");
}
} else if (qname.equals("LocalPortForwarding") ||
qname.equals("RemotePortForwarding")) {
String name = attrs.getValue("Name");
String addressToBind = attrs.getValue("AddressToBind");
String portToBind = attrs.getValue("PortToBind");
String addressToConnect = attrs.getValue(
"AddressToConnect");
String portToConnect = attrs.getValue("PortToConnect");
if ((name == null) || (addressToBind == null) ||
(portToBind == null) ||
(addressToConnect == null) ||
(portToConnect == null)) {
throw new SAXException(
"Required attribute missing for <" + qname +
"> element");
}
ForwardingConfiguration config = new ForwardingConfiguration(name,
addressToBind, Integer.parseInt(portToBind),
addressToConnect,
Integer.parseInt(portToConnect));
if (qname.equals("LocalPortForwarding")) {
localForwardings.put(name, config);
} else {
remoteForwardings.put(name, config);
}
} else if (qname.equals("ForwardingAutoStart")) {
try {
forwardingAutoStart = Boolean.valueOf(attrs.getValue(
"value")).booleanValue();
} catch (Throwable ex1) {
}
} else {
throw new SAXException("Unexpected element <" + qname +
"> after SshToolsConnectionProfile");
}
} else if (currentElement.equals("AuthenticationMethod")) {
if (qname.equals("AuthenticationProperty")) {
String name = attrs.getValue("Name");
String value = attrs.getValue("Value");
if ((name == null) || (value == null)) {
throw new SAXException(
"Required attribute missing for <AuthenticationProperty> element");
}
currentProperties.setProperty(name, value);
} else {
throw new SAXException("Unexpected element <" + qname +
"> found after AuthenticationMethod");
}
}
}
currentElement = qname;
}
public void characters(char[] ch, int pos, int len) {
executeCommands += new String(ch, pos, len);
}
public void endElement(String uri, String localName, String qname)
throws SAXException {
if (currentElement != null) {
if (!currentElement.equals(qname)) {
throw new SAXException("Unexpected end element found " +
qname);
} else if (qname.equals("SshToolsConnectionProfile")) {
currentElement = null;
} else if (qname.startsWith("Prefered")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("OnceAuthenticated")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("ExecuteCommands")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("ApplicationProperty")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("SftpFavorite")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("AuthenticationProperty")) {
currentElement = "AuthenticationMethod";
} else if (qname.equals("LocalPortForwarding") ||
qname.equals("RemotePortForwarding") ||
qname.equals("ForwardingAutoStart")) {
currentElement = "SshToolsConnectionProfile";
} else if (qname.equals("AuthenticationMethod")) {
currentElement = "SshToolsConnectionProfile";
try {
SshAuthenticationClient auth = SshAuthenticationClientFactory.newInstance(currentAuthentication);
auth.setPersistableProperties(currentProperties);
authMethods.put(currentAuthentication, auth);
} catch (AlgorithmNotSupportedException anse) {
log.warn(
"AuthenticationMethod element ignored because '" +
currentAuthentication +
"' authentication is not supported");
} finally {
currentAuthentication = null;
}
} else {
throw new SAXException("Unexpected end element <" + qname +
"> found");
}
}
}
}
}