/* GoCheese -- Python private package repository and caching proxy Copyright (C) 2019-2021 Sergey Matveev 2019-2021 Elena Balakhonova This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "bufio" "errors" "log" "os" "strings" "sync" ) var ( Passwords map[string]Auther = make(map[string]Auther) PasswordsM sync.RWMutex ) type Auther interface { Auth(password string) bool } func strToAuther(verifier string) (string, Auther, error) { st := strings.SplitN(verifier, "$", 3) if len(st) != 3 || st[0] != "" { return "", nil, errors.New("invalid verifier structure") } algorithm := st[1] var auther Auther var err error switch algorithm { case "argon2i": auther, err = parseArgon2i(st[2]) case "sha256": auther, err = parseSHA256(st[2]) default: err = errors.New("unknown hashing algorithm") } return algorithm, auther, err } func passwdReader(fd *os.File) bool { isGood := true scanner := bufio.NewScanner(fd) for scanner.Scan() { t := scanner.Text() if len(t) == 0 { continue } splitted := strings.Split(t, ":") if len(splitted) != 2 { log.Println("wrong login:password format:", t) isGood = false continue } login := splitted[0] passwd := splitted[1] if passwd == "" { log.Println("deleting login:", login) PasswordsM.Lock() delete(Passwords, login) PasswordsM.Unlock() continue } _, auther, err := strToAuther(passwd) if err != nil { log.Println("login:", login, "invalid password:", err) isGood = false continue } log.Println("adding password for:", login) PasswordsM.Lock() Passwords[login] = auther PasswordsM.Unlock() } return isGood } func passwdLister(fd *os.File) { PasswordsM.RLock() logins := make([]string, 0, len(Passwords)) for login := range Passwords { logins = append(logins, login) } PasswordsM.RUnlock() for _, login := range logins { fd.WriteString(login + "\n") } }