From 140d57aecbd1325a08992cde55ab6d6f7a7a04c9 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Tue, 15 Nov 2022 13:20:16 +0800 Subject: [PATCH] feat: use runner token hash --- models/bots/runner.go | 22 +++++++++++++++++++++- routers/api/bots/runner/runner.go | 5 +++-- routers/api/bots/runner/unary.go | 3 ++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/models/bots/runner.go b/models/bots/runner.go index 6c101814e2..4fc5e2dd7d 100644 --- a/models/bots/runner.go +++ b/models/bots/runner.go @@ -8,11 +8,16 @@ import ( "context" "fmt" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + runnerv1 "gitea.com/gitea/proto-go/runner/v1" + gouuid "github.com/google/uuid" "xorm.io/builder" ) @@ -43,7 +48,11 @@ type Runner struct { Description string `xorm:"TEXT"` Base int // 0 native 1 docker 2 virtual machine RepoRange string // glob match which repositories could use this runner - Token string `xorm:"CHAR(36) UNIQUE"` + + Token string `xorm:"-"` + TokenHash string `xorm:"UNIQUE"` // sha256 of token + TokenSalt string + // TokenLastEight string `xorm:"token_last_eight"` // it's unnecessary because we don't find runners by token // instance status (idle, active, offline) Status runnerv1.RunnerStatus @@ -126,6 +135,17 @@ func (r *Runner) LoadAttributes(ctx context.Context) error { return nil } +func (r *Runner) GenerateToken() error { + salt, err := util.CryptoRandomString(10) + if err != nil { + return err + } + r.TokenSalt = salt + r.Token = base.EncodeSha1(gouuid.New().String()) + r.TokenHash = auth_model.HashToken(r.Token, r.TokenSalt) + return nil +} + func init() { db.RegisterModel(&Runner{}) } diff --git a/routers/api/bots/runner/runner.go b/routers/api/bots/runner/runner.go index 7db973a01e..555cb80cc2 100644 --- a/routers/api/bots/runner/runner.go +++ b/routers/api/bots/runner/runner.go @@ -14,7 +14,6 @@ import ( git_model "code.gitea.io/gitea/models/git" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/bots" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -82,11 +81,13 @@ func (s *Service) Register( Name: req.Msg.Name, OwnerID: runnerToken.OwnerID, RepoID: runnerToken.RepoID, - Token: base.EncodeSha1(gouuid.New().String())[:36], Status: runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE, AgentLabels: req.Msg.AgentLabels, CustomLabels: req.Msg.CustomLabels, } + if err := runner.GenerateToken(); err != nil { + return nil, errors.New("can't generate token") + } // create new runner if err := bots_model.NewRunner(ctx, runner); err != nil { diff --git a/routers/api/bots/runner/unary.go b/routers/api/bots/runner/unary.go index be553d7e26..a0d287da7d 100644 --- a/routers/api/bots/runner/unary.go +++ b/routers/api/bots/runner/unary.go @@ -9,6 +9,7 @@ import ( "crypto/subtle" "strings" + auth_model "code.gitea.io/gitea/models/auth" bots_model "code.gitea.io/gitea/models/bots" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" @@ -39,7 +40,7 @@ var WithRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar } return nil, status.Error(codes.Internal, err.Error()) } - if subtle.ConstantTimeCompare([]byte(token), []byte(runner.Token)) != 1 { + if subtle.ConstantTimeCompare([]byte(runner.TokenHash), []byte(auth_model.HashToken(token, runner.TokenSalt))) != 1 { return nil, status.Error(codes.Unauthenticated, "unregistered runner") }