From 5c140d011faecabee26821632219a15b0de526c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=BB=E9=AD=82=E5=9C=A3=E4=BD=BF?= Date: Sun, 23 Feb 2025 16:36:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5=E5=AE=A2=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/mod.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +- src/packet/mod.rs | 2 +- src/server/Client.rs | 3 +- src/server/accept.rs | 22 +--------- src/stream.rs | 29 +++++++++++++ 6 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 src/client/mod.rs create mode 100644 src/stream.rs diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..de9d7da --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,99 @@ +// 版权所有 (c) ling 保留所有权利。 +// 除非另行说明,否则仅允许在LingTransmit中使用此文件中的代码。 +// +// 由 ling 创建于 2025/1/19. +#![allow(non_snake_case)] + +use crate::packet::code::*; +use crate::stream::{OwnedReadHalfAbstraction, OwnedWriteHalfAbstraction}; +use log::trace; +use openssl::x509::{X509NameEntryRef, X509}; +use std::io; +use std::sync::Arc; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::{TcpStream, ToSocketAddrs}; +use tokio::sync::Mutex; + +/// 客户端 +pub struct Client { + read: Arc>, + write: Arc>, +} + +impl Client { + fn init( + read: Arc>, + write: Arc>, + ) -> Self { + Client { read, write } + } + + pub async fn tcp_connect(addr: A, ca: X509) -> io::Result { + let stream = TcpStream::connect(addr).await?; + let (read, write) = stream.into_split(); + + let read: Arc> = Arc::new(Mutex::new(read)); + let write: Arc> = Arc::new(Mutex::new(write)); + + let buffer = Self::protocol_connection(read.clone(), write.clone()).await?; + let cert = X509::from_pem(&*buffer)?; + //先验证证书签名 + let ca_public = ca + .public_key() + .map_err(|_| io::Error::new(io::ErrorKind::NotFound, "无法提取CA公钥"))?; + + if !cert.verify(&ca_public).map_err(|e| { + io::Error::new( + io::ErrorKind::NotFound, + format!("无法验证服务器证书签名:{}", e.to_string()), + ) + })? { + return Err(io::Error::new( + io::ErrorKind::NotFound, + "服务器证书缺少信任的CA签名", + )); + } + //在此实现中阻止私域证书 + let subject_name = cert.subject_name(); + let cn = match subject_name + .entries_by_nid(openssl::nid::Nid::COMMONNAME) + .next() + { + None => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + "无法获得签发对象信息", + )); + } + Some(cn) => cn, + }; + + todo!() + } + + /// 执行协议握手, + async fn protocol_connection( + read: Arc>, + write: Arc>, + ) -> io::Result> { + let mut write = write.lock().await; + let mut read = read.lock().await; + //请求执行 Ling Transmit V1.1 握手 + write.write_i32_le(LING_SYN_V1).await?; + //读取证书大小 + let ca_size = read.read_i64_le().await?; + if ca_size <= 0 { + return Err(io::Error::new( + io::ErrorKind::NetworkDown, + format!("读取到异常数据包大小:{}", ca_size), + )); + } + trace!("证书大小:{:X}", ca_size); + //读取服务器证书 + let mut buffer = Vec::new(); + buffer.resize(ca_size as usize, 0u8); + read.read_exact(&mut buffer).await?; + + Ok(buffer) + } +} diff --git a/src/lib.rs b/src/lib.rs index b8edd5f..42ce047 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,4 +2,6 @@ pub mod server; pub mod close_sender; pub mod packet; pub mod ssl; -pub mod shell; \ No newline at end of file +pub mod shell; +pub mod client; +pub mod stream; \ No newline at end of file diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 688d76c..b843be7 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -7,13 +7,13 @@ pub mod code; use crate::packet::code::*; -use crate::server::accept::OwnedReadHalfAbstraction; use crate::server::Client::Client; use std::fmt::format; use std::sync::atomic::Ordering; use std::sync::Arc; use std::{error, io}; use tokio::io::AsyncReadExt; +use crate::stream::OwnedReadHalfAbstraction; /// 数据包 pub enum NetworkPackets { diff --git a/src/server/Client.rs b/src/server/Client.rs index f3575c6..cbe099d 100644 --- a/src/server/Client.rs +++ b/src/server/Client.rs @@ -7,7 +7,6 @@ use crate::close_sender::CloseSender; use crate::packet::code::{SERVER_ACK, SERVER_ERROR}; use crate::packet::{read_packet, NetworkPackets}; -use crate::server::accept::{OwnedReadHalfAbstraction, OwnedWriteHalfAbstraction, SocketAddr}; use crate::server::event::ServerEvent; use crate::server::ClientID; use crate::ssl::ServerCert; @@ -20,6 +19,8 @@ use std::sync::{Arc, OnceLock}; use std::time::Duration; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::sync::Mutex; +use crate::server::accept::SocketAddr; +use crate::stream::{OwnedReadHalfAbstraction, OwnedWriteHalfAbstraction}; pub type ReadSoc = Mutex>>; pub type WriteSoc = Mutex>; diff --git a/src/server/accept.rs b/src/server/accept.rs index 696c7b9..d0f60af 100644 --- a/src/server/accept.rs +++ b/src/server/accept.rs @@ -6,28 +6,8 @@ use async_trait::async_trait; use tokio::io; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::{tcp, unix, TcpListener, UnixListener}; - -/// 读取抽象 -#[async_trait] -pub trait OwnedReadHalfAbstraction: AsyncRead + Unpin + Send + Sync {} - -/// 写入抽象 -#[async_trait] -pub trait OwnedWriteHalfAbstraction: AsyncWrite + Unpin + Send + Sync {} - -#[async_trait] -impl OwnedReadHalfAbstraction for tcp::OwnedReadHalf {} - -#[async_trait] -impl OwnedReadHalfAbstraction for unix::OwnedReadHalf {} - -#[async_trait] -impl OwnedWriteHalfAbstraction for tcp::OwnedWriteHalf {} - -#[async_trait] -impl OwnedWriteHalfAbstraction for unix::OwnedWriteHalf {} +use crate::stream::{OwnedReadHalfAbstraction, OwnedWriteHalfAbstraction}; #[async_trait] pub trait AcceptSocket: Send + Sync { diff --git a/src/stream.rs b/src/stream.rs new file mode 100644 index 0000000..a03ccbe --- /dev/null +++ b/src/stream.rs @@ -0,0 +1,29 @@ +// 版权所有 (c) ling 保留所有权利。 +// 除非另行说明,否则仅允许在LingTransmit中使用此文件中的代码。 +// +// 由 ling 创建于 2025/1/19. +#![allow(non_snake_case)] + +use async_trait::async_trait; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::net::{tcp, unix}; + +/// 读取抽象 +#[async_trait] +pub trait OwnedReadHalfAbstraction: AsyncRead + Unpin + Send + Sync {} + +/// 写入抽象 +#[async_trait] +pub trait OwnedWriteHalfAbstraction: AsyncWrite + Unpin + Send + Sync {} + +#[async_trait] +impl OwnedReadHalfAbstraction for tcp::OwnedReadHalf {} + +#[async_trait] +impl OwnedReadHalfAbstraction for unix::OwnedReadHalf {} + +#[async_trait] +impl OwnedWriteHalfAbstraction for tcp::OwnedWriteHalf {} + +#[async_trait] +impl OwnedWriteHalfAbstraction for unix::OwnedWriteHalf {} \ No newline at end of file