Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7b0156775c |
7
TODO
7
TODO
@ -1,8 +1,9 @@
|
|||||||
|
- refactor the elevation detection stuff. I'm not terribly happy with it.
|
||||||
|
|
||||||
- password generator utility/library
|
- password generator utility/library
|
||||||
|
-- incorporate with r00t2.io/pwgen
|
||||||
-- incorporate with https://github.com/tredoe/osutil ?
|
-- incorporate with https://github.com/tredoe/osutil ?
|
||||||
-- cli flag to dump flat hashes too
|
-- cli flag to dump flat hashes too (https://github.com/hlandau/passlib and others soon in pwgen)
|
||||||
--- 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.
|
- auger needs to be build-constrained to linux.
|
||||||
|
|
||||||
|
163
funcs_idstate.go
Normal file
163
funcs_idstate.go
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
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
|
||||||
|
}
|
50
funcs_linux.go
Normal file
50
funcs_linux.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
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
paths/TODO
Normal file
1
paths/TODO
Normal file
@ -0,0 +1 @@
|
|||||||
|
- 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)
|
53
types_linux.go
Normal file
53
types_linux.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user