Golang : Get login name from environment and prompt for password
Problem:
You want to write a Golang script(short program for administrating server, etc) that grab the current user's login name, but prompt for a password rather than hardcoding it into the script.
When the user enter the password, it should not have echo or masking(i.e replace the typed characters with *). Once the password has been accepted, the script will compare the password with the retrieved password from database. If the password matched, it will let it pass and perform futher operation. If not, abort.
Discussion:
It is important to prompt the login user for password again whenever the user was about to execute a script that could cause potential damage from wrong usage. Why? Security risk. The real logged in user might have walked away from his/her desktop to somewhere else leaving the terminal open for someone else to use. Such as executing some potential harmful commands. Prompting password again will minimize the security risk. For additional layer on security, you might want to conside implementing 2 Factor Authentication as well.
Solution:
Retrieve the logged-in username from the environment variable with os.Getenv()
function. Prompt for password with github.com/howeyc/gopass
package.
Here you go!
package main
import (
"fmt"
"log"
"github.com/howeyc/gopass"
"os"
)
func authService(username, password string) bool {
// this where you want to bcrypt the password
// first before comparing with value retrieved
// from database or other sources base on the given username
// -- this will be application specific
// for the sake of this tutorial, we just
// put the password as abc123 ( don't use this in production!!)
// REMEMBER, do not hardcode the password in your script!
var retrievedPassword string
if username != "" {
retrievedPassword = "abc123"
}
if password == retrievedPassword {
return true
} else {
return false
}
}
func main() {
// get login user name
// from environment variables
loginUser := os.Getenv("USER")
if loginUser == "" {
log.Fatalf("Unable to get username from environment variable.\n")
}
// get user to enter their password
// without echo or mask
fmt.Printf("Enter your password to execute this script: ")
passwordFromUser, err := gopass.GetPasswd() // no echo - silent
if err != nil {
log.Printf("Get password error %v\n", err)
}
authentication := authService(loginUser, string(passwordFromUser))
fmt.Println("Authenticated ? : ", authentication)
}
Sample output:
(enter wrong password)
Enter your password to execute this script:
Authenticated ? : false
(enter right password)
Enter your password to execute this script:
Authenticated ? : true
Happy coding!
References:
https://www.socketloop.com/tutorials/golang-set-get-and-list-environment-variables
https://www.socketloop.com/tutorials/golang-get-password-from-console-input-without-echo-or-masked
https://www.socketloop.com/tutorials/golang-check-if-password-length-meet-the-requirement
See also : Golang : How to implement two-factor authentication?
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+18.5k Golang : When to use public and private identifier(variable) and how to make the identifier public or private?
+12.1k Golang : Send data to /dev/null a.k.a blackhole with ioutil.Discard
+19.5k Golang : Reset or rewind io.Reader or io.Writer
+16.3k Golang : Fix cannot convert buffer (type *bytes.Buffer) to type string error
+9.6k Golang : Bcrypting password
+9.8k Golang : How to get quoted string into another string?
+16.5k Golang : Get input from keyboard
+33.2k Golang : How to check if slice or array is empty?
+5.6k Golang : Compound interest over time example
+16.4k Golang : How to generate QR codes?
+7.7k Golang : Multiplexer with net/http and map
+10.5k Golang : Replace a parameter's value inside a configuration file example