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 }