diff --git a/.github/actions/setup-runner/action.yml b/.github/actions/setup-runner/action.yml index b95a16c3..aeb927f8 100644 --- a/.github/actions/setup-runner/action.yml +++ b/.github/actions/setup-runner/action.yml @@ -6,7 +6,6 @@ runs: - name: Set environment variables shell: bash run: | - echo "DOTNET_VERSION=10.x" >> $GITHUB_ENV echo "DOTNET_NOLOGO=false" >> $GITHUB_ENV echo "DOTNET_CLI_TELEMETRY_OPTOUT=true" >> $GITHUB_ENV echo "NUKE_TELEMETRY_OPTOUT=true" >> $GITHUB_ENV @@ -14,7 +13,7 @@ runs: - name: Set up .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: ${{ env.DOTNET_VERSION }} + global-json-file: global.json - name: Restore .NET tools shell: bash diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dcebc3c1..65a02899 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,6 +19,10 @@ on: - 'detailed' - 'diagnostic' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test-linux: name: 🐧 Test diff --git a/renovate.json b/renovate.json index aa2bce41..61a24bdb 100644 --- a/renovate.json +++ b/renovate.json @@ -1,15 +1,19 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:best-practices"], "timezone": "Europe/Berlin", "addLabels": [ "dependencies" ], - "minimumReleaseAge": "14 days", + "minimumReleaseAge": "7 days", "internalChecksFilter": "strict", - "prCreation": "not-pending", "dependencyDashboard": true, "prConcurrentLimit": 5, "prHourlyLimit": 0, + "vulnerabilityAlerts": { + "labels": ["security"], + "minimumReleaseAge": "1 day" + }, "automerge": false, "dockerfile": { //"pinDigests": true diff --git a/src/Scanning/Arp/LinuxArpTableProvider.cs b/src/Scanning/Arp/LinuxArpTableProvider.cs index 7ed3697c..907affd8 100644 --- a/src/Scanning/Arp/LinuxArpTableProvider.cs +++ b/src/Scanning/Arp/LinuxArpTableProvider.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.Net; using System.Runtime.Versioning; using Drift.Domain.Device.Addresses; @@ -6,22 +5,21 @@ namespace Drift.Scanning.Arp; internal class LinuxArpTableProvider : ArpTableProviderBase { - // TODO read from /proc/net/arp instead of spawning processes + private const string ProcArpPath = "/proc/net/arp"; + [SupportedOSPlatform( "linux" )] protected override ArpTable ReadSystemArpCache() { - const string procArpPath = "/proc/net/arp"; - - if ( !File.Exists( procArpPath ) ) { - throw new FileNotFoundException( $"Path not found: {procArpPath}" ); + if ( !File.Exists( ProcArpPath ) ) { + throw new FileNotFoundException( $"Path not found: {ProcArpPath}" ); } - using var streamReader = new StreamReader( procArpPath ); + using var streamReader = new StreamReader( ProcArpPath ); return ParseArpOutput( streamReader ); } /// - /// Parses the output of /proc/net/arp into an . + /// Parses the contents of /proc/net/arp into an . /// /// /// Format: @@ -33,10 +31,17 @@ protected override ArpTable ReadSystemArpCache() { internal static ArpTable ParseArpOutput( TextReader reader ) { var map = new Dictionary(); - reader.ReadLine(); // Skip header - while ( reader.ReadLine() is { } line ) { var parts = line.Split( (char[]?) null, StringSplitOptions.RemoveEmptyEntries ); + + if ( + parts[0].Count( c => c == '.' ) != 3 && // Dots in an IPv4 address + parts[3].Count( c => c == ':' ) != 5 // Semicolons in a Linux-reported MAC. E.g., 00:11:22:33:44:55 + ) { + Console.Error.WriteLine( $"Skipping invalid ARP entry: {line}" ); + continue; + } + var ip = IPAddress.Parse( parts[0] ); var mac = new MacAddress( parts[3] ); map[ip] = mac; diff --git a/src/Scanning/Arp/WindowsArpTableProvider.cs b/src/Scanning/Arp/WindowsArpTableProvider.cs index 067f7593..6c5bf201 100644 --- a/src/Scanning/Arp/WindowsArpTableProvider.cs +++ b/src/Scanning/Arp/WindowsArpTableProvider.cs @@ -41,14 +41,17 @@ protected override ArpTable ReadSystemArpCache() { internal static ArpTable ParseArpOutput( TextReader reader ) { var map = new Dictionary(); - reader.ReadLine(); // Skip empty line - reader.ReadLine(); // Skip interface - reader.ReadLine(); // Skip header - while ( reader.ReadLine() is { } line ) { + if ( string.IsNullOrWhiteSpace( line ) ) { + continue; + } + var parts = line.Split( (char[]?) null, StringSplitOptions.RemoveEmptyEntries ); - if ( parts[0].Count( c => c == '.' ) != 3 ) { // Should look like an IPv4 address + if ( + parts[0].Count( c => c == '.' ) != 3 && // Dots in an IPv4 address + parts[1].Count( c => c == '-' ) != 5 // Hyphens in a Windows-reported MAC. E.g., 00-11-22-33-44-55 + ) { Console.Error.WriteLine( $"Skipping invalid ARP entry: {line}" ); continue; }