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 |
