tun2proxy/src/tun2proxy.rs

515 lines
18 KiB
Rust
Raw Normal View History

2022-08-01 14:36:58 +00:00
use crate::virtdevice::VirtualTunDevice;
2021-09-02 11:30:23 +02:00
use mio::event::Event;
2022-08-01 14:36:58 +00:00
use mio::net::TcpStream;
2021-09-02 11:30:23 +02:00
use mio::unix::SourceFd;
2022-08-01 14:36:58 +00:00
use mio::{Events, Interest, Poll, Token};
use smoltcp::iface::{Interface, InterfaceBuilder, Routes, SocketHandle};
2021-09-02 11:30:23 +02:00
use smoltcp::phy::{Device, Medium, RxToken, TunTapInterface, TxToken};
2022-08-01 14:36:58 +00:00
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
2021-09-02 11:30:23 +02:00
use smoltcp::time::Instant;
2022-08-01 14:36:58 +00:00
use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Packet, Ipv6Packet, TcpPacket, UdpPacket};
use std::collections::{BTreeMap, HashMap};
use std::convert::From;
use std::io::{Read, Write};
2021-09-02 21:02:17 +02:00
use std::net::Shutdown::Both;
2022-08-01 14:36:58 +00:00
use std::net::{IpAddr, Shutdown, SocketAddr};
use std::os::unix::io::AsRawFd;
2021-09-02 11:30:23 +02:00
2021-09-02 21:02:17 +02:00
pub struct ProxyError {
2022-08-01 14:36:58 +00:00
message: String,
2021-09-02 21:02:17 +02:00
}
impl ProxyError {
pub fn new(message: String) -> Self {
2022-08-01 14:36:58 +00:00
Self { message }
2021-09-02 21:02:17 +02:00
}
pub fn message(&self) -> String {
self.message.clone()
}
}
2021-09-02 11:30:23 +02:00
2022-08-01 14:36:58 +00:00
#[derive(Hash, Clone, Copy, Eq, PartialEq)]
2021-09-02 11:30:23 +02:00
pub struct Connection {
pub src: std::net::SocketAddr,
pub dst: std::net::SocketAddr,
2022-08-01 14:36:58 +00:00
pub proto: u8,
2021-09-02 11:30:23 +02:00
}
2021-09-02 21:02:17 +02:00
impl std::fmt::Display for Connection {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{} -> {}", self.src, self.dst)
}
}
2021-09-02 11:30:23 +02:00
#[derive(Eq, PartialEq, Debug)]
pub(crate) enum IncomingDirection {
FromServer,
2022-08-01 14:36:58 +00:00
FromClient,
2021-09-02 11:30:23 +02:00
}
#[derive(Eq, PartialEq, Debug)]
pub(crate) enum OutgoingDirection {
ToServer,
2022-08-01 14:36:58 +00:00
ToClient,
2021-09-02 11:30:23 +02:00
}
#[allow(dead_code)]
pub(crate) enum ConnectionEvent<'a> {
NewConnection(&'a Connection),
2022-08-01 14:36:58 +00:00
ConnectionClosed(&'a Connection),
2021-09-02 11:30:23 +02:00
}
pub(crate) struct DataEvent<'a, T> {
pub(crate) direction: T,
2022-08-01 14:36:58 +00:00
pub(crate) buffer: &'a [u8],
2021-09-02 11:30:23 +02:00
}
pub(crate) type IncomingDataEvent<'a> = DataEvent<'a, IncomingDirection>;
pub(crate) type OutgoingDataEvent<'a> = DataEvent<'a, OutgoingDirection>;
2022-08-01 14:36:58 +00:00
fn get_transport_info(
proto: u8,
transport_offset: usize,
packet: &[u8],
) -> Option<((u16, u16), bool, usize, usize)> {
2021-09-02 11:30:23 +02:00
if proto == smoltcp::wire::IpProtocol::Udp.into() {
match UdpPacket::new_checked(packet) {
2022-08-01 14:36:58 +00:00
Ok(result) => Some((
(result.src_port(), result.dst_port()),
false,
transport_offset + 8,
packet.len() - 8,
)),
Err(_) => None,
2021-09-02 11:30:23 +02:00
}
} else if proto == smoltcp::wire::IpProtocol::Tcp.into() {
match TcpPacket::new_checked(packet) {
2022-08-01 14:36:58 +00:00
Ok(result) => Some((
(result.src_port(), result.dst_port()),
result.syn() && !result.ack(),
transport_offset + result.header_len() as usize,
packet.len(),
)),
Err(_) => None,
2021-09-02 11:30:23 +02:00
}
2022-08-01 14:36:58 +00:00
} else {
2021-09-02 11:30:23 +02:00
None
}
}
fn connection_tuple(frame: &[u8]) -> Option<(Connection, bool, usize, usize)> {
2022-08-01 14:36:58 +00:00
if let Ok(packet) = Ipv4Packet::new_checked(frame) {
let proto: u8 = packet.protocol().into();
let mut a: [u8; 4] = Default::default();
a.copy_from_slice(packet.src_addr().as_bytes());
let src_addr = IpAddr::from(a);
a.copy_from_slice(packet.dst_addr().as_bytes());
let dst_addr = IpAddr::from(a);
if let Some((ports, first_packet, payload_offset, payload_size)) = get_transport_info(
proto,
packet.header_len().into(),
&frame[packet.header_len().into()..],
) {
let connection = Connection {
src: SocketAddr::new(src_addr, ports.0),
dst: SocketAddr::new(dst_addr, ports.1),
proto,
};
return Some((connection, first_packet, payload_offset, payload_size));
} else {
return None;
2021-09-02 11:30:23 +02:00
}
}
match Ipv6Packet::new_checked(frame) {
Ok(packet) => {
// TODO: Support extension headers.
2022-08-01 14:36:58 +00:00
let proto: u8 = packet.next_header().into();
2021-09-02 11:30:23 +02:00
let mut a: [u8; 16] = Default::default();
a.copy_from_slice(packet.src_addr().as_bytes());
let src_addr = IpAddr::from(a);
a.copy_from_slice(packet.dst_addr().as_bytes());
let dst_addr = IpAddr::from(a);
2022-08-01 14:36:58 +00:00
if let Some((ports, first_packet, payload_offset, payload_size)) =
get_transport_info(proto, packet.header_len(), &frame[packet.header_len()..])
{
2021-09-02 11:30:23 +02:00
let connection = Connection {
src: SocketAddr::new(src_addr, ports.0),
dst: SocketAddr::new(dst_addr, ports.1),
2022-08-01 14:36:58 +00:00
proto,
2021-09-02 11:30:23 +02:00
};
Some((connection, first_packet, payload_offset, payload_size))
} else {
None
}
}
2022-08-01 14:36:58 +00:00
_ => None,
2021-09-02 11:30:23 +02:00
}
}
struct ConnectionState {
smoltcp_handle: SocketHandle,
mio_stream: TcpStream,
2021-09-02 22:36:47 +02:00
token: Token,
2022-08-01 14:36:58 +00:00
handler: std::boxed::Box<dyn TcpProxy>,
2021-09-02 11:30:23 +02:00
}
pub(crate) trait TcpProxy {
2021-09-02 21:02:17 +02:00
fn push_data(&mut self, event: IncomingDataEvent<'_>) -> Result<(), ProxyError>;
2021-09-02 11:30:23 +02:00
fn consume_data(&mut self, dir: OutgoingDirection, size: usize);
fn peek_data(&mut self, dir: OutgoingDirection) -> OutgoingDataEvent;
2021-09-02 21:02:17 +02:00
fn connection_established(&self) -> bool;
2021-09-02 11:30:23 +02:00
}
pub(crate) trait ConnectionManager {
fn handles_connection(&self, connection: &Connection) -> bool;
fn new_connection(&mut self, connection: &Connection) -> Option<std::boxed::Box<dyn TcpProxy>>;
fn close_connection(&mut self, connection: &Connection);
fn get_server(&self) -> SocketAddr;
}
pub(crate) struct TunToProxy<'a> {
tun: TunTapInterface,
poll: Poll,
tun_token: Token,
udp_token: Token,
iface: Interface<'a, VirtualTunDevice>,
connections: HashMap<Connection, ConnectionState>,
connection_managers: Vec<std::boxed::Box<dyn ConnectionManager>>,
next_token: usize,
token_to_connection: HashMap<Token, Connection>,
}
impl<'a> TunToProxy<'a> {
pub(crate) fn new(interface: &str) -> Self {
let tun_token = Token(0);
let tun = TunTapInterface::new(interface, Medium::Ip).unwrap();
let poll = Poll::new().unwrap();
2022-08-01 14:36:58 +00:00
poll.registry()
.register(
&mut SourceFd(&tun.as_raw_fd()),
tun_token,
Interest::READABLE,
)
.unwrap();
2021-09-02 11:30:23 +02:00
let virt = VirtualTunDevice::new(tun.capabilities());
2022-08-01 14:36:58 +00:00
let builder = InterfaceBuilder::new(virt, vec![]);
let ip_addrs = [IpCidr::new(IpAddress::v4(0, 0, 0, 1), 0)];
2021-09-02 11:30:23 +02:00
let mut routes = Routes::new(BTreeMap::new());
2022-08-01 14:36:58 +00:00
routes
.add_default_ipv4_route(Ipv4Address::new(0, 0, 0, 1))
.unwrap();
2021-09-02 11:30:23 +02:00
2022-08-01 14:36:58 +00:00
let iface = builder
.any_ip(true)
.ip_addrs(ip_addrs)
.routes(routes)
.finalize();
2021-09-02 11:30:23 +02:00
Self {
tun,
poll,
tun_token,
udp_token: Token(1),
iface,
connections: Default::default(),
next_token: 2,
token_to_connection: Default::default(),
2022-08-01 14:36:58 +00:00
connection_managers: Default::default(),
2021-09-02 11:30:23 +02:00
}
}
pub(crate) fn add_connection_manager(&mut self, manager: Box<dyn ConnectionManager>) {
self.connection_managers.push(manager);
}
fn expect_smoltcp_send(&mut self) {
2022-08-01 14:36:58 +00:00
self.iface.poll(Instant::now()).unwrap();
2021-09-02 11:30:23 +02:00
while let Some(vec) = self.iface.device_mut().exfiltrate_packet() {
let slice = vec.as_slice();
// TODO: Actual write. Replace.
2022-08-01 14:36:58 +00:00
self.tun
.transmit()
.unwrap()
.consume(Instant::now(), slice.len(), |buf| {
buf[..].clone_from_slice(slice);
Ok(())
})
.unwrap();
2021-09-02 11:30:23 +02:00
}
}
fn remove_connection(&mut self, connection: &Connection) {
let mut connection_state = self.connections.remove(connection).unwrap();
self.token_to_connection.remove(&connection_state.token);
2022-08-01 14:36:58 +00:00
self.poll
.registry()
.deregister(&mut connection_state.mio_stream)
.unwrap();
2021-09-02 21:02:17 +02:00
println!("[{:?}] CLOSE {}", chrono::offset::Local::now(), connection);
2021-09-02 11:30:23 +02:00
}
2022-08-01 14:36:58 +00:00
fn get_connection_manager(&self, connection: &Connection) -> Option<&dyn ConnectionManager> {
2021-09-02 11:30:23 +02:00
for manager in self.connection_managers.iter() {
if manager.handles_connection(connection) {
2022-08-01 14:36:58 +00:00
return Some(manager.as_ref());
2021-09-02 11:30:23 +02:00
}
}
None
}
2021-09-02 21:02:17 +02:00
fn print_error(error: ProxyError) {
println!("Error: {}", error.message());
}
2021-09-02 11:30:23 +02:00
fn tunsocket_read_and_forward(&mut self, connection: &Connection) {
2022-08-01 14:36:58 +00:00
if let Some(state) = self.connections.get_mut(connection) {
2021-09-02 11:30:23 +02:00
let closed = {
2022-08-01 14:36:58 +00:00
let socket = self.iface.get_socket::<TcpSocket>(state.smoltcp_handle);
2021-09-02 21:02:17 +02:00
let mut error = Ok(());
while socket.can_recv() && error.is_ok() {
2022-08-01 14:36:58 +00:00
socket
.recv(|data| {
let event = IncomingDataEvent {
direction: IncomingDirection::FromClient,
buffer: data,
};
error = state.handler.push_data(event);
2021-09-02 11:30:23 +02:00
2022-08-01 14:36:58 +00:00
(data.len(), ())
})
.unwrap();
2021-09-02 11:30:23 +02:00
}
2022-08-01 14:36:58 +00:00
match error {
Ok(_) => socket.state() == smoltcp::socket::TcpState::CloseWait,
Err(e) => {
Self::print_error(e);
true
}
2021-09-02 21:02:17 +02:00
}
2021-09-02 11:30:23 +02:00
};
if closed {
2022-08-01 14:36:58 +00:00
let connection_state = self.connections.get_mut(connection).unwrap();
connection_state
.mio_stream
.shutdown(Shutdown::Both)
.unwrap();
self.remove_connection(connection);
2021-09-02 11:30:23 +02:00
}
}
}
fn receive_tun(&mut self, frame: &mut [u8]) {
2022-08-01 14:36:58 +00:00
if let Some((connection, first_packet, _payload_offset, _payload_size)) =
connection_tuple(frame)
{
2021-09-02 11:30:23 +02:00
if connection.proto == smoltcp::wire::IpProtocol::Tcp.into() {
let cm = self.get_connection_manager(&connection);
2022-08-01 14:36:58 +00:00
if cm.is_none() {
2021-09-02 11:30:23 +02:00
return;
}
let server = cm.unwrap().get_server();
if first_packet {
2021-09-02 22:36:47 +02:00
for manager in self.connection_managers.iter_mut() {
if let Some(handler) = manager.new_connection(&connection) {
let mut socket = TcpSocket::new(
TcpSocketBuffer::new(vec![0; 4096]),
2022-08-01 14:36:58 +00:00
TcpSocketBuffer::new(vec![0; 4096]),
);
2021-09-02 22:36:47 +02:00
socket.set_ack_delay(None);
socket.listen(connection.dst).unwrap();
2022-08-01 14:36:58 +00:00
let handle = self.iface.add_socket(socket);
2021-09-02 11:30:23 +02:00
2022-08-01 14:36:58 +00:00
let client = TcpStream::connect(server).unwrap();
2021-09-02 11:30:23 +02:00
2021-09-02 22:36:47 +02:00
let token = Token(self.next_token);
self.next_token += 1;
2021-09-02 11:30:23 +02:00
2021-09-02 22:36:47 +02:00
let mut state = ConnectionState {
smoltcp_handle: handle,
mio_stream: client,
token,
2022-08-01 14:36:58 +00:00
handler,
2021-09-02 22:36:47 +02:00
};
2021-09-02 11:30:23 +02:00
2021-09-02 22:36:47 +02:00
self.token_to_connection.insert(token, connection);
2022-08-01 14:36:58 +00:00
self.poll
.registry()
.register(
&mut state.mio_stream,
token,
Interest::READABLE | Interest::WRITABLE,
)
.unwrap();
2021-09-02 11:30:23 +02:00
2021-09-02 22:36:47 +02:00
self.connections.insert(connection, state);
2021-09-02 11:30:23 +02:00
2022-08-01 14:36:58 +00:00
println!(
"[{:?}] CONNECT {}",
chrono::offset::Local::now(),
connection
);
2021-09-02 11:30:23 +02:00
break;
}
}
} else if !self.connections.contains_key(&connection) {
return;
}
// Inject the packet to advance the smoltcp socket state
self.iface.device_mut().inject_packet(frame);
// Having advanced the socket state, we expect the socket to ACK
// Exfiltrate the response packets generated by the socket and inject them
// into the tunnel interface.
self.expect_smoltcp_send();
// Read from the smoltcp socket and push the data to the connection handler.
self.tunsocket_read_and_forward(&connection);
// The connection handler builds up the connection or encapsulates the data.
// Therefore, we now expect it to write data to the server.
self.write_to_server(&connection);
2022-08-01 14:36:58 +00:00
} else if connection.proto == smoltcp::wire::IpProtocol::Udp.into() {
2021-09-02 11:30:23 +02:00
/* // UDP is not yet supported.
if payload_offset > frame.len() || payload_offset + payload_offset > frame.len() {
return;
}
let payload = &frame[payload_offset..payload_offset+payload_size]; */
}
}
}
fn write_to_server(&mut self, connection: &Connection) {
2022-08-01 14:36:58 +00:00
if let Some(state) = self.connections.get_mut(connection) {
2021-09-02 22:36:47 +02:00
let event = state.handler.peek_data(OutgoingDirection::ToServer);
2022-08-01 14:36:58 +00:00
if event.buffer.is_empty() {
2021-09-02 11:30:23 +02:00
return;
}
2021-09-02 22:36:47 +02:00
let result = state.mio_stream.write(event.buffer);
2021-09-02 11:30:23 +02:00
match result {
Ok(consumed) => {
2022-08-01 14:36:58 +00:00
state
.handler
.consume_data(OutgoingDirection::ToServer, consumed);
2021-09-02 11:30:23 +02:00
}
2022-08-01 14:36:58 +00:00
Err(error) if error.kind() != std::io::ErrorKind::WouldBlock => {
2021-09-02 11:30:23 +02:00
panic!("Error: {:?}", error);
}
_ => {
// println!("{:?}", result);
}
}
}
}
fn write_to_client(&mut self, connection: &Connection) {
2022-08-01 14:36:58 +00:00
if let Some(state) = self.connections.get_mut(connection) {
2021-09-02 22:36:47 +02:00
let event = state.handler.peek_data(OutgoingDirection::ToClient);
2022-08-01 14:36:58 +00:00
let socket = &mut self.iface.get_socket::<TcpSocket>(state.smoltcp_handle);
2021-09-02 11:30:23 +02:00
if socket.may_send() {
let consumed = socket.send_slice(event.buffer).unwrap();
2022-08-01 14:36:58 +00:00
state
.handler
.consume_data(OutgoingDirection::ToClient, consumed);
2021-09-02 11:30:23 +02:00
}
}
}
fn tun_event(&mut self, event: &Event) {
if event.is_readable() {
while let Some((rx_token, _)) = self.tun.receive() {
if let Err(err) = rx_token.consume(Instant::now(), |frame| {
self.receive_tun(frame);
Ok(())
}) {
panic!("Error: {}", err);
}
}
}
}
fn mio_socket_event(&mut self, event: &Event) {
let connection = *self.token_to_connection.get(&event.token()).unwrap();
if event.is_readable() {
{
let state = self.connections.get_mut(&connection).unwrap();
let mut buf = [0u8; 4096];
let read = state.mio_stream.read(&mut buf).unwrap();
2021-09-02 21:02:17 +02:00
if read == 0 {
{
2022-08-01 14:36:58 +00:00
let socket = self.iface.get_socket::<TcpSocket>(
self.connections.get(&connection).unwrap().smoltcp_handle,
);
2021-09-02 21:02:17 +02:00
socket.close();
}
self.expect_smoltcp_send();
self.remove_connection(&connection.clone());
return;
}
2021-09-02 11:30:23 +02:00
let event = IncomingDataEvent {
direction: IncomingDirection::FromServer,
buffer: &buf[0..read],
};
2021-09-02 22:36:47 +02:00
if let Err(error) = state.handler.push_data(event) {
2021-09-02 21:02:17 +02:00
state.mio_stream.shutdown(Both).unwrap();
{
2022-08-01 14:36:58 +00:00
let socket = self.iface.get_socket::<TcpSocket>(
self.connections.get(&connection).unwrap().smoltcp_handle,
);
2021-09-02 21:02:17 +02:00
socket.close();
}
self.expect_smoltcp_send();
Self::print_error(error);
self.remove_connection(&connection.clone());
return;
}
2021-09-02 11:30:23 +02:00
}
// We have read from the proxy server and pushed the data to the connection handler.
// Thus, expect data to be processed (e.g. decapsulated) and forwarded to the client.
//self.expect_smoltcp_send();
self.write_to_client(&connection);
self.expect_smoltcp_send();
}
if event.is_writable() {
self.write_to_server(&connection);
}
}
2022-08-01 14:36:58 +00:00
fn udp_event(&mut self, _event: &Event) {}
2021-09-02 11:30:23 +02:00
pub(crate) fn run(&mut self) {
let mut events = Events::with_capacity(1024);
loop {
self.poll.poll(&mut events, None).unwrap();
for event in events.iter() {
if event.token() == self.tun_token {
self.tun_event(event);
} else if event.token() == self.udp_token {
self.udp_event(event);
} else {
self.mio_socket_event(event);
}
}
}
}
2022-08-01 14:36:58 +00:00
}