mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-16 11:39:57 +00:00
* Wraps syestem info / posture checks into a goroutine with timeout e.checks = checks is set before doing the SyncMeta, so if it fails next time isCheckEquals compares true and bypasses the update. This is to avoid another repeating the 15 seconds hang. The checks will be synced on reconnect or posture checks changes push from mgmt. * Propagate context to OS calls that can leverage its cancellation / timeout * Distinguish timeout from cancellation in logs * Dont log twice * Block on timeout failure and reapply the exclude_ips * Refactor for complexity
232 lines
5.6 KiB
Go
232 lines
5.6 KiB
Go
package system
|
|
|
|
import (
|
|
"context"
|
|
"runtime"
|
|
"strings"
|
|
"syscall/js"
|
|
|
|
"github.com/netbirdio/netbird/version"
|
|
)
|
|
|
|
// UpdateStaticInfoAsync is a no-op on JS as there is no static info to update
|
|
func UpdateStaticInfoAsync() {
|
|
// do nothing
|
|
}
|
|
|
|
// GetInfo retrieves system information for WASM environment
|
|
func GetInfo(_ context.Context) *Info {
|
|
info := &Info{
|
|
GoOS: runtime.GOOS,
|
|
Kernel: runtime.GOARCH,
|
|
KernelVersion: runtime.GOARCH,
|
|
Platform: runtime.GOARCH,
|
|
OS: runtime.GOARCH,
|
|
Hostname: "wasm-client",
|
|
CPUs: runtime.NumCPU(),
|
|
NetbirdVersion: version.NetbirdVersion(),
|
|
}
|
|
|
|
collectBrowserInfo(info)
|
|
collectLocationInfo(info)
|
|
collectSystemInfo(info)
|
|
return info
|
|
}
|
|
|
|
func collectBrowserInfo(info *Info) {
|
|
navigator := js.Global().Get("navigator")
|
|
if navigator.IsUndefined() {
|
|
return
|
|
}
|
|
|
|
collectUserAgent(info, navigator)
|
|
collectPlatform(info, navigator)
|
|
collectCPUInfo(info, navigator)
|
|
}
|
|
|
|
func collectUserAgent(info *Info, navigator js.Value) {
|
|
ua := navigator.Get("userAgent")
|
|
if ua.IsUndefined() {
|
|
return
|
|
}
|
|
|
|
userAgent := ua.String()
|
|
os, osVersion := parseOSFromUserAgent(userAgent)
|
|
if os != "" {
|
|
info.OS = os
|
|
}
|
|
if osVersion != "" {
|
|
info.OSVersion = osVersion
|
|
}
|
|
}
|
|
|
|
func collectPlatform(info *Info, navigator js.Value) {
|
|
// Try regular platform property
|
|
if plat := navigator.Get("platform"); !plat.IsUndefined() {
|
|
if platStr := plat.String(); platStr != "" {
|
|
info.Platform = platStr
|
|
}
|
|
}
|
|
|
|
// Try newer userAgentData API for more accurate platform
|
|
userAgentData := navigator.Get("userAgentData")
|
|
if userAgentData.IsUndefined() {
|
|
return
|
|
}
|
|
|
|
platformInfo := userAgentData.Get("platform")
|
|
if !platformInfo.IsUndefined() {
|
|
if platStr := platformInfo.String(); platStr != "" {
|
|
info.Platform = platStr
|
|
}
|
|
}
|
|
}
|
|
|
|
func collectCPUInfo(info *Info, navigator js.Value) {
|
|
hardwareConcurrency := navigator.Get("hardwareConcurrency")
|
|
if !hardwareConcurrency.IsUndefined() {
|
|
info.CPUs = hardwareConcurrency.Int()
|
|
}
|
|
}
|
|
|
|
func collectLocationInfo(info *Info) {
|
|
location := js.Global().Get("location")
|
|
if location.IsUndefined() {
|
|
return
|
|
}
|
|
|
|
if host := location.Get("hostname"); !host.IsUndefined() {
|
|
hostnameStr := host.String()
|
|
if hostnameStr != "" && hostnameStr != "localhost" {
|
|
info.Hostname = hostnameStr
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkFileAndProcess(_ context.Context, _ []string) ([]File, error) {
|
|
return []File{}, nil
|
|
}
|
|
|
|
func collectSystemInfo(info *Info) {
|
|
navigator := js.Global().Get("navigator")
|
|
if navigator.IsUndefined() {
|
|
return
|
|
}
|
|
|
|
if vendor := navigator.Get("vendor"); !vendor.IsUndefined() {
|
|
info.SystemManufacturer = vendor.String()
|
|
}
|
|
|
|
if product := navigator.Get("product"); !product.IsUndefined() {
|
|
info.SystemProductName = product.String()
|
|
}
|
|
|
|
if userAgent := navigator.Get("userAgent"); !userAgent.IsUndefined() {
|
|
ua := userAgent.String()
|
|
info.Environment = detectEnvironmentFromUA(ua)
|
|
}
|
|
}
|
|
|
|
func parseOSFromUserAgent(userAgent string) (string, string) {
|
|
if userAgent == "" {
|
|
return "", ""
|
|
}
|
|
|
|
switch {
|
|
case strings.Contains(userAgent, "Windows NT"):
|
|
return parseWindowsVersion(userAgent)
|
|
case strings.Contains(userAgent, "Mac OS X"):
|
|
return parseMacOSVersion(userAgent)
|
|
case strings.Contains(userAgent, "FreeBSD"):
|
|
return "FreeBSD", ""
|
|
case strings.Contains(userAgent, "OpenBSD"):
|
|
return "OpenBSD", ""
|
|
case strings.Contains(userAgent, "NetBSD"):
|
|
return "NetBSD", ""
|
|
case strings.Contains(userAgent, "Linux"):
|
|
return parseLinuxVersion(userAgent)
|
|
case strings.Contains(userAgent, "iPhone") || strings.Contains(userAgent, "iPad"):
|
|
return parseiOSVersion(userAgent)
|
|
case strings.Contains(userAgent, "CrOS"):
|
|
return "ChromeOS", ""
|
|
default:
|
|
return "", ""
|
|
}
|
|
}
|
|
|
|
func parseWindowsVersion(userAgent string) (string, string) {
|
|
switch {
|
|
case strings.Contains(userAgent, "Windows NT 10.0; Win64; x64"):
|
|
return "Windows", "10/11"
|
|
case strings.Contains(userAgent, "Windows NT 10.0"):
|
|
return "Windows", "10"
|
|
case strings.Contains(userAgent, "Windows NT 6.3"):
|
|
return "Windows", "8.1"
|
|
case strings.Contains(userAgent, "Windows NT 6.2"):
|
|
return "Windows", "8"
|
|
case strings.Contains(userAgent, "Windows NT 6.1"):
|
|
return "Windows", "7"
|
|
default:
|
|
return "Windows", "Unknown"
|
|
}
|
|
}
|
|
|
|
func parseMacOSVersion(userAgent string) (string, string) {
|
|
idx := strings.Index(userAgent, "Mac OS X ")
|
|
if idx == -1 {
|
|
return "macOS", "Unknown"
|
|
}
|
|
|
|
versionStart := idx + len("Mac OS X ")
|
|
versionEnd := strings.Index(userAgent[versionStart:], ")")
|
|
if versionEnd <= 0 {
|
|
return "macOS", "Unknown"
|
|
}
|
|
|
|
ver := userAgent[versionStart : versionStart+versionEnd]
|
|
ver = strings.ReplaceAll(ver, "_", ".")
|
|
return "macOS", ver
|
|
}
|
|
|
|
func parseLinuxVersion(userAgent string) (string, string) {
|
|
if strings.Contains(userAgent, "Android") {
|
|
return "Android", extractAndroidVersion(userAgent)
|
|
}
|
|
if strings.Contains(userAgent, "Ubuntu") {
|
|
return "Ubuntu", ""
|
|
}
|
|
return "Linux", ""
|
|
}
|
|
|
|
func parseiOSVersion(userAgent string) (string, string) {
|
|
idx := strings.Index(userAgent, "OS ")
|
|
if idx == -1 {
|
|
return "iOS", "Unknown"
|
|
}
|
|
|
|
versionStart := idx + 3
|
|
versionEnd := strings.Index(userAgent[versionStart:], " ")
|
|
if versionEnd <= 0 {
|
|
return "iOS", "Unknown"
|
|
}
|
|
|
|
ver := userAgent[versionStart : versionStart+versionEnd]
|
|
ver = strings.ReplaceAll(ver, "_", ".")
|
|
return "iOS", ver
|
|
}
|
|
|
|
func extractAndroidVersion(userAgent string) string {
|
|
if idx := strings.Index(userAgent, "Android "); idx != -1 {
|
|
versionStart := idx + len("Android ")
|
|
versionEnd := strings.IndexAny(userAgent[versionStart:], ";)")
|
|
if versionEnd > 0 {
|
|
return userAgent[versionStart : versionStart+versionEnd]
|
|
}
|
|
}
|
|
return "Unknown"
|
|
}
|
|
|
|
func detectEnvironmentFromUA(_ string) Environment {
|
|
return Environment{}
|
|
}
|