aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2019-10-15 21:50:34 -0400
committerGuillaume Horel <guillaume.horel@gmail.com>2019-10-15 21:50:34 -0400
commit2ab5b1aa4c0d01a5012a7f9599fd00241f8d33a7 (patch)
tree8915f6e15a6bea3a8185be7367b871316f9246a6
parent848ba1309bffd560a4bcc93881d31b92ded4dbfa (diff)
downloadid-2ab5b1aa4c0d01a5012a7f9599fd00241f8d33a7.tar.gz
WIP to handle different hashing schemes
-rw-r--r--main.go22
-rw-r--r--store.go30
2 files changed, 37 insertions, 15 deletions
diff --git a/main.go b/main.go
index 05ca229..d1ec9b1 100644
--- a/main.go
+++ b/main.go
@@ -1,7 +1,6 @@
package main
import (
- "crypto/subtle"
"flag"
"fmt"
"html/template"
@@ -61,10 +60,14 @@ func (app *App) loginHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusSeeOther)
} else if r.Method == http.MethodPost {
username := r.FormValue("username")
- hash := md5hex([]byte(r.FormValue("password")))
+ password := r.FormValue("password")
next := r.FormValue("next")
- u, ok := app.GetUser(username)
- if ok && subtle.ConstantTimeCompare(u.Password, hash) == 1 {
+ if u, err := app.ValidateUser(username, password); err != nil {
+ app.Template.ExecuteTemplate(w, "login.tmpl", struct {
+ Next string
+ Flash string
+ }{next, err.Error()})
+ } else {
s := app.NewSession(u.Id)
c := http.Cookie{
Name: "id",
@@ -73,17 +76,6 @@ func (app *App) loginHandler(w http.ResponseWriter, r *http.Request) {
}
http.SetCookie(w, &c)
http.Redirect(w, r, next, http.StatusSeeOther)
- } else {
- var flash string
- if !ok {
- flash = "Utilisateur non enregistré"
- } else if subtle.ConstantTimeCompare(u.Password, hash) != 1 {
- flash = "Mot de passe incorrect"
- }
- app.Template.ExecuteTemplate(w, "login.tmpl", struct {
- Next string
- Flash string
- }{next, flash})
}
} else if r.Method == http.MethodGet {
next := r.FormValue("next")
diff --git a/store.go b/store.go
index d830150..1744ada 100644
--- a/store.go
+++ b/store.go
@@ -1,7 +1,10 @@
package main
import (
+ "bytes"
+ "crypto/subtle"
"database/sql"
+ "errors"
"log"
"time"
@@ -24,6 +27,7 @@ type Store interface {
GetSession(id string) (*Session, bool)
NewSession(userId int64) *Session
GetUser(name string) (*User, bool)
+ ValidateUser(name string, password string) (*User, error)
DeleteSession(id string)
ChangePassword(userId int64, hash []byte)
}
@@ -88,3 +92,29 @@ func (store *PgStore) GetUser(name string) (*User, bool) {
}
return u, true
}
+
+func (store *PgStore) ValidateUser(name string, password string) (*User, error) {
+ u := &User{Name: name}
+ row := store.QueryRow(
+ "SELECT id, password FROM users WHERE name = $1",
+ name,
+ )
+ if err := row.Scan(&u.Id, &u.Password); err != nil {
+ return nil, errors.New("Utilisateur non enregistré")
+ }
+ z := bytes.SplitN(u.Password, []byte("}"), 2)
+ scheme := string(z[0][:len(z[0])])
+ true_hash := z[1]
+ var hash []byte
+ switch scheme {
+ case "PLAIN-MD5":
+ hash = md5hex([]byte(password))
+ default:
+ return nil, errors.New("Unknown password hashing scheme.")
+ }
+ if subtle.ConstantTimeCompare(true_hash, hash) != 1 {
+ return nil, errors.New("Mot de passe incorrect.")
+ } else {
+ return u, nil
+ }
+}