blob: 53260730984ee2234957e4155b792f4e520eb5c7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package config
import (
"fmt"
"regexp"
"golang.org/x/sys/unix"
)
var reValidGameName = regexp.MustCompile(`^[\w\._]+$`)
var reValidFileMode = regexp.MustCompile(`^0[\d]{3}$`)
var reSpace = regexp.MustCompile(`^\s$`)
// Game struct containers the configuration for a game
type Game struct {
// ChrootPath is the chroot path for the game
ChrootPath string `yaml:"ChrootPath"`
// FileMode is the file mode to use when copying files
FileMode string `yaml:"FileMode"`
// Commands is the command list
Commands []string `yaml:"Commands"`
// Env is the environment in which to exec the commands
Env map[string]string `yaml:"Env"`
}
func (g *Game) validate(name string) error {
// Game name
if ok := reValidGameName.MatchString(name); !ok {
return fmt.Errorf("Invalid Game name, must match regex `^[\\w\\._]+$` : " + name)
}
// ChrootPath TODO
if err := unix.Access(g.ChrootPath, unix.R_OK|unix.X_OK); err != nil {
return fmt.Errorf("Invalid ChrootPath %s : %w", g.ChrootPath, err)
}
// FileMode
if ok := reValidFileMode.MatchString(g.FileMode); !ok {
return fmt.Errorf("Invalid File Mode, must match regex `^0[\\d]{3}$` : " + name)
}
// Commands
if len(g.Commands) == 0 {
return fmt.Errorf("Invalid game " + name + " has no commands")
}
for i := 0; i < len(g.Commands); i++ {
if err := validateCommand(g.Commands[i]); err != nil {
return fmt.Errorf("Failed to validate Commands for game %s : %w", name, err)
}
}
// Env
for k, _ := range g.Env {
for _, c := range k {
switch c {
case '=':
return fmt.Errorf("Environment variable key must not contain equal sign")
case '\000':
return fmt.Errorf("Environment variable key must not contain null character")
}
if reSpace.MatchString(string(c)) {
return fmt.Errorf("Environment variable key must not contain spaces")
}
}
}
return nil
}
|