Improve terminal handling and make server arg more helpful
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/term"
|
||||
@@ -196,7 +199,7 @@ func credReadCache(serverURL string, logf func(string, ...interface{})) (*ExecCr
|
||||
return &ec, true
|
||||
}
|
||||
|
||||
func credWriteCache(serverURL string, ec *ExecCredential, logf func(string, ...interface{})) {
|
||||
func credWriteCache(serverURL string, ec *ExecCredential, logf func(string, ...any)) {
|
||||
dir := credCacheDir()
|
||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||
logf("cache: failed to create dir: %v", err)
|
||||
@@ -218,10 +221,7 @@ func credWriteCache(serverURL string, ec *ExecCredential, logf func(string, ...i
|
||||
// ── Kerberos helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
func krb5ConfigPath() string {
|
||||
if v := os.Getenv("KRB5_CONFIG"); v != "" {
|
||||
return v
|
||||
}
|
||||
return "/etc/krb5.conf"
|
||||
return cmp.Or(os.Getenv("KRB5_CONFIG"), "/etc/krb5.conf")
|
||||
}
|
||||
|
||||
// ccachePath returns the path to the active Kerberos credential cache.
|
||||
@@ -238,14 +238,31 @@ func ccachePath() string {
|
||||
// ── Password prompt ────────────────────────────────────────────────────────────
|
||||
|
||||
func credPromptPassword(username string) (string, error) {
|
||||
if !term.IsTerminal(int(os.Stdin.Fd())) {
|
||||
terminal, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"stdin is not a terminal and $WARD_PASSWORD is not set\n" +
|
||||
"cannot open terminal and $WARD_PASSWORD is not set\n" +
|
||||
"hint: run 'kinit' for Kerberos auth, or set $WARD_PASSWORD for non-interactive use")
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Password for %s: ", username)
|
||||
pw, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||
fmt.Fprintln(os.Stderr) // newline after the hidden input
|
||||
|
||||
oldState, err := term.MakeRaw(int(terminal.Fd()))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("setting terminal raw mode: %w", err)
|
||||
}
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigCh
|
||||
term.Restore(int(terminal.Fd()), oldState)
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
fmt.Fprintf(terminal, "Password for %s: ", username)
|
||||
pw, err := term.ReadPassword(int(terminal.Fd()))
|
||||
fmt.Fprintf(terminal, "\r\n") // newline after the hidden input
|
||||
signal.Stop(sigCh)
|
||||
term.Restore(int(terminal.Fd()), oldState)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading password: %w", err)
|
||||
}
|
||||
|
||||
11
main.go
11
main.go
@@ -253,6 +253,17 @@ Debug output goes to stderr (kubectl surfaces this to the terminal):
|
||||
return fmt.Errorf("--server is required")
|
||||
}
|
||||
|
||||
// prepend https if no scheme is given, for user convenience
|
||||
if !strings.Contains(server, "://") {
|
||||
server = "https://" + server
|
||||
}
|
||||
|
||||
// append port 8443 if no port is given
|
||||
parts := strings.Split(server, ":")
|
||||
if len(parts) == 2 {
|
||||
server += ":8443"
|
||||
}
|
||||
|
||||
logf := func(format string, a ...interface{}) {
|
||||
if debugFlag {
|
||||
fmt.Fprintf(os.Stderr, "[ward] "+format+"\n", a...)
|
||||
|
||||
Reference in New Issue
Block a user