Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions modules/git/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,6 @@ func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, err
return strings.TrimSpace(commitID), nil
}

// GetRepositoryDefaultPublicGPGKey returns the default public key for this commit
func (c *Commit) GetRepositoryDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, error) {
if c.repo == nil {
return nil, nil
}
return c.repo.GetDefaultPublicGPGKey(forceUpdate)
}

func IsStringLikelyCommitID(objFmt ObjectFormat, s string, minLength ...int) bool {
maxLen := 64 // sha256
if objFmt != nil {
Expand Down
102 changes: 102 additions & 0 deletions modules/git/gpg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package git

import (
"context"
"fmt"
"os"
"strings"
"sync"

"code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/process"
)

// GPGSettings represents the default GPG settings for this repository
type GPGSettings struct {
Sign bool
KeyID string
Email string
Name string
PublicKeyContent string
Format string
}

// LoadPublicKeyContent will load the key from gpg
func (gpgSettings *GPGSettings) LoadPublicKeyContent() error {
if gpgSettings.PublicKeyContent != "" {
return nil
}

if gpgSettings.Format == SigningKeyFormatSSH {
content, err := os.ReadFile(gpgSettings.KeyID)
if err != nil {
return fmt.Errorf("unable to read SSH public key file: %s, %w", gpgSettings.KeyID, err)
}
gpgSettings.PublicKeyContent = string(content)
return nil
}
content, stderr, err := process.GetManager().Exec(
"gpg -a --export",
"gpg", "-a", "--export", gpgSettings.KeyID)
if err != nil {
return fmt.Errorf("unable to get default signing key: %s, %s, %w", gpgSettings.KeyID, stderr, err)
}
gpgSettings.PublicKeyContent = content
return nil
}

var (
loadPublicGPGKeyMutex sync.RWMutex
globalGPGSettings *GPGSettings
)

// GetDefaultPublicGPGKey will return and cache the default public GPG settings
func GetDefaultPublicGPGKey(ctx context.Context, forceUpdate bool) (*GPGSettings, error) {
if !forceUpdate {
loadPublicGPGKeyMutex.RLock()
if globalGPGSettings != nil {
defer loadPublicGPGKeyMutex.RUnlock()
return globalGPGSettings, nil
}
loadPublicGPGKeyMutex.RUnlock()
}

loadPublicGPGKeyMutex.Lock()
defer loadPublicGPGKeyMutex.Unlock()

if globalGPGSettings != nil && !forceUpdate {
return globalGPGSettings, nil
}

globalGPGSettings = &GPGSettings{
Sign: true,
}

value, _, _ := gitcmd.NewCommand("config", "--global", "--get", "commit.gpgsign").RunStdString(ctx)
sign, valid := ParseBool(strings.TrimSpace(value))
if !sign || !valid {
globalGPGSettings.Sign = false
return globalGPGSettings, nil
}

signingKey, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.signingkey").RunStdString(ctx)
globalGPGSettings.KeyID = strings.TrimSpace(signingKey)

format, _, _ := gitcmd.NewCommand("config", "--global", "--default", SigningKeyFormatOpenPGP, "--get", "gpg.format").RunStdString(ctx)
globalGPGSettings.Format = strings.TrimSpace(format)

defaultEmail, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.email").RunStdString(ctx)
globalGPGSettings.Email = strings.TrimSpace(defaultEmail)

defaultName, _, _ := gitcmd.NewCommand("config", "--global", "--get", "user.name").RunStdString(ctx)
globalGPGSettings.Name = strings.TrimSpace(defaultName)

if err := globalGPGSettings.LoadPublicKeyContent(); err != nil {
return nil, err
}
return globalGPGSettings, nil
}
12 changes: 6 additions & 6 deletions modules/git/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ func (s *SigningKey) String() string {
}

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

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

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

if strings.TrimSpace(signingKey) == "" {
return nil, nil
Expand Down
10 changes: 0 additions & 10 deletions modules/git/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ import (
"code.gitea.io/gitea/modules/proxy"
)

// GPGSettings represents the default GPG settings for this repository
type GPGSettings struct {
Sign bool
KeyID string
Email string
Name string
PublicKeyContent string
Format string
}

const prettyLogFormat = `--pretty=format:%H`

func (repo *Repository) ShowPrettyFormatLogToList(ctx context.Context, revisionRange string) ([]*Commit, error) {
Expand Down
1 change: 0 additions & 1 deletion modules/git/repo_base_gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ type Repository struct {

gogitRepo *gogit.Repository
gogitStorage *filesystem.Storage
gpgSettings *GPGSettings

Ctx context.Context
LastCommitCache *LastCommitCache
Expand Down
2 changes: 0 additions & 2 deletions modules/git/repo_base_nogogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ type Repository struct {

tagCache *ObjectCache[*Tag]

gpgSettings *GPGSettings

batchInUse bool
batch *Batch

Expand Down
71 changes: 0 additions & 71 deletions modules/git/repo_gpg.go

This file was deleted.

4 changes: 2 additions & 2 deletions modules/gitrepo/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import (
"code.gitea.io/gitea/modules/git"
)

func GetSigningKey(ctx context.Context, repo Repository) (*git.SigningKey, *git.Signature) {
return git.GetSigningKey(ctx, repoPath(repo))
func GetSigningKey(ctx context.Context) (*git.SigningKey, *git.Signature) {
return git.GetSigningKey(ctx)
}
9 changes: 2 additions & 7 deletions routers/api/v1/misc/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,8 @@ import (
)

func getSigningKey(ctx *context.APIContext, expectedFormat string) {
// if the handler is in the repo's route group, get the repo's signing key
// otherwise, get the global signing key
path := ""
if ctx.Repo != nil && ctx.Repo.Repository != nil {
path = ctx.Repo.Repository.RepoPath()
}
content, format, err := asymkey_service.PublicSigningKey(ctx, path)
// get the global signing key
content, format, err := asymkey_service.PublicSigningKey(ctx)
if err != nil {
ctx.APIErrorInternal(err)
return
Expand Down
4 changes: 2 additions & 2 deletions routers/web/repo/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func SettingsCtxData(ctx *context.Context) {
ctx.Data["MinimumMirrorInterval"] = setting.Mirror.MinInterval
ctx.Data["CanConvertFork"] = ctx.Repo.Repository.IsFork && ctx.Doer.CanCreateRepoIn(ctx.Repo.Repository.Owner)

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

signing, _ := gitrepo.GetSigningKey(ctx, ctx.Repo.Repository)
signing, _ := gitrepo.GetSigningKey(ctx)
ctx.Data["SigningKeyAvailable"] = signing != nil
ctx.Data["SigningSettings"] = setting.Repository.Signing
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
Expand Down
2 changes: 1 addition & 1 deletion services/asymkey/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func parseCommitWithGPGSignature(ctx context.Context, c *git.Commit, committer *
}
}

defaultGPGSettings, err := c.GetRepositoryDefaultPublicGPGKey(false)
defaultGPGSettings, err := git.GetDefaultPublicGPGKey(ctx, false)
if err != nil {
log.Error("Error getting default public gpg key: %v", err)
} else if defaultGPGSettings == nil {
Expand Down
24 changes: 12 additions & 12 deletions services/asymkey/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,34 +108,34 @@ func IsErrWontSign(err error) bool {
return ok
}

// PublicSigningKey gets the public signing key within a provided repository directory
func PublicSigningKey(ctx context.Context, repoPath string) (content, format string, err error) {
signingKey, _ := git.GetSigningKey(ctx, repoPath)
// PublicSigningKey gets the public signing key of the entire instance
func PublicSigningKey(ctx context.Context) (content, format string, err error) {
signingKey, _ := git.GetSigningKey(ctx)
if signingKey == nil {
return "", "", nil
}
if signingKey.Format == git.SigningKeyFormatSSH {
content, err := os.ReadFile(signingKey.KeyID)
if err != nil {
log.Error("Unable to read SSH public key file in %s: %s, %v", repoPath, signingKey, err)
log.Error("Unable to read SSH public key file: %s, %v", signingKey, err)
return "", signingKey.Format, err
}
return string(content), signingKey.Format, nil
}

content, stderr, err := process.GetManager().ExecDir(ctx, -1, repoPath,
content, stderr, err := process.GetManager().ExecDir(ctx, -1, setting.Git.HomePath,
"gpg --export -a", "gpg", "--export", "-a", signingKey.KeyID)
if err != nil {
log.Error("Unable to get default signing key in %s: %s, %s, %v", repoPath, signingKey, stderr, err)
log.Error("Unable to get default signing key: %s, %s, %v", signingKey, stderr, err)
return "", signingKey.Format, err
}
return content, signingKey.Format, nil
}

// SignInitialCommit determines if we should sign the initial commit to this repository
func SignInitialCommit(ctx context.Context, repoPath string, u *user_model.User) (bool, *git.SigningKey, *git.Signature, error) {
func SignInitialCommit(ctx context.Context, u *user_model.User) (bool, *git.SigningKey, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit)
signingKey, sig := git.GetSigningKey(ctx, repoPath)
signingKey, sig := git.GetSigningKey(ctx)
if signingKey == nil {
return false, nil, nil, &ErrWontSign{noKey}
}
Expand Down Expand Up @@ -171,7 +171,7 @@ Loop:
// SignWikiCommit determines if we should sign the commits to this repository wiki
func SignWikiCommit(ctx context.Context, repo *repo_model.Repository, u *user_model.User) (bool, *git.SigningKey, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
signingKey, sig := gitrepo.GetSigningKey(ctx, repo.WikiStorageRepo())
signingKey, sig := gitrepo.GetSigningKey(ctx)
if signingKey == nil {
return false, nil, nil, &ErrWontSign{noKey}
}
Expand Down Expand Up @@ -222,9 +222,9 @@ Loop:
}

// SignCRUDAction determines if we should sign a CRUD commit to this repository
func SignCRUDAction(ctx context.Context, repoPath string, u *user_model.User, tmpBasePath, parentCommit string) (bool, *git.SigningKey, *git.Signature, error) {
func SignCRUDAction(ctx context.Context, u *user_model.User, tmpBasePath, parentCommit string) (bool, *git.SigningKey, *git.Signature, error) {
rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
signingKey, sig := git.GetSigningKey(ctx, repoPath)
signingKey, sig := git.GetSigningKey(ctx)
if signingKey == nil {
return false, nil, nil, &ErrWontSign{noKey}
}
Expand Down Expand Up @@ -288,7 +288,7 @@ func SignMerge(ctx context.Context, pr *issues_model.PullRequest, u *user_model.
}
repo := pr.BaseRepo

signingKey, signer := gitrepo.GetSigningKey(ctx, repo)
signingKey, signer := gitrepo.GetSigningKey(ctx)
if signingKey == nil {
return false, nil, nil, &ErrWontSign{noKey}
}
Expand Down
2 changes: 1 addition & 1 deletion services/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func PrepareCommitFormOptions(ctx *Context, doer *user_model.User, targetRepo *r
protectionRequireSigned = protectedBranch.RequireSignedCommits
}

willSign, signKey, _, err := asymkey_service.SignCRUDAction(ctx, targetRepo.RepoPath(), doer, targetRepo.RepoPath(), refName.String())
willSign, signKey, _, err := asymkey_service.SignCRUDAction(ctx, doer, targetRepo.RepoPath(), refName.String())
wontSignReason := ""
if asymkey_service.IsErrWontSign(err) {
wontSignReason = string(err.(*asymkey_service.ErrWontSign).Reason)
Expand Down
2 changes: 1 addition & 1 deletion services/repository/files/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (opts *ApplyDiffPatchOptions) Validate(ctx context.Context, repo *repo_mode
}
}
if protectedBranch != nil && protectedBranch.RequireSignedCommits {
_, _, _, err := asymkey_service.SignCRUDAction(ctx, repo.RepoPath(), doer, repo.RepoPath(), opts.OldBranch)
_, _, _, err := asymkey_service.SignCRUDAction(ctx, doer, repo.RepoPath(), opts.OldBranch)
if err != nil {
if !asymkey_service.IsErrWontSign(err) {
return err
Expand Down
Loading