From 54ffde4be8e0fa6eae9b932a9333b6e4e2d464b7 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 26 Jun 2019 11:50:30 +0800 Subject: [PATCH 1/3] shadow the password on cache and session config on admin panel --- routers/admin/admin.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 2836b7ddc789e..38d7144bc3ec8 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -202,6 +202,17 @@ func SendTestMail(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/admin/config") } +func shadowPassword(cfgItem string) string { + fields := strings.Split(cfgItem, ",") + for i := 0; i < len(fields); i++ { + if strings.HasPrefix(fields[i], "password=") { + fields[i] = "password=******" + break + } + } + return strings.Join(fields, ",") +} + // Config show admin config page func Config(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.config") @@ -239,10 +250,14 @@ func Config(ctx *context.Context) { ctx.Data["CacheAdapter"] = setting.CacheService.Adapter ctx.Data["CacheInterval"] = setting.CacheService.Interval - ctx.Data["CacheConn"] = setting.CacheService.Conn + + ctx.Data["CacheConn"] = shadowPassword(setting.CacheService.Conn) ctx.Data["CacheItemTTL"] = setting.CacheService.TTL - ctx.Data["SessionConfig"] = setting.SessionConfig + sessionCfg := setting.SessionConfig + sessionCfg.ProviderConfig = shadowPassword(sessionCfg.ProviderConfig) + + ctx.Data["SessionConfig"] = sessionCfg ctx.Data["DisableGravatar"] = setting.DisableGravatar ctx.Data["EnableFederatedAvatar"] = setting.EnableFederatedAvatar From f3636a7182a0009e8055cc335c4e11d6262ed6cd Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 26 Jun 2019 15:19:36 +0800 Subject: [PATCH 2/3] add shadow password of mysql/postgres/couchbase --- routers/admin/admin.go | 59 ++++++++++++++++++++++++++++--- routers/admin/admin_test.go | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 routers/admin/admin_test.go diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 38d7144bc3ec8..a6acc322884c8 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -6,6 +7,7 @@ package admin import ( "fmt" + "net/url" "os" "runtime" "strings" @@ -21,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/log" ) const ( @@ -202,15 +205,61 @@ func SendTestMail(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/admin/config") } -func shadowPassword(cfgItem string) string { - fields := strings.Split(cfgItem, ",") +func shadownPasswordKV(cfgItem, splitter string) string { + fields := strings.Split(cfgItem, splitter) for i := 0; i < len(fields); i++ { if strings.HasPrefix(fields[i], "password=") { fields[i] = "password=******" break } } - return strings.Join(fields, ",") + return strings.Join(fields, splitter) +} + +func shadownURL(provider, cfgItem string) string { + u, err := url.Parse(cfgItem) + if err != nil { + log.Error("shodowPassword %v failed: %v", provider, err) + return cfgItem + } + if u.User != nil { + atIdx := strings.Index(cfgItem, "@") + if atIdx > 0 { + colonIdx := strings.LastIndex(cfgItem[:atIdx], ":") + if colonIdx > 0 { + return cfgItem[:colonIdx+1] + "******" + cfgItem[atIdx:] + } + } + } + return cfgItem +} + +func shadowPassword(provider, cfgItem string) string { + switch provider { + case "redis": + return shadownPasswordKV(cfgItem, ",") + case "mysql": + //root:@tcp(localhost:3306)/macaron?charset=utf8 + atIdx := strings.Index(cfgItem, "@") + if atIdx > 0 { + colonIdx := strings.Index(cfgItem[:atIdx], ":") + if colonIdx > 0 { + return cfgItem[:colonIdx+1] + "******" + cfgItem[atIdx:] + } + } + return cfgItem + case "postgres": + // user=jiahuachen dbname=macaron port=5432 sslmode=disable + if !strings.HasPrefix(cfgItem, "postgres://") { + return shadownPasswordKV(cfgItem, " ") + } + + // postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full + // Notice: use shadwonURL + } + + // "couchbase" + return shadownURL(provider, cfgItem) } // Config show admin config page @@ -251,11 +300,11 @@ func Config(ctx *context.Context) { ctx.Data["CacheAdapter"] = setting.CacheService.Adapter ctx.Data["CacheInterval"] = setting.CacheService.Interval - ctx.Data["CacheConn"] = shadowPassword(setting.CacheService.Conn) + ctx.Data["CacheConn"] = shadowPassword(setting.CacheService.Adapter, setting.CacheService.Conn) ctx.Data["CacheItemTTL"] = setting.CacheService.TTL sessionCfg := setting.SessionConfig - sessionCfg.ProviderConfig = shadowPassword(sessionCfg.ProviderConfig) + sessionCfg.ProviderConfig = shadowPassword(sessionCfg.Provider, sessionCfg.ProviderConfig) ctx.Data["SessionConfig"] = sessionCfg diff --git a/routers/admin/admin_test.go b/routers/admin/admin_test.go new file mode 100644 index 0000000000000..da404e50d7381 --- /dev/null +++ b/routers/admin/admin_test.go @@ -0,0 +1,69 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package admin + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestShadowPassword(t *testing.T) { + var kases = []struct { + Provider string + CfgItem string + Result string + }{ + { + Provider: "redis", + CfgItem: "network=tcp,addr=:6379,password=gitea,db=0,pool_size=100,idle_timeout=180", + Result: "network=tcp,addr=:6379,password=******,db=0,pool_size=100,idle_timeout=180", + }, + { + Provider: "mysql", + CfgItem: "root:@tcp(localhost:3306)/gitea?charset=utf8", + Result: "root:******@tcp(localhost:3306)/gitea?charset=utf8", + }, + { + Provider: "mysql", + CfgItem: "/gitea?charset=utf8", + Result: "/gitea?charset=utf8", + }, + { + Provider: "mysql", + CfgItem: "user:mypassword@/dbname", + Result: "user:******@/dbname", + }, + { + Provider: "postgres", + CfgItem: "user=pqgotest dbname=pqgotest sslmode=verify-full", + Result: "user=pqgotest dbname=pqgotest sslmode=verify-full", + }, + { + Provider: "postgres", + CfgItem: "user=pqgotest password= dbname=pqgotest sslmode=verify-full", + Result: "user=pqgotest password=****** dbname=pqgotest sslmode=verify-full", + }, + { + Provider: "postgres", + CfgItem: "postgres://user:pass@hostname/dbname", + Result: "postgres://user:******@hostname/dbname", + }, + { + Provider: "couchbase", + CfgItem: "http://dev-couchbase.example.com:8091/", + Result: "http://dev-couchbase.example.com:8091/", + }, + { + Provider: "couchbase", + CfgItem: "http://user:the_password@dev-couchbase.example.com:8091/", + Result: "http://user:******@dev-couchbase.example.com:8091/", + }, + } + + for _, k := range kases { + assert.EqualValues(t, k.Result, shadowPassword(k.Provider, k.CfgItem)) + } +} From 55de1bc4c7225f25ffcd8adb83e0aa4a2a5caca2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 26 Jun 2019 15:23:07 +0800 Subject: [PATCH 3/3] fix log import --- routers/admin/admin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/admin/admin.go b/routers/admin/admin.go index a6acc322884c8..370f8165252e3 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -21,9 +21,9 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/cron" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/log" ) const (