Browse Source

Check deploy keys when Gogs is run with Service.RequireSignInView=true (#4078)

* Check deploy keys when Gogs is run with require_sign_in_view

Check if the deploy key can access to a repository. A deploy key
doesn't represent an gogs user, so in a site with Service.RequireSignInView
activated we should give read access only in the repositories where
this deploy key is in use. In other case, a deploy service or system
using an active deploy key can get read access to all the repositories
in a Gogs service.

* Refactoring: Comments starts in a new line

* Minor change in a comment

* Code cleaning. Replace spaces with tabs
pull/4079/head
Pablo Saavedra 8 years ago committed by 无闻
parent
commit
0081c6911d
  1. 70
      cmd/serve.go
  2. 4
      modules/setting/setting.go

70
cmd/serve.go

@ -41,6 +41,7 @@ var CmdServ = cli.Command{
func setup(logPath string) { func setup(logPath string) {
setting.NewContext() setting.NewContext()
setting.NewService()
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
models.LoadConfigs() models.LoadConfigs()
@ -61,6 +62,37 @@ func parseCmd(cmd string) (string, string) {
return ss[0], strings.Replace(ss[1], "'/", "'", 1) return ss[0], strings.Replace(ss[1], "'/", "'", 1)
} }
func getKey(cmdKey string) *models.PublicKey {
keys := strings.Split(cmdKey, "-")
if len(keys) != 2 {
fail("Key ID format error", "Invalid key argument: %s", cmdKey)
}
key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
if err != nil {
fail("Invalid key ID", "Invalid key ID[%s]: %v", cmdKey, err)
}
return key
}
func checkDeployKey(key *models.PublicKey, repo *models.Repository) {
// Check if this deploy key belongs to current repository.
if !models.HasDeployKey(key.ID, repo.ID) {
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
// Update deploy key activity.
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
if err != nil {
fail("Internal error", "GetDeployKey: %v", err)
}
deployKey.Updated = time.Now()
if err = models.UpdateDeployKey(deployKey); err != nil {
fail("Internal error", "UpdateDeployKey: %v", err)
}
}
var ( var (
allowedCommands = map[string]models.AccessMode{ allowedCommands = map[string]models.AccessMode{
"git-upload-pack": models.ACCESS_MODE_READ, "git-upload-pack": models.ACCESS_MODE_READ,
@ -199,38 +231,15 @@ func runServ(c *cli.Context) error {
keyID int64 keyID int64
user *models.User user *models.User
) )
key := getKey(c.Args()[0])
keyID = key.ID
if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate { if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate {
keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 {
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
}
key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
if err != nil {
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
}
keyID = key.ID
// Check deploy key or user key. // Check deploy key or user key.
if key.Type == models.KEY_TYPE_DEPLOY { if key.Type == models.KEY_TYPE_DEPLOY {
if key.Mode < requestedMode { if key.Mode < requestedMode {
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
} }
// Check if this deploy key belongs to current repository. checkDeployKey(key, repo)
if !models.HasDeployKey(key.ID, repo.ID) {
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
// Update deploy key activity.
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
if err != nil {
fail("Internal error", "GetDeployKey: %v", err)
}
deployKey.Updated = time.Now()
if err = models.UpdateDeployKey(deployKey); err != nil {
fail("Internal error", "UpdateDeployKey: %v", err)
}
} else { } else {
user, err = models.GetUserByKeyID(key.ID) user, err = models.GetUserByKeyID(key.ID)
if err != nil { if err != nil {
@ -250,6 +259,15 @@ func runServ(c *cli.Context) error {
user.Name, requestedMode, repoPath) user.Name, requestedMode, repoPath)
} }
} }
} else {
// if public and read ...
// Check if the key can access to the repository in case of it is a deploy key (a deploy keys != user key).
// A deploy key doesn't represent a signed in user, so in a site with Service.RequireSignInView activated
// we should give read access only in repositories where this deploy key is in use. In other case, a server
// or system using an active deploy key can get read access to all the repositories in a Gogs service.
if key.Type == models.KEY_TYPE_DEPLOY && setting.Service.RequireSignInView {
checkDeployKey(key, repo)
}
} }
uuid := gouuid.NewV4().String() uuid := gouuid.NewV4().String()

4
modules/setting/setting.go

@ -806,6 +806,10 @@ func newWebhookService() {
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10) Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
} }
func NewService() {
newService()
}
func NewServices() { func NewServices() {
newService() newService()
newLogService() newLogService()

Loading…
Cancel
Save