Skip to content

Commit 2d213b6

Browse files
lunnytechknowlogick
authored andcommitted
use native golang SSH library but ssh-keygen when enable built-in SSH server to remove dependent on that command lines (go-gitea#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
1 parent 06a1739 commit 2d213b6

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

integrations/git_helper_for_declarative_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ import (
1212
"net/http"
1313
"net/url"
1414
"os"
15-
"os/exec"
1615
"path/filepath"
1716
"testing"
1817
"time"
1918

2019
"code.gitea.io/git"
2120
"code.gitea.io/gitea/modules/setting"
21+
"code.gitea.io/gitea/modules/ssh"
2222
"github.com/Unknwon/com"
2323
"github.com/stretchr/testify/assert"
2424
)
2525

2626
func withKeyFile(t *testing.T, keyname string, callback func(string)) {
2727
keyFile := filepath.Join(setting.AppDataPath, keyname)
28-
err := exec.Command("ssh-keygen", "-f", keyFile, "-t", "rsa", "-N", "").Run()
28+
err := ssh.GenKeyPair(keyFile)
2929
assert.NoError(t, err)
3030

3131
//Setup ssh wrapper

modules/ssh/ssh.go

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
// Copyright 2014 The Gogs Authors. All rights reserved.
2+
// Copyright 2017 The Gitea Authors. All rights reserved.
23
// Use of this source code is governed by a MIT-style
34
// license that can be found in the LICENSE file.
45

56
package ssh
67

78
import (
9+
"crypto/rand"
10+
"crypto/rsa"
11+
"crypto/x509"
12+
"encoding/pem"
813
"io"
914
"io/ioutil"
1015
"net"
@@ -176,9 +181,9 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
176181
log.Error(4, "Failed to create dir %s: %v", filePath, err)
177182
}
178183

179-
_, stderr, err := com.ExecCmd("ssh-keygen", "-f", keyPath, "-t", "rsa", "-N", "")
184+
err := GenKeyPair(keyPath)
180185
if err != nil {
181-
log.Fatal(4, "Failed to generate private key: %v - %s", err, stderr)
186+
log.Fatal(4, "Failed to generate private key: %v", err)
182187
}
183188
log.Trace("SSH: New private key is generateed: %s", keyPath)
184189
}
@@ -195,3 +200,39 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
195200

196201
go listen(config, host, port)
197202
}
203+
204+
// GenKeyPair make a pair of public and private keys for SSH access.
205+
// Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
206+
// Private Key generated is PEM encoded
207+
func GenKeyPair(keyPath string) error {
208+
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
209+
if err != nil {
210+
return err
211+
}
212+
213+
privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}
214+
f, err := os.OpenFile(keyPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
215+
if err != nil {
216+
return err
217+
}
218+
defer f.Close()
219+
220+
if err := pem.Encode(f, privateKeyPEM); err != nil {
221+
return err
222+
}
223+
224+
// generate public key
225+
pub, err := ssh.NewPublicKey(&privateKey.PublicKey)
226+
if err != nil {
227+
return err
228+
}
229+
230+
public := ssh.MarshalAuthorizedKey(pub)
231+
p, err := os.OpenFile(keyPath+".pub", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
232+
if err != nil {
233+
return err
234+
}
235+
defer p.Close()
236+
_, err = p.Write(public)
237+
return err
238+
}

0 commit comments

Comments
 (0)