upload working
This commit is contained in:
parent
369c3617bc
commit
6a2c1ec15d
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -93,6 +93,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
@ -251,7 +257,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dnstp"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dnstplib",
|
||||
@ -261,8 +267,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dnstp-client"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"clap",
|
||||
"dnstplib",
|
||||
"log",
|
||||
@ -272,9 +279,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dnstplib"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"aes-gcm-siv",
|
||||
"base64",
|
||||
"log",
|
||||
"p256",
|
||||
"rand_core",
|
||||
|
@ -6,3 +6,8 @@ members = [
|
||||
"dnstp-client",
|
||||
"dnstp-server",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.1"
|
||||
authors = ["sarsoo <andy@sarsoo.xyz>"]
|
||||
documentation = "https://sarsoo.github.io/dnstp"
|
@ -1,6 +1,8 @@
|
||||
[package]
|
||||
name = "dnstp-client"
|
||||
version = "0.1.0"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
documentation.workspace = true
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
@ -12,3 +14,4 @@ clap = { version = "4.5.11", features = ["derive"] }
|
||||
log = "0.4.22"
|
||||
simplelog = "0.12.2"
|
||||
rand = "0.8.5"
|
||||
base64 = "0.22.1"
|
@ -1,6 +1,6 @@
|
||||
use crate::NetSettings;
|
||||
|
||||
pub fn download(net_settings: NetSettings)
|
||||
pub fn download(_net_settings: NetSettings)
|
||||
{
|
||||
|
||||
}
|
@ -15,6 +15,7 @@ use crate::test::send_test_requests;
|
||||
use crate::upload::upload;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "DNSTP")]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
#[clap(subcommand)]
|
||||
@ -33,7 +34,7 @@ enum Command {
|
||||
#[clap(flatten)]
|
||||
net_options: NetSettings,
|
||||
#[arg(short, long)]
|
||||
value: String
|
||||
value: Vec<String>
|
||||
},
|
||||
/// Download a payload from the remote server
|
||||
Download {
|
||||
|
@ -4,7 +4,7 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
use log::info;
|
||||
use rand::RngCore;
|
||||
use dnstplib::client_crypto_context::ClientCryptoContext;
|
||||
use dnstplib::session::client_crypto_context::ClientCryptoContext;
|
||||
use dnstplib::DomainConfig;
|
||||
use dnstplib::message::DNSMessage;
|
||||
use dnstplib::net::{DNSSocket, NetworkMessage};
|
||||
@ -42,10 +42,12 @@ pub fn send_test_requests(args: NetSettings)
|
||||
|
||||
let bytes = message.to_bytes();
|
||||
|
||||
tx_channel.send(Box::new(NetworkMessage {
|
||||
if let Err(_) = tx_channel.send(Box::new(NetworkMessage {
|
||||
buffer: Box::new(bytes),
|
||||
peer: args.address.parse().unwrap()
|
||||
}));
|
||||
})) {
|
||||
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
@ -3,16 +3,14 @@ use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use log::info;
|
||||
use rand::RngCore;
|
||||
use rand::rngs::OsRng;
|
||||
use dnstplib::client_crypto_context::ClientCryptoContext;
|
||||
use dnstplib::session::{ClientCryptoContext, generate_client_handshake_message, generate_string_encryption_message};
|
||||
use dnstplib::{DomainConfig, send_message};
|
||||
use dnstplib::message::{Direction, DNSHeader, DNSMessage, DNSQuestion, Opcode, QClass, QType, ResponseCode};
|
||||
use dnstplib::net::DNSSocket;
|
||||
use dnstplib::processor::ResponseProcesor;
|
||||
use crate::NetSettings;
|
||||
|
||||
pub fn upload(net_settings: NetSettings, value: String)
|
||||
pub fn upload(net_settings: NetSettings, values: Vec<String>)
|
||||
{
|
||||
let address = SocketAddr::from(([127, 0, 0, 1], 0));
|
||||
|
||||
@ -35,39 +33,7 @@ pub fn upload(net_settings: NetSettings, value: String)
|
||||
|
||||
info!("sending handshake...");
|
||||
|
||||
let message = DNSMessage {
|
||||
header: DNSHeader {
|
||||
id: OsRng.next_u32() as u16,
|
||||
direction: Direction::Request,
|
||||
opcode: Opcode::Query,
|
||||
authoritative: false,
|
||||
truncation: false,
|
||||
recursion_desired: false,
|
||||
recursion_available: false,
|
||||
valid_zeroes: true,
|
||||
response: ResponseCode::NoError,
|
||||
question_count: 2,
|
||||
answer_record_count: 0,
|
||||
authority_record_count: 0,
|
||||
additional_record_count: 0,
|
||||
},
|
||||
questions: vec![
|
||||
DNSQuestion {
|
||||
qname: domain_config.get_fq_key_endpoint(),
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
},
|
||||
DNSQuestion {
|
||||
qname: crypto_context.lock().unwrap().get_public_key_domain(&domain_config.base_domain),
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
}
|
||||
],
|
||||
answer_records: vec![],
|
||||
authority_records: vec![],
|
||||
additional_records: vec![],
|
||||
peer: net_settings.address.parse().unwrap(),
|
||||
};
|
||||
let message = generate_client_handshake_message(&mut OsRng, &domain_config, crypto_context.clone(), &net_settings.address);
|
||||
|
||||
send_message(message, &tx_channel);
|
||||
|
||||
@ -78,4 +44,19 @@ pub fn upload(net_settings: NetSettings, value: String)
|
||||
}
|
||||
|
||||
info!("crypto complete, sending data");
|
||||
|
||||
for v in values {
|
||||
|
||||
info!("sending [{}]", v);
|
||||
|
||||
if let Ok(encryption_message) = generate_string_encryption_message(
|
||||
v,
|
||||
&mut OsRng,
|
||||
&domain_config,
|
||||
crypto_context.clone(),
|
||||
&net_settings.address
|
||||
) {
|
||||
send_message(encryption_message, &tx_channel);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
[package]
|
||||
name = "dnstp"
|
||||
version = "0.1.0"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
documentation.workspace = true
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
@ -17,6 +17,7 @@ use dnstplib::processor::RequestProcesor;
|
||||
|
||||
/// Command-line arguments for configuring the server
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "DNSTPd")]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Addresses to bind server to
|
||||
|
@ -1,6 +1,8 @@
|
||||
[package]
|
||||
name = "dnstplib"
|
||||
version = "0.1.0"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
documentation.workspace = true
|
||||
edition = "2021"
|
||||
publish = ["sargit"]
|
||||
|
||||
@ -13,3 +15,4 @@ urlencoding = "2.1.3"
|
||||
rand_core = { version = "0.6.4", features = ["getrandom"] }
|
||||
p256 = { version = "0.13.2", features = ["ecdh"] }
|
||||
aes-gcm-siv = "0.11.1"
|
||||
base64 = "0.22.1"
|
@ -49,14 +49,6 @@ pub fn get_shared_asym_secret(secret: &EphemeralSecret, opposing_public_key: &St
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn generate_aes_nonce() -> Nonce
|
||||
// {
|
||||
// let mut nonce_buffer: [u8; 12] = [0; 12];
|
||||
// &OsRng.fill_bytes(&mut nonce_buffer);
|
||||
//
|
||||
// Nonce::from(nonce_buffer)
|
||||
// }
|
||||
|
||||
/// Generate a safe nonce to use in symmetric encryption
|
||||
pub fn generate_aes_nonce() -> Nonce
|
||||
{
|
||||
|
@ -1,8 +1,6 @@
|
||||
//! # Common Functionality
|
||||
//! The vast majority of functionality is in this library crate. The client and server executable crates are really just wiring up bits and pieces from this library.
|
||||
|
||||
pub mod message_parser;
|
||||
|
||||
mod byte;
|
||||
pub mod processor;
|
||||
pub mod message;
|
||||
@ -10,10 +8,9 @@ pub mod net;
|
||||
pub mod string;
|
||||
pub mod config;
|
||||
pub mod crypto;
|
||||
pub mod clients;
|
||||
pub mod client_crypto_context;
|
||||
pub mod session;
|
||||
|
||||
use std::sync::mpsc::{Sender};
|
||||
use std::sync::mpsc::Sender;
|
||||
use log::error;
|
||||
pub use config::DomainConfig;
|
||||
use crate::message::DNSMessage;
|
||||
|
@ -102,29 +102,29 @@ impl DNSHeader {
|
||||
{
|
||||
let mut header_bytes: [u8; 12] = [0; 12];
|
||||
|
||||
apply_split_bytes(&mut header_bytes, self.id, crate::message_parser::ID_START);
|
||||
apply_split_bytes(&mut header_bytes, self.id, crate::message::message_parser::ID_START);
|
||||
|
||||
let mut flags: u16 = 0;
|
||||
|
||||
if self.direction == Response {
|
||||
flags |= 0b1 << crate::message_parser::DIRECTION_SHIFT;
|
||||
flags |= 0b1 << crate::message::message_parser::DIRECTION_SHIFT;
|
||||
}
|
||||
|
||||
flags |= (self.opcode as u16) << crate::message_parser::OPCODE_SHIFT;
|
||||
flags |= (self.opcode as u16) << crate::message::message_parser::OPCODE_SHIFT;
|
||||
|
||||
flags |= (self.authoritative as u16) << crate::message_parser::AUTHORITATIVE_SHIFT;
|
||||
flags |= (self.truncation as u16) << crate::message_parser::TRUNCATION_SHIFT;
|
||||
flags |= (self.recursion_desired as u16) << crate::message_parser::RECURSION_DESIRED_SHIFT;
|
||||
flags |= (self.recursion_available as u16) << crate::message_parser::RECURSION_AVAILABLE_SHIFT;
|
||||
flags |= (self.authoritative as u16) << crate::message::message_parser::AUTHORITATIVE_SHIFT;
|
||||
flags |= (self.truncation as u16) << crate::message::message_parser::TRUNCATION_SHIFT;
|
||||
flags |= (self.recursion_desired as u16) << crate::message::message_parser::RECURSION_DESIRED_SHIFT;
|
||||
flags |= (self.recursion_available as u16) << crate::message::message_parser::RECURSION_AVAILABLE_SHIFT;
|
||||
|
||||
flags |= self.response as u16;
|
||||
|
||||
apply_split_bytes(&mut header_bytes, flags, crate::message_parser::FLAGS_START);
|
||||
apply_split_bytes(&mut header_bytes, flags, crate::message::message_parser::FLAGS_START);
|
||||
|
||||
apply_split_bytes(&mut header_bytes, self.question_count, crate::message_parser::QUESTION_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.answer_record_count, crate::message_parser::ANSWER_RECORD_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.authority_record_count, crate::message_parser::AUTHORITY_RECORD_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.additional_record_count, crate::message_parser::ADDITIONAL_RECORD_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.question_count, crate::message::message_parser::QUESTION_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.answer_record_count, crate::message::message_parser::ANSWER_RECORD_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.authority_record_count, crate::message::message_parser::AUTHORITY_RECORD_COUNT_START);
|
||||
apply_split_bytes(&mut header_bytes, self.additional_record_count, crate::message::message_parser::ADDITIONAL_RECORD_COUNT_START);
|
||||
|
||||
header_bytes
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ impl DNSMessage {
|
||||
response
|
||||
}
|
||||
|
||||
pub fn protocol_error_from_request(&self, error_code: RequestError) -> DNSMessage
|
||||
pub fn protocol_error_from_request(&self, _error_code: RequestError) -> DNSMessage
|
||||
{
|
||||
let txt = Box::new(TXTRdata::from(String::new()));
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::byte;
|
||||
use crate::message::{DNSMessage, Direction, DNSHeader, Opcode, ResponseCode, QuestionParseError, questions_from_bytes, records_from_bytes, RecordParseError};
|
||||
use crate::net::NetworkMessage;
|
||||
use crate::message_parser::MessageParseError::{HeaderParse, QuesionsParse};
|
||||
use crate::message::MessageParseError::{HeaderParse, QuesionsParse};
|
||||
|
||||
pub const ID_START: usize = 0;
|
||||
pub const FLAGS_START: usize = 2;
|
@ -3,8 +3,10 @@ pub mod header;
|
||||
pub mod question;
|
||||
pub mod message;
|
||||
pub mod record;
|
||||
pub mod message_parser;
|
||||
|
||||
pub use question::{DNSQuestion, QClass, QType, QuestionParseError, questions_to_bytes, questions_from_bytes};
|
||||
pub use record::{ResourceRecord, RawRData, RData, ARdata, AAAARdata, TXTRdata, RecordParseError, records_to_bytes, records_from_bytes};
|
||||
pub use header::{DNSHeader, Direction, Opcode, ResponseCode, HEADER_SIZE};
|
||||
pub use question::{DNSQuestion, QClass, QType, QuestionParseError, questions_from_bytes, questions_to_bytes};
|
||||
pub use record::{AAAARdata, ARdata, RawRData, RData, RecordParseError, records_from_bytes, records_to_bytes, ResourceRecord, TXTRdata};
|
||||
pub use header::{Direction, DNSHeader, HEADER_SIZE, Opcode, ResponseCode};
|
||||
pub use message::DNSMessage;
|
||||
pub use message_parser::*;
|
@ -19,7 +19,7 @@ fn one_question_back_and_forth() {
|
||||
let mut q_bytes = q.to_bytes();
|
||||
q_bytes.append(&mut vec![0, 0, 0, 0, 0, 0]);
|
||||
|
||||
let (q_reconstructed, q_remaining) = questions_from_bytes(q_bytes, 1).unwrap();
|
||||
let (q_reconstructed, _q_remaining) = questions_from_bytes(q_bytes, 1).unwrap();
|
||||
|
||||
assert_questions_eq!(q, q_reconstructed[0]);
|
||||
}
|
||||
@ -43,7 +43,7 @@ fn two_questions_back_and_forth() {
|
||||
|
||||
q_bytes.append(&mut q2_bytes);
|
||||
|
||||
let (q_reconstructed, q_remaining) = questions_from_bytes(q_bytes, 2).unwrap();
|
||||
let (q_reconstructed, _q_remaining) = questions_from_bytes(q_bytes, 2).unwrap();
|
||||
|
||||
assert_questions_eq!(q, q_reconstructed[0]);
|
||||
assert_questions_eq!(q2, q_reconstructed[1]);
|
||||
@ -76,7 +76,7 @@ fn three_questions_back_and_forth() {
|
||||
q_bytes.append(&mut q2_bytes);
|
||||
q_bytes.append(&mut q3_bytes);
|
||||
|
||||
let (q_reconstructed, q_remaining) = questions_from_bytes(q_bytes, 3).unwrap();
|
||||
let (q_reconstructed, _q_remaining) = questions_from_bytes(q_bytes, 3).unwrap();
|
||||
|
||||
assert_questions_eq!(q, q_reconstructed[0]);
|
||||
assert_questions_eq!(q2, q_reconstructed[1]);
|
||||
|
@ -28,7 +28,7 @@ fn one_answer_back_and_forth() {
|
||||
let mut q_bytes = q.to_bytes();
|
||||
q_bytes.append(&mut vec![0, 0, 0, 0, 0, 0]);
|
||||
|
||||
let (q_reconstructed, q_remaining) = records_from_bytes(q_bytes, 1).unwrap();
|
||||
let (q_reconstructed, _q_remaining) = records_from_bytes(q_bytes, 1).unwrap();
|
||||
|
||||
assert_record_eq!(q, q_reconstructed[0]);
|
||||
}
|
||||
@ -59,7 +59,7 @@ fn two_answers_back_and_forth() {
|
||||
q_bytes.append(&mut q_2.to_bytes());
|
||||
q_bytes.append(&mut vec![0, 0, 0, 0, 0, 0]);
|
||||
|
||||
let (q_reconstructed, q_remaining) = records_from_bytes(q_bytes, 2).unwrap();
|
||||
let (q_reconstructed, _q_remaining) = records_from_bytes(q_bytes, 2).unwrap();
|
||||
|
||||
assert_record_eq!(q, q_reconstructed[0]);
|
||||
assert_record_eq!(q_2, q_reconstructed[1]);
|
||||
|
@ -84,10 +84,12 @@ impl DNSSocket {
|
||||
Ok((read_count, peer)) => {
|
||||
|
||||
if read_count > HEADER_SIZE {
|
||||
message_sender.send(Box::new(NetworkMessage {
|
||||
if let Err(_) = message_sender.send(Box::new(NetworkMessage {
|
||||
buffer: buf,
|
||||
peer
|
||||
}));
|
||||
})) {
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
debug!("skipping processing message from [{}], message isn't longer than standard header", peer);
|
||||
@ -155,11 +157,15 @@ impl DNSSocket {
|
||||
{
|
||||
// if let Some(t) = &mut self.thread {
|
||||
if let Some(k) = &self.rx_thread_killer {
|
||||
k.send(());
|
||||
if let Err(_) = k.send(()) {
|
||||
|
||||
}
|
||||
// t.join();
|
||||
}
|
||||
if let Some(k) = &self.tx_thread_killer {
|
||||
k.send(());
|
||||
if let Err(_) = k.send(()) {
|
||||
|
||||
}
|
||||
// t.join();
|
||||
}
|
||||
// }
|
||||
|
@ -7,8 +7,7 @@ use std::net::SocketAddr;
|
||||
use log::error;
|
||||
pub use request::RequestProcesor;
|
||||
pub use response::ResponseProcesor;
|
||||
use crate::message::{QuestionParseError, RecordParseError};
|
||||
use crate::message_parser::{HeaderParseError, MessageParseError};
|
||||
use crate::message::{QuestionParseError, RecordParseError, HeaderParseError, MessageParseError};
|
||||
|
||||
pub fn print_error(e: MessageParseError, peer: &SocketAddr)
|
||||
{
|
||||
|
@ -0,0 +1,20 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use log::{error, info};
|
||||
use crate::session::clients::Clients;
|
||||
use crate::message::DNSMessage;
|
||||
use crate::net::NetworkMessagePtr;
|
||||
use crate::processor::RequestProcesor;
|
||||
|
||||
impl RequestProcesor {
|
||||
pub fn handle_download_request(r: DNSMessage, _sending_channel: &Sender<NetworkMessagePtr>, clients: &Arc<Mutex<Clients>>, peer: SocketAddr)
|
||||
{
|
||||
info!("[{}] received download request", peer);
|
||||
let client_id = &r.questions[0].qname;
|
||||
|
||||
if let Err(_) = clients.lock().unwrap().bump_last_seen(client_id) {
|
||||
error!("[{}] failed to bump last seen time", peer);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use std::net::Ipv4Addr;
|
||||
use p256::ecdh::EphemeralSecret;
|
||||
use crate::clients::Client;
|
||||
use crate::session::clients::Client;
|
||||
use crate::crypto::{asym_to_sym_key, get_random_asym_pair, get_shared_asym_secret, trim_public_key};
|
||||
use crate::message::{ARdata, DNSMessage, QClass, QType, ResourceRecord};
|
||||
use crate::message::record::CnameRdata;
|
||||
|
@ -2,13 +2,12 @@ use std::net::SocketAddr;
|
||||
use std::sync::{Arc, mpsc, Mutex};
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
use std::thread;
|
||||
use log::{error, info};
|
||||
use crate::clients::Clients;
|
||||
use log::{debug, error, info};
|
||||
use crate::session::Clients;
|
||||
use crate::config::DomainConfig;
|
||||
|
||||
use crate::message::{DNSMessage, QType};
|
||||
use crate::message::{DNSMessage, QType, parse_message};
|
||||
use crate::net::{NetworkMessagePtr};
|
||||
use crate::message_parser::parse_message;
|
||||
use crate::processor::print_error;
|
||||
use crate::processor::request::encryption::{decode_key_request, DecodeKeyRequestError};
|
||||
use crate::{RequestError, send_message};
|
||||
@ -60,7 +59,7 @@ impl RequestProcesor {
|
||||
|
||||
match parse_message(*m) {
|
||||
Ok(r) => {
|
||||
info!("received dns message: {:?}", r);
|
||||
debug!("received dns message: {:?}", r);
|
||||
|
||||
// If there is a question containing the protocol base domain, treat it as a dnstp request
|
||||
// (handshake, upload, download) and handle as such
|
||||
@ -156,20 +155,6 @@ impl RequestProcesor {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_download_request(r: DNSMessage, sending_channel: &Sender<NetworkMessagePtr>, clients: &Arc<Mutex<Clients>>, peer: SocketAddr)
|
||||
{
|
||||
info!("[{}] received download request", peer);
|
||||
let client_id = &r.questions[0].qname;
|
||||
clients.lock().unwrap().bump_last_seen(client_id);
|
||||
}
|
||||
|
||||
fn handle_upload_request(r: DNSMessage, sending_channel: &Sender<NetworkMessagePtr>, clients: &Arc<Mutex<Clients>>, peer: SocketAddr)
|
||||
{
|
||||
info!("[{}] received upload request", peer);
|
||||
let client_id = &r.questions[0].qname;
|
||||
clients.lock().unwrap().bump_last_seen(client_id);
|
||||
}
|
||||
|
||||
pub fn get_message_channel(&mut self) -> Option<Sender<NetworkMessagePtr>>
|
||||
{
|
||||
self.message_channel.clone()
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::string::encode_domain_name;
|
||||
use super::*;
|
||||
// use super::*;
|
||||
use super::encryption::*;
|
||||
|
||||
#[test]
|
||||
fn encryption()
|
||||
{
|
||||
let (private, public) = get_key_request_with_base_domain(String::from("sarsoo.xyz"));
|
||||
let (_private, public) = get_key_request_with_base_domain(String::from("sarsoo.xyz"));
|
||||
|
||||
let encoded = encode_domain_name(&public);
|
||||
let _encoded = encode_domain_name(&public);
|
||||
// let decoded = decode_domain_name();
|
||||
|
||||
assert_eq!(1, 1);
|
||||
|
@ -0,0 +1,61 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use aes_gcm_siv::Nonce;
|
||||
use log::{info, error};
|
||||
use base64::prelude::*;
|
||||
|
||||
// use std::fs::OpenOptions;
|
||||
// use std::io::prelude::*;
|
||||
|
||||
use crate::session::clients::Clients;
|
||||
use crate::crypto::decrypt;
|
||||
use crate::message::DNSMessage;
|
||||
use crate::net::NetworkMessagePtr;
|
||||
use crate::processor::RequestProcesor;
|
||||
|
||||
impl RequestProcesor {
|
||||
pub fn handle_upload_request(r: DNSMessage, _sending_channel: &Sender<NetworkMessagePtr>, clients: &Arc<Mutex<Clients>>, peer: SocketAddr)
|
||||
{
|
||||
info!("[{}] received upload request", peer);
|
||||
let client_id = &r.questions[0].qname;
|
||||
|
||||
if let Err(_) = clients.lock().unwrap().bump_last_seen(client_id) {
|
||||
error!("[{}] failed to bump last seen time", peer);
|
||||
}
|
||||
|
||||
let encrypted_value = BASE64_STANDARD.decode(r.questions[1].qname.clone());
|
||||
let nonce_value = BASE64_STANDARD.decode(r.questions[2].qname.clone());
|
||||
|
||||
match (encrypted_value, nonce_value) {
|
||||
(Ok(encrypted_value), Ok(nonce_value)) => {
|
||||
let nonce = Nonce::from_slice(nonce_value.as_slice());
|
||||
let decrypted = decrypt(clients.lock().unwrap().get_shared_key(client_id).unwrap(), nonce, &encrypted_value).unwrap();
|
||||
let decrypted_string = String::from_utf8(decrypted).unwrap();
|
||||
|
||||
info!("[{}] decrypted [{}] from peer", peer, decrypted_string.as_str());
|
||||
|
||||
// let mut file = OpenOptions::new()
|
||||
// .read(true)
|
||||
// .write(true)
|
||||
// .append(true)
|
||||
// .create(true)
|
||||
// .open(client_id)
|
||||
// .unwrap();
|
||||
//
|
||||
// if let Err(e) = file.write(decrypted_string.as_bytes()) {
|
||||
// error!("[{}] couldn't write to file: {}", peer, e);
|
||||
// }
|
||||
// if let Err(e) = file.write("\n".as_bytes()) {
|
||||
// error!("[{}] couldn't write to file: {}", peer, e);
|
||||
// }
|
||||
}
|
||||
(Err(e), _) => {
|
||||
error!("[{}] failed to decode encrypted value from peer: {}", peer, e);
|
||||
}
|
||||
(_, Err(e)) => {
|
||||
error!("[{}] failed to decode nonce from peer: {}", peer, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::client_crypto_context::ClientCryptoContext;
|
||||
use crate::session::client_crypto_context::ClientCryptoContext;
|
||||
use crate::crypto::{asym_to_sym_key, get_shared_asym_secret};
|
||||
use crate::message::DNSMessage;
|
||||
use crate::string::get_fattened_public_key;
|
||||
|
@ -3,10 +3,10 @@ mod encryption;
|
||||
use std::sync::{Arc, mpsc, Mutex};
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
use std::thread;
|
||||
use log::{error, info};
|
||||
use crate::client_crypto_context::ClientCryptoContext;
|
||||
use log::{error, info, debug};
|
||||
use crate::session::client_crypto_context::ClientCryptoContext;
|
||||
use crate::net::raw_request::NetworkMessagePtr;
|
||||
use crate::message_parser::parse_message;
|
||||
use crate::message::parse_message;
|
||||
use crate::processor::print_error;
|
||||
use crate::processor::response::encryption::{decode_key_response, DecodeKeyResponseError};
|
||||
use crate::string::DomainDecodeError;
|
||||
@ -39,7 +39,7 @@ impl ResponseProcesor {
|
||||
|
||||
match parse_message(*m) {
|
||||
Ok(r) => {
|
||||
info!("received dns message: {:?}", r);
|
||||
debug!("received dns message: {:?}", r);
|
||||
|
||||
match decode_key_response(&r, crypto_context.clone())
|
||||
{
|
||||
|
@ -73,4 +73,15 @@ impl Clients {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_shared_key(&mut self, client_id: &String) -> Result<&Aes256GcmSiv, ()>
|
||||
{
|
||||
match self.client_map.get_mut(client_id)
|
||||
{
|
||||
None => Err(()),
|
||||
Some(client) => {
|
||||
Ok(&client.shared_key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
115
dnstp/src/session/message_generator.rs
Normal file
115
dnstp/src/session/message_generator.rs
Normal file
@ -0,0 +1,115 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use base64::Engine;
|
||||
use base64::prelude::BASE64_STANDARD;
|
||||
use rand_core::{OsRng, RngCore};
|
||||
use crate::crypto::{encrypt, generate_aes_nonce};
|
||||
use crate::DomainConfig;
|
||||
use crate::message::{Direction, DNSHeader, DNSMessage, DNSQuestion, Opcode, QClass, QType, ResponseCode};
|
||||
use crate::session::ClientCryptoContext;
|
||||
|
||||
pub fn generate_client_handshake_message(rand: &mut OsRng, domain_config: &DomainConfig, crypto_context: Arc<Mutex<ClientCryptoContext>>, peer: &String) -> DNSMessage {
|
||||
get_client_handshake_message(
|
||||
rand.next_u32() as u16,
|
||||
domain_config.get_fq_key_endpoint(),
|
||||
crypto_context.lock().unwrap().get_public_key_domain(&domain_config.base_domain),
|
||||
peer
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_client_handshake_message(msg_id: u16, key_domain: String, public_key_domain: String, peer: &String) -> DNSMessage {
|
||||
DNSMessage {
|
||||
header: DNSHeader {
|
||||
id: msg_id,
|
||||
direction: Direction::Request,
|
||||
opcode: Opcode::Query,
|
||||
authoritative: false,
|
||||
truncation: false,
|
||||
recursion_desired: false,
|
||||
recursion_available: false,
|
||||
valid_zeroes: true,
|
||||
response: ResponseCode::NoError,
|
||||
question_count: 2,
|
||||
answer_record_count: 0,
|
||||
authority_record_count: 0,
|
||||
additional_record_count: 0,
|
||||
},
|
||||
questions: vec![
|
||||
DNSQuestion {
|
||||
qname: key_domain,
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
},
|
||||
DNSQuestion {
|
||||
qname: public_key_domain,
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
}
|
||||
],
|
||||
answer_records: vec![],
|
||||
authority_records: vec![],
|
||||
additional_records: vec![],
|
||||
peer: peer.parse().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_string_encryption_message(value: String, rand: &mut OsRng, domain_config: &DomainConfig, crypto_context: Arc<Mutex<ClientCryptoContext>>, peer: &String) -> Result<DNSMessage, ()> {
|
||||
|
||||
let nonce = generate_aes_nonce();
|
||||
let encrypted = encrypt(&crypto_context.lock().unwrap().shared_key.clone().unwrap(), &nonce, &value.clone().into_bytes());
|
||||
|
||||
if let Ok(e) = encrypted {
|
||||
let encrypted_string = BASE64_STANDARD.encode(e);
|
||||
let nonce_string = BASE64_STANDARD.encode(nonce);
|
||||
|
||||
return Ok(get_string_encryption_message(
|
||||
rand.next_u32() as u16,
|
||||
crypto_context.lock().unwrap().get_public_key_domain(&domain_config.base_domain),
|
||||
encrypted_string,
|
||||
nonce_string,
|
||||
peer
|
||||
))
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
|
||||
pub fn get_string_encryption_message(msg_id: u16, public_key_domain: String, encrypted_string: String, nonce_string: String, peer: &String) -> DNSMessage {
|
||||
DNSMessage {
|
||||
header: DNSHeader {
|
||||
id: msg_id,
|
||||
direction: Direction::Request,
|
||||
opcode: Opcode::Query,
|
||||
authoritative: false,
|
||||
truncation: false,
|
||||
recursion_desired: false,
|
||||
recursion_available: false,
|
||||
valid_zeroes: true,
|
||||
response: ResponseCode::NoError,
|
||||
question_count: 3,
|
||||
answer_record_count: 0,
|
||||
authority_record_count: 0,
|
||||
additional_record_count: 0,
|
||||
},
|
||||
questions: vec![
|
||||
DNSQuestion {
|
||||
qname: public_key_domain,
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
},
|
||||
DNSQuestion {
|
||||
qname: encrypted_string,
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
},
|
||||
DNSQuestion {
|
||||
qname: nonce_string,
|
||||
qtype: QType::A,
|
||||
qclass: QClass::Internet,
|
||||
}
|
||||
],
|
||||
answer_records: vec![],
|
||||
authority_records: vec![],
|
||||
additional_records: vec![],
|
||||
peer: peer.parse().unwrap(),
|
||||
}
|
||||
}
|
7
dnstp/src/session/mod.rs
Normal file
7
dnstp/src/session/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub mod clients;
|
||||
pub mod client_crypto_context;
|
||||
mod message_generator;
|
||||
|
||||
pub use clients::Clients;
|
||||
pub use client_crypto_context::ClientCryptoContext;
|
||||
pub use message_generator::{generate_client_handshake_message, generate_string_encryption_message};
|
Loading…
Reference in New Issue
Block a user