pass

package module
v0.0.0-...-985fef1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2018 License: GPL-3.0 Imports: 10 Imported by: 0

README

go-pass

GoDoc

go get snai.pe/go-pass

go-pass is a small library providing functions to securely prompt users for their passwords.

It features the following:

  • A secure Password slice type that gets allocated out of the garbage collector, is locked in RAM, and providing functions to wipe, unmap, and create string views safely.
  • Multiple Read functions to retrieve the input from any reader and store it in a secure password slice, or a user-provided slice, if absolutely needed.
  • Convenience functions to display a prompt before requesting a password.

Why?

Go is infamous for leaking secrets to uncontrollable memory when not careful. A slice allocated by the garbage collector can and will get copied around, and the string(slice) construct copies the content of slice to a new string, which makes usual idioms like zeroing out the password after usage non-trivial to implement.

I evaluated a few of the existing solutions but consistently found that dumping the core of my go process after wiping the password and grepping said password out of the core file yielded positive matches, and I decided to roll my own library.

go-pass addresses this by allocating a secure buffer outside of the garbage collector to write the password to, and locks the pages in RAM to prevent passwords leaking to swap (although be warned that most operating systems will still copy RAM to swap during hibernation). In addition, the secure password type provides a String() function that doesn't copy the buffer to a GC-allocated string, but rather creates a string view of the underlying buffer.

Lastly, we have a unit test case that scans the core dump of the test process before and after wiping the password to make sure we got you covered.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// ErrInterrupted is returned when the password input has been interrupted
	// by ^C.
	ErrInterrupted = errors.New("Input interrupted")
)

Functions

func ReadTo

func ReadTo(rd io.Reader, out []byte) (int, error)

ReadTo behaves like Read, except that the password is written to `out` rather than in an allocated secure buffer, and returns the number of bytes written to out.

The byte count is returned even if an error occured.

At most `len(out)` bytes are consumed from the reader and written to `out`. Consumers of this function should make sure that a slice of sufficient size is passed.

Types

type AskOptions

type AskOptions struct {
	// If non-empty, will be printed to Out, followed by ": ".
	Prompt string

	// If non-empty, will be executed and the password will be read from its stdout.
	Program string

	// The destination of the prompt string. If nil, means os.Stdout.
	Out io.Writer

	// The allocated size of the secure password buffer.
	MaxSize int
}

type Password

type Password []byte

Password is a chunk of memory that lives outside of the Go garbage collector. The memory is locked to prevent it from leaking to swap, but note that this does not prevent the operating system from doing so during hibernation.

It requires to be freed manually after its usage.

func Ask

func Ask(opts AskOptions) (Password, error)

Ask is a convenience function that prompts the user for a password using the options passed as parameter.

It returns the password as a secure buffer that needs to be manually freed.

func Prompt

func Prompt(prompt string) (Password, error)

Prompt is a convenience function that prints its parameter followed by a ": ", then reads a password from stdin.

It returns the password as a secure buffer that needs to be manually freed.

func Read

func Read(rd io.Reader) (Password, error)

Read reads a password from the passed reader until a newline or EOF is reached, and returns it in a secure buffer without the newline.

If the reader is backed by a TTY, the following control characters are supported:

  • Backspace (\b) and Delete (DEL) removes the last character from the current input
  • ^C (ETX) interrupts the input, and ErrInterrupted is returned
  • ^D (EOT) acts like EOF.

The maximum size of a password is one page, usually 4096 bytes.

func ReadSize

func ReadSize(rd io.Reader, size int) (Password, error)

ReadSize behaves like Read, except that the secure buffer is allocated with the specified size.

If the size is zero, the allocated size will be one page, usually 4096 bytes.

func (*Password) Free

func (p *Password) Free()

Free unmaps the slice from memory, wiping it beforehand.

func (Password) String

func (p Password) String() (s string)

String returns a string view of the password buffer, not copying its contents.

func (Password) Wipe

func (p Password) Wipe()

Wipe zeroes out the entire password buffer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL