176 lines
4.1 KiB
Go
Executable File
176 lines
4.1 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/jinzhu/configor"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
// Configuration Structure.
|
|
type Config struct {
|
|
BindAddr string `default:""`
|
|
Port uint `default:"7789"`
|
|
|
|
KeyDefaults struct {
|
|
Type string `default:"OKP"`
|
|
Curve string `default:"Ed25519"`
|
|
Size int `default:"2048"`
|
|
}
|
|
|
|
Evironments []struct {
|
|
Name string `required:"true"`
|
|
CAKeyFile string `required:"true"`
|
|
SystemGroup string
|
|
APIServer bool `default:"false"`
|
|
APIKey string
|
|
APIWhitelist []string
|
|
HostKey bool `default:"false"`
|
|
UserKey bool `default:"false"`
|
|
|
|
SignOptions struct {
|
|
KeyID string `default:"USERNAME"`
|
|
AllowAPIOverrideKeyID bool `default:"false"`
|
|
ValidPrincipals []string
|
|
AllowAPIOverrideValidPrincipals bool `default:"false"`
|
|
Options map[string]string
|
|
AllowAPIOverrideOptions bool `default:"false"`
|
|
Extensions map[string]string
|
|
AllowAPIOverrideExtensions bool `default:"false"`
|
|
Duration time.Duration `default:"3600"`
|
|
AllowAPIOverrideDuration bool `default:"false"`
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load the configuration.
|
|
func initConfig(c *cli.Context) Config {
|
|
usr, err := user.Current()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Configuration paths.
|
|
localConfig, _ := filepath.Abs("./config.json")
|
|
homeDirConfig := usr.HomeDir + "/.config/ssh-ca/config.json"
|
|
etcConfig := "/etc/ssh-ca/config.json"
|
|
|
|
// Determine which configuration to use.
|
|
var configFile string
|
|
if _, err := os.Stat(c.String("config")); err == nil {
|
|
configFile = c.String("config")
|
|
} else if _, err := os.Stat(localConfig); err == nil {
|
|
configFile = localConfig
|
|
} else if _, err := os.Stat(homeDirConfig); err == nil {
|
|
configFile = homeDirConfig
|
|
} else if _, err := os.Stat(etcConfig); err == nil {
|
|
configFile = etcConfig
|
|
} else {
|
|
log.Fatal("Unable to find a configuration file.")
|
|
}
|
|
|
|
// Load the configuration file.
|
|
config := Config{}
|
|
err = configor.Load(&config, configFile)
|
|
if config.Port == 0 {
|
|
fmt.Println(err)
|
|
log.Fatal("Unable to load the configuration file.")
|
|
}
|
|
return config
|
|
}
|
|
|
|
// Flags for the server command.
|
|
func configTestFlags() []cli.Flag {
|
|
return []cli.Flag{}
|
|
}
|
|
|
|
func configTest(c *cli.Context) error {
|
|
config := initConfig(c)
|
|
|
|
foundError := false
|
|
|
|
if config.BindAddr != "" && net.ParseIP(config.BindAddr) == nil {
|
|
fmt.Println("Invalid bind address.")
|
|
foundError = true
|
|
}
|
|
|
|
if config.Port > 65535 {
|
|
fmt.Println("Invalid port number.")
|
|
foundError = true
|
|
}
|
|
|
|
switch config.KeyDefaults.Type {
|
|
case "EC":
|
|
switch config.KeyDefaults.Curve {
|
|
case "P-256":
|
|
case "P-384":
|
|
case "P-521":
|
|
// We are valid.
|
|
break
|
|
default:
|
|
fmt.Println("Invalid curve setting in KeyDefaults.")
|
|
foundError = true
|
|
}
|
|
break
|
|
case "RSA":
|
|
switch config.KeyDefaults.Size {
|
|
case 512:
|
|
case 1024:
|
|
case 2048:
|
|
case 4096:
|
|
case 8192:
|
|
case 16384:
|
|
// We are valid.
|
|
break
|
|
default:
|
|
fmt.Println("Invalid size setting in KeyDefaults.")
|
|
foundError = true
|
|
}
|
|
break
|
|
case "OKP":
|
|
if config.KeyDefaults.Curve != "Ed25519" {
|
|
fmt.Println("Invalid curve setting in KeyDefaults.")
|
|
foundError = true
|
|
}
|
|
break
|
|
case "oct":
|
|
// We are valid.
|
|
break
|
|
default:
|
|
fmt.Println("Invalid key type in KeyDefaults.")
|
|
foundError = true
|
|
}
|
|
|
|
var validName = regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)
|
|
|
|
for _, environment := range config.Evironments {
|
|
if !validName.MatchString(environment.Name) {
|
|
fmt.Println("Invalid environment name:", environment.Name)
|
|
foundError = true
|
|
}
|
|
|
|
if environment.SystemGroup != "" && !validName.MatchString(environment.SystemGroup) {
|
|
fmt.Println("Invalid environment system group:", environment.SystemGroup)
|
|
foundError = true
|
|
}
|
|
|
|
if _, err := os.Stat(environment.CAKeyFile); err != nil {
|
|
fmt.Println("Key file does not exist:", environment.CAKeyFile)
|
|
foundError = true
|
|
}
|
|
}
|
|
|
|
if !foundError {
|
|
fmt.Println("All configurations appear to be fine.")
|
|
}
|
|
|
|
return nil
|
|
}
|