mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
Merge pull request #201 from iterate-ch/feature/algorithms-verifier
Add option for client to verify negotiated key exchange algorithms.
This commit is contained in:
@@ -39,6 +39,7 @@ import net.schmizz.sshj.transport.TransportImpl;
|
|||||||
import net.schmizz.sshj.transport.compression.DelayedZlibCompression;
|
import net.schmizz.sshj.transport.compression.DelayedZlibCompression;
|
||||||
import net.schmizz.sshj.transport.compression.NoneCompression;
|
import net.schmizz.sshj.transport.compression.NoneCompression;
|
||||||
import net.schmizz.sshj.transport.compression.ZlibCompression;
|
import net.schmizz.sshj.transport.compression.ZlibCompression;
|
||||||
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
|
import net.schmizz.sshj.transport.verification.OpenSSHKnownHosts;
|
||||||
import net.schmizz.sshj.userauth.UserAuth;
|
import net.schmizz.sshj.userauth.UserAuth;
|
||||||
@@ -158,10 +159,19 @@ public class SSHClient
|
|||||||
* Add a {@link HostKeyVerifier} which will be invoked for verifying host key during connection establishment and
|
* Add a {@link HostKeyVerifier} which will be invoked for verifying host key during connection establishment and
|
||||||
* future key exchanges.
|
* future key exchanges.
|
||||||
*
|
*
|
||||||
* @param hostKeyVerifier {@link HostKeyVerifier} instance
|
* @param verifier {@link HostKeyVerifier} instance
|
||||||
*/
|
*/
|
||||||
public void addHostKeyVerifier(HostKeyVerifier hostKeyVerifier) {
|
public void addHostKeyVerifier(HostKeyVerifier verifier) {
|
||||||
trans.addHostKeyVerifier(hostKeyVerifier);
|
trans.addHostKeyVerifier(verifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link AlgorithmsVerifier} which will be invoked for verifying negotiated algorithms.
|
||||||
|
*
|
||||||
|
* @param verifier {@link AlgorithmsVerifier} instance
|
||||||
|
*/
|
||||||
|
public void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||||
|
trans.addAlgorithmsVerifier(verifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import net.schmizz.sshj.transport.digest.Digest;
|
|||||||
import net.schmizz.sshj.transport.kex.KeyExchange;
|
import net.schmizz.sshj.transport.kex.KeyExchange;
|
||||||
import net.schmizz.sshj.transport.mac.MAC;
|
import net.schmizz.sshj.transport.mac.MAC;
|
||||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||||
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -68,6 +70,8 @@ final class KeyExchanger
|
|||||||
*/
|
*/
|
||||||
private final Queue<HostKeyVerifier> hostVerifiers = new LinkedList<HostKeyVerifier>();
|
private final Queue<HostKeyVerifier> hostVerifiers = new LinkedList<HostKeyVerifier>();
|
||||||
|
|
||||||
|
private final Queue<AlgorithmsVerifier> algorithmVerifiers = new LinkedList<AlgorithmsVerifier>();
|
||||||
|
|
||||||
private final AtomicBoolean kexOngoing = new AtomicBoolean();
|
private final AtomicBoolean kexOngoing = new AtomicBoolean();
|
||||||
|
|
||||||
/** What we are expecting from the next packet */
|
/** What we are expecting from the next packet */
|
||||||
@@ -108,6 +112,10 @@ final class KeyExchanger
|
|||||||
hostVerifiers.add(hkv);
|
hostVerifiers.add(hkv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||||
|
algorithmVerifiers.add(verifier);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session identifier computed during key exchange.
|
* Returns the session identifier computed during key exchange.
|
||||||
*
|
*
|
||||||
@@ -218,6 +226,13 @@ final class KeyExchanger
|
|||||||
final Proposal serverProposal = new Proposal(buf);
|
final Proposal serverProposal = new Proposal(buf);
|
||||||
negotiatedAlgs = clientProposal.negotiate(serverProposal);
|
negotiatedAlgs = clientProposal.negotiate(serverProposal);
|
||||||
log.debug("Negotiated algorithms: {}", negotiatedAlgs);
|
log.debug("Negotiated algorithms: {}", negotiatedAlgs);
|
||||||
|
for(AlgorithmsVerifier v: algorithmVerifiers) {
|
||||||
|
log.debug("Trying to verify algorithms with {}", v);
|
||||||
|
if(!v.verify(negotiatedAlgs)) {
|
||||||
|
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED,
|
||||||
|
"Failed to verify negotiated algorithms `" + negotiatedAlgs + "`");
|
||||||
|
}
|
||||||
|
}
|
||||||
kex = Factory.Named.Util.create(transport.getConfig().getKeyExchangeFactories(),
|
kex = Factory.Named.Util.create(transport.getConfig().getKeyExchangeFactories(),
|
||||||
negotiatedAlgs.getKeyExchangeAlgorithm());
|
negotiatedAlgs.getKeyExchangeAlgorithm());
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import net.schmizz.sshj.Service;
|
|||||||
import net.schmizz.sshj.common.DisconnectReason;
|
import net.schmizz.sshj.common.DisconnectReason;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
import net.schmizz.sshj.common.SSHPacketHandler;
|
import net.schmizz.sshj.common.SSHPacketHandler;
|
||||||
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -51,6 +52,13 @@ public interface Transport
|
|||||||
*/
|
*/
|
||||||
void addHostKeyVerifier(HostKeyVerifier hkv);
|
void addHostKeyVerifier(HostKeyVerifier hkv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the specified verifier.
|
||||||
|
*
|
||||||
|
* @param verifier The verifier to call with negotiated algorithms
|
||||||
|
*/
|
||||||
|
void addAlgorithmsVerifier(AlgorithmsVerifier verifier);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do key exchange and algorithm negotiation. This can be the initial one or for algorithm renegotiation.
|
* Do key exchange and algorithm negotiation. This can be the initial one or for algorithm renegotiation.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import net.schmizz.sshj.common.IOUtils;
|
|||||||
import net.schmizz.sshj.common.Message;
|
import net.schmizz.sshj.common.Message;
|
||||||
import net.schmizz.sshj.common.SSHException;
|
import net.schmizz.sshj.common.SSHException;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -235,6 +236,11 @@ public final class TransportImpl
|
|||||||
kexer.addHostKeyVerifier(hkv);
|
kexer.addHostKeyVerifier(hkv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||||
|
kexer.addAlgorithmsVerifier(verifier);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doKex()
|
public void doKex()
|
||||||
throws TransportException {
|
throws TransportException {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2009 sshj contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package net.schmizz.sshj.transport.verification;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.transport.NegotiatedAlgorithms;
|
||||||
|
|
||||||
|
public interface AlgorithmsVerifier {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback is invoked when algorithms have been negotiated between client and server.
|
||||||
|
* @return False to interrupt the connection
|
||||||
|
*/
|
||||||
|
boolean verify(NegotiatedAlgorithms algorithms);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user