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  }