]> Sergey Matveev's repositories - godlighty.git/blob - auth.go
Use mtime instead of ctime
[godlighty.git] / auth.go
1 // godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server
2 // Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 package godlighty
17
18 import (
19         "crypto/sha256"
20         "encoding/hex"
21         "errors"
22         "fmt"
23         "net/http"
24         "os"
25         "strings"
26 )
27
28 var Unauthorized = errors.New("failed authorization")
29
30 func performAuth(w http.ResponseWriter, r *http.Request, cfg *AuthCfg) (string, error) {
31         username, password, ok := r.BasicAuth()
32         if !ok {
33                 w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, cfg.Realm))
34                 w.WriteHeader(http.StatusUnauthorized)
35                 return username, Unauthorized
36         }
37         data, err := os.ReadFile(cfg.Passwords)
38         if err != nil {
39                 return username, err
40         }
41         for _, line := range strings.Split(string(data), "\n") {
42                 if len(line) == 0 || line[0] == '#' {
43                         continue
44                 }
45                 cols := strings.Split(line, ":")
46                 if len(cols) != 2 {
47                         continue
48                 }
49                 if cols[0] == username {
50                         d := sha256.Sum256([]byte(password))
51                         if hex.EncodeToString(d[:]) == cols[1] {
52                                 return username, nil
53                         } else {
54                                 w.WriteHeader(http.StatusUnauthorized)
55                                 return username, Unauthorized
56                         }
57                 }
58         }
59         w.WriteHeader(http.StatusUnauthorized)
60         return username, Unauthorized
61 }