Mercurial > go > multipass
annotate file/auth.go @ 20:ef2ef22ca4b1 default tip
Add pfish.zone/go/multipass/file import directive to 'file' package.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sun, 01 Nov 2015 13:00:54 -0500 |
parents | 00d30c67b56d |
children |
rev | line source |
---|---|
18
00d30c67b56d
Put all the library stuff into multipass/file.
Paul Fisher <paul@pfish.zone>
parents:
14
diff
changeset
|
1 package file |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
2 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
3 import ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
4 "crypto/rand" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
5 "encoding/base64" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
6 "errors" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
7 "math/big" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
8 "strconv" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
9 "strings" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
10 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
11 "golang.org/x/crypto/bcrypt" |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
12 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
13 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
14 const ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
15 // default cost stolen from python bcrypt |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
16 bcryptCost = 12 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
17 // we only generate passwords from lowercases for non-ambiguity |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
18 lowercases = "abcdefghijklmnopqrstuvwxyz" |
12 | 19 template = "????-????-????-????" |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
20 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
21 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
22 var ( |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
23 lowercaseLen *big.Int = big.NewInt(int64(len(lowercases))) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
24 maxID = big.NewInt(0) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
25 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
26 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
27 var ( |
14 | 28 WrongLengthError error = errors.New("multipass/auth: password entry must have 3 fields") |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
29 BadIDError = errors.New("multipass/auth: ID field invalid") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
30 Base64Error = errors.New("multipass/auth: can't decode base64 data") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
31 LongDescriptionError = errors.New("multipass/auth: description must be less than 255 bytes") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
32 ) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
33 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
34 func init() { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
35 one := big.NewInt(1) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
36 maxID.Lsh(one, 64) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
37 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
38 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
39 // Entry represents a single entry in the a multipass file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
40 type Entry struct { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
41 id uint64 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
42 hash string |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
43 description string |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
44 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
45 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
46 // EntryFromShadow creates a new entry from a line in a multipass shadow file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
47 // The line should not end in a newline. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
48 func EntryFromShadow(shadow string) (*Entry, error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
49 segments := strings.Split(shadow, ":") |
12 | 50 if len(segments) != 3 { |
51 return nil, WrongLengthError | |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
52 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
53 entry := new(Entry) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
54 id, err := strconv.ParseUint(segments[0], 10, 64) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
55 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
56 return nil, BadIDError |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
57 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
58 entry.id = id |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
59 entry.hash = segments[1] |
12 | 60 description, err := base64.StdEncoding.DecodeString(segments[2]) |
61 if err != nil { | |
62 return nil, Base64Error | |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
63 } |
12 | 64 entry.description = string(description) |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
65 return entry, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
66 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
67 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
68 // NewEntry creates an Entry for the given description. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
69 // It returns the Entry itself and a generated password. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
70 func NewEntry(description string) (entry *Entry, password string, err error) { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
71 if len(description) > 255 { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
72 return nil, "", LongDescriptionError |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
73 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
74 passBytes := genPassword() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
75 password = string(passBytes) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
76 hashBytes, err := bcrypt.GenerateFromPassword(passBytes, bcryptCost) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
77 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
78 // This is very unexpected. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
79 return nil, "", err |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
80 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
81 e := new(Entry) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
82 e.id = newID() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
83 e.hash = string(hashBytes) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
84 e.description = description |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
85 return e, password, nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
86 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
87 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
88 // ID is a unique 64-bit integer which identifies the entry. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
89 func (e *Entry) ID() uint64 { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
90 return e.id |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
91 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
92 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
93 // Description is the user's description of their password. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
94 func (e *Entry) Description() string { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
95 return e.description |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
96 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
97 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
98 // Authenticate tests whether the password is correct. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
99 func (e *Entry) Authenticate(password string) bool { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
100 err := bcrypt.CompareHashAndPassword([]byte(e.hash), []byte(password)) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
101 return err == nil |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
102 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
103 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
104 // Encode encodes this Entry to a bytestring for writing to a multipass shadow file. |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
105 func (e *Entry) Encode() string { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
106 segments := []string{ |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
107 strconv.FormatUint(e.id, 10), |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
108 e.hash, |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
109 base64.StdEncoding.EncodeToString([]byte(e.description)), |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
110 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
111 return strings.Join(segments, ":") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
112 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
113 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
114 func genPassword() []byte { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
115 password := []byte(template) |
12 | 116 for i, chr := range password { |
117 if chr == '?' { | |
118 password[i] = randChr() | |
0
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
119 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
120 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
121 return password |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
122 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
123 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
124 func randChr() byte { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
125 bigIdx, err := rand.Int(rand.Reader, lowercaseLen) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
126 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
127 panic("multipass/auth: can't get a random number") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
128 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
129 idx := bigIdx.Int64() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
130 return byte(lowercases[idx]) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
131 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
132 |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
133 func newID() uint64 { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
134 bigID, err := rand.Int(rand.Reader, maxID) |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
135 if err != nil { |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
136 panic("multipass/auth: can't get a random number") |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
137 } |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
138 return bigID.Uint64() |
c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
Paul Fisher <paul@pfish.zone>
parents:
diff
changeset
|
139 } |