github.com/iDigitalFlame/xmt@v0.5.4/device/local/local.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 // Package local contains many functions and variables that contain information 18 // about the local device. 19 package local 20 21 import ( 22 "crypto/hmac" 23 "crypto/rand" 24 "crypto/sha256" 25 "os" 26 27 "github.com/iDigitalFlame/xmt/device" 28 "github.com/iDigitalFlame/xmt/device/local/tags" 29 ) 30 31 // UUID is the device specific and session specific identifier. 32 var UUID = getID() 33 34 // Version is the local machine's Operating System version information. 35 var Version = version() 36 37 // Device is the pointer to the local machine instance. This instance is loaded 38 // at runtime and is used for local data gathering and identification. 39 var Device = (&local{Machine: device.Machine{ 40 ID: UUID, 41 PID: uint32(os.Getpid()), 42 PPID: getPPID(), 43 User: getUsername(), 44 System: systemType(), 45 Version: Version, 46 Network: make(device.Network, 0), 47 Elevated: isElevated(), 48 Capabilities: tags.Enabled, 49 }}).init() 50 51 type local struct { 52 device.Machine 53 } 54 55 // Elevated will return true if the current process has elevated privileges, 56 // false otherwise. 57 // 58 // This function is evaluated at runtime. 59 func Elevated() bool { 60 return Device.Elevated&1 == 1 61 } 62 func getID() device.ID { 63 var i device.ID 64 if s := sysID(); len(s) > 0 { 65 h := hmac.New(sha256.New, s) 66 h.Write([]byte(vers)) 67 copy(i[:], h.Sum(nil)) 68 h.Reset() 69 } else { 70 rand.Read(i[:]) 71 } 72 // NOTE(dij): This code below changes how IDs are generated 73 // An extra bit is taken away from the random address space 74 // (8 => 7), thus short IDs from the same machine will ALWAYS 75 // have the same two first bits for easy identification. 76 if rand.Read(i[device.MachineIDSize+1:]); i[0] == 0 { 77 i[0] = 1 78 } 79 if i[device.MachineIDSize] == 0 { 80 i[device.MachineIDSize] = 1 81 } 82 return i 83 } 84 func (l *local) init() *local { 85 l.Hostname, _ = os.Hostname() 86 l.Network.Refresh() 87 l.fixHostname() 88 return l 89 } 90 func (l *local) fixHostname() { 91 for c, i := 0, 0; i < len(l.Hostname); i++ { 92 if l.Hostname[i] != '.' { 93 continue 94 } 95 if c++; c > 1 { 96 l.Hostname = l.Hostname[:i] 97 return 98 } 99 } 100 } 101 func (l *local) Refresh() error { 102 l.User = getUsername() 103 var err error 104 if l.Hostname, err = os.Hostname(); err != nil { 105 return err 106 } 107 if err := l.Network.Refresh(); err != nil { 108 return err 109 } 110 l.PID = uint32(os.Getpid()) 111 l.PPID = getPPID() 112 l.Elevated = isElevated() 113 l.fixHostname() 114 return nil 115 }