forked from andlabs/reallymine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
asker.go
111 lines (100 loc) · 2.4 KB
/
asker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// 24 september 2016
package kek
import (
"fmt"
"os"
"encoding/hex"
"github.com/hashicorp/vault/helper/password"
)
type Asker struct {
cmdstr string
kek []byte
count uint
err error
}
func NewAsker(cmdstr string) *Asker {
return &Asker{
cmdstr: cmdstr,
}
}
const (
AskReal = "-real"
AskOnce = "-askonce"
AskOnly = "-onlyask"
AskDefault = "-default"
)
const (
noteNeedsPassword = "You need the WD password to decrypt this drive."
notePasswordWrong = "Wrong WD password."
)
// TODO how to get the secure insert icon in OS X Terminal?
func (a *Asker) realAsk(note string) bool {
if note != "" {
fmt.Printf("%s\n", note)
}
fmt.Print("Enter WD password: ")
pw, err := password.Read(os.Stdin)
fmt.Println() // because password.Read() doesn't
if err != nil { // including cancelled
a.err = err
return false
}
a.kek = FromPassword(pw)
return true
}
// TODO clean this up somehow
func (a *Asker) Ask() bool {
defer func() {
a.count++
}()
switch a.cmdstr {
case AskReal:
switch a.count {
case 0: // first time, return default
a.kek = Default
return true
case 1: // second time, say that one is needed
return a.realAsk(noteNeedsPassword)
}
// all other times, note password is wrong
return a.realAsk(notePasswordWrong)
case AskOnce:
// only ask once, then return no more
// note not needed since we explicitly asked
if a.count != 0 {
return false
}
return a.realAsk("")
case AskOnly:
if a.count == 0 {
return a.realAsk("")
}
return a.realAsk(notePasswordWrong)
case AskDefault:
if a.count != 0 {
return false
}
a.kek = Default
return true
}
// otherwise treat as a hex string
if a.count != 0 {
return false
}
a.kek, a.err = hex.DecodeString(a.cmdstr)
return a.err == nil
}
func (a *Asker) KEK() []byte {
return a.kek
}
func (a *Asker) Err() error {
return a.err
}
const AskerDescription = "" +
"This specifies a KEK to decrypt the key sector with. " +
"This argument can be one of the following strings:\n" +
"- " + AskReal + " to use the default KEK and then ask for a password until the correct one is used, just like the main decrypt command\n" +
"- " + AskOnce + " to ask for a password once and only use the resultant KEK\n" +
"- " + AskOnly + " to only ask for passwords until the correct one is used\n" +
"- " + AskDefault + " to only use the default KEK\n" +
"Any other string is taken as a hexadecimal string to use as the KEK."