Mercurial > go > multipass
comparison auth/auth.go @ 12:1c194fa9bbf4
Fix auth tests.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 29 Oct 2015 21:25:12 -0400 |
parents | c18bc7b9d1d9 |
children | 4368a377ff64 |
comparison
equal
deleted
inserted
replaced
11:e246c8a4d28e | 12:1c194fa9bbf4 |
---|---|
16 const ( | 16 const ( |
17 // default cost stolen from python bcrypt | 17 // default cost stolen from python bcrypt |
18 bcryptCost = 12 | 18 bcryptCost = 12 |
19 // we only generate passwords from lowercases for non-ambiguity | 19 // we only generate passwords from lowercases for non-ambiguity |
20 lowercases = "abcdefghijklmnopqrstuvwxyz" | 20 lowercases = "abcdefghijklmnopqrstuvwxyz" |
21 template = "____-____-____-____" | 21 template = "????-????-????-????" |
22 ) | 22 ) |
23 | 23 |
24 var ( | 24 var ( |
25 lowercaseLen *big.Int = big.NewInt(int64(len(lowercases))) | 25 lowercaseLen *big.Int = big.NewInt(int64(len(lowercases))) |
26 maxID = big.NewInt(0) | 26 maxID = big.NewInt(0) |
27 ) | 27 ) |
28 | 28 |
29 var ( | 29 var ( |
30 ShortEntryError error = errors.New("multipass/auth: password entry must have 3 or more fields") | 30 WrongLengthError error = errors.New("multipass/auth: password entry must have 3 fields") |
31 BadIDError = errors.New("multipass/auth: ID field invalid") | 31 BadIDError = errors.New("multipass/auth: ID field invalid") |
32 Base64Error = errors.New("multipass/auth: can't decode base64 data") | 32 Base64Error = errors.New("multipass/auth: can't decode base64 data") |
33 LongDescriptionError = errors.New("multipass/auth: description must be less than 255 bytes") | 33 LongDescriptionError = errors.New("multipass/auth: description must be less than 255 bytes") |
34 ) | 34 ) |
35 | 35 |
41 // Entry represents a single entry in the a multipass file. | 41 // Entry represents a single entry in the a multipass file. |
42 type Entry struct { | 42 type Entry struct { |
43 id uint64 | 43 id uint64 |
44 hash string | 44 hash string |
45 description string | 45 description string |
46 rest []string | |
47 } | 46 } |
48 | 47 |
49 // EntryFromShadow creates a new entry from a line in a multipass shadow file. | 48 // EntryFromShadow creates a new entry from a line in a multipass shadow file. |
50 // The line should not end in a newline. | 49 // The line should not end in a newline. |
51 func EntryFromShadow(shadow string) (*Entry, error) { | 50 func EntryFromShadow(shadow string) (*Entry, error) { |
52 segments := strings.Split(shadow, ":") | 51 segments := strings.Split(shadow, ":") |
53 if len(segments) < 2 { | 52 if len(segments) != 3 { |
54 return nil, ShortEntryError | 53 return nil, WrongLengthError |
55 } | 54 } |
56 entry := new(Entry) | 55 entry := new(Entry) |
57 id, err := strconv.ParseUint(segments[0], 10, 64) | 56 id, err := strconv.ParseUint(segments[0], 10, 64) |
58 if err != nil { | 57 if err != nil { |
59 return nil, BadIDError | 58 return nil, BadIDError |
60 } | 59 } |
61 entry.id = id | 60 entry.id = id |
62 entry.hash = segments[1] | 61 entry.hash = segments[1] |
63 if len(segments) > 2 { | 62 description, err := base64.StdEncoding.DecodeString(segments[2]) |
64 description, err := base64.StdEncoding.DecodeString(segments[2]) | 63 if err != nil { |
65 if err != nil { | 64 return nil, Base64Error |
66 return nil, Base64Error | |
67 } | |
68 entry.description = string(description) | |
69 entry.rest = segments[3:] | |
70 } | 65 } |
66 entry.description = string(description) | |
71 return entry, nil | 67 return entry, nil |
72 } | 68 } |
73 | 69 |
74 // NewEntry creates an Entry for the given description. | 70 // NewEntry creates an Entry for the given description. |
75 // It returns the Entry itself and a generated password. | 71 // It returns the Entry itself and a generated password. |
112 segments := []string{ | 108 segments := []string{ |
113 strconv.FormatUint(e.id, 10), | 109 strconv.FormatUint(e.id, 10), |
114 e.hash, | 110 e.hash, |
115 base64.StdEncoding.EncodeToString([]byte(e.description)), | 111 base64.StdEncoding.EncodeToString([]byte(e.description)), |
116 } | 112 } |
117 segments = append(segments, e.rest...) | |
118 return strings.Join(segments, ":") | 113 return strings.Join(segments, ":") |
119 } | 114 } |
120 | 115 |
121 func genPassword() []byte { | 116 func genPassword() []byte { |
122 password := []byte(template) | 117 password := []byte(template) |
123 for group := 0; group < 4; group++ { | 118 for i, chr := range password { |
124 base := group * 5 | 119 if chr == '?' { |
125 for chr := 0; chr < 4; chr++ { | 120 password[i] = randChr() |
126 password[base+chr] = randChr() | |
127 } | 121 } |
128 } | 122 } |
129 return password | 123 return password |
130 } | 124 } |
131 | 125 |