github.com/iDigitalFlame/xmt@v0.5.4/device/y_nix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package device
    21  
    22  import (
    23  	"os"
    24  	"os/user"
    25  	"runtime/debug"
    26  	"syscall"
    27  
    28  	"github.com/iDigitalFlame/xmt/cmd/filter"
    29  	"github.com/iDigitalFlame/xmt/util/xerr"
    30  )
    31  
    32  // ErrNoWindows is an error that is returned when a non-Windows device attempts
    33  // a Windows specific function.
    34  var ErrNoWindows = xerr.Sub("only supported on Windows devices", 0x20)
    35  
    36  // GoExit attempts to walk through the process threads and will forcefully
    37  // kill all Golang based OS-Threads based on their starting address (which
    38  // should be the same when starting from CGo).
    39  //
    40  // This function can be used on binaries, shared libraries or Zombified processes.
    41  //
    42  // Only works on Windows devices and is a wrapper for 'syscall.Exit(0)' for
    43  // *nix devices.
    44  //
    45  // DO NOT EXPECT ANYTHING (INCLUDING DEFERS) TO HAPPEN AFTER THIS FUNCTION.
    46  func GoExit() {
    47  	syscall.Exit(0)
    48  }
    49  
    50  // FreeOSMemory forces a garbage collection followed by an
    51  // attempt to return as much memory to the operating system
    52  // as possible. (Even if this is not called, the runtime gradually
    53  // returns memory to the operating system in a background task.)
    54  //
    55  // On Windows, this function also calls 'SetProcessWorkingSetSizeEx(-1, -1, 0)'
    56  // to force the OS to clear any free'd pages.
    57  func FreeOSMemory() {
    58  	debug.FreeOSMemory()
    59  }
    60  func proxyInit() config {
    61  	return config{
    62  		HTTPProxy:  dualEnv("HTTP_PROXY", "http_proxy"),
    63  		HTTPSProxy: dualEnv("HTTPS_PROXY", "https_proxy"),
    64  		NoProxy:    dualEnv("NO_PROXY", "no_proxy"),
    65  		CGI:        os.Getenv("REQUEST_METHOD") != "",
    66  	}
    67  }
    68  
    69  // RevertToSelf function terminates the impersonation of a client application.
    70  // Returns an error if no impersonation is being done.
    71  //
    72  // Always returns 'ErrNoWindows' on non-Windows devices.
    73  func RevertToSelf() error {
    74  	// TODO(dij): *nix support?
    75  	return ErrNoWindows
    76  }
    77  
    78  // Whoami returns the current user name. This function is different than the
    79  // "local.Device.User" variable as this will be fresh everytime this is called,
    80  // but also means that any API functions called will be re-done each call and
    81  // are not cached.
    82  //
    83  // If caching or multiple fast calls are needed, use the "local" package instead.
    84  //
    85  // This function returns an error if determining the username results in an
    86  // error.
    87  func Whoami() (string, error) {
    88  	u, err := user.Current()
    89  	if err != nil {
    90  		return "", err
    91  	}
    92  	switch {
    93  	case len(u.Username) > 0:
    94  		return u.Username, nil
    95  	case len(u.Uid) > 0:
    96  		return u.Uid, nil
    97  	}
    98  	return u.Name, nil
    99  }
   100  func dualEnv(o, t string) string {
   101  	if v, ok := syscall.Getenv(o); ok {
   102  		return v
   103  	}
   104  	if v, ok := syscall.Getenv(t); ok {
   105  		return v
   106  	}
   107  	return ""
   108  }
   109  
   110  // SetCritical will set the critical flag on the current process. This function
   111  // requires administrative privileges and will attempt to get the
   112  // "SeDebugPrivilege" first before running.
   113  //
   114  // If successful, "critical" processes will BSOD the host when killed or will
   115  // be prevented from running.
   116  //
   117  // The boolean returned is the last Critical status. It's set to True if the
   118  // process was already marked as critical.
   119  //
   120  // Use this function with "false" to disable the critical flag.
   121  //
   122  // NOTE: THIS MUST BE DISABLED ON PROCESS EXIT OTHERWISE THE HOST WILL BSOD!!!
   123  //
   124  // Any errors when setting or obtaining privileges will be returned.
   125  //
   126  // Always returns 'ErrNoWindows' on non-Windows devices.
   127  func SetCritical(_ bool) (bool, error) {
   128  	return false, ErrNoWindows
   129  }
   130  
   131  // Impersonate attempts to steal the Token in use by the target process of the
   132  // supplied filter.
   133  //
   134  // This will set the permissions of all threads in use by the runtime. Once work
   135  // has completed, it is recommended to call the 'RevertToSelf' function to
   136  // revert the token changes.
   137  //
   138  // Always returns 'ErrNoWindows' on non-Windows devices.
   139  func Impersonate(_ *filter.Filter) error {
   140  	// TODO(dij): *nix support?
   141  	return ErrNoWindows
   142  }
   143  
   144  // ImpersonateUser attempts to log in with the supplied credentials and
   145  // impersonate the logged in account.
   146  //
   147  // This will set the permissions of all threads in use by the runtime. Once work
   148  // has completed, it is recommended to call the 'RevertToSelf' function to
   149  // revert the token changes.
   150  //
   151  // This impersonation is locally based, similar to impersonating a Process token.
   152  //
   153  // This also loads the user profile.
   154  //
   155  // Always returns 'ErrNoWindows' on non-Windows devices.
   156  func ImpersonateUser(_, _, _ string) error {
   157  	// TODO(dij): *nix support?
   158  	return ErrNoWindows
   159  }
   160  
   161  // ImpersonateUserNetwork attempts to log in with the supplied credentials and impersonate
   162  // the logged in account.
   163  //
   164  // This will set the permissions of all threads in use by the runtime. Once work
   165  // has completed, it is recommended to call the 'RevertToSelf' function to
   166  // revert the token changes.
   167  //
   168  // This impersonation is network based, unlike impersonating a Process token.
   169  // (Windows-only).
   170  //
   171  // Always returns 'ErrNoWindows' on non-Windows devices.
   172  func ImpersonateUserNetwork(_, _, _ string) error {
   173  	// TODO(dij): *nix support?
   174  	return ErrNoWindows
   175  }