1
0
Fork 0
mirror of https://github.com/Luzifer/password.git synced 2024-11-14 12:12:46 +00:00
password/vendor/github.com/tredoe/osutil/user/crypt.go

146 lines
3.4 KiB
Go
Raw Normal View History

// Copyright 2013 Jonas mg
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Passwords
//
// If the passwd field contains some string that is not a valid result of
// hashing, for instance "!" or "*", the user will not be able to use a unix
// passwd to log in (but the user may log in the system by other means).
//
// A passwd field which starts with a exclamation mark means that the passwd is
// locked. The remaining characters on the line represent the passwd field before
// the passwd was locked.
package user
import (
"bufio"
"errors"
"io"
"log"
"os"
"github.com/tredoe/osutil/user/crypt"
_ "github.com/tredoe/osutil/user/crypt/md5_crypt"
_ "github.com/tredoe/osutil/user/crypt/sha256_crypt"
_ "github.com/tredoe/osutil/user/crypt/sha512_crypt"
//_ "github.com/tredoe/osutil/user/crypt/bcrypt"
)
const _LOCK_CHAR = '!' // Character added at the beginning of the passwd to lock it.
var ErrShadowPasswd = errors.New("no found user with shadowed passwd")
// lookupCrypter returns the first crypt function found in shadowed passwd file.
func lookupCrypter() (crypt.Crypter, error) {
f, err := os.Open(_SHADOW_FILE)
if err != nil {
return nil, err
}
defer f.Close()
buf := bufio.NewReader(f)
for {
line, _, err := buf.ReadLine()
if err != nil {
if err == io.EOF {
return nil, ErrShadowPasswd
}
log.Print(err)
continue
}
shadow, err := parseShadow(string(line))
if err != nil {
log.Print(err)
continue
}
if shadow.password[0] == '$' {
return crypt.NewFromHash(shadow.password), nil
}
}
return nil, ErrShadowPasswd
}
// SetCrypter sets the crypt function to can hash the passwords.
// The type "crypt.Crypt" comes from package "github.com/tredoe/osutil/user/crypt".
func SetCrypter(c crypt.Crypt) {
loadConfig()
config.crypter = crypt.New(c)
}
// Passwd sets a hashed passwd for the actual user.
// The passwd must be supplied in clear-text.
func (s *Shadow) Passwd(key []byte) {
loadConfig()
s.password, _ = config.crypter.Generate(key, nil)
s.setChange()
}
// Passwd sets a hashed passwd for the actual group.
// The passwd must be supplied in clear-text.
func (gs *GShadow) Passwd(key []byte) {
loadConfig()
gs.password, _ = config.crypter.Generate(key, nil)
}
// == Change passwd
// ChPasswd updates passwd.
// The passwd must be supplied in clear-text.
func ChPasswd(user string, key []byte) error {
shadow, err := LookupShadow(user)
if err != nil {
return err
}
shadow.Passwd(key)
return edit(user, shadow)
}
// ChGPasswd updates group passwd.
// The passwd must be supplied in clear-text.
func ChGPasswd(group string, key []byte) error {
gshadow, err := LookupGShadow(group)
if err != nil {
return err
}
gshadow.Passwd(key)
return edit(group, gshadow)
}
// == Locking
// LockUser locks the passwd of the given user.
func LockUser(name string) error {
shadow, err := LookupShadow(name)
if err != nil {
return err
}
if shadow.password[0] != _LOCK_CHAR {
shadow.password = string(_LOCK_CHAR) + shadow.password
return edit(name, shadow)
}
return nil
}
// UnlockUser unlocks the passwd of the given user.
func UnlockUser(name string) error {
shadow, err := LookupShadow(name)
if err != nil {
return err
}
if shadow.password[0] == _LOCK_CHAR {
shadow.password = shadow.password[1:]
return edit(name, shadow)
}
return nil
}