Commit 16c57380 authored by Thomas Gatzweiler's avatar Thomas Gatzweiler
Browse files

Rename Session to Connection

parent 5d81f21f
use std::io::{self, BufRead, BufReader, Read, Write};
use key_exchange::{self, KeyExchange, KeyExchangeResult};
use message::MessageType;
use packet::{Packet, ReadPacketExt, WritePacketExt};
use std::io::Write;
use public_key::KeyPair;
#[derive(PartialEq)]
enum SessionState {
enum ConnectionState {
Initial,
KeyExchange,
Established,
}
#[derive(PartialEq)]
pub enum SessionType {
pub enum ConnectionType {
Server,
Client,
}
pub struct Session<W: Write> {
stype: SessionType,
state: SessionState,
pub struct Connection<W: Write> {
ctype: ConnectionType,
state: ConnectionState,
key_exchange: Option<Box<KeyExchange>>,
stream: W,
my_id: String,
peer_id: Option<String>,
}
impl<W: Write> Session<W> {
pub fn new(stype: SessionType, stream: W) -> Session<W> {
Session {
stype: stype,
state: SessionState::Initial,
impl<W: Write> Connection<W> {
pub fn new(ctype: ConnectionType, stream: W) -> Connection<W> {
Connection {
ctype: ctype,
state: ConnectionState::Initial,
key_exchange: None,
stream: stream,
my_id: format!(
"SSH-2.0-RedoxSSH_{}\r\n",
env!("CARGO_PKG_VERSION")
),
peer_id: None,
}
}
pub fn run(&mut self, mut stream: &mut Read) -> io::Result<()> {
self.stream.write(self.my_id.as_bytes())?;
self.peer_id = Some(self.read_id(stream)?);
if let Some(ref peer_id) = self.peer_id {
println!("Identifies as {:?}", peer_id);
}
loop {
let packet = Packet::read_from(&mut stream).unwrap();
println!("packet: {:?}", packet);
self.process(&packet);
}
}
fn read_id(&mut self, stream: &mut Read) -> io::Result<String> {
// The identification string has a maximum length of 255 bytes
// TODO: Make sure to stop reading if the client sends too much
let mut reader = BufReader::new(stream);
let mut id = String::new();
while !id.starts_with("SSH-") {
reader.read_line(&mut id)?;
}
Ok(id.trim_right().to_owned())
}
pub fn process(&mut self, packet: &Packet) {
match packet.msg_type() {
match packet.msg_type()
{
MessageType::KexInit => {
println!("Starting Key Exchange!");
self.kex_init(packet);
}
MessageType::KeyExchange(_) => {
if let Some(ref mut kex) = self.key_exchange {
match kex.process(packet) {
KeyExchangeResult::Ok(Some(packet)) => { packet.write_to(&mut self.stream); },
KeyExchangeResult::Error(Some(packet)) => { packet.write_to(&mut self.stream); },
KeyExchangeResult::Done(Some(packet)) => { packet.write_to(&mut self.stream); },
match kex.process(packet)
{
KeyExchangeResult::Ok(Some(packet)) => {
packet.write_to(&mut self.stream);
}
KeyExchangeResult::Error(Some(packet)) => {
packet.write_to(&mut self.stream);
}
KeyExchangeResult::Done(Some(packet)) => {
packet.write_to(&mut self.stream);
}
KeyExchangeResult::Ok(None) |
KeyExchangeResult::Error(None) |
KeyExchangeResult::Done(None) => {}
};
} else {
}
else {
warn!("Received KeyExchange packet without KexInit");
}
}
......@@ -74,10 +121,12 @@ impl<W: Write> Session<W> {
let comp_algos_s2c = reader.read_enum_list::<CompressionAlgorithm>();
let kex_algo = negotiate(KEY_EXCHANGE, kex_algos.unwrap().as_slice());
let srv_host_key_algo = negotiate(HOST_KEY, srv_host_key_algos.unwrap().as_slice());
let srv_host_key_algo =
negotiate(HOST_KEY, srv_host_key_algos.unwrap().as_slice());
let enc_algo = negotiate(ENCRYPTION, enc_algos_s2c.unwrap().as_slice());
let mac_algo = negotiate(MAC, mac_algos_s2c.unwrap().as_slice());
let comp_algo = negotiate(COMPRESSION, comp_algos_s2c.unwrap().as_slice());
let comp_algo =
negotiate(COMPRESSION, comp_algos_s2c.unwrap().as_slice());
println!("Negotiated Kex Algorithm: {:?}", kex_algo);
println!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
......@@ -107,7 +156,7 @@ impl<W: Write> Session<W> {
Ok(())
});
self.state = SessionState::KeyExchange;
self.state = ConnectionState::KeyExchange;
self.key_exchange = Some(Box::new(key_exchange::Curve25519::new()));
packet.write_to(&mut self.stream);
}
......
......@@ -4,7 +4,6 @@ mod dh_group_sha1;
pub use self::curve25519::Curve25519;
pub use self::dh_group_sha1::DhGroupSha1;
use session::Session;
use packet::Packet;
pub enum KeyExchangeResult {
......
......@@ -6,10 +6,9 @@ extern crate num_bigint;
extern crate log;
mod algorithm;
mod protocol;
mod packet;
mod message;
mod session;
mod connection;
mod key_exchange;
pub mod public_key;
......
use std::io::{Read, Write, BufReader, BufRead};
use std::io;
pub fn send_identification<W: Write>(stream: &mut W) -> io::Result<usize> {
let id = format!("SSH-2.0-RedoxSSH_{}\r\n", env!("CARGO_PKG_VERSION"));
stream.write(id.as_bytes())
}
pub fn read_identification<R: Read>(stream: &mut R) -> io::Result<String> {
// The identification string has a maximum length of 255 bytes
// TODO: Make sure that we stop reading when the client sends more than that
let mut reader = BufReader::new(stream);
let mut id = String::new();
while !id.starts_with("SSH-") {
reader.read_line(&mut id)?;
}
Ok(id.trim_right().to_owned())
}
use std::net::TcpListener;
use std::io::{self, Write};
use std::net::TcpListener;
use std::thread;
use session::{Session, SessionType};
use connection::{Connection, ConnectionType};
use packet::Packet;
use public_key::KeyPair;
use protocol;
pub struct ServerConfig {
pub host: String,
pub port: u16,
pub key: Box<KeyPair>
pub key: Box<KeyPair>,
}
pub struct Server {
......@@ -22,28 +22,32 @@ impl Server {
}
pub fn run(&self) -> io::Result<()> {
let listener = TcpListener::bind((&*self.config.host, self.config.port)).expect(&*format!(
let listener = TcpListener::bind(
(&*self.config.host, self.config.port),
).expect(&*format!(
"sshd: failed to bind to {}:{}",
self.config.host,
self.config.port
));
let (mut stream, addr) = listener.accept().expect(&*format!(
"sshd: failed to establish incoming connection"
));
println!("Incoming connection from {}", addr);
protocol::send_identification(&mut stream)?;
loop {
let (mut stream, addr) = listener.accept().expect(&*format!(
"sshd: failed to establish incoming connection"
));
let id = protocol::read_identification(&mut stream)?;
println!("{} identifies as {}", addr, id);
println!("Incoming connection from {}", addr);
let mut session = Session::new(SessionType::Server, stream.try_clone().unwrap());
thread::spawn(move || {
let mut connection = Connection::new(
ConnectionType::Server,
stream.try_clone().unwrap(),
);
connection.run(&mut stream);
});
loop {
let packet = Packet::read_from(&mut stream).unwrap();
println!("packet: {:?}", packet);
session.process(&packet);
}
Ok(())
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment