diff --git a/main.go b/main.go index 34fa4a90432bf83e20b99a1194576f3f8d502246..ddb2b8c527ba0bc8c21fbdd099cbd4209fa059e0 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "os" + "os/user" "path/filepath" "runtime" "strconv" @@ -24,6 +25,7 @@ var ( CertBase string KeyBase string GroupName string + GroupID int RedisBaseURL string VaultBaseURL string certificateDestination string @@ -209,12 +211,11 @@ func GetVaultKey(vaulturl string, vaulttoken string) string { } // create directory structure and write certificate to file -func WriteToFile(content string, destination string, groupname string, filemode os.FileMode, dirmode os.FileMode) { +func WriteToFile(content string, destination string, filemode os.FileMode) { baseDir := filepath.Dir(destination) if _, err := os.Stat(baseDir); os.IsNotExist(err) { os.MkdirAll(baseDir, 0755) } - os.Chmod(baseDir, dirmode) file, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, filemode) if err != nil { @@ -226,6 +227,27 @@ func WriteToFile(content string, destination string, groupname string, filemode file.Close() } +// move temp file to destination +func moveFile(source string, destination string, groupid int, filemode os.FileMode, dirmode os.FileMode) { + baseDir := filepath.Dir(destination) + if _, err := os.Stat(baseDir); os.IsNotExist(err) { + os.MkdirAll(baseDir, 0755) + } + err := os.Rename(source, destination) + if err != nil { + fmt.Printf("[ERR] Fail to install %v: %v\n", destination, err) + appExit(255) + } + if runtime.GOOS != "windows" { + err = os.Chown(destination, 0, groupid) + if err != nil { + fmt.Printf("[ERR] Changing file owner to %v", groupid) + appExit(255) + } + } + fmt.Printf("[INFO] installed: %v\n", destination) +} + // ReadOSRelease from /etc/os-release func ReadOSRelease(configfile string) map[string]string { ConfigParams := make(map[string]string) @@ -283,7 +305,7 @@ Options: --redis-token=REDISTOKEN Redis access token --vault-token=VAULTTOKEN Vault access token --cert-name=CERTNAME Certificate name - --team-name=TEAMNAME Team name: swd, dream_team, it, ne, ti... + --team-name=TEAMNAME Team name: swd, it, ne, ti... --days=DAYS Days before expiration [default: 30] --type=TYPE Type, EV or OV [default: EV] --cert-destination=CERTDESTINATION Cert Destination [default: %v/<cert-name>.crt] @@ -304,11 +326,18 @@ Options: tmpFullchainDestination = "C:\\tmp\\acme-downloader\\cert\\amce_fullchain.pem" tmpCaDestination = "C:\\tmp\\acme-downloader\\cert\\amce_ca.pem" tmpKeyDestination = "C:\\tmp\\acme-downloader\\key\\amce_key.pem" + GroupID = 0 // just a fake one } else { tmpCertificateDestination = "/tmp/acme-downloader/cert/amce_cert.pem" tmpFullchainDestination = "/tmp/acme-downloader/cert/amce_fullchain.pem" tmpCaDestination = "/tmp/acme-downloader/cert/amce_ca.pem" tmpKeyDestination = "/tmp/acme-downloader/key/amce_key.pem" + group, groupErr := user.LookupGroup(GroupName) + if groupErr != nil { + fmt.Printf("[ERR] Fail looking up %v user user info", GroupName) + appExit(255) + } + GroupID, _ = strconv.Atoi(group.Gid) } VaultToken := arguments["--vault-token"].(string) @@ -330,9 +359,7 @@ Options: RedisCAURL := fmt.Sprintf("%v/%v:%v:redis_%v_chain_pem.txt", RedisBaseURL, TeamName, CertName, CertNameUndercored) RedisFullChainURL := fmt.Sprintf("%v/%v:%v:redis_%v_fullchain_pem.txt", RedisBaseURL, TeamName, CertName, CertNameUndercored) - // fmt.Println(filepath.Join("a", "b", "c")) if arguments["--cert-destination"] == fmt.Sprintf(filepath.Join(CertBase, "<cert-name>.crt")) { - // certificateDestination = fmt.Sprintf("%v/%v.crt", CertBase, CertName) certificateDestination = fmt.Sprintf(filepath.Join(CertBase, fmt.Sprintf("%v.crt", CertName))) } else { certificateDestination = arguments["--cert-destination"].(string) @@ -365,22 +392,18 @@ Options: privKey := GetVaultKey(VaultURL, VaultToken) // download and test certificates on a temporary location - WriteToFile(certificate, tmpCertificateDestination, GroupName, 0644, 0755) - WriteToFile(fullChain, tmpFullchainDestination, GroupName, 0644, 0755) - WriteToFile(ca, tmpCaDestination, GroupName, 0644, 0755) - WriteToFile(privKey, tmpKeyDestination, GroupName, 0640, 0750) + WriteToFile(certificate, tmpCertificateDestination, 0644) + WriteToFile(fullChain, tmpFullchainDestination, 0644) + WriteToFile(ca, tmpCaDestination, 0644) + WriteToFile(privKey, tmpKeyDestination, 0640) checkCerificates(CertName, tmpCertificateDestination, tmpFullchainDestination, tmpCaDestination, tmpKeyDestination, Days, true) - WriteToFile(certificate, certificateDestination, GroupName, 0644, 0755) - WriteToFile(fullChain, fullchainDestination, GroupName, 0644, 0755) - WriteToFile(ca, caDestination, GroupName, 0644, 0755) - WriteToFile(privKey, keyDestination, GroupName, 0640, 0750) - - fmt.Printf("[INFO] installed: %v\n", certificateDestination) - fmt.Printf("[INFO] installed: %v\n", caDestination) - fmt.Printf("[INFO] installed: %v\n", fullchainDestination) - fmt.Printf("[INFO] installed: %v\n", keyDestination) + // move certificates in place + moveFile(tmpCertificateDestination, certificateDestination, GroupID, 0644, 0755) + moveFile(tmpFullchainDestination, fullchainDestination, GroupID, 0644, 0755) + moveFile(tmpCaDestination, caDestination, GroupID, 0644, 0755) + moveFile(tmpKeyDestination, keyDestination, GroupID, 0640, 0750) // Exit 1 means application needs to be reloaded appExit(1)