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