1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Updated and improved the security widget

* Merged all windows kludges into unified files
* Removed window kludges
* Improved UI
* Fixed faulty Windows username detection
* Fixed dodgy Window firewall detection
* Fixed overlapping/overflowing DNS in UI
* Added fine-grained Windows firewall status
* Added correct and sanitized PowerShell Calls

Affcted Files:

	modified:   dns.go
	deleted:    dns_windows.go
	modified:   firewall.go
	modified:   users.go
	deleted:    users_windows.go
	renamed:    widget_windows.go -> widget.go
This commit is contained in:
E3V3A 2019-02-05 10:52:13 +02:00
parent 3ffefcd2d8
commit b67339662c
7 changed files with 88 additions and 106 deletions

View File

@ -1,5 +1,3 @@
// +build !windows
package security package security
import ( import (
@ -18,6 +16,8 @@ func DnsServers() []string {
return dnsLinux() return dnsLinux()
case "darwin": case "darwin":
return dnsMacOS() return dnsMacOS()
case "windows":
return dnsWindows()
default: default:
return []string{runtime.GOOS} return []string{runtime.GOOS}
} }
@ -56,3 +56,10 @@ func dnsMacOS() []string {
return []string{} return []string{}
} }
func dnsWindows() []string {
cmd := exec.Command("powershell.exe", "-NoProfile", "Get-DnsClientServerAddress | Select-Object ExpandProperty ServerAddresses")
return []string{wtf.ExecuteCommand(cmd)}
}

View File

@ -1,14 +0,0 @@
// +build windows
package security
import (
"os/exec"
"github.com/wtfutil/wtf/wtf"
)
func DnsServers() []string {
cmd := exec.Command("powershell.exe", "Get-DnsClientServerAddress | Select-Object ExpandProperty ServerAddresses")
return []string{wtf.ExecuteCommand(cmd)}
}

View File

@ -20,6 +20,8 @@ func FirewallState() string {
return firewallStateLinux() return firewallStateLinux()
case "darwin": case "darwin":
return firewallStateMacOS() return firewallStateMacOS()
case "windows":
return firewallStateWindows()
default: default:
return "" return ""
} }
@ -31,6 +33,8 @@ func FirewallStealthState() string {
return firewallStealthStateLinux() return firewallStealthStateLinux()
case "darwin": case "darwin":
return firewallStealthStateMacOS() return firewallStealthStateMacOS()
case "windows":
return firewallStealthStateWindows()
default: default:
return "" return ""
} }
@ -56,7 +60,7 @@ func firewallStateLinux() string { // might be very Ubuntu specific
return "[green]Enabled[white]" return "[green]Enabled[white]"
} }
} else { } else {
return "[red]NA[white]" return "[red]N/A[white]"
} }
} }
@ -67,8 +71,38 @@ func firewallStateMacOS() string {
return statusLabel(str) 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 := wtf.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 { func firewallStealthStateLinux() string {
return "[red]NA[white]" return "[white]N/A[white]"
} }
func firewallStealthStateMacOS() string { func firewallStealthStateMacOS() string {
@ -78,6 +112,11 @@ func firewallStealthStateMacOS() string {
return statusLabel(str) return statusLabel(str)
} }
func firewallStealthStateWindows() string {
return "[white]N/A[white]"
}
func statusLabel(str string) string { func statusLabel(str string) string {
label := "off" label := "off"

View File

@ -1,5 +1,3 @@
// +build !windows
package security package security
// http://applehelpwriter.com/2017/05/21/how-to-reveal-hidden-users/ // http://applehelpwriter.com/2017/05/21/how-to-reveal-hidden-users/
@ -20,6 +18,8 @@ func LoggedInUsers() []string {
return loggedInUsersLinux() return loggedInUsersLinux()
case "darwin": case "darwin":
return loggedInUsersMacOs() return loggedInUsersMacOs()
case "windows":
return loggedInUsersWindows()
default: default:
return []string{} return []string{}
} }
@ -66,12 +66,10 @@ func loggedInUsersLinux() []string {
clean = false clean = false
} }
} }
if clean { if clean {
cleaned = append(cleaned, col[0]) cleaned = append(cleaned, col[0])
} }
} }
} }
return cleaned return cleaned
@ -83,3 +81,20 @@ func loggedInUsersMacOs() []string {
return cleanUsers(strings.Split(users, "\n")) return cleanUsers(strings.Split(users, "\n"))
} }
func loggedInUsersWindows() []string {
// We can use either one:
// (Get-WMIObject -class Win32_ComputerSystem | select username).username
// [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
// The original was:
// cmd := exec.Command("powershell.exe", "(query user) -replace '\\s{2,}', ','")
// But that didn't work!
// The real powershell command reads:
// powershell.exe -NoProfile -Command "& { [System.Security.Principal.WindowsIdentity]::GetCurrent().Name }"
// But we here have to write it as:
cmd := exec.Command("powershell.exe", "-NoProfile", "-Command", "& { [System.Security.Principal.WindowsIdentity]::GetCurrent().Name }")
// ToDo: Make list for multi-user systems
users := wtf.ExecuteCommand(cmd)
return cleanUsers(strings.Split(users, "\n"))
}

