Skip to content

Commit 26602fd

Browse files
lunnydelvh
andauthored
Remove undocumented support of signing key in the repository git configuration file (#36143)
Per-repository signing keys have never been officially supported, as they would require users to modify the repository’s config file. At this point, it is clear that only global signing keys (GPG or SSH) should be allowed. If we want to introduce per-repository signing keys in the future, it will require a complete design proposal. The endpoint will not be removed for repository special signing key, but it will reference the global signing key. --------- Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: delvh <dev.lh@web.de>
1 parent ff70ed6 commit 26602fd

File tree

17 files changed

+133
-128
lines changed

17 files changed

+133
-128
lines changed

modules/git/commit.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,14 +323,6 @@ func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, err
323323
return strings.TrimSpace(commitID), nil
324324
}
325325

326-
// GetRepositoryDefaultPublicGPGKey returns the default public key for this commit
327-
func (c *Commit) GetRepositoryDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, error) {
328-
if c.repo == nil {
329-
return nil, nil
330-
}
331-
return c.repo.GetDefaultPublicGPGKey(forceUpdate)
332-
}
333-
334326
func IsStringLikelyCommitID(objFmt ObjectFormat, s string, minLength ...int) bool {
335327
maxLen := 64 // sha256
336328
if objFmt != nil {

modules/git/gpg.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright 2015 The Gogs Authors. All rights reserved.
2+
// Copyright 2017 The Gitea Authors. All rights reserved.
3+
// SPDX-License-Identifier: MIT
4+
5+
package git
6+
7+
import (
8+
"context"
9+
"fmt"
10+
"os"
11+
"strings"
12+
"sync"
13+
14+
"code.gitea.io/gitea/modules/git/gitcmd"
15+
"code.gitea.io/gitea/modules/process"
16+
)
17+
18+
// GPGSettings represents the default GPG settings for this repository
19+
type GPGSettings struct {
20+
Sign bool
21+
KeyID string
22+
Email string
23+
Name string
24+
PublicKeyContent string
25+
Format string
26+
}
27+
28+
// LoadPublicKeyContent will load the key from gpg
29+
func (gpgSettings *GPGSettings) LoadPublicKeyContent() error {
30+
if gpgSettings.PublicKeyContent != "" {
31+
return nil
32+
}
33+
34+
if gpgSettings.Format == SigningKeyFormatSSH {
35+
content, err := os.ReadFile(gpgSettings.KeyID)
36+
if err != nil {
37+
return fmt.Errorf("unable to read SSH public key file: %s, %w", gpgSettings.KeyID, err)
38+
}
39+
gpgSettings.PublicKeyContent = string(content)
40+
return nil
41+
}
42+
content, stderr, err := process.GetManager().Exec(
43+
"gpg -a --export",
44+
"gpg", "-a", "--export", gpgSettings.KeyID)
45+
if err != nil {
46+
return fmt.Errorf("unable to get default signing key: %s, %s, %w", gpgSettings.KeyID, stderr, err)
47+
}
48+
gpgSettings.PublicKeyContent = content
49+
return nil
50+
}
51+
52+
var (
53+
loadPublicGPGKeyMutex sync.RWMutex
54+
globalGPGSettings *GPGSettings
55+
)
56+
57+
// GetDefaultPublicGPGKey will return and cache the default public GPG settings
58+
func GetDefaultPublicGPGKey(ctx context.Context, forceUpdate bool) (*GPGSettings, error) {
59+
if !forceUpdate {
60+
loadPublicGPGKeyMutex.RLock()
61+
if globalGPGSettings != nil {
62+
defer loadPublicGPGKeyMutex.RUnlock()
63+
return globalGPGSettings, nil
64+
}
65+
loadPublicGPGKeyMutex.RUnlock()
66+
}
67+
68+
loadPublicGPGKeyMutex.Lock()
69+
defer loadPublicGPGKeyMutex.Unlock()
70+
71+
if globalGPGSettings != nil && !forceUpdate {
72+
return globalGPGSettings, nil
73+
}
74+
75+
globalGPGSettings = &GPGSettings{
76+
Sign: true,
77+
}
78+
79+
value, _, _ := gitcmd.NewCommand("config", "--global", "--get", "commit.gpgsign").RunStdString(ctx)
80+
sign, valid := ParseBool(strings.TrimSpace(value))
81+
if !sign || !valid {
82+
globalGPGSettings.Sign = false
83+
return globalGPGSettings, nil
84+
}
85+
86+
signingKey, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.signingkey").RunStdString(ctx)
87+
globalGPGSettings.KeyID = strings.TrimSpace(signingKey)
88+
89+
format, _, _ := gitcmd.NewCommand("config", "--global", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx)
90+
globalGPGSettings.Format = strings.TrimSpace(format)
91+
92+
defaultEmail, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.email").RunStdString(ctx)
93+
globalGPGSettings.Email = strings.TrimSpace(defaultEmail)
94+
95+
defaultName, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.name").RunStdString(ctx)
96+
globalGPGSettings.Name = strings.TrimSpace(defaultName)
97+
98+
if err := globalGPGSettings.LoadPublicKeyContent(); err != nil {
99+
return nil, err
100+
}
101+
return globalGPGSettings, nil
102+
}

modules/git/key.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ func (s *SigningKey) String() string {
3232
}
3333

3434
// GetSigningKey returns the KeyID and git Signature for the repo
35-
func GetSigningKey(ctx context.Context, repoPath string) (*SigningKey, *Signature) {
35+
func GetSigningKey(ctx context.Context) (*SigningKey, *Signature) {
3636
if setting.Repository.Signing.SigningKey == "none" {
3737
return nil, nil
3838
}
3939

4040
if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
4141
// Can ignore the error here as it means that commit.gpgsign is not set
42-
value, _, _ := gitcmd.NewCommand("config", "--get", "commit.gpgsign").WithDir(repoPath).RunStdString(ctx)
42+
value, _, _ := gitcmd.NewCommand("config", "--global", "--get", "commit.gpgsign").RunStdString(ctx)
4343
sign, valid := ParseBool(strings.TrimSpace(value))
4444
if !sign || !valid {
4545
return nil, nil
4646
}
4747

48-
format, _, _ := gitcmd.NewCommand("config", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").WithDir(repoPath).RunStdString(ctx)
49-
signingKey, _, _ := gitcmd.NewCommand("config", "--get", "user.signingkey").WithDir(repoPath).RunStdString(ctx)
50-
signingName, _, _ := gitcmd.NewCommand("config", "--get", "user.name").WithDir(repoPath).RunStdString(ctx)
51-
signingEmail, _, _ := gitcmd.NewCommand("config", "--get", "user.email").WithDir(repoPath).RunStdString(ctx)
48+
format, _, _ := gitcmd.NewCommand("config", "--global", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx)
49+
signingKey, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.signingkey").RunStdString(ctx)
50+
signingName, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.name").RunStdString(ctx)
51+
signingEmail, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.email").RunStdString(ctx)
5252

5353
if strings.TrimSpace(signingKey) == "" {
5454
return nil, nil

modules/git/repo.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ import (
2020
"code.gitea.io/gitea/modules/proxy"
2121
)
2222

23-
// GPGSettings represents the default GPG settings for this repository
24-
type GPGSettings struct {
25-
Sign bool
26-
KeyID string
27-
Email string
28-
Name string
29-
PublicKeyContent string
30-
Format string
31-
}
32-
3323
const prettyLogFormat = `--pretty=format:%H`
3424

3525
func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) {

modules/git/repo_base_gogit.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ type Repository struct {
3232

3333
gogitRepo *gogit.Repository
3434
gogitStorage *filesystem.Storage
35-
gpgSettings *GPGSettings
3635

3736
Ctx context.Context
3837
LastCommitCache *LastCommitCache

modules/git/repo_base_nogogit.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ type Repository struct {
2323

2424
tagCache *ObjectCache[*Tag]
2525

26-
gpgSettings *GPGSettings
27-
2826
batchInUse bool
2927
batch *Batch
3028

modules/git/repo_gpg.go

Lines changed: 0 additions & 71 deletions
This file was deleted.

modules/gitrepo/signing.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ import (
99
"code.gitea.io/gitea/modules/git"
1010
)
1111

12-
func GetSigningKey(ctx context.Context, repo Repository) (*git.SigningKey, *git.Signature) {
13-
return git.GetSigningKey(ctx, repoPath(repo))
12+
func GetSigningKey(ctx context.Context) (*git.SigningKey, *git.Signature) {
13+
return git.GetSigningKey(ctx)
1414
}

routers/api/v1/misc/signing.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,8 @@ import (
1010
)
1111

1212
func getSigningKey(ctx *context.APIContext, expectedFormat string) {
13-
// if the handler is in the repo's route group, get the repo's signing key
14-
// otherwise, get the global signing key
15-
path := ""
16-
if ctx.Repo != nil && ctx.Repo.Repository != nil {
17-
path = ctx.Repo.Repository.RepoPath()
18-
}
19-
content, format, err := asymkey_service.PublicSigningKey(ctx, path)
13+
// get the global signing key
14+
content, format, err := asymkey_service.PublicSigningKey(ctx)
2015
if err != nil {
2116
ctx.APIErrorInternal(err)
2217
return

routers/web/repo/setting/setting.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func SettingsCtxData(ctx *context.Context) {
6161
ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
6262
ctx.Data["CanConvertFork"] = ctx.Repo.Repository.IsFork && ctx.Doer.CanCreateRepoIn(ctx.Repo.Repository.Owner)
6363

64-
signing, _ := gitrepo.GetSigningKey(ctx, ctx.Repo.Repository)
64+
signing, _ := gitrepo.GetSigningKey(ctx)
6565
ctx.Data["SigningKeyAvailable"] = signing != nil
6666
ctx.Data["SigningSettings"] = setting.Repository.Signing
6767
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
@@ -104,7 +104,7 @@ func SettingsPost(ctx *context.Context) {
104104
ctx.Data["DefaultMirrorInterval"] = setting.Mirror.DefaultInterval
105105
ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
106106

107-
signing, _ := gitrepo.GetSigningKey(ctx, ctx.Repo.Repository)
107+
signing, _ := gitrepo.GetSigningKey(ctx)
108108
ctx.Data["SigningKeyAvailable"] = signing != nil
109109
ctx.Data["SigningSettings"] = setting.Repository.Signing
110110
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled

0 commit comments

Comments
 (0)