Add version comparison on connect

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent e0ea66f7c1
commit 34a1fd2cf0
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,7 +1,7 @@
[package]
name = "vented"
description = "Event driven encrypted tcp communicaton"
version = "0.1.2"
version = "0.1.3"
authors = ["trivernis <trivernis@protonmail.com>"]
edition = "2018"
readme = "README.md"

@ -1,3 +1,4 @@
use crate::server::CRATE_VERSION;
use std::error::Error;
use std::{fmt, io};
@ -16,6 +17,7 @@ pub enum VentedError {
UnknownNode(String),
Rejected,
AuthFailed,
VersionMismatch(String),
}
impl fmt::Display for VentedError {
@ -32,6 +34,11 @@ impl fmt::Display for VentedError {
Self::NotAServer(n) => write!(f, "The given node {} is not a server", n),
Self::Rejected => write!(f, "The connection was rejected"),
Self::AuthFailed => write!(f, "Failed to authenticate the other party"),
Self::VersionMismatch(version) => write!(
f,
"Version mismatch: Expected {} got {}",
CRATE_VERSION, version
),
}
}
}

@ -11,8 +11,8 @@ use crate::result::VentedError::UnknownNode;
use crate::result::{VentedError, VentedResult};
use crate::server::data::{Node, ServerConnectionContext};
use crate::server::server_events::{
AuthPayload, ChallengePayload, NodeInformationPayload, ACCEPT_EVENT, AUTH_EVENT,
CHALLENGE_EVENT, CONNECT_EVENT, READY_EVENT, REJECT_EVENT,
AuthPayload, ChallengePayload, NodeInformationPayload, VersionMismatchPayload, ACCEPT_EVENT,
AUTH_EVENT, CHALLENGE_EVENT, CONNECT_EVENT, MISMATCH_EVENT, READY_EVENT, REJECT_EVENT,
};
use crossbeam_utils::sync::WaitGroup;
use parking_lot::Mutex;
@ -24,6 +24,8 @@ use x25519_dalek::StaticSecret;
pub mod data;
pub mod server_events;
pub(crate) const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION");
/// The vented server that provides parallel handling of connections
/// Usage:
/// ```rust
@ -296,6 +298,7 @@ impl VentedServer {
&NodeInformationPayload {
public_key: secret_key.public_key().to_bytes(),
node_id: own_node_id,
vented_version: CRATE_VERSION.to_string(),
},
)
.as_bytes(),
@ -308,8 +311,21 @@ impl VentedServer {
let NodeInformationPayload {
public_key,
node_id,
vented_version,
} = event.get_payload::<NodeInformationPayload>().unwrap();
if !Self::compare_version(&vented_version, CRATE_VERSION) {
stream.write(
&Event::with_payload(
MISMATCH_EVENT,
&VersionMismatchPayload::new(CRATE_VERSION, &vented_version),
)
.as_bytes(),
)?;
stream.flush()?;
return Err(VentedError::VersionMismatch(vented_version));
}
let public_key = PublicKey::from(public_key);
let secret_box = ChaChaBox::new(&public_key, &secret_key);
@ -348,9 +364,22 @@ impl VentedServer {
let NodeInformationPayload {
public_key,
node_id,
vented_version,
} = event.get_payload::<NodeInformationPayload>().unwrap();
let public_key = PublicKey::from(public_key);
if !Self::compare_version(&vented_version, CRATE_VERSION) {
stream.write(
&Event::with_payload(
MISMATCH_EVENT,
&VersionMismatchPayload::new(CRATE_VERSION, &vented_version),
)
.as_bytes(),
)?;
stream.flush()?;
return Err(VentedError::VersionMismatch(vented_version));
}
let public_key = PublicKey::from(public_key);
let node_data = if let Some(data) = known_nodes.lock().iter().find(|n| n.id == node_id) {
data.clone()
} else {
@ -365,6 +394,7 @@ impl VentedServer {
&NodeInformationPayload {
public_key: secret_key.public_key().to_bytes(),
node_id: own_node_id,
vented_version: CRATE_VERSION.to_string(),
},
)
.as_bytes(),
@ -443,4 +473,12 @@ impl VentedServer {
Ok(())
}
}
/// Compares two version for their major and minor value
fn compare_version(a: &str, b: &str) -> bool {
let parts_a = a.split('.').collect::<Vec<&str>>();
let parts_b = b.split('.').collect::<Vec<&str>>();
parts_a.get(0) == parts_b.get(0) && parts_a.get(1) == parts_b.get(1)
}
}

@ -5,6 +5,7 @@ pub(crate) const AUTH_EVENT: &str = "conn:authenticate";
pub(crate) const CHALLENGE_EVENT: &str = "conn:challenge";
pub(crate) const ACCEPT_EVENT: &str = "conn:accept";
pub(crate) const REJECT_EVENT: &str = "conn:reject";
pub(crate) const MISMATCH_EVENT: &str = "conn:reject_version_mismatch";
pub const READY_EVENT: &str = "connection:ready";
@ -12,6 +13,7 @@ pub const READY_EVENT: &str = "connection:ready";
pub(crate) struct NodeInformationPayload {
pub node_id: String,
pub public_key: [u8; 32],
pub vented_version: String,
}
#[derive(Serialize, Deserialize, Debug)]
@ -23,3 +25,18 @@ pub(crate) struct ChallengePayload {
pub(crate) struct AuthPayload {
pub calculated_secret: [u8; 32],
}
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct VersionMismatchPayload {
pub expected: String,
pub got: String,
}
impl VersionMismatchPayload {
pub fn new(expected: &str, got: &str) -> Self {
Self {
expected: expected.to_string(),
got: got.to_string(),
}
}
}

Loading…
Cancel
Save