forgejo/modules/doctor/authorizedkeys.go
zeripath 5cb0c9aa0d
Propagate context and ensure git commands run in request context ()
This PR continues the work in  by progressively ensuring that git
commands run within the request context.

This now means that the if there is a git repo already open in the context it will be used instead of reopening it.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2022-01-19 23:26:57 +00:00

96 lines
2.9 KiB
Go

// Copyright 2020 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 doctor
import (
"bufio"
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
const tplCommentPrefix = `# gitea public key`
func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) error {
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil
}
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
f, err := os.Open(fPath)
if err != nil {
if !autofix {
logger.Critical("Unable to open authorized_keys file. ERROR: %v", err)
return fmt.Errorf("Unable to open authorized_keys file. ERROR: %v", err)
}
logger.Warn("Unable to open authorized_keys. (ERROR: %v). Attempting to rewrite...", err)
if err = asymkey_model.RewriteAllPublicKeys(); err != nil {
logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err)
return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %v", err)
}
}
defer f.Close()
linesInAuthorizedKeys := map[string]bool{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, tplCommentPrefix) {
continue
}
linesInAuthorizedKeys[line] = true
}
f.Close()
// now we regenerate and check if there are any lines missing
regenerated := &bytes.Buffer{}
if err := asymkey_model.RegeneratePublicKeys(regenerated); err != nil {
logger.Critical("Unable to regenerate authorized_keys file. ERROR: %v", err)
return fmt.Errorf("Unable to regenerate authorized_keys file. ERROR: %v", err)
}
scanner = bufio.NewScanner(regenerated)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, tplCommentPrefix) {
continue
}
if ok := linesInAuthorizedKeys[line]; ok {
continue
}
if !autofix {
logger.Critical(
"authorized_keys file %q is out of date.\nRegenerate it with:\n\t\"%s\"\nor\n\t\"%s\"",
fPath,
"gitea admin regenerate keys",
"gitea doctor --run authorized_keys --fix")
return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized_keys --fix"`)
}
logger.Warn("authorized_keys is out of date. Attempting rewrite...")
err = asymkey_model.RewriteAllPublicKeys()
if err != nil {
logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err)
return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %v", err)
}
}
return nil
}
func init() {
Register(&Check{
Title: "Check if OpenSSH authorized_keys file is up-to-date",
Name: "authorized-keys",
IsDefault: true,
Run: checkAuthorizedKeys,
Priority: 4,
})
}