types.rs
1 use super::error; 2 use super::wire; 3 4 use ed25519_dalek::{SigningKey, VerifyingKey}; 5 use embedded_io_async::{ErrorType, Read, Write}; 6 use rand::{CryptoRng, Rng}; 7 8 /// Secret key associated with a host server. 9 #[derive(Debug)] 10 pub enum SecretKey { 11 /// An Ed25519 secret key. 12 Ed25519 { 13 /// The secret key. 14 secret_key: SigningKey, 15 }, 16 } 17 18 /// Public key associated with a user identity. 19 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 20 pub enum PublicKey { 21 /// An Ed25519 public key. 22 Ed25519 { 23 /// The public key. 24 public_key: VerifyingKey, 25 }, 26 } 27 28 impl<'a> From<&'a PublicKey> for wire::PublicKey<'a> { 29 fn from(value: &'a PublicKey) -> Self { 30 match value { 31 PublicKey::Ed25519 { public_key } => Self::Ed25519 { 32 public_key: public_key.as_bytes(), 33 }, 34 } 35 } 36 } 37 38 /// Authentication method that a user may choose. 39 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 40 pub enum AuthMethod { 41 /// No authentication provided. 42 None, 43 /// Public-key authentication. 44 PublicKey(PublicKey), 45 } 46 47 /// Request associated with an SSH channel. 48 #[derive(Clone, Copy, Debug)] 49 pub enum Request<T> { 50 /// User requested a shell. 51 Shell, 52 /// User requested the execution of a command. 53 Exec(T), 54 } 55 56 /// Description of aspects of the server's behavior. 57 pub trait Behavior { 58 /// The underlying stream type. 59 type Stream: Read + Write; 60 61 /// The underlying stream type to be used. 62 fn stream(&mut self) -> &mut Self::Stream; 63 64 /// The underlying random type. 65 type Random: CryptoRng + Rng; 66 67 /// The underlying random type to be used. 68 fn random(&mut self) -> &mut Self::Random; 69 70 /// The secret key advertised by the server. 71 fn host_secret_key(&self) -> &SecretKey; 72 73 /// The server's identification string. 74 /// 75 /// This will be sent to the client during the initial version handshake. It must 76 /// comply with RFC4253 section 4.2 except it should not contain the final CR LF. 77 fn server_id(&self) -> &'static str { 78 "SSH-2.0-microvisor" 79 } 80 81 /// Allow a given user to authenticate with a given auth method. 82 /// 83 /// Returns None if the user's auth method is not acceptable (e.g. public key does 84 /// not match a whitelist), otherwise returns a type representing a user identity. 85 /// 86 /// This may be called more than once if the client uses probe requests. 87 fn allow_user(&mut self, username: &str, auth_method: &AuthMethod) -> Option<Self::User>; 88 89 /// Type representing an authenticated user. 90 type User: Clone; 91 92 /// Whether to allow shell channel requests. 93 /// 94 /// Note that if this returns true, the server code must be prepared to handle shell 95 /// requests by accepting interactive input in ways similar to a real shell process. 96 fn allow_shell(&self) -> bool { 97 false 98 } 99 100 /// Called when the client requests a PTY with terminal dimensions. 101 fn on_pty_request(&mut self, _width: u32, _height: u32) {} 102 103 /// Type representing a user-supplied command. 104 type Command: Clone; 105 106 /// Parse a user-supplied command string into a command. 107 /// 108 /// It is not permitted to "fail" to parse a command, instead just represent invalid 109 /// commands as a "print usage" command variant so as to handle all possible inputs. 110 fn parse_command(&mut self, command: &str) -> Self::Command; 111 } 112 113 /// Convenience type alias describing the transport error type for a given behavior type. 114 pub type TransportError<T> = error::Error<<<T as Behavior>::Stream as ErrorType>::Error>;