Compare commits

..

No commits in common. "master" and "v1.12.0" have entirely different histories.

5 changed files with 3 additions and 271 deletions

7
TODO

@ -1,9 +1,8 @@
- refactor the elevation detection stuff. I'm not terribly happy with it.

- password generator utility/library
-- incorporate with r00t2.io/pwgen
-- incorporate with https://github.com/tredoe/osutil ?
-- cli flag to dump flat hashes too (https://github.com/hlandau/passlib and others soon in pwgen)
-- cli flag to dump flat hashes too
--- https://github.com/hlandau/passlib
-- incoprporated separately; https://git.r00t2.io/r00t2/PWGen (import r00t2.io/pwgen)

- auger needs to be build-constrained to linux.


@ -1,163 +0,0 @@
package sysutils

// Checked consolidates all the provided checked functions.
func (i *IDState) Checked() (checked bool) {

if i == nil {
return
}

checked = i.uidsChecked &&
i.gidsChecked &&
i.sudoChecked &&
i.ppidUidChecked &&
i.ppidGidChecked

return
}

/*
IsReal consolidates all the elevation/dropped-privs checks into a single method.

It will only return true if no sudo was detected and *all* UIDs/GIDs match.
*/
func (i *IDState) IsReal(real bool) {

if i == nil {
return
}

real = true

for _, b := range []bool{
i.IsSuid(),
i.IsSgid(),
i.IsSudoUser(),
i.IsSudoGroup(),
} {
if b {
real = false
return
}
}

return
}

/*
IsSudoGroup is true if any of the group sudo env vars are set,
or the parent process has a different group (and is not PID 1).

It will always return false if SudoChecked returns false oor PPIDGIDsChecked returns false.
*/
func (i *IDState) IsSudoGroup() (sudo bool) {

if i == nil || !i.sudoChecked || !i.ppidGidChecked {
return
}

sudo = i.SudoEnvGroup || !i.PPIDGidMatch

return
}

/*
IsSudoUser is true if any of the user sudo env vars are set,
or the parent process has a different owner (and is not PID 1).

It will always return false if SudoChecked returns false or PPIDUIDsChecked returns false.
*/
func (i *IDState) IsSudoUser() (sudo bool) {

if i == nil || !i.sudoChecked || !i.ppidUidChecked {
return
}

sudo = i.SudoEnvUser || !i.PPIDUidMatch

return
}

// IsSuid is true if the RUID does not match EUID or SUID. It will always return false if UIDsChecked returns false.
func (i *IDState) IsSuid() (suid bool) {

if i == nil || !i.uidsChecked {
return
}

suid = i.RUID != i.EUID || i.RUID != i.SUID

return
}

// IsSgid is true if the RGID does not match EGID or SGID. It will always return false if GIDsChecked returns false.
func (i *IDState) IsSgid() (sgid bool) {

if i == nil || !i.gidsChecked {
return
}

sgid = i.RGID != i.EGID || i.RGID != i.SGID

return
}

// GIDsChecked is true if the GIDs presented can be trusted.
func (i *IDState) GIDsChecked() (checked bool) {

if i == nil {
return
}

checked = i.gidsChecked

return
}

// PPIDGIDsChecked is true if PPIDGidMatch can be trusted.
func (i *IDState) PPIDGIDsChecked() (checked bool) {

if i == nil {
return
}

checked = i.ppidGidChecked

return
}

// PPIDUIDsChecked is true if PPIDUidMatch can be trusted.
func (i *IDState) PPIDUIDsChecked() (checked bool) {

if i == nil {
return
}

checked = i.ppidUidChecked

return
}

// SudoChecked is true if SudoEnvVars can be trusted
func (i *IDState) SudoChecked() (checked bool) {

if i == nil {
return
}

checked = i.sudoChecked

return
}

// UIDsChecked is true if the UIDs presented can be trusted.
func (i *IDState) UIDsChecked() (checked bool) {

if i == nil {
return
}

checked = i.uidsChecked

return
}

@ -1,50 +0,0 @@
package sysutils

import (
`fmt`
`os`

`golang.org/x/sys/unix`
`r00t2.io/sysutils/envs`
)

// GetIDState returns current ID/elevation information. An IDState should *not* be explicitly created/defined.
func GetIDState() (ids IDState) {

var err error

ids.RUID, ids.EUID, ids.SUID = unix.Getresuid()
ids.uidsChecked = true
ids.RGID, ids.EGID, ids.SGID = unix.Getresgid()
ids.gidsChecked = true

ids.SudoEnvCmd = envs.HasEnv("SUDO_COMMAND")
ids.SudoEnvHome = envs.HasEnv("SUDO_HOME")
ids.SudoEnvGroup = envs.HasEnv("SUDO_GID")
ids.SudoEnvUser = envs.HasEnv("SUDO_UID") || envs.HasEnv("SUDO_USER")
if ids.SudoEnvCmd || ids.SudoEnvHome || ids.SudoEnvGroup || ids.SudoEnvUser {
ids.SudoEnvVars = true
}
ids.sudoChecked = true

// PID 1 will *always* be root, so that can return a false positive for sudo.
if os.Getppid() != 1 {
ids.stat = new(unix.Stat_t)
if err = unix.Stat(
fmt.Sprintf("/proc/%d/stat", os.Getppid()),
ids.stat,
); err != nil {
err = nil
} else {
ids.PPIDUidMatch = ids.RUID == int(ids.stat.Uid)
ids.ppidUidChecked = true
ids.PPIDGidMatch = ids.RGID == int(ids.stat.Gid)
ids.ppidGidChecked = true
}
} else {
ids.ppidUidChecked = true
ids.ppidGidChecked = true
}

return
}

@ -1 +0,0 @@
- search criteria should *also* support a timestamp range (e.g. so a search can be restricted to both older than AND newer than; e.g. older than 00:00, newer than 01:00)

@ -1,53 +0,0 @@
package sysutils

import (
`golang.org/x/sys/unix`
)

/*
IDState collects information about the current running process.
It should only be used as returned from GetIDState().
Its methods WILL return false information if any of these values are altered.

FSUID/FSGID are not supported.
*/
type IDState struct {
// RUID: Real UID
RUID int
// EUID: Effective UID
EUID int
// SUID: Saved Set UID
SUID int
// RGID: Real GID
RGID int
// EGID: Effective GID
EGID int
// SGID: Saved Set GID
SGID int
// SudoEnvUser is true if SUDO_USER or SUDO_UID is set.
SudoEnvUser bool
// SudoEnvGroup is true if SUDO_GID is set.
SudoEnvGroup bool
// SudoEnvCmd is true if SUDO_COMMAND is set.
SudoEnvCmd bool
// SudoEnvHome is true if SUDO_HOME is set.
SudoEnvHome bool
// SudoEnvVars is true if any of the "well-known" sudo environment variables are set.
SudoEnvVars bool
// PPIDUidMatch is true if the parent PID UID matches the current process UID (mismatch usually indicates sudo invocation).
PPIDUidMatch bool
// PPIDGidMatch is true if the parent PID GID matches the current process GID (mismatch usually indicates sudo invocation).
PPIDGidMatch bool
// uidsChecked is true if the RUID, EUID, and SUID have been populated. (They will be 0 if unset OR if root.)
uidsChecked bool
// gidsChecked is true if the RGID, EGID, and SGID have been populated. (They will be 0 if unset OR if root.)
gidsChecked bool
// sudoChecked is true if the SudoEnvVars is set.
sudoChecked bool
// ppidUidChecked is true if the PPIDUidMatch is set.
ppidUidChecked bool
// ppidGidChecked is true if the PPIDGidMatch is set.
ppidGidChecked bool
// stat holds the stat information for the parent PID.
stat *unix.Stat_t
}