use native golang SSH library but ssh-keygen when enable built-in SSH server to remove dependent on that command lines (#5976)
* use native golang SSH library but ssh-keygen when enable built-in SSH server to remove dependent on that command lines * fix tests and add comment head
This commit is contained in:
parent
06a1739553
commit
2d213b64d1
2 changed files with 45 additions and 4 deletions
|
@ -12,20 +12,20 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/git"
|
"code.gitea.io/git"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/ssh"
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func withKeyFile(t *testing.T, keyname string, callback func(string)) {
|
func withKeyFile(t *testing.T, keyname string, callback func(string)) {
|
||||||
keyFile := filepath.Join(setting.AppDataPath, keyname)
|
keyFile := filepath.Join(setting.AppDataPath, keyname)
|
||||||
err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run()
|
err := ssh.GenKeyPair(keyFile)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
//Setup ssh wrapper
|
//Setup ssh wrapper
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package ssh
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
@ -176,9 +181,9 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
|
||||||
log.Error(4, "Failed to create dir %s: %v", filePath, err)
|
log.Error(4, "Failed to create dir %s: %v", filePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, stderr, err := com.ExecCmd("ssh-keygen", "-f", keyPath, "-t", "rsa", "-N", "")
|
err := GenKeyPair(keyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(4, "Failed to generate private key: %v - %s", err, stderr)
|
log.Fatal(4, "Failed to generate private key: %v", err)
|
||||||
}
|
}
|
||||||
log.Trace("SSH: New private key is generateed: %s", keyPath)
|
log.Trace("SSH: New private key is generateed: %s", keyPath)
|
||||||
}
|
}
|
||||||
|
@ -195,3 +200,39 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
|
||||||
|
|
||||||
go listen(config, host, port)
|
go listen(config, host, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// Private Key generated is PEM encoded
|
||||||
|
func GenKeyPair(keyPath string) error {
|
||||||
|
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
if err != nil {
|
||||||
|
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, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if err := pem.Encode(f, privateKeyPEM); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate public key
|
||||||
|
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
public := ssh.MarshalAuthorizedKey(pub)
|
||||||
|
p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer p.Close()
|
||||||
|
_, err = p.Write(public)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
Reference in a new issue