register.go 3.06 KB
Newer Older
1 2 3
package main

import (
Loïck Bonniot's avatar
Loïck Bonniot committed
4
	"bufio"
5 6
	"errors"
	"fmt"
Loïck Bonniot's avatar
Loïck Bonniot committed
7 8 9 10 11
	"os"
	osuser "os/user"
	"strconv"
	"strings"
	"time"
12

Loïck Bonniot's avatar
Loïck Bonniot committed
13
	"dfss/dfssc/user"
14 15 16
	"golang.org/x/crypto/ssh/terminal"
)

Loïck Bonniot's avatar
Loïck Bonniot committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
func registerUser() {
	fmt.Println("Registering a new user")
	// Initialize variables
	var country, mail, organization, unit, passphrase string
	var bits int

	u, err := osuser.Current()
	if err != nil {
		fmt.Println("An error occurred : ", err.Error())
		return
	}

	// Get all the necessary parameters
	readStringParam("Mail", "", &mail)
	readStringParam("Country", time.Now().Location().String(), &country)
	readStringParam("Organization", u.Name, &organization)
	readStringParam("Organizational unit", u.Name, &unit)
	readIntParam("Length of the key (2048 or 4096)", "2048", &bits)
	err = readPassword(&passphrase, true)
	if err != nil {
		fmt.Println("An error occurred:", err.Error())
38
		os.Exit(1)
Loïck Bonniot's avatar
Loïck Bonniot committed
39 40 41 42 43 44 45
		return
	}

	recapUser(mail, country, organization, unit)
	err = user.Register(fca, fcert, fkey, addrPort, passphrase, country, organization, unit, mail, bits)
	if err != nil {
		fmt.Println("An error occurred:", err.Error())
46
		os.Exit(2)
Loïck Bonniot's avatar
Loïck Bonniot committed
47 48 49
	}
}

50 51 52
// We need to use ONLY ONE reader: buffio buffers some data (= consumes from stdin)
var reader *bufio.Reader

53 54
// Get a string parameter from standard input
func readStringParam(message, def string, ptr *string) {
Loïck Bonniot's avatar
Loïck Bonniot committed
55 56 57 58 59 60
	fmt.Print(message)
	if len(def) > 0 {
		fmt.Printf(" [%s]", def)
	}
	fmt.Print(": ")

61 62 63
	if reader == nil {
		reader = bufio.NewReader(os.Stdin)
	}
Loïck Bonniot's avatar
Loïck Bonniot committed
64 65 66 67 68 69 70 71
	value, _ := reader.ReadString('\n')

	// Trim newline symbols
	value = strings.TrimRight(value, "\n")
	value = strings.TrimRight(value, "\r")

	*ptr = value
	if value == "" {
72 73
		*ptr = def
	}
Loïck Bonniot's avatar
Loïck Bonniot committed
74

75 76
}

Loïck Bonniot's avatar
Loïck Bonniot committed
77 78 79 80 81 82 83 84
func readIntParam(message, def string, ptr *int) {
	var str string
	readStringParam(message, def, &str)
	value, err := strconv.Atoi(str)
	if err != nil {
		*ptr = 0
	} else {
		*ptr = value
85 86 87 88
	}
}

// Get the password from standard input
Loïck Bonniot's avatar
Loïck Bonniot committed
89
func readPassword(ptr *string, needConfirm bool) error {
90 91 92 93 94 95 96 97 98

	if !terminal.IsTerminal(0) {
		fmt.Println("+------------------------- WARNING --------------------------+")
		fmt.Println("| This is not a UNIX terminal, your password will be visible |")
		fmt.Println("+------------------------- WARNING --------------------------+")
		readStringParam("Enter your passphrase", "", ptr)
		return nil
	}

99 100 101 102 103
	oldState, err := terminal.MakeRaw(0)
	if err != nil {
		return err
	}

Loïck Bonniot's avatar
Loïck Bonniot committed
104
	fmt.Print("Enter your passphrase: ")
105
	passphrase, err := terminal.ReadPassword(0)
Loïck Bonniot's avatar
Loïck Bonniot committed
106
	fmt.Println()
107 108 109 110
	if err != nil {
		return err
	}

Loïck Bonniot's avatar
Loïck Bonniot committed
111 112 113 114 115 116 117
	if needConfirm {
		fmt.Print("Confirm your passphrase: ")
		confirm, err := terminal.ReadPassword(0)
		fmt.Println()
		if err != nil {
			return err
		}
118

Loïck Bonniot's avatar
Loïck Bonniot committed
119 120 121
		if fmt.Sprintf("%s", passphrase) != fmt.Sprintf("%s", confirm) {
			return errors.New("Password do not match")
		}
122 123 124 125 126 127 128 129
	}

	*ptr = fmt.Sprintf("%s", passphrase)
	_ = terminal.Restore(0, oldState)

	return nil
}

Loïck Bonniot's avatar
Loïck Bonniot committed
130 131 132 133 134 135
func recapUser(mail, country, organization, unit string) {
	fmt.Println("Summary of the new user:")
	fmt.Println("  Common Name:", mail)
	fmt.Println("  Country:", country)
	fmt.Println("  Organization:", organization)
	fmt.Println("  Organizational unit:", unit)
136
}