getpasswd for Go

1,804 views
Skip to first unread message

RogerV

unread,
Jan 25, 2010, 10:19:33 PM1/25/10
to golang-nuts
Would like to be able to take password entry from the stdin console,
but, of course, without echoing what the user types.

Is there something comparable to getpasswd functionality in Go?

I tried using syscall.Read, but it echoes what is typed.

Ostsol

unread,
Jan 26, 2010, 12:01:39 AM1/26/10
to golang-nuts
I found a bit about C's 'getpass', but it's marked as obsolete due to
not being threadsafe. The only other thing I found that might help is
termios, which is found in glibc. Unfortunately I could not figure
out how to use it in C, let alone Go, due to my lack of experience in
manipulating /dev/tty*.

-Ostsol

Joe

unread,
Jan 26, 2010, 2:54:09 AM1/26/10
to golang-nuts

RogerV

unread,
Jan 26, 2010, 3:08:58 AM1/26/10
to golang-nuts
func Getpasswd(prompt string) (passwd string, err os.Error) {
fmt.Print(prompt);
const stty_arg0 = "/bin/stty";
stty_argv_e_off := []string{"stty","-echo"};
stty_argv_e_on := []string{"stty","echo"};
const exec_cwdir = "";
fd := []*os.File{os.Stdin,os.Stdout,os.Stderr};
pid, err := os.ForkExec
(stty_arg0,stty_argv_e_off,nil,exec_cwdir,fd);
if err != nil {
return passwd, os.NewError(fmt.Sprintf("Failed turning off
console echo for password entry:\n\t%s",err))
}
rd := bufio.NewReader(os.Stdin);
os.Wait(pid,0);
line, err := rd.ReadString('\n');
if err == nil {
passwd = str.TrimSpace(line)
} else {
err = os.NewError(fmt.Sprintf("Failed during password entry:
%s",err))
}
pid, e := os.ForkExec(stty_arg0,stty_argv_e_on,nil,exec_cwdir,fd);
if e == nil {
os.Wait(pid,0)
} else if err == nil {
err = os.NewError(fmt.Sprintf("Failed turning on console echo
post password entry:\n\t%s",e))
}
return passwd, err
}

Ray Hollett

unread,
Jan 26, 2010, 7:32:54 AM1/26/10
to golang-nuts
I used a similar technique (calling stty) for reading a single
uncooked character.
However, as was pointed out to me calling stty is rather unportable.
I think that Go needs to support more file control attributes.

Ian Lance Taylor

unread,
Jan 26, 2010, 10:26:21 AM1/26/10
to Ray Hollett, golang-nuts
Ray Hollett <holl...@googlemail.com> writes:

> I used a similar technique (calling stty) for reading a single
> uncooked character.
> However, as was pointed out to me calling stty is rather unportable.
> I think that Go needs to support more file control attributes.

Everything in the area of terminal control is unportable. I took a
quick look at Tcl, which tries pretty hard to be portable across
operating systems, but it doesn't appear to handle this either.

The POSIX termios interface is pretty widely available on Unix systems
these days, thank goodness. However, it is a poor match for Windows.
Termios is used to control the command line, pseudo-terminals, and
serial ports, which are all different things on Windows. For echo the
relevant case here is what Windows call the console, but there is no
exact mapping between termios options and console options (e.g.,
termios separates raw-mode from echo-mode, but Windows does not).

Perhaps the Unix syscall interface should add Termios, Tcsetattr, and
friends, and the Windows syscall interface should add SetConsoleMode.
Then somebody can think about a higher level package which provides
simple functions like turning off echo, and has different
implementations on Unix and Windows.

Ian

Joe Poirier

unread,
Jan 26, 2010, 3:03:36 PM1/26/10
to golang-nuts
Would something like termcap work?
http://www.gnu.org/software/termutils/manual/termcap-1.3/html_mono/termcap.html
Higher level packages could then build on top of it, similar to how
readline builds on top of termcap.

On Jan 26, 9:26 am, Ian Lance Taylor <i...@google.com> wrote:

RogerV

unread,
Jan 26, 2010, 11:47:58 PM1/26/10
to golang-nuts
Does anyone really develop full-blown terminal/console applications
anymore?

If I'm doing a perl script utility and feel compelled to have a UI, I
slap on a TK/Perl form, which is windowing GUI-based.

Most of us tend to do something like a daemon service and hang a web
UI on to it for any admin, etc. So cgi support in Apache, or the
various Go web frameworks would seem to fill the bill.

Or we do command line tools that take all their UI needs on the
invocation command line. The one exception being a way to convey a
password without exposing it to the passerby.

Hmm, would seem like Getpasswd() may be a sufficient effort for
special console UI needs that meets what folks actually write code to
do.

About three weeks ago I solved this same get-password-with-no-echo
problem for a Perl script on Windows - used the Windows Console APIs,
which are exposed in an ActiveState Perl package.

So looks like a Go portable solution for Getpasswd() would be stty on
*nix platforms and Console APIs on Windows. Thereafter Go would sport
a portable means to solve this specific need.

Abstracting full blown terminal UI across platforms sounds like a lot
of work for perhaps too small an audience.

Reply all
Reply to author
Forward
0 new messages