Skip to content
Permalink
Browse files

Specify a "Sudo password:" prompt for sudo

Fixes #178
Closes #185
  • Loading branch information...
FiloSottile committed Aug 16, 2019
1 parent 2d05f3b commit aa4dd610664a3b092f35cb7c996d94e3c3da6159
Showing with 28 additions and 20 deletions.
  1. +17 −0 main.go
  2. +4 −5 truststore_darwin.go
  3. +2 −2 truststore_java.go
  4. +5 −13 truststore_linux.go
17 main.go
@@ -16,10 +16,12 @@ import (
"net/url"
"os"
"os/exec"
"os/user"
"path/filepath"
"regexp"
"runtime"
"strings"
"sync"

"golang.org/x/net/idna"
)
@@ -345,3 +347,18 @@ func binaryExists(name string) bool {
_, err := exec.LookPath(name)
return err == nil
}

var sudoWarningOnce sync.Once

func commandWithSudo(cmd ...string) *exec.Cmd {
if u, err := user.Current(); err == nil && u.Uid == "0" {
return exec.Command(cmd[0], cmd[1:]...)
}
if !binaryExists("sudo") {
sudoWarningOnce.Do(func() {
log.Println(`Warning: "sudo" is not available, and mkcert is not running as root. The (un)install operation might fail. ⚠️`)
})
return exec.Command(cmd[0], cmd[1:]...)
}
return exec.Command("sudo", append([]string{"--prompt=Sudo password:", "--"}, cmd...)...)
}
@@ -10,7 +10,6 @@ import (
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"

"howett.net/plist"
@@ -51,7 +50,7 @@ var trustSettingsData = []byte(`
`)

func (m *mkcert) installPlatform() bool {
cmd := exec.Command("sudo", "security", "add-trusted-cert", "-d", "-k", "/Library/Keychains/System.keychain", filepath.Join(m.CAROOT, rootName))
cmd := commandWithSudo("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)

@@ -62,7 +61,7 @@ func (m *mkcert) installPlatform() bool {
fatalIfErr(err, "failed to create temp file")
defer os.Remove(plistFile.Name())

cmd = exec.Command("sudo", "security", "trust-settings-export", "-d", plistFile.Name())
cmd = commandWithSudo("security", "trust-settings-export", "-d", plistFile.Name())
out, err = cmd.CombinedOutput()
fatalIfCmdErr(err, "security trust-settings-export", out)

@@ -96,15 +95,15 @@ func (m *mkcert) installPlatform() bool {
err = ioutil.WriteFile(plistFile.Name(), plistData, 0600)
fatalIfErr(err, "failed to write trust settings")

cmd = exec.Command("sudo", "security", "trust-settings-import", "-d", plistFile.Name())
cmd = commandWithSudo("security", "trust-settings-import", "-d", plistFile.Name())
out, err = cmd.CombinedOutput()
fatalIfCmdErr(err, "security trust-settings-import", out)

return true
}

func (m *mkcert) uninstallPlatform() bool {
cmd := exec.Command("sudo", "security", "remove-trusted-cert", "-d", filepath.Join(m.CAROOT, rootName))
cmd := commandWithSudo("security", "remove-trusted-cert", "-d", filepath.Join(m.CAROOT, rootName))
out, err := cmd.CombinedOutput()
fatalIfCmdErr(err, "security remove-trusted-cert", out)

@@ -106,12 +106,12 @@ func (m *mkcert) uninstallJava() {
}

// execKeytool will execute a "keytool" command and if needed re-execute
// the command wrapped in 'sudo' to work around file permissions.
// the command with commandWithSudo to work around file permissions.
func (m *mkcert) execKeytool(cmd *exec.Cmd) ([]byte, error) {
out, err := cmd.CombinedOutput()
if err != nil && bytes.Contains(out, []byte("java.io.FileNotFoundException")) && runtime.GOOS != "windows" {
origArgs := cmd.Args[1:]
cmd = exec.Command("sudo", keytoolPath)
cmd = commandWithSudo(keytoolPath)
cmd.Args = append(cmd.Args, origArgs...)
cmd.Env = []string{
"JAVA_HOME=" + javaHome,
@@ -10,7 +10,6 @@ import (
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
)
@@ -65,12 +64,12 @@ func (m *mkcert) installPlatform() bool {
cert, err := ioutil.ReadFile(filepath.Join(m.CAROOT, rootName))
fatalIfErr(err, "failed to read root certificate")

cmd := CommandWithSudo("tee", m.systemTrustFilename())
cmd := commandWithSudo("tee", m.systemTrustFilename())
cmd.Stdin = bytes.NewReader(cert)
out, err := cmd.CombinedOutput()
fatalIfCmdErr(err, "tee", out)

cmd = CommandWithSudo(SystemTrustCommand...)
cmd = commandWithSudo(SystemTrustCommand...)
out, err = cmd.CombinedOutput()
fatalIfCmdErr(err, strings.Join(SystemTrustCommand, " "), out)

@@ -82,28 +81,21 @@ func (m *mkcert) uninstallPlatform() bool {
return false
}

cmd := CommandWithSudo("rm", "-f", m.systemTrustFilename())
cmd := commandWithSudo("rm", "-f", m.systemTrustFilename())
out, err := cmd.CombinedOutput()
fatalIfCmdErr(err, "rm", out)

// We used to install under non-unique filenames.
legacyFilename := fmt.Sprintf(SystemTrustFilename, "mkcert-rootCA")
if pathExists(legacyFilename) {
cmd := CommandWithSudo("rm", "-f", legacyFilename)
cmd := commandWithSudo("rm", "-f", legacyFilename)
out, err := cmd.CombinedOutput()
fatalIfCmdErr(err, "rm (legacy filename)", out)
}

cmd = CommandWithSudo(SystemTrustCommand...)
cmd = commandWithSudo(SystemTrustCommand...)
out, err = cmd.CombinedOutput()
fatalIfCmdErr(err, strings.Join(SystemTrustCommand, " "), out)

return true
}

func CommandWithSudo(cmd ...string) *exec.Cmd {
if !binaryExists("sudo") {
return exec.Command(cmd[0], cmd[1:]...)
}
return exec.Command("sudo", append([]string{"--"}, cmd...)...)
}

0 comments on commit aa4dd61

Please sign in to comment.
You can’t perform that action at this time.