mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							06a1739553
						
					
				
				
					commit
					2d213b64d1
				
			@@ -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 New Issue
	
	Block a user