From 564b41305c34b37318c3f3130c32d87980af074e Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Wed, 4 Jul 2018 00:06:50 -0400 Subject: [PATCH] Polish Linux system store support --- cert.go | 4 ++++ main.go | 17 ++++++++-------- truststore_darwin.go | 8 ++++++-- truststore_linux.go | 46 ++++++++++++++++++++++++++++++-------------- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/cert.go b/cert.go index 314322f..02f927e 100644 --- a/cert.go +++ b/cert.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package main import ( diff --git a/main.go b/main.go index f1e3192..25c7471 100644 --- a/main.go +++ b/main.go @@ -162,13 +162,10 @@ func getCAROOT() string { func (m *mkcert) install() { var printed bool if !m.checkPlatform() { - m.installPlatform() - m.ignoreCheckFailure = true // TODO: replace with a check for a successful install - - if runtime.GOOS != "linux" { + if m.installPlatform() { log.Print("The local CA is now installed in the system trust store! ⚡️") } - + m.ignoreCheckFailure = true // TODO: replace with a check for a successful install printed = true } if hasNSS && !m.checkNSS() { @@ -187,7 +184,6 @@ func (m *mkcert) install() { } func (m *mkcert) uninstall() { - m.uninstallPlatform() if hasNSS { if hasCertutil { m.uninstallNSS() @@ -198,8 +194,13 @@ func (m *mkcert) uninstall() { log.Print("") } } - log.Print("The local CA is now uninstalled from the system trust store(s)! 👋") - log.Print("") + if m.uninstallPlatform() { + log.Print("The local CA is now uninstalled from the system trust store(s)! 👋") + log.Print("") + } else if hasCertutil { + log.Printf("The local CA is now uninstalled from the %s trust store(s)! 👋", NSSBrowsers) + log.Print("") + } } func (m *mkcert) checkPlatform() bool { diff --git a/truststore_darwin.go b/truststore_darwin.go index b78dba6..46a5a73 100644 --- a/truststore_darwin.go +++ b/truststore_darwin.go @@ -51,7 +51,7 @@ var trustSettingsData = []byte(` `) -func (m *mkcert) installPlatform() { +func (m *mkcert) installPlatform() bool { cmd := exec.Command("sudo", "security", "add-trusted-cert", "-d", "-k", "/Library/Keychains/System.keychain", filepath.Join(m.CAROOT, rootName)) out, err := cmd.CombinedOutput() fatalIfCmdErr(err, "security add-trusted-cert", out) @@ -100,10 +100,14 @@ func (m *mkcert) installPlatform() { cmd = exec.Command("sudo", "security", "trust-settings-import", "-d", plistFile.Name()) out, err = cmd.CombinedOutput() fatalIfCmdErr(err, "security trust-settings-import", out) + + return true } -func (m *mkcert) uninstallPlatform() { +func (m *mkcert) uninstallPlatform() bool { cmd := exec.Command("sudo", "security", "remove-trusted-cert", "-d", filepath.Join(m.CAROOT, rootName)) out, err := cmd.CombinedOutput() fatalIfCmdErr(err, "security remove-trusted-cert", out) + + return true } diff --git a/truststore_linux.go b/truststore_linux.go index d2c092f..64757a9 100644 --- a/truststore_linux.go +++ b/truststore_linux.go @@ -29,44 +29,62 @@ func init() { if !os.IsNotExist(err) { SystemTrustFilename = "/etc/pki/ca-trust/source/anchors/mkcert-rootCA.pem" SystemTrustCommand = []string{"update-ca-trust", "extract"} - return + } else { + _, err = os.Stat("/usr/local/share/ca-certificates/") + if !os.IsNotExist(err) { + SystemTrustFilename = "/usr/local/share/ca-certificates/mkcert-rootCA.crt" + SystemTrustCommand = []string{"update-ca-certificates"} + } } - - _, err = os.Stat("/usr/local/share/ca-certificates/") - if !os.IsNotExist(err) { - SystemTrustFilename = "/usr/local/share/ca-certificates/mkcert-rootCA.crt" - SystemTrustCommand = []string{"update-ca-certificates"} + if SystemTrustCommand != nil { + _, err := exec.LookPath(SystemTrustCommand[0]) + if err != nil { + SystemTrustCommand = nil + } } } -func (m *mkcert) installPlatform() { +func (m *mkcert) installPlatform() bool { if SystemTrustCommand == nil { - log.Fatalf("-install is not yet supported on this Linux 😣\nYou can manually install the root certificate at %q in the meantime.", filepath.Join(m.CAROOT, rootName)) + log.Printf("Installing to the system store is not yet supported on this Linux 😣 but %s will still work.", NSSBrowsers) + log.Printf("You can also manually install the root certificate at %q.", filepath.Join(m.CAROOT, rootName)) + return false } cert, err := ioutil.ReadFile(filepath.Join(m.CAROOT, rootName)) fatalIfErr(err, "failed to read root certificate") - cmd := exec.Command("sudo", "tee", SystemTrustFilename) + cmd := CommandWithSudo("tee", SystemTrustFilename) cmd.Stdin = bytes.NewReader(cert) out, err := cmd.CombinedOutput() fatalIfCmdErr(err, "tee", out) - cmd = exec.Command("sudo", SystemTrustCommand...) + cmd = CommandWithSudo(SystemTrustCommand...) out, err = cmd.CombinedOutput() fatalIfCmdErr(err, strings.Join(SystemTrustCommand, " "), out) + + return true } -func (m *mkcert) uninstallPlatform() { +func (m *mkcert) uninstallPlatform() bool { if SystemTrustCommand == nil { - log.Fatal("-uninstall is not yet supported on this Linux 😣") + return false } - cmd := exec.Command("sudo", "rm", SystemTrustFilename) + cmd := CommandWithSudo("rm", SystemTrustFilename) out, err := cmd.CombinedOutput() fatalIfCmdErr(err, "rm", out) - cmd = exec.Command("sudo", SystemTrustCommand...) + cmd = CommandWithSudo(SystemTrustCommand...) out, err = cmd.CombinedOutput() fatalIfCmdErr(err, strings.Join(SystemTrustCommand, " "), out) + + return true +} + +func CommandWithSudo(cmd ...string) *exec.Cmd { + if _, err := exec.LookPath("sudo"); err != nil { + return exec.Command(cmd[0], cmd[1:]...) + } + return exec.Command("sudo", append([]string{"--"}, cmd...)...) }