mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 07:10:53 +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.NoneCompression;
|
||||
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.OpenSSHKnownHosts;
|
||||
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
|
||||
* future key exchanges.
|
||||
*
|
||||
* @param hostKeyVerifier {@link HostKeyVerifier} instance
|
||||
* @param verifier {@link HostKeyVerifier} instance
|
||||
*/
|
||||
public void addHostKeyVerifier(HostKeyVerifier hostKeyVerifier) {
|
||||
trans.addHostKeyVerifier(hostKeyVerifier);
|
||||
public void addHostKeyVerifier(HostKeyVerifier verifier) {
|
||||
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.mac.MAC;
|
||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -68,6 +70,8 @@ final class KeyExchanger
|
||||
*/
|
||||
private final Queue<HostKeyVerifier> hostVerifiers = new LinkedList<HostKeyVerifier>();
|
||||
|
||||
private final Queue<AlgorithmsVerifier> algorithmVerifiers = new LinkedList<AlgorithmsVerifier>();
|
||||
|
||||
private final AtomicBoolean kexOngoing = new AtomicBoolean();
|
||||
|
||||
/** What we are expecting from the next packet */
|
||||
@@ -108,6 +112,10 @@ final class KeyExchanger
|
||||
hostVerifiers.add(hkv);
|
||||
}
|
||||
|
||||
synchronized void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||
algorithmVerifiers.add(verifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the session identifier computed during key exchange.
|
||||
*
|
||||
@@ -218,6 +226,13 @@ final class KeyExchanger
|
||||
final Proposal serverProposal = new Proposal(buf);
|
||||
negotiatedAlgs = clientProposal.negotiate(serverProposal);
|
||||
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(),
|
||||
negotiatedAlgs.getKeyExchangeAlgorithm());
|
||||
try {
|
||||
|
||||
@@ -20,6 +20,7 @@ import net.schmizz.sshj.Service;
|
||||
import net.schmizz.sshj.common.DisconnectReason;
|
||||
import net.schmizz.sshj.common.SSHPacket;
|
||||
import net.schmizz.sshj.common.SSHPacketHandler;
|
||||
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||
|
||||
import java.io.InputStream;
|
||||
@@ -51,6 +52,13 @@ public interface Transport
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@ import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.common.Message;
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
import net.schmizz.sshj.common.SSHPacket;
|
||||
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||
import net.schmizz.sshj.transport.verification.HostKeyVerifier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -235,6 +236,11 @@ public final class TransportImpl
|
||||
kexer.addHostKeyVerifier(hkv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAlgorithmsVerifier(AlgorithmsVerifier verifier) {
|
||||
kexer.addAlgorithmsVerifier(verifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doKex()
|
||||
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