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/url" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"code.gitea.io/git" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/ssh" | ||||
| 	"github.com/Unknwon/com" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func withKeyFile(t *testing.T, keyname string, callback func(string)) { | ||||
| 	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) | ||||
| 
 | ||||
| 	//Setup ssh wrapper
 | ||||
|  |  | |||
|  | @ -1,10 +1,15 @@ | |||
| // 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
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package ssh | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"crypto/rsa" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/pem" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"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) | ||||
| 		} | ||||
| 
 | ||||
| 		_, stderr, err := com.ExecCmd("ssh-keygen", "-f", keyPath, "-t", "rsa", "-N", "") | ||||
| 		err := GenKeyPair(keyPath) | ||||
| 		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) | ||||
| 	} | ||||
|  | @ -195,3 +200,39 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs | |||
| 
 | ||||
| 	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 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue