mirror of
https://github.com/Luzifer/password.git
synced 2024-11-14 12:12:46 +00:00
146 lines
3.4 KiB
Go
146 lines
3.4 KiB
Go
|
// 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
|
||
|
}
|