diff options
author | Pablo Saavedra <saavedra.pablo@gmail.com> | 2017-02-02 03:08:59 +0100 |
---|---|---|
committer | 无闻 <u@gogs.io> | 2017-02-01 21:08:59 -0500 |
commit | 0081c6911d7ea28eb617b56e32012ba4dc9af90b (patch) | |
tree | b7cf55f5a462b5e28e884de7afcac8592e16a149 /cmd/serve.go | |
parent | 2527037973441054692ee11446196d3ac6b135c3 (diff) |
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
Diffstat (limited to 'cmd/serve.go')
-rw-r--r-- | cmd/serve.go | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/cmd/serve.go b/cmd/serve.go index 53d33b2e..06ef89bf 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -41,6 +41,7 @@ var CmdServ = cli.Command{ func setup(logPath string) { setting.NewContext() + setting.NewService() log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath)) models.LoadConfigs() @@ -61,6 +62,37 @@ func parseCmd(cmd string) (string, string) { 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 ( allowedCommands = map[string]models.AccessMode{ "git-upload-pack": models.ACCESS_MODE_READ, @@ -199,38 +231,15 @@ func runServ(c *cli.Context) error { keyID int64 user *models.User ) + key := getKey(c.Args()[0]) + keyID = key.ID 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. if key.Type == models.KEY_TYPE_DEPLOY { if key.Mode < requestedMode { fail("Key permission denied", "Cannot push with deployment key: %d", key.ID) } - // 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) - } + checkDeployKey(key, repo) } else { user, err = models.GetUserByKeyID(key.ID) if err != nil { @@ -250,6 +259,15 @@ func runServ(c *cli.Context) error { 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() |