Skip to content

Commit 42c98a6

Browse files
committed
fixed #227 - only advertise host key algos for present host keys
1 parent 1541fe5 commit 42c98a6

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

russh/src/client/kex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl KexInit {
6969
write_buffer: &mut SSHBuffer,
7070
) -> Result<(), crate::Error> {
7171
self.exchange.client_kex_init.clear();
72-
negotiation::write_kex(&config.preferred, &mut self.exchange.client_kex_init, false)?;
72+
negotiation::write_kex(&config.preferred, &mut self.exchange.client_kex_init, None)?;
7373
self.sent = true;
7474
cipher.write(&self.exchange.client_kex_init, write_buffer);
7575
Ok(())

russh/src/negotiation.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use russh_keys::key::{KeyPair, PublicKey};
2424
use crate::cipher::CIPHERS;
2525
use crate::compression::*;
2626
use crate::kex::{EXTENSION_OPENSSH_STRICT_KEX_AS_CLIENT, EXTENSION_OPENSSH_STRICT_KEX_AS_SERVER};
27+
use crate::server::Config;
2728
use crate::{cipher, kex, mac, msg, Error};
2829

2930
#[derive(Debug)]
@@ -40,11 +41,11 @@ pub struct Names {
4041
}
4142

4243
/// Lists of preferred algorithms. This is normally hard-coded into implementations.
43-
#[derive(Debug)]
44+
#[derive(Debug, Clone)]
4445
pub struct Preferred {
4546
/// Preferred key exchange algorithms.
4647
pub kex: &'static [kex::Name],
47-
/// Preferred public key algorithms.
48+
/// Preferred host & public key algorithms.
4849
pub key: &'static [key::Name],
4950
/// Preferred symmetric ciphers.
5051
pub cipher: &'static [cipher::Name],
@@ -316,7 +317,11 @@ impl Select for Client {
316317
}
317318
}
318319

319-
pub fn write_kex(prefs: &Preferred, buf: &mut CryptoVec, as_server: bool) -> Result<(), Error> {
320+
pub fn write_kex(
321+
prefs: &Preferred,
322+
buf: &mut CryptoVec,
323+
server_config: Option<&Config>,
324+
) -> Result<(), Error> {
320325
// buf.clear();
321326
buf.push(msg::KEXINIT);
322327

@@ -325,7 +330,7 @@ pub fn write_kex(prefs: &Preferred, buf: &mut CryptoVec, as_server: bool) -> Res
325330

326331
buf.extend(&cookie); // cookie
327332
buf.extend_list(prefs.kex.iter().filter(|k| {
328-
!(if as_server {
333+
!(if server_config.is_some() {
329334
[
330335
crate::kex::EXTENSION_SUPPORT_AS_CLIENT,
331336
crate::kex::EXTENSION_OPENSSH_STRICT_KEX_AS_CLIENT,
@@ -339,7 +344,17 @@ pub fn write_kex(prefs: &Preferred, buf: &mut CryptoVec, as_server: bool) -> Res
339344
.contains(*k)
340345
})); // kex algo
341346

342-
buf.extend_list(prefs.key.iter());
347+
if let Some(server_config) = server_config {
348+
// Only advertise host key algorithms that we have keys for.
349+
buf.extend_list(
350+
prefs
351+
.key
352+
.iter()
353+
.filter(|name| server_config.keys.iter().any(|k| k.name() == name.0)),
354+
);
355+
} else {
356+
buf.extend_list(prefs.key.iter());
357+
}
343358

344359
buf.extend_list(prefs.cipher.iter()); // cipher client to server
345360
buf.extend_list(prefs.cipher.iter()); // cipher server to client

russh/src/server/kex.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ impl KexInit {
6161
write_buffer: &mut SSHBuffer,
6262
) -> Result<(), Error> {
6363
self.exchange.server_kex_init.clear();
64-
negotiation::write_kex(&config.preferred, &mut self.exchange.server_kex_init, true)?;
64+
negotiation::write_kex(
65+
&config.preferred,
66+
&mut self.exchange.server_kex_init,
67+
Some(config),
68+
)?;
6569
debug!("server kex init: {:?}", &self.exchange.server_kex_init[..]);
6670
self.sent = true;
6771
cipher.write(&self.exchange.server_kex_init, write_buffer);

0 commit comments

Comments
 (0)