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
}