aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Saavedra <saavedra.pablo@gmail.com>2017-02-02 03:08:59 +0100
committer无闻 <u@gogs.io>2017-02-01 21:08:59 -0500
commit0081c6911d7ea28eb617b56e32012ba4dc9af90b (patch)
treeb7cf55f5a462b5e28e884de7afcac8592e16a149
parent2527037973441054692ee11446196d3ac6b135c3 (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
-rw-r--r--cmd/serve.go70
-rw-r--r--modules/setting/setting.go4
2 files changed, 48 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()
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 3b3aa69a..54a837e2 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -806,6 +806,10 @@ func newWebhookService() {
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
}
+func NewService() {
+ newService()
+}
+
func NewServices() {
newService()
newLogService()