2c14ff7385
This commit adds support for building for Illumos-derived operating systems. Regrettably, the cyrpto/ssh/terminal package does not include implementations of the functions IsTerminal, MakeRaw or Restore for the solaris OS. Consequently this commit implements them in Vault. makeRaw(fd int) is based on the Illumos implementation of the getpass function [1] for the correct flags. isTerminal(fd int) is based on the Illumos libc implementation [2] of isatty. [1] http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c [2] http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
56 lines
1.4 KiB
Go
56 lines
1.4 KiB
Go
// +build solaris
|
|
|
|
package password
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func read(f *os.File) (string, error) {
|
|
fd := int(f.Fd())
|
|
if !isTerminal(fd) {
|
|
return "", fmt.Errorf("File descriptor %d is not a terminal", fd)
|
|
}
|
|
|
|
oldState, err := makeRaw(fd)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer unix.IoctlSetTermios(fd, unix.TCSETS, oldState)
|
|
|
|
return readline(f)
|
|
}
|
|
|
|
// isTerminal returns true if there is a terminal attached to the given
|
|
// file descriptor.
|
|
// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
|
|
func isTerminal(fd int) bool {
|
|
var termio unix.Termio
|
|
err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio)
|
|
return err == nil
|
|
}
|
|
|
|
// makeRaw puts the terminal connected to the given file descriptor into raw
|
|
// mode and returns the previous state of the terminal so that it can be
|
|
// restored.
|
|
// Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
|
|
func makeRaw(fd int) (*unix.Termios, error) {
|
|
oldTermiosPtr, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
oldTermios := *oldTermiosPtr
|
|
|
|
newTermios := oldTermios
|
|
newTermios.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL
|
|
if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return oldTermiosPtr, nil
|
|
}
|