192 lines
5.0 KiB
Go
192 lines
5.0 KiB
Go
package shared
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.nevets.tech/Keys/certman/common"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
VersionCmd = basicCmd("version", "Show version", versionCmd)
|
|
NewKeyCmd = basicCmd("gen-key", "Generates encryption key", newKeyCmd)
|
|
DevCmd = basicCmd("dev", "Dev Function", devCmd)
|
|
|
|
domainCertDir string
|
|
NewDomainCmd = &cobra.Command{
|
|
Use: "new-domain",
|
|
Short: "Create config and directories for new domain",
|
|
Args: cobra.ExactArgs(1),
|
|
SilenceUsage: true,
|
|
SilenceErrors: true,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
dirOverridden := cmd.Flags().Changed("dir")
|
|
return newDomainCmd(args[0], domainCertDir, dirOverridden)
|
|
},
|
|
}
|
|
|
|
modeFlag string
|
|
thinInstallFlag bool
|
|
InstallCmd = &cobra.Command{
|
|
Use: "install",
|
|
Short: "Create certman files and directories",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
switch modeFlag {
|
|
case "server", "client":
|
|
return installCmd(thinInstallFlag, modeFlag)
|
|
default:
|
|
return fmt.Errorf("invalid --mode %q (must be server or client)", modeFlag)
|
|
}
|
|
},
|
|
}
|
|
)
|
|
|
|
func init() {
|
|
NewDomainCmd.Flags().StringVar(&domainCertDir, "dir", "/var/local/certman/certificates/", "Alternate directory for certificates")
|
|
|
|
InstallCmd.Flags().StringVar(&modeFlag, "mode", "client", "CertManager mode [server, client]")
|
|
InstallCmd.Flags().BoolVarP(&thinInstallFlag, "thin", "t", false, "Thin install (skip creating dirs)")
|
|
}
|
|
|
|
func devCmd(cmd *cobra.Command, args []string) {
|
|
testDomain := "lunamc.org"
|
|
err := LoadConfig()
|
|
if err != nil {
|
|
log.Fatalf("Error loading configuration: %v\n", err)
|
|
}
|
|
err = LoadDomainConfigs()
|
|
if err != nil {
|
|
log.Fatalf("Error loading configs: %v\n", err)
|
|
}
|
|
|
|
fmt.Println(testDomain)
|
|
}
|
|
|
|
func versionCmd(cmd *cobra.Command, args []string) {
|
|
fmt.Printf("CertManager (certman) - Steven Tracey\nVersion: %s build-%s\n",
|
|
common.Version, common.Build,
|
|
)
|
|
}
|
|
|
|
func newKeyCmd(cmd *cobra.Command, args []string) {
|
|
key, err := common.GenerateKey()
|
|
if err != nil {
|
|
log.Fatalf("%v", err)
|
|
}
|
|
fmt.Printf(key)
|
|
}
|
|
|
|
func newDomainCmd(domain, domainDir string, dirOverridden bool) error {
|
|
//TODO add config option for "overridden dir"
|
|
if !common.IsValidFQDN(domain) {
|
|
return fmt.Errorf("invalid FQDN: %q", domain)
|
|
}
|
|
|
|
err := LoadConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Creating new domain %s\n", domain)
|
|
err = CreateDomainConfig(domain)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
CreateDomainCertsDir(domain, domainDir, dirOverridden)
|
|
|
|
certmanUser, err := user.Lookup("certman")
|
|
if err != nil {
|
|
return fmt.Errorf("error getting user certman: %v", err)
|
|
}
|
|
uid, err := strconv.Atoi(strings.TrimSpace(certmanUser.Uid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
gid, err := strconv.Atoi(strings.TrimSpace(certmanUser.Gid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = common.ChownRecursive("/etc/certman/domains", uid, gid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = common.ChownRecursive("/var/local/certman", uid, gid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("Successfully created domain entry for " + domain + "\nUpdate config file as needed in /etc/certman/domains/" + domain + ".conf\n")
|
|
return nil
|
|
}
|
|
|
|
func installCmd(isThin bool, mode string) error {
|
|
if !isThin {
|
|
if os.Geteuid() != 0 {
|
|
return fmt.Errorf("installation must be run as root")
|
|
}
|
|
|
|
MakeDirs()
|
|
CreateConfig(mode)
|
|
|
|
err := LoadConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
f, err := os.OpenFile("/var/run/certman.pid", os.O_RDONLY|os.O_CREATE, 0755)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating pid file: %v", err)
|
|
}
|
|
err = f.Close()
|
|
if err != nil {
|
|
return fmt.Errorf("error closing pid file: %v", err)
|
|
}
|
|
|
|
newUserCmd := exec.Command("useradd", "-d", "/var/local/certman", "-U", "-r", "-s", "/sbin/nologin", "certman")
|
|
if output, err := newUserCmd.CombinedOutput(); err != nil {
|
|
if !strings.Contains(err.Error(), "exit status 9") {
|
|
return fmt.Errorf("error creating user: %v: output %s", err, output)
|
|
}
|
|
}
|
|
newGroupCmd := exec.Command("groupadd", "-r", "-U", "certman", "certsock")
|
|
if output, err := newGroupCmd.CombinedOutput(); err != nil {
|
|
if !strings.Contains(err.Error(), "exit status 9") {
|
|
return fmt.Errorf("error creating group: %v: output %s", err, output)
|
|
}
|
|
}
|
|
certmanUser, err := user.Lookup("certman")
|
|
if err != nil {
|
|
return fmt.Errorf("error getting user certman: %v", err)
|
|
}
|
|
uid, err := strconv.Atoi(strings.TrimSpace(certmanUser.Uid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
gid, err := strconv.Atoi(strings.TrimSpace(certmanUser.Gid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = common.ChownRecursive("/etc/certman", uid, gid)
|
|
if err != nil {
|
|
return fmt.Errorf("error changing uid/gid: %v", err)
|
|
}
|
|
err = common.ChownRecursive("/var/local/certman", uid, gid)
|
|
if err != nil {
|
|
return fmt.Errorf("error changing uid/gid: %v", err)
|
|
}
|
|
err = os.Chown("/var/run/certman.pid", uid, gid)
|
|
if err != nil {
|
|
return fmt.Errorf("error changing uid/gid: %v", err)
|
|
}
|
|
} else {
|
|
CreateConfig(mode)
|
|
}
|
|
return nil
|
|
}
|