open-vault/helper/password/password_solaris.go
James Nugent 2c14ff7385 build: Add support for building on Illumos
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
2016-08-13 00:20:15 -04:00

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
}