View File

@ -1,25 +0,0 @@
// +build windows
package security
import (
"os/exec"
"strings"
"github.com/wtfutil/wtf/wtf"
)
func LoggedInUsers() []string {
cmd := exec.Command("powershell.exe", "(query user) -replace '\\s{2,}', ','")
users := wtf.ExecuteCommand(cmd)
return cleanUsers(strings.Split(users, "\n")[1:])
}
func cleanUsers(users []string) []string {
cleaned := make([]string, 0)
for _, user := range users {
usr := strings.Split(user, ",")
cleaned = append(cleaned, usr[0])
}
return cleaned
}

View File

@ -1,5 +1,3 @@
// +build !windows
package security package security
import ( import (
@ -25,6 +23,11 @@ func NewWidget(app *tview.Application) *Widget {
/* -------------------- Exported Functions -------------------- */ /* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() { func (widget *Widget) Refresh() {
if widget.Disabled() {
return
}
data := NewSecurityData() data := NewSecurityData()
data.Fetch() data.Fetch()
@ -38,12 +41,22 @@ func (widget *Widget) contentFrom(data *SecurityData) string {
str = str + fmt.Sprintf(" %8s: %s\n", "Network", data.WifiName) str = str + fmt.Sprintf(" %8s: %s\n", "Network", data.WifiName)
str = str + fmt.Sprintf(" %8s: %s\n", "Crypto", data.WifiEncryption) str = str + fmt.Sprintf(" %8s: %s\n", "Crypto", data.WifiEncryption)
str = str + "\n" str = str + "\n"
str = str + " [red]Firewall[white] [red]DNS[white]\n"
str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Enabled", widget.labelColor(data.FirewallEnabled), data.FirewallEnabled, data.DnsAt(0)) str = str + " [red]Firewall[white]\n"
str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Stealth", widget.labelColor(data.FirewallStealth), data.FirewallStealth, data.DnsAt(1)) str = str + fmt.Sprintf(" %8s: %4s\n", "Status", data.FirewallEnabled)
str = str + fmt.Sprintf(" %8s: %4s\n", "Stealth", data.FirewallStealth)
str = str + "\n" str = str + "\n"
str = str + " [red]Users[white]\n" str = str + " [red]Users[white]\n"
str = str + fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, ", ")) str = str + fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, "\n "))
str = str + "\n"
str = str + " [red]DNS[white]\n"
//str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Enabled", widget.labelColor(data.FirewallEnabled), data.FirewallEnabled, data.DnsAt(0))
//str = str + fmt.Sprintf(" %8s: [%s]%-3s[white] %-16s\n", "Stealth", widget.labelColor(data.FirewallStealth), data.FirewallStealth, data.DnsAt(1))
str = str + fmt.Sprintf(" %12s\n", data.DnsAt(0))
str = str + fmt.Sprintf(" %12s\n", data.DnsAt(1))
str = str + "\n"
return str return str
} }

View File

@ -1,53 +0,0 @@
// +build windows
package security
import (
"fmt"
"strings"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf"
)
type Widget struct {
wtf.TextWidget
}
func NewWidget(app *tview.Application) *Widget {
widget := Widget{
TextWidget: wtf.NewTextWidget(app, "Security", "security", false),
}
return &widget
}
/* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() {
if widget.Disabled() {
return
}
data := NewSecurityData()
data.Fetch()
widget.View.SetText(widget.contentFrom(data))
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) contentFrom(data *SecurityData) string {
str := " [red]WiFi[white]\n"
str = str + fmt.Sprintf(" %8s: %s\n", "Network", data.WifiName)
str = str + fmt.Sprintf(" %8s: %s\n", "Crypto", data.WifiEncryption)
str = str + "\n"
str = str + " [red]Firewall[white] [red]DNS[white]\n"
str = str + fmt.Sprintf(" %8s: %4s %12s\n", "Enabled", data.FirewallEnabled, data.DnsAt(0))
str = str + fmt.Sprintf(" %8s: %4s %12s\n", "Stealth", data.FirewallStealth, data.DnsAt(1))
str = str + "\n"
str = str + " [red]Users[white]\n"
str = str + fmt.Sprintf(" %s", strings.Join(data.LoggedInUsers, ","))
return str
}