package security import ( "bytes" "os/exec" "os/user" "runtime" "strings" "github.com/wtfutil/wtf/utils" ) const osxFirewallCmd = "/usr/libexec/ApplicationFirewall/socketfilterfw" /* -------------------- Exported Functions -------------------- */ func FirewallState() string { switch runtime.GOOS { case "linux": return firewallStateLinux() case "darwin": return firewallStateMacOS() case "windows": return firewallStateWindows() default: return "" } } func FirewallStealthState() string { switch runtime.GOOS { case "linux": return firewallStealthStateLinux() case "darwin": return firewallStealthStateMacOS() case "windows": return firewallStealthStateWindows() default: return "" } } /* -------------------- Unexported Functions -------------------- */ func firewallStateLinux() string { // might be very Ubuntu specific user, _ := user.Current() if strings.Contains(user.Username, "root") { cmd := exec.Command("ufw", "status") var o bytes.Buffer cmd.Stdout = &o if err := cmd.Run(); err != nil { return "[red]NA[white]" } if strings.Contains(o.String(), "inactive") { return "[red]Disabled[white]" } else { return "[green]Enabled[white]" } } else { return "[red]N/A[white]" } } func firewallStateMacOS() string { cmd := exec.Command(osxFirewallCmd, "--getglobalstate") str := utils.ExecuteCommand(cmd) return statusLabel(str) } func firewallStateWindows() string { // The raw way to do this in PS, not using netsh, nor registry, is the following: // if (((Get-NetFirewallProfile | select name,enabled) // | where { $_.Enabled -eq $True } | measure ).Count -eq 3) // { Write-Host "OK" -ForegroundColor Green} else { Write-Host "OFF" -ForegroundColor Red } cmd := exec.Command("powershell.exe", "-NoProfile", "-Command", "& { ((Get-NetFirewallProfile | select name,enabled) | where { $_.Enabled -eq $True } | measure ).Count }") fwStat := utils.ExecuteCommand(cmd) fwStat = strings.TrimSpace(fwStat) // Always sanitize PowerShell output: "3\r\n" //fmt.Printf("%d %q\n", len(fwStat), fwStat) switch fwStat { case "3": return "[green]Good[white] (3/3)" case "2": return "[orange]Poor[white] (2/3)" case "1": return "[yellow]Bad[white] (1/3)" case "0": return "[red]Disabled[white]" default: return "[white]N/A[white]" } } /* -------------------- Getting Stealth State ------------------- */ // "Stealth": Not responding to pings from unauthorized devices func firewallStealthStateLinux() string { return "[white]N/A[white]" } func firewallStealthStateMacOS() string { cmd := exec.Command(osxFirewallCmd, "--getstealthmode") str := utils.ExecuteCommand(cmd) return statusLabel(str) } func firewallStealthStateWindows() string { return "[white]N/A[white]" } func statusLabel(str string) string { label := "off" if strings.Contains(str, "enabled") { label = "on" } return label }