From 26dee8967201cf4dc157fa5efd0008b9e2b08b4e Mon Sep 17 00:00:00 2001 From: simon987 Date: Sat, 30 Mar 2019 10:16:46 -0400 Subject: [PATCH] Rework auth --- api/log.go | 2 +- api/project.go | 4 ++-- api/task.go | 64 +++++++++++++------------------------------------- api/worker.go | 2 +- test/common.go | 29 ++++------------------- 5 files changed, 25 insertions(+), 76 deletions(-) diff --git a/api/log.go b/api/log.go index f8862a6..9be3802 100644 --- a/api/log.go +++ b/api/log.go @@ -47,7 +47,7 @@ func (api *WebAPI) SetupLogger() { func (api *WebAPI) parseLogEntry(r *Request) (*LogRequest, error) { - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { return nil, err } diff --git a/api/project.go b/api/project.go index 6f0f6dc..b4f44d9 100644 --- a/api/project.go +++ b/api/project.go @@ -380,7 +380,7 @@ func (api *WebAPI) CreateWorkerAccess(r *Request) { return } - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { r.Json(JsonResponse{ Ok: false, @@ -578,7 +578,7 @@ func (api *WebAPI) GetSecret(r *Request) { var secret string - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err == nil { secret, err = api.Database.GetSecret(pid, worker.Id) if err != nil { diff --git a/api/task.go b/api/task.go index 6d967c7..48694c2 100644 --- a/api/task.go +++ b/api/task.go @@ -2,22 +2,19 @@ package api import ( "bytes" - "crypto" - "crypto/hmac" - "encoding/hex" + "encoding/base64" "encoding/json" "errors" "github.com/dchest/siphash" "github.com/simon987/task_tracker/storage" "github.com/sirupsen/logrus" - "math" "strconv" "time" ) func (api *WebAPI) SubmitTask(r *Request) { - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { r.Json(JsonResponse{ Ok: false, @@ -96,7 +93,7 @@ func (api *WebAPI) SubmitTask(r *Request) { func (api *WebAPI) GetTaskFromProject(r *Request) { - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { r.Json(JsonResponse{ Ok: false, @@ -152,34 +149,16 @@ func (api *WebAPI) GetTaskFromProject(r *Request) { }) } -func (api *WebAPI) validateSignature(r *Request) (*storage.Worker, error) { +func (api *WebAPI) validateSecret(r *Request) (*storage.Worker, error) { widStr := string(r.Ctx.Request.Header.Peek("X-Worker-Id")) - timeStampStr := string(r.Ctx.Request.Header.Peek("Timestamp")) - signature := r.Ctx.Request.Header.Peek("X-Signature") + secretHeader := r.Ctx.Request.Header.Peek("X-Secret") if widStr == "" { return nil, errors.New("worker id not specified") } - if timeStampStr == "" { - return nil, errors.New("date is not specified") - } - - timestamp, err := time.Parse(time.RFC1123, timeStampStr) - if err != nil { - logrus.WithError(err).WithFields(logrus.Fields{ - "date": timeStampStr, - }).Warn("Can't parse Timestamp") - - return nil, err - } - - if math.Abs(float64(timestamp.Unix()-time.Now().Unix())) > 60 { - logrus.WithError(err).WithFields(logrus.Fields{ - "date": timeStampStr, - }).Warn("Invalid Timestamp") - - return nil, errors.New("invalid Timestamp") + if bytes.Equal(secretHeader, []byte("")) { + return nil, errors.New("secret is not specified") } wid, err := strconv.ParseInt(widStr, 10, 64) @@ -201,29 +180,18 @@ func (api *WebAPI) validateSignature(r *Request) (*storage.Worker, error) { return nil, errors.New("worker id does not match any valid worker") } - var body []byte - if r.Ctx.Request.Header.IsGet() { - body = r.Ctx.Request.RequestURI() - } else { - body = r.Ctx.Request.Body() - } - - mac := hmac.New(crypto.SHA256.New, worker.Secret) - mac.Write(body) - mac.Write([]byte(timeStampStr)) - - expectedMac := make([]byte, 64) - hex.Encode(expectedMac, mac.Sum(nil)) - matches := bytes.Compare(expectedMac, signature) == 0 + secret := make([]byte, base64.StdEncoding.EncodedLen(len(worker.Secret))) + secretLen, _ := base64.StdEncoding.Decode(secret, secretHeader) + matches := bytes.Equal(worker.Secret, secret[:secretLen]) logrus.WithFields(logrus.Fields{ - "expected": string(expectedMac), - "signature": string(signature), - "matches": matches, - }).Trace("Validating Worker signature") + "expected": string(worker.Secret), + "header": string(secretHeader), + "matches": matches, + }).Trace("Validating Worker secret") if !matches { - return nil, errors.New("invalid signature") + return nil, errors.New("invalid secret") } return worker, nil @@ -231,7 +199,7 @@ func (api *WebAPI) validateSignature(r *Request) (*storage.Worker, error) { func (api *WebAPI) ReleaseTask(r *Request) { - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { r.Json(JsonResponse{ Ok: false, diff --git a/api/worker.go b/api/worker.go index 31d2bf1..69ba291 100644 --- a/api/worker.go +++ b/api/worker.go @@ -92,7 +92,7 @@ func (api *WebAPI) GetWorker(r *Request) { func (api *WebAPI) UpdateWorker(r *Request) { - worker, err := api.validateSignature(r) + worker, err := api.validateSecret(r) if err != nil { r.Json(JsonResponse{ Ok: false, diff --git a/test/common.go b/test/common.go index e231f4c..d5588b9 100644 --- a/test/common.go +++ b/test/common.go @@ -2,9 +2,7 @@ package test import ( "bytes" - "crypto" - "crypto/hmac" - "encoding/hex" + "encoding/base64" "encoding/json" "fmt" "github.com/simon987/task_tracker/api" @@ -14,7 +12,6 @@ import ( "io/ioutil" "net/http" "strconv" - "time" ) type SessionContext struct { @@ -40,17 +37,9 @@ func Post(path string, x interface{}, worker *storage.Worker, s *http.Client) *h handleErr(err) if worker != nil { - - ts := time.Now().Format(time.RFC1123) - - mac := hmac.New(crypto.SHA256.New, worker.Secret) - mac.Write(body) - mac.Write([]byte(ts)) - sig := hex.EncodeToString(mac.Sum(nil)) - req.Header.Add("X-Worker-Id", strconv.FormatInt(worker.Id, 10)) - req.Header.Add("X-Signature", sig) - req.Header.Add("Timestamp", ts) + secretHeader := base64.StdEncoding.EncodeToString(worker.Secret) + req.Header.Add("X-Secret", string(secretHeader)) } r, err := s.Do(req) @@ -69,17 +58,9 @@ func Get(path string, worker *storage.Worker, s *http.Client) *http.Response { req, err := http.NewRequest("GET", url, nil) if worker != nil { - - ts := time.Now().Format(time.RFC1123) - - mac := hmac.New(crypto.SHA256.New, worker.Secret) - mac.Write([]byte(path)) - mac.Write([]byte(ts)) - sig := hex.EncodeToString(mac.Sum(nil)) - req.Header.Add("X-Worker-Id", strconv.FormatInt(worker.Id, 10)) - req.Header.Add("X-Signature", sig) - req.Header.Add("Timestamp", ts) + secretHeader := base64.StdEncoding.EncodeToString(worker.Secret) + req.Header.Add("X-Secret", string(secretHeader)) } r, err := s.Do(req)