mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-10 13:23:39 +00:00
ecbef41c06
Migrate away from this thin ssh wrapper module while adding more test coverage. Removes `sessionPartial`, which hand-copied the layout of a private `gliderlabs/ssh` struct and reinterpreted a pointer to it via `reflect.UnsafePointer` to reach the permissions of the authenticated connection. The layout is unchecked, so an upstream field reorder would mismatch silently. The builtin server only needs the session channel with `exec` and `shell`. Serving those on `x/crypto` drops the hack and the dependency, since `PublicKeyCallback` returns permissions per key and `x/crypto` assigns them only after verifying the signature. Two benign behavior changes: 1. Internal session handler errors report exit status 1 rather than 0, so a client no longer reads a failure as success. 1. An unusable host key is fatal at startup instead of being replaced by an ephemeral one that would trigger an error at the client.
60 lines
1.8 KiB
Go
60 lines
1.8 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package ssh
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gitea.dev/modules/graceful"
|
|
"gitea.dev/modules/log"
|
|
"gitea.dev/modules/setting"
|
|
"gitea.dev/modules/util"
|
|
)
|
|
|
|
// builtinUnused informs our cleanup routine that we will not be using a ssh port
|
|
func builtinUnused() {
|
|
graceful.GetManager().InformCleanup()
|
|
}
|
|
|
|
func Init() error {
|
|
if setting.SSH.Disabled {
|
|
builtinUnused()
|
|
return nil
|
|
}
|
|
|
|
if setting.SSH.StartBuiltinServer {
|
|
Listen(setting.SSH.ListenHost, setting.SSH.ListenPort, setting.SSH.ServerCiphers, setting.SSH.ServerKeyExchanges, setting.SSH.ServerMACs)
|
|
log.Info("SSH server started on %q. Ciphers: %v, key exchange algorithms: %v, MACs: %v",
|
|
net.JoinHostPort(setting.SSH.ListenHost, strconv.Itoa(setting.SSH.ListenPort)),
|
|
util.Iif[any](setting.SSH.ServerCiphers == nil, "default", setting.SSH.ServerCiphers),
|
|
util.Iif[any](setting.SSH.ServerKeyExchanges == nil, "default", setting.SSH.ServerKeyExchanges),
|
|
util.Iif[any](setting.SSH.ServerMACs == nil, "default", setting.SSH.ServerMACs),
|
|
)
|
|
return nil
|
|
}
|
|
|
|
builtinUnused()
|
|
|
|
if len(setting.SSH.TrustedUserCAKeys) > 0 && setting.SSH.AuthorizedPrincipalsEnabled {
|
|
caKeysFileName := setting.SSH.TrustedUserCAKeysFile
|
|
caKeysFileDir := filepath.Dir(caKeysFileName)
|
|
|
|
err := os.MkdirAll(caKeysFileDir, 0o700) // SSH.RootPath by default (That is `~/.ssh` in most cases)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create directory %q for ssh trusted ca keys: %w", caKeysFileDir, err)
|
|
}
|
|
|
|
if err := os.WriteFile(caKeysFileName, []byte(strings.Join(setting.SSH.TrustedUserCAKeys, "\n")), 0o600); err != nil {
|
|
return fmt.Errorf("failed to write ssh trusted ca keys to %q: %w", caKeysFileName, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|