mirror of
https://github.com/go-gitea/gitea.git
synced 2025-05-18 00:49:09 -04:00
Merge 8b5c59a6542a022df374529b3e6da28e347983ce into 319d03fbc049de34a6fa0bc3019107ec5b724ff2
This commit is contained in:
commit
368f0455d3
@ -5,13 +5,17 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/generate"
|
"code.gitea.io/gitea/modules/generate"
|
||||||
|
|
||||||
"github.com/mattn/go-isatty"
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -21,6 +25,7 @@ var (
|
|||||||
Usage: "Generate Gitea's secrets/keys/tokens",
|
Usage: "Generate Gitea's secrets/keys/tokens",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
subcmdSecret,
|
subcmdSecret,
|
||||||
|
subcmdKeygen,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +38,17 @@ var (
|
|||||||
microcmdGenerateSecretKey,
|
microcmdGenerateSecretKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
keygenFlags = []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "bits", Aliases: []string{"b"}, Usage: "Number of bits in the key, ignored when key is ed25519"},
|
||||||
|
&cli.StringFlag{Name: "type", Aliases: []string{"t"}, Value: "ed25519", Usage: "Keytype to generate"},
|
||||||
|
&cli.StringFlag{Name: "file", Aliases: []string{"f"}, Usage: "Specifies the filename of the key file", Required: true},
|
||||||
|
}
|
||||||
|
subcmdKeygen = &cli.Command{
|
||||||
|
Name: "ssh-keygen",
|
||||||
|
Usage: "Generate a ssh keypair",
|
||||||
|
Flags: keygenFlags,
|
||||||
|
Action: runGenerateKeyPair,
|
||||||
|
}
|
||||||
|
|
||||||
microcmdGenerateInternalToken = &cli.Command{
|
microcmdGenerateInternalToken = &cli.Command{
|
||||||
Name: "INTERNAL_TOKEN",
|
Name: "INTERNAL_TOKEN",
|
||||||
@ -98,3 +114,49 @@ func runGenerateSecretKey(c *cli.Context) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runGenerateKeyPair(c *cli.Context) error {
|
||||||
|
file := c.String("file")
|
||||||
|
|
||||||
|
// Check if file exists to prevent overwrites
|
||||||
|
if _, err := os.Stat(file); err == nil {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
fmt.Printf("%s already exists.\nOverwrite (y/n)? ", file)
|
||||||
|
scanner.Scan()
|
||||||
|
if strings.ToLower(strings.TrimSpace(scanner.Text())) != "y" {
|
||||||
|
fmt.Println("Aborting")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keytype := c.String("type")
|
||||||
|
bits := c.Int("bits")
|
||||||
|
// provide defaults for bits, ed25519 ignores bit length so it's omitted
|
||||||
|
if bits == 0 {
|
||||||
|
if keytype == "rsa" {
|
||||||
|
bits = 3072
|
||||||
|
} else {
|
||||||
|
bits = 256
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, priv, err := generate.NewSSHKey(keytype, bits)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
err = pem.Encode(f, priv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Your identification has been saved in %s\n", file)
|
||||||
|
err = os.WriteFile(file+".pub", ssh.MarshalAuthorizedKey(pub), 0o644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Your public key has been saved in %s", file+".pub")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -5,8 +5,14 @@
|
|||||||
package generate
|
package generate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
@ -14,6 +20,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
|
// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
|
||||||
@ -72,3 +79,59 @@ func NewSecretKey() (string, error) {
|
|||||||
|
|
||||||
return secretKey, nil
|
return secretKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSSHKey(keytype string, bits int) (ssh.PublicKey, *pem.Block, error) {
|
||||||
|
pub, priv, err := commonKeyGen(keytype, bits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
pemPriv, err := ssh.MarshalPrivateKey(priv, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
sshPub, err := ssh.NewPublicKey(pub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sshPub, pemPriv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// commonKeyGen is an abstraction over rsa, ecdsa and ed25519 generating functions
|
||||||
|
func commonKeyGen(keytype string, bits int) (publicKey, privateKey crypto.PublicKey, err error) {
|
||||||
|
switch keytype {
|
||||||
|
case "rsa":
|
||||||
|
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return &privateKey.PublicKey, privateKey, nil
|
||||||
|
case "ed25519":
|
||||||
|
return ed25519.GenerateKey(rand.Reader)
|
||||||
|
case "ecdsa":
|
||||||
|
curve, err := getElipticCurve(bits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return &privateKey.PublicKey, privateKey, nil
|
||||||
|
default:
|
||||||
|
return nil, nil, fmt.Errorf("unknown keytype: %s", keytype)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getElipticCurve(bits int) (elliptic.Curve, error) {
|
||||||
|
switch bits {
|
||||||
|
case 256:
|
||||||
|
return elliptic.P256(), nil
|
||||||
|
case 384:
|
||||||
|
return elliptic.P384(), nil
|
||||||
|
case 521:
|
||||||
|
return elliptic.P521(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported ECDSA curve bit length: %d", bits)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -56,7 +56,7 @@ var SSH = struct {
|
|||||||
ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1"},
|
ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1"},
|
||||||
MinimumKeySizeCheck: true,
|
MinimumKeySizeCheck: true,
|
||||||
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 3071},
|
MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 3071},
|
||||||
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"},
|
ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gitea.ed25519", "ssh/gitea.ecdsa", "ssh/gogs.rsa"},
|
||||||
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
|
AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}",
|
||||||
PerWriteTimeout: PerWriteTimeout,
|
PerWriteTimeout: PerWriteTimeout,
|
||||||
PerWritePerKbTimeout: PerWritePerKbTimeout,
|
PerWritePerKbTimeout: PerWritePerKbTimeout,
|
||||||
|
@ -6,9 +6,6 @@ package ssh
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
@ -23,6 +20,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||||
|
"code.gitea.io/gitea/modules/generate"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/process"
|
"code.gitea.io/gitea/modules/process"
|
||||||
@ -54,6 +52,14 @@ import (
|
|||||||
|
|
||||||
const giteaPermissionExtensionKeyID = "gitea-perm-ext-key-id"
|
const giteaPermissionExtensionKeyID = "gitea-perm-ext-key-id"
|
||||||
|
|
||||||
|
type KeyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RSA KeyType = "rsa"
|
||||||
|
ECDSA KeyType = "ecdsa"
|
||||||
|
ED25519 KeyType = "ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
func getExitStatusFromError(err error) int {
|
func getExitStatusFromError(err error) int {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return 0
|
return 0
|
||||||
@ -367,17 +373,17 @@ func Listen(host string, port int, ciphers, keyExchanges, macs []string) {
|
|||||||
|
|
||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
filePath := filepath.Dir(setting.SSH.ServerHostKeys[0])
|
filePath := filepath.Dir(setting.SSH.ServerHostKeys[0])
|
||||||
|
|
||||||
if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
|
||||||
log.Error("Failed to create dir %s: %v", filePath, err)
|
log.Error("Failed to create dir %s: %v", filePath, err)
|
||||||
}
|
}
|
||||||
|
err := initDefaultKeys(filePath)
|
||||||
err := GenKeyPair(setting.SSH.ServerHostKeys[0])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to generate private key: %v", err)
|
log.Fatal("Failed to generate private key: %v", err)
|
||||||
}
|
}
|
||||||
log.Trace("New private key is generated: %s", setting.SSH.ServerHostKeys[0])
|
for _, keytype := range []string{"rsa", "ecdsa", "ed25519"} {
|
||||||
keys = append(keys, setting.SSH.ServerHostKeys[0])
|
filename := filePath + "/gitea." + keytype
|
||||||
|
keys = append(keys, filename)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
@ -387,7 +393,6 @@ func Listen(host string, port int, ciphers, keyExchanges, macs []string) {
|
|||||||
log.Error("Failed to set Host Key. %s", err)
|
log.Error("Failed to set Host Key. %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
_, _, finished := process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "Service: Built-in SSH server", process.SystemProcessType, true)
|
_, _, finished := process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "Service: Built-in SSH server", process.SystemProcessType, true)
|
||||||
defer finished()
|
defer finished()
|
||||||
@ -398,13 +403,17 @@ func Listen(host string, port int, ciphers, keyExchanges, macs []string) {
|
|||||||
// GenKeyPair make a pair of public and private keys for SSH access.
|
// GenKeyPair make a pair of public and private keys for SSH access.
|
||||||
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
|
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
|
||||||
// Private Key generated is PEM encoded
|
// Private Key generated is PEM encoded
|
||||||
func GenKeyPair(keyPath string) error {
|
func GenKeyPair(keyPath, keytype string) error {
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
bits := 4096
|
||||||
|
if keytype == "ecdsa" {
|
||||||
|
bits = 256
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKey, privateKeyPEM, err := generate.NewSSHKey(keytype, bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
|
|
||||||
f, err := os.OpenFile(keyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
f, err := os.OpenFile(keyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -419,13 +428,7 @@ func GenKeyPair(keyPath string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate public key
|
public := gossh.MarshalAuthorizedKey(publicKey)
|
||||||
pub, err := gossh.NewPublicKey(&privateKey.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
public := gossh.MarshalAuthorizedKey(pub)
|
|
||||||
p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -438,3 +441,19 @@ func GenKeyPair(keyPath string) error {
|
|||||||
_, err = p.Write(public)
|
_, err = p.Write(public)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initDefaultKeys mirrors how ssh-keygen -A operates
|
||||||
|
// it runs checks if public and private keys are already defined and creates new ones if not present
|
||||||
|
// key naming does not follow the openssh convention due to existing settings being gitea.{keytype} so generation follows gitea convention
|
||||||
|
func initDefaultKeys(path string) error {
|
||||||
|
var errs []error
|
||||||
|
keytypes := []string{"rsa", "ecdsa", "ed25519"}
|
||||||
|
for _, keytype := range keytypes {
|
||||||
|
privExists, _ := util.IsExist(path + "/gitea." + keytype)
|
||||||
|
pubExists, _ := util.IsExist(path + "/gitea." + keytype + ".pub")
|
||||||
|
if !privExists || !pubExists {
|
||||||
|
errs = append(errs, GenKeyPair(path+"/gitea."+keytype, keytype))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.Join(errs...)
|
||||||
|
}
|
||||||
|
118
modules/ssh/ssh_test.go
Normal file
118
modules/ssh/ssh_test.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package ssh
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rsa"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
gossh "golang.org/x/crypto/ssh"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenKeyPair(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
keyType string
|
||||||
|
expectedType any
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
keyType: "rsa",
|
||||||
|
expectedType: &rsa.PrivateKey{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keyType: "ed25519",
|
||||||
|
expectedType: &ed25519.PrivateKey{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keyType: "ecdsa",
|
||||||
|
expectedType: &ecdsa.PrivateKey{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tC := range testCases {
|
||||||
|
t.Run("Generate "+filepath.Ext(tC.keyType), func(t *testing.T) {
|
||||||
|
path := t.TempDir() + "gitea." + tC.keyType
|
||||||
|
require.NoError(t, GenKeyPair(path, tC.keyType))
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
bytes, err := io.ReadAll(file)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
privateKey, err := gossh.ParseRawPrivateKey(bytes)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.IsType(t, tC.expectedType, privateKey)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
t.Run("Generate unknown keytype", func(t *testing.T) {
|
||||||
|
path := t.TempDir() + "gitea.badkey"
|
||||||
|
|
||||||
|
err := GenKeyPair(path, "badkey")
|
||||||
|
require.Error(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitKeys(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
keytypes := []string{"rsa", "ecdsa", "ed25519"}
|
||||||
|
for _, keytype := range keytypes {
|
||||||
|
privKeyPath := filepath.Join(tempDir, "gitea."+keytype)
|
||||||
|
pubKeyPath := filepath.Join(tempDir, "gitea."+keytype+".pub")
|
||||||
|
assert.NoFileExists(t, privKeyPath)
|
||||||
|
assert.NoFileExists(t, pubKeyPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test basic creation
|
||||||
|
err := initDefaultKeys(tempDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
metadata := map[string]os.FileInfo{}
|
||||||
|
for _, keytype := range keytypes {
|
||||||
|
privKeyPath := filepath.Join(tempDir, "gitea."+keytype)
|
||||||
|
pubKeyPath := filepath.Join(tempDir, "gitea."+keytype+".pub")
|
||||||
|
assert.FileExists(t, privKeyPath)
|
||||||
|
assert.FileExists(t, pubKeyPath)
|
||||||
|
|
||||||
|
info, err := os.Stat(privKeyPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
metadata[privKeyPath] = info
|
||||||
|
|
||||||
|
info, err = os.Stat(pubKeyPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
metadata[pubKeyPath] = info
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test recreation on missing public or private key
|
||||||
|
require.NoError(t, os.Remove(filepath.Join(tempDir, "gitea.ecdsa.pub")))
|
||||||
|
require.NoError(t, os.Remove(filepath.Join(tempDir, "gitea.ed25519")))
|
||||||
|
|
||||||
|
err = initDefaultKeys(tempDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
for _, keytype := range keytypes {
|
||||||
|
privKeyPath := filepath.Join(tempDir, "gitea."+keytype)
|
||||||
|
pubKeyPath := filepath.Join(tempDir, "gitea."+keytype+".pub")
|
||||||
|
assert.FileExists(t, privKeyPath)
|
||||||
|
assert.FileExists(t, pubKeyPath)
|
||||||
|
|
||||||
|
infoPriv, err := os.Stat(privKeyPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
infoPub, err := os.Stat(pubKeyPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if keytype == "rsa" {
|
||||||
|
assert.Equal(t, metadata[privKeyPath], infoPriv)
|
||||||
|
assert.Equal(t, metadata[pubKeyPath], infoPub)
|
||||||
|
} else {
|
||||||
|
assert.NotEqual(t, metadata[privKeyPath], infoPriv)
|
||||||
|
assert.NotEqual(t, metadata[pubKeyPath], infoPub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,7 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
keyFile := filepath.Join(tmpDir, keyname)
|
keyFile := filepath.Join(tmpDir, keyname)
|
||||||
err = ssh.GenKeyPair(keyFile)
|
err = ssh.GenKeyPair(keyFile, "ecdsa")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = os.WriteFile(filepath.Join(tmpDir, "ssh"), []byte("#!/bin/bash\n"+
|
err = os.WriteFile(filepath.Join(tmpDir, "ssh"), []byte("#!/bin/bash\n"+
|
||||||
|
Loading…
x
Reference in New Issue
Block a user