mirror of
https://github.com/safing/portmaster
synced 2025-04-25 13:29:10 +00:00
[windows_kext] Remove inbound ALE layer
This commit is contained in:
parent
9fe140bd02
commit
1730250a86
4 changed files with 35 additions and 93 deletions
windows_kext
|
@ -7,10 +7,7 @@ use smoltcp::wire::{
|
|||
IpAddress, IpProtocol, Ipv4Address, Ipv6Address, IPV4_HEADER_LEN, IPV6_HEADER_LEN,
|
||||
};
|
||||
use wdk::filter_engine::callout_data::CalloutData;
|
||||
use wdk::filter_engine::layer::{
|
||||
self, FieldsAleAuthConnectV4, FieldsAleAuthConnectV6, FieldsAleAuthRecvAcceptV4,
|
||||
FieldsAleAuthRecvAcceptV6, ValueType,
|
||||
};
|
||||
use wdk::filter_engine::layer::{self, FieldsAleAuthConnectV4, FieldsAleAuthConnectV6, ValueType};
|
||||
use wdk::filter_engine::net_buffer::NetBufferList;
|
||||
use wdk::filter_engine::packet::{Injector, TransportPacketList};
|
||||
|
||||
|
@ -87,24 +84,6 @@ pub fn ale_layer_connect_v4(data: CalloutData) {
|
|||
ale_layer_auth(data, ale_data);
|
||||
}
|
||||
|
||||
pub fn ale_layer_accept_v4(data: CalloutData) {
|
||||
type Fields = FieldsAleAuthRecvAcceptV4;
|
||||
let ale_data = AleLayerData {
|
||||
is_ipv6: false,
|
||||
reauthorize: data.is_reauthorize(Fields::Flags as usize),
|
||||
process_id: data.get_process_id().unwrap_or(0),
|
||||
protocol: get_protocol(&data, Fields::IpProtocol as usize),
|
||||
direction: Direction::Inbound,
|
||||
local_ip: get_ipv4_address(&data, Fields::IpLocalAddress as usize),
|
||||
local_port: data.get_value_u16(Fields::IpLocalPort as usize),
|
||||
remote_ip: get_ipv4_address(&data, Fields::IpRemoteAddress as usize),
|
||||
remote_port: data.get_value_u16(Fields::IpRemotePort as usize),
|
||||
interface_index: data.get_value_u32(Fields::InterfaceIndex as usize),
|
||||
sub_interface_index: data.get_value_u32(Fields::SubInterfaceIndex as usize),
|
||||
};
|
||||
ale_layer_auth(data, ale_data);
|
||||
}
|
||||
|
||||
pub fn ale_layer_connect_v6(data: CalloutData) {
|
||||
type Fields = FieldsAleAuthConnectV6;
|
||||
|
||||
|
@ -125,24 +104,6 @@ pub fn ale_layer_connect_v6(data: CalloutData) {
|
|||
ale_layer_auth(data, ale_data);
|
||||
}
|
||||
|
||||
pub fn ale_layer_accept_v6(data: CalloutData) {
|
||||
type Fields = FieldsAleAuthRecvAcceptV6;
|
||||
let ale_data = AleLayerData {
|
||||
is_ipv6: true,
|
||||
reauthorize: data.is_reauthorize(Fields::Flags as usize),
|
||||
process_id: data.get_process_id().unwrap_or(0),
|
||||
protocol: get_protocol(&data, Fields::IpProtocol as usize),
|
||||
direction: Direction::Inbound,
|
||||
local_ip: get_ipv6_address(&data, Fields::IpLocalAddress as usize),
|
||||
local_port: data.get_value_u16(Fields::IpLocalPort as usize),
|
||||
remote_ip: get_ipv6_address(&data, Fields::IpRemoteAddress as usize),
|
||||
remote_port: data.get_value_u16(Fields::IpRemotePort as usize),
|
||||
interface_index: data.get_value_u32(Fields::InterfaceIndex as usize),
|
||||
sub_interface_index: data.get_value_u32(Fields::SubInterfaceIndex as usize),
|
||||
};
|
||||
ale_layer_auth(data, ale_data);
|
||||
}
|
||||
|
||||
fn ale_layer_auth(mut data: CalloutData, ale_data: AleLayerData) {
|
||||
let Some(device) = crate::entry::get_device() else {
|
||||
return;
|
||||
|
@ -287,7 +248,21 @@ fn save_packet(
|
|||
ale_data: &AleLayerData,
|
||||
pend: bool,
|
||||
) -> Result<Packet, alloc::string::String> {
|
||||
let packet_list = create_packet_list(device, callout_data, ale_data);
|
||||
let mut packet_list = None;
|
||||
let mut save_packet_list = true;
|
||||
match ale_data.protocol {
|
||||
IpProtocol::Tcp => {
|
||||
if let Direction::Outbound = ale_data.direction {
|
||||
// Only time a packet data is missing is during connect state of outbound TCP connection.
|
||||
// Don't save packet list only if connection is outbound, reauthorize is false and the protocol is TCP.
|
||||
save_packet_list = ale_data.reauthorize;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
if save_packet_list {
|
||||
packet_list = create_packet_list(device, callout_data, ale_data);
|
||||
}
|
||||
if pend && matches!(ale_data.protocol, IpProtocol::Tcp | IpProtocol::Udp) {
|
||||
match callout_data.pend_operation(packet_list) {
|
||||
Ok(classify_defer) => Ok(Packet::AleLayer(classify_defer)),
|
||||
|
|
|
@ -20,15 +20,6 @@ pub fn get_callout_vec() -> Vec<Callout> {
|
|||
FilterType::Resettable,
|
||||
ale_callouts::ale_layer_connect_v4,
|
||||
),
|
||||
Callout::new(
|
||||
"AleLayerInboundV4",
|
||||
"ALE layer for inbound connections for ipv4",
|
||||
0xc6021395_0724_4e2c_ae20_3dde51fc3c68,
|
||||
Layer::AleAuthRecvAcceptV4,
|
||||
consts::FWP_ACTION_CALLOUT_TERMINATING,
|
||||
FilterType::Resettable,
|
||||
ale_callouts::ale_layer_accept_v4,
|
||||
),
|
||||
Callout::new(
|
||||
"AleLayerOutboundV6",
|
||||
"ALE layer for outbound connections for ipv6",
|
||||
|
@ -38,15 +29,6 @@ pub fn get_callout_vec() -> Vec<Callout> {
|
|||
FilterType::Resettable,
|
||||
ale_callouts::ale_layer_connect_v6,
|
||||
),
|
||||
Callout::new(
|
||||
"AleLayerInboundV6",
|
||||
"ALE layer for inbound connections for ipv6",
|
||||
0xd24480da_38fa_4099_9383_b5c83b69e4f2,
|
||||
Layer::AleAuthRecvAcceptV6,
|
||||
consts::FWP_ACTION_CALLOUT_TERMINATING,
|
||||
FilterType::Resettable,
|
||||
ale_callouts::ale_layer_accept_v6,
|
||||
),
|
||||
// -----------------------------------------
|
||||
// ALE connection end layers
|
||||
Callout::new(
|
||||
|
|
|
@ -13,7 +13,6 @@ use crate::connection_cache::ConnectionCache;
|
|||
use crate::connection_map::Key;
|
||||
use crate::device::{Device, Packet};
|
||||
use crate::packet_util::{get_key_from_nbl_v4, get_key_from_nbl_v6, Redirect};
|
||||
use crate::{err, warn};
|
||||
|
||||
// IP packet layers
|
||||
pub fn ip_packet_layer_outbound_v4(data: CalloutData) {
|
||||
|
@ -141,7 +140,7 @@ fn ip_packet_layer(
|
|||
} {
|
||||
Ok(key) => key,
|
||||
Err(err) => {
|
||||
warn!("failed to get key from nbl: {}", err);
|
||||
crate::warn!("failed to get key from nbl: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -151,7 +150,7 @@ fn ip_packet_layer(
|
|||
return;
|
||||
}
|
||||
|
||||
let mut is_tmp_verdict = false;
|
||||
let mut send_request_to_portmaster = true;
|
||||
let mut process_id = 0;
|
||||
|
||||
if matches!(
|
||||
|
@ -164,13 +163,17 @@ fn ip_packet_layer(
|
|||
process_id = conn_info.process_id;
|
||||
// Check if there is action for this connection.
|
||||
match conn_info.verdict {
|
||||
Verdict::Undecided | Verdict::Accept | Verdict::Block | Verdict::Drop => {
|
||||
is_tmp_verdict = true
|
||||
Verdict::Undecided | Verdict::Accept | Verdict::Block | Verdict::Drop => {}
|
||||
Verdict::PermanentAccept => {
|
||||
send_request_to_portmaster = false;
|
||||
data.action_permit();
|
||||
}
|
||||
Verdict::PermanentBlock => {
|
||||
send_request_to_portmaster = false;
|
||||
data.action_block();
|
||||
}
|
||||
Verdict::PermanentAccept => data.action_permit(),
|
||||
Verdict::PermanentBlock => data.action_block(),
|
||||
Verdict::Undeterminable | Verdict::PermanentDrop | Verdict::Failed => {
|
||||
data.block_and_absorb()
|
||||
data.block_and_absorb();
|
||||
}
|
||||
Verdict::RedirectNameServer | Verdict::RedirectTunnel => {
|
||||
if let Some(redirect_info) = conn_info.redirect_info.take() {
|
||||
|
@ -186,10 +189,10 @@ fn ip_packet_layer(
|
|||
Ok(mut packet) => {
|
||||
let _ = packet.redirect(redirect_info);
|
||||
if let Err(err) = device.inject_packet(packet, false) {
|
||||
err!("failed to inject packet: {}", err);
|
||||
crate::err!("failed to inject packet: {}", err);
|
||||
}
|
||||
}
|
||||
Err(err) => err!("failed to clone packet: {}", err),
|
||||
Err(err) => crate::err!("failed to clone packet: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,25 +201,11 @@ fn ip_packet_layer(
|
|||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// TCP and UDP always need to go through ALE layer first.
|
||||
if matches!(direction, Direction::Inbound) {
|
||||
// If it's an inbound packet and the connection is not found, we need to continue to ALE layer
|
||||
data.action_permit();
|
||||
return;
|
||||
} else {
|
||||
// This happens sometimes. Leave the decision for portmaster. TODO(vladimir): Find out why.
|
||||
err!("Invalid state for: {}", key);
|
||||
is_tmp_verdict = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Every other protocol treat as a tmp verdict.
|
||||
is_tmp_verdict = true;
|
||||
}
|
||||
|
||||
// Clone packet and send to Portmaster if it's a temporary verdict.
|
||||
if is_tmp_verdict {
|
||||
// Clone packet and send to Portmaster.
|
||||
if send_request_to_portmaster {
|
||||
let packet = match clone_packet(
|
||||
device,
|
||||
nbl,
|
||||
|
@ -228,7 +217,7 @@ fn ip_packet_layer(
|
|||
) {
|
||||
Ok(p) => p,
|
||||
Err(err) => {
|
||||
err!("failed to clone packet: {}", err);
|
||||
crate::err!("failed to clone packet: {}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -236,6 +225,7 @@ fn ip_packet_layer(
|
|||
let info = device
|
||||
.packet_cache
|
||||
.push((key, packet), process_id, direction, false);
|
||||
|
||||
// Send to Portmaster
|
||||
if let Some(info) = info {
|
||||
let _ = device.event_queue.push(info);
|
||||
|
|
|
@ -32,13 +32,8 @@ impl ClassifyDefer {
|
|||
unsafe {
|
||||
match self {
|
||||
ClassifyDefer::Initial(context, packet_list) => {
|
||||
if let Some(packet) = packet_list {
|
||||
FwpsCompleteOperation0(context, packet.net_buffer_list.nbl as _);
|
||||
return Ok(Some(packet));
|
||||
} else {
|
||||
FwpsCompleteOperation0(context, core::ptr::null_mut());
|
||||
}
|
||||
return Ok(None);
|
||||
FwpsCompleteOperation0(context, core::ptr::null_mut());
|
||||
return Ok(packet_list);
|
||||
}
|
||||
ClassifyDefer::Reauthorization(_callout_id, packet_list) => {
|
||||
// There is no way to reset single filter. If another request for filter reset is trigger at the same time it will fail.
|
||||
|
|
Loading…
Add table
Reference in a new issue