mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-17 20:51:55 +01:00
Simplify regex and fix tests for pamparse (#1712)
Simplifies the regex so it doesn't have as many negations. Adds an option to pass the `/etc/passwd` values needed for pamparse so that we can mock them for the tests. Also allows us to only grab those values once at launch, since they shouldn't change.
This commit is contained in:
parent
ffcab2a16a
commit
37929d90c1
@ -541,6 +541,8 @@ const etcEnvironmentPath = "/etc/environment"
|
||||
const etcSecurityPath = "/etc/security/pam_env.conf"
|
||||
const userEnvironmentPath = "~/.pam_environment"
|
||||
|
||||
var pamParseOpts *pamparse.PamParseOpts = pamparse.ParsePasswdSafe()
|
||||
|
||||
/*
|
||||
tryGetPamEnvVars tries to get the environment variables from /etc/environment,
|
||||
/etc/security/pam_env.conf, and ~/.pam_environment.
|
||||
@ -556,11 +558,11 @@ func tryGetPamEnvVars() map[string]string {
|
||||
if err != nil {
|
||||
log.Printf("error parsing %s: %v", etcEnvironmentPath, err)
|
||||
}
|
||||
envVars2, err := pamparse.ParseEnvironmentConfFile(etcSecurityPath)
|
||||
envVars2, err := pamparse.ParseEnvironmentConfFile(etcSecurityPath, pamParseOpts)
|
||||
if err != nil {
|
||||
log.Printf("error parsing %s: %v", etcSecurityPath, err)
|
||||
}
|
||||
envVars3, err := pamparse.ParseEnvironmentConfFile(wavebase.ExpandHomeDirSafe(userEnvironmentPath))
|
||||
envVars3, err := pamparse.ParseEnvironmentConfFile(wavebase.ExpandHomeDirSafe(userEnvironmentPath), pamParseOpts)
|
||||
if err != nil {
|
||||
log.Printf("error parsing %s: %v", userEnvironmentPath, err)
|
||||
}
|
||||
|
@ -12,6 +12,11 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PamParseOpts struct {
|
||||
Home string
|
||||
Shell string
|
||||
}
|
||||
|
||||
// Parses a file in the format of /etc/environment. Accepts a path to the file and returns a map of environment variables.
|
||||
func ParseEnvironmentFile(path string) (map[string]string, error) {
|
||||
rtn := make(map[string]string)
|
||||
@ -33,14 +38,19 @@ func ParseEnvironmentFile(path string) (map[string]string, error) {
|
||||
}
|
||||
|
||||
// Parses a file in the format of /etc/security/pam_env.conf or ~/.pam_environment. Accepts a path to the file and returns a map of environment variables.
|
||||
func ParseEnvironmentConfFile(path string) (map[string]string, error) {
|
||||
func ParseEnvironmentConfFile(path string, opts *PamParseOpts) (map[string]string, error) {
|
||||
rtn := make(map[string]string)
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
home, shell, err := parsePasswd()
|
||||
if opts == nil {
|
||||
opts, err = ParsePasswd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -56,16 +66,16 @@ func ParseEnvironmentConfFile(path string) (map[string]string, error) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
rtn[key] = replaceHomeAndShell(val, home, shell)
|
||||
rtn[key] = replaceHomeAndShell(val, opts.Home, opts.Shell)
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
// Gets the home directory and shell from /etc/passwd for the current user.
|
||||
func parsePasswd() (string, string, error) {
|
||||
func ParsePasswd() (*PamParseOpts, error) {
|
||||
file, err := os.Open("/etc/passwd")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
userPrefix := fmt.Sprintf("%s:", os.Getenv("USER"))
|
||||
@ -75,15 +85,30 @@ func parsePasswd() (string, string, error) {
|
||||
if strings.HasPrefix(line, userPrefix) {
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) < 7 {
|
||||
return "", "", fmt.Errorf("invalid passwd entry: insufficient fields")
|
||||
return nil, fmt.Errorf("invalid passwd entry: insufficient fields")
|
||||
}
|
||||
return parts[5], parts[6], nil
|
||||
return &PamParseOpts{
|
||||
Home: parts[5],
|
||||
Shell: parts[6],
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", "", fmt.Errorf("error reading passwd file: %w", err)
|
||||
return nil, fmt.Errorf("error reading passwd file: %w", err)
|
||||
}
|
||||
return "", "", nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Gets the home directory and shell from /etc/passwd for the current user and returns a map of environment variables from /etc/security/pam_env.conf or ~/.pam_environment.
|
||||
Returns nil if an error occurs.
|
||||
*/
|
||||
func ParsePasswdSafe() *PamParseOpts {
|
||||
opts, err := ParsePasswd()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// Replaces @{HOME} and @{SHELL} placeholders in a string with the provided values. Follows guidance from https://wiki.archlinux.org/title/Environment_variables#Using_pam_env
|
||||
@ -105,7 +130,7 @@ func parseEnvironmentLine(line string) (string, string) {
|
||||
}
|
||||
|
||||
// Regex to parse a line from /etc/security/pam_env.conf or ~/.pam_environment. Follows the guidance from https://wiki.archlinux.org/title/Environment_variables#Using_pam_env
|
||||
var confFileLineRe = regexp.MustCompile(`^([A-Z0-9_]+[A-Za-z0-9]*)\s+(?:(?:DEFAULT=)([^\s]+(?: \w+)*))\s*(?:(?:OVERRIDE=)([^\s]+(?: \w+)*))?\s*$`)
|
||||
var confFileLineRe = regexp.MustCompile(`^([A-Z0-9_]+[A-Za-z0-9]*)\s+(?:(?:DEFAULT=)(\S+(?: \S+)*))\s*(?:(?:OVERRIDE=)(\S+(?: \S+)*))?\s*$`)
|
||||
|
||||
func parseEnvironmentConfLine(line string) (string, string) {
|
||||
m := confFileLineRe.FindStringSubmatch(line)
|
||||
|
@ -78,14 +78,17 @@ FOO11="foo#bar"
|
||||
}
|
||||
|
||||
// parse the file
|
||||
got, err := pamparse.ParseEnvironmentConfFile(tempFile)
|
||||
got, err := pamparse.ParseEnvironmentConfFile(tempFile, &pamparse.PamParseOpts{
|
||||
Home: "/home/user",
|
||||
Shell: "/bin/bash"},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse pam environment conf file: %v", err)
|
||||
}
|
||||
|
||||
want := map[string]string{
|
||||
"TEST": "./config\\ s:@{HOME}/.config\\ state",
|
||||
"FOO": "@{HOME}/.config\\ s",
|
||||
"TEST": "./config\\ s:/home/user/.config\\ state",
|
||||
"FOO": "/home/user/.config\\ s",
|
||||
"STRING": "string",
|
||||
"STRINGOVERRIDE": "string2:string",
|
||||
"FOO11": "foo",
|
||||
|
Loading…
Reference in New Issue
Block a user