mirror of
https://github.com/cirruslabs/softnet.git
synced 2026-10-01 04:21:54 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5fd48cf03 | ||
|
|
d805100161 | ||
|
|
0528ec2002 |
@@ -5,6 +5,8 @@ project_name: softnet
|
||||
builds:
|
||||
- builder: rust
|
||||
command: build
|
||||
env:
|
||||
- SOFTNET_VERSION={{ .Version }}-{{ .ShortCommit }}
|
||||
targets:
|
||||
- aarch64-apple-darwin
|
||||
- x86_64-apple-darwin
|
||||
|
||||
Generated
+18
-8
@@ -368,9 +368,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.6.5"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301b56658598e48f3648647ac6fc887be7e7108eddfa4e9b63fcf3ec58c0cadf"
|
||||
checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -378,9 +378,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.6.5"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94a65403d1a1bd28f7dc68eb8506e8874808ee5eecb59298de588e2e1407a078"
|
||||
checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -458,6 +458,16 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@@ -2152,7 +2162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"core-foundation",
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
@@ -2596,12 +2606,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b"
|
||||
checksum = "501336eb7ba9e417300a6a0fa985721065467aa83a6dcf0422a8e43e4c0328fa"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"core-foundation",
|
||||
"core-foundation 0.10.1",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
|
||||
+26
-13
@@ -8,6 +8,13 @@ use dhcproto::v4::Opcode;
|
||||
use smoltcp::phy::ChecksumCapabilities;
|
||||
use smoltcp::wire::{EthernetFrame, EthernetProtocol, Ipv4Packet, Ipv4Repr, UdpPacket};
|
||||
|
||||
/// DhcpResponseDisposition distinguishes non-DHCP traffic from allowed and rejected DHCP replies.
|
||||
enum DhcpResponseDisposition {
|
||||
NotDhcp,
|
||||
Allow,
|
||||
Reject,
|
||||
}
|
||||
|
||||
impl Proxy<'_> {
|
||||
pub(crate) fn process_frame_from_host(&mut self, frame: &EthernetFrame<&[u8]>) -> Result<()> {
|
||||
if self.allowed_from_host(frame).is_none() {
|
||||
@@ -55,13 +62,14 @@ impl Proxy<'_> {
|
||||
}
|
||||
|
||||
pub(super) fn allowed_from_host_ipv4(&mut self, ipv4_pkt: &Ipv4Packet<&[u8]>) -> Option<()> {
|
||||
// Backwards compatibility with Softnet consumers that only use stateless rules
|
||||
if self.flows.is_none() {
|
||||
return Some(());
|
||||
match self.dhcp_response_disposition(ipv4_pkt) {
|
||||
DhcpResponseDisposition::NotDhcp => { /* Fall through to generic policy */ }
|
||||
DhcpResponseDisposition::Allow => return Some(()),
|
||||
DhcpResponseDisposition::Reject => return None,
|
||||
}
|
||||
|
||||
// DHCP is required to maintain the VM's lease and must bypass user-specified rules
|
||||
if self.is_allowed_dhcp_response(ipv4_pkt) {
|
||||
// Backwards compatibility with Softnet consumers that only use stateless rules
|
||||
if self.flows.is_none() {
|
||||
return Some(());
|
||||
}
|
||||
|
||||
@@ -119,8 +127,9 @@ impl Proxy<'_> {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if !self.is_allowed_dhcp_response(&ipv4_pkt) {
|
||||
return;
|
||||
match self.dhcp_response_disposition(&ipv4_pkt) {
|
||||
DhcpResponseDisposition::Allow => { /* Continue snooping */ }
|
||||
DhcpResponseDisposition::NotDhcp | DhcpResponseDisposition::Reject => return,
|
||||
}
|
||||
|
||||
let udp_pkt = match UdpPacket::new_checked(ipv4_pkt.payload()) {
|
||||
@@ -137,30 +146,34 @@ impl Proxy<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_allowed_dhcp_response(&self, ipv4_pkt: &Ipv4Packet<&[u8]>) -> bool {
|
||||
fn dhcp_response_disposition(&self, ipv4_pkt: &Ipv4Packet<&[u8]>) -> DhcpResponseDisposition {
|
||||
if ipv4_pkt.src_addr() != self.host.gateway_ip
|
||||
|| ipv4_pkt.next_header() != smoltcp::wire::IpProtocol::Udp
|
||||
{
|
||||
return false;
|
||||
return DhcpResponseDisposition::NotDhcp;
|
||||
}
|
||||
|
||||
let Ok(udp_pkt) = UdpPacket::new_checked(ipv4_pkt.payload()) else {
|
||||
return false;
|
||||
return DhcpResponseDisposition::NotDhcp;
|
||||
};
|
||||
|
||||
// Require the standard DHCP server and client ports
|
||||
if !udp_pkt.is_dhcp_response() {
|
||||
return false;
|
||||
return DhcpResponseDisposition::NotDhcp;
|
||||
}
|
||||
|
||||
// Require the BOOTP client hardware address to match this VM
|
||||
// (symmetric with is_allowed_dhcp_request / #191 on the VM→host path)
|
||||
let mut decoder = dhcproto::v4::Decoder::new(udp_pkt.payload());
|
||||
let Ok(message) = dhcproto::v4::Message::decode(&mut decoder) else {
|
||||
return false;
|
||||
return DhcpResponseDisposition::Reject;
|
||||
};
|
||||
|
||||
message_matches_bootp_client(&message, Opcode::BootReply, self.vm_mac_address.0)
|
||||
if message_matches_bootp_client(&message, Opcode::BootReply, self.vm_mac_address.0) {
|
||||
DhcpResponseDisposition::Allow
|
||||
} else {
|
||||
DhcpResponseDisposition::Reject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,13 @@ use system_configuration::sys::preferences::{
|
||||
};
|
||||
use uzers::{get_current_groupname, get_current_username, get_effective_uid};
|
||||
|
||||
const VERSION: &str = match option_env!("SOFTNET_VERSION") {
|
||||
Some(version) => version,
|
||||
None => "unknown-unknown",
|
||||
};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version = VERSION)]
|
||||
struct Args {
|
||||
#[clap(
|
||||
long,
|
||||
|
||||
Reference in New Issue
Block a user