#[cfg(not(target_arch = "wasm32"))]
pub use server::*;
use crate::{strict_kex_violation, Error};
pub const DISCONNECT: u8 = 1;
#[allow(dead_code)]
pub const IGNORE: u8 = 2;
#[allow(dead_code)]
pub const UNIMPLEMENTED: u8 = 3;
#[allow(dead_code)]
pub const DEBUG: u8 = 4;
pub const SERVICE_REQUEST: u8 = 5;
pub const SERVICE_ACCEPT: u8 = 6;
pub const EXT_INFO: u8 = 7;
pub const KEXINIT: u8 = 20;
pub const NEWKEYS: u8 = 21;
pub const KEX_ECDH_INIT: u8 = 30;
pub const KEX_ECDH_REPLY: u8 = 31;
pub const KEX_DH_GEX_REQUEST: u8 = 34;
pub const KEX_DH_GEX_GROUP: u8 = 31;
pub const KEX_DH_GEX_INIT: u8 = 32;
pub const KEX_DH_GEX_REPLY: u8 = 33;
pub const KEX_HYBRID_INIT: u8 = 30;
#[allow(dead_code)]
pub const KEX_HYBRID_REPLY: u8 = 31;
pub const USERAUTH_REQUEST: u8 = 50;
pub const USERAUTH_FAILURE: u8 = 51;
pub const USERAUTH_SUCCESS: u8 = 52;
pub const USERAUTH_BANNER: u8 = 53;
pub const USERAUTH_INFO_RESPONSE: u8 = 61;
pub const USERAUTH_INFO_REQUEST_OR_USERAUTH_PK_OK: u8 = 60;
pub const GLOBAL_REQUEST: u8 = 80;
pub const REQUEST_SUCCESS: u8 = 81;
pub const REQUEST_FAILURE: u8 = 82;
pub const CHANNEL_OPEN: u8 = 90;
pub const CHANNEL_OPEN_CONFIRMATION: u8 = 91;
pub const CHANNEL_OPEN_FAILURE: u8 = 92;
pub const CHANNEL_WINDOW_ADJUST: u8 = 93;
pub const CHANNEL_DATA: u8 = 94;
pub const CHANNEL_EXTENDED_DATA: u8 = 95;
pub const CHANNEL_EOF: u8 = 96;
pub const CHANNEL_CLOSE: u8 = 97;
pub const CHANNEL_REQUEST: u8 = 98;
pub const CHANNEL_SUCCESS: u8 = 99;
pub const CHANNEL_FAILURE: u8 = 100;
#[allow(dead_code)]
pub const SSH_OPEN_CONNECT_FAILED: u8 = 2;
pub const SSH_OPEN_UNKNOWN_CHANNEL_TYPE: u8 = 3;
#[allow(dead_code)]
pub const SSH_OPEN_RESOURCE_SHORTAGE: u8 = 4;
#[cfg(not(target_arch = "wasm32"))]
mod server {
pub const USERAUTH_INFO_REQUEST: u8 = 60;
pub const USERAUTH_PK_OK: u8 = 60;
pub const SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: u8 = 1;
}
fn validate_msg_strict_kex(msg_type: u8, seqno: usize, order: &[u8]) -> Option<bool> {
order.get(seqno).map(|expected| expected == &msg_type)
}
fn validate_msg_strict_kex_alt_order(msg_type: u8, seqno: usize, orders: &[&[u8]]) -> Option<bool> {
let mut valid = None; for order in orders {
let result = validate_msg_strict_kex(msg_type, seqno, order);
valid = match (valid, result) {
(Some(true), _) | (_, Some(true)) => Some(true),
(None | Some(false), Some(false)) => Some(false),
(x, None) => x,
};
}
valid
}
pub(crate) fn validate_client_msg_strict_kex(msg_type: u8, seqno: usize) -> Result<(), Error> {
if Some(false)
== validate_msg_strict_kex_alt_order(
msg_type,
seqno,
&[
&[KEXINIT, KEX_ECDH_INIT, NEWKEYS],
&[KEXINIT, KEX_DH_GEX_REQUEST, KEX_DH_GEX_INIT, NEWKEYS],
],
)
{
return Err(strict_kex_violation(msg_type, seqno));
}
Ok(())
}
pub(crate) fn validate_server_msg_strict_kex(msg_type: u8, seqno: usize) -> Result<(), Error> {
if Some(false)
== validate_msg_strict_kex_alt_order(
msg_type,
seqno,
&[
&[KEXINIT, KEX_ECDH_REPLY, NEWKEYS],
&[KEXINIT, KEX_DH_GEX_GROUP, KEX_DH_GEX_REPLY, NEWKEYS],
],
)
{
return Err(strict_kex_violation(msg_type, seqno));
}
Ok(())
}
const ALL_KEX_MESSAGES: &[u8] = &[
KEXINIT,
KEX_ECDH_INIT,
KEX_ECDH_REPLY,
KEX_DH_GEX_GROUP,
KEX_DH_GEX_INIT,
KEX_DH_GEX_REPLY,
KEX_DH_GEX_REQUEST,
NEWKEYS,
];
pub(crate) fn is_kex_msg(msg: u8) -> bool {
ALL_KEX_MESSAGES.contains(&msg)
}