123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package zsshrpc_server
- import (
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "golang.org/x/crypto/ssh"
- "io/ioutil"
- "os"
- )
- type PasswdCb func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error)
- type PubKeyCb func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error)
- type KeyIntCb func(conn ssh.ConnMetadata, cli ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error)
- type AuthLogCb func(conn ssh.ConnMetadata, method string, err error)
- type SvrLogFunc func(level int, msg string, err error)
- type ZSshRpcServerCfg struct {
- HostKey ssh.Signer
- NoClientAuth bool
- MaxAuthTries int
- PasswordCallback PasswdCb
- PublicKeyCallback PubKeyCb
- KeyboardInteractiveCallback KeyIntCb
- AuthLogCallback AuthLogCb
- ServerLogger SvrLogFunc
- Support_AES128_CBC bool
- OperationHandler ZSshRpcOperationHandler
- IOBlockSize int
- }
- func NewDefaultZSshRpcServerCfg(host_key_store_path string) (*ZSshRpcServerCfg, error) {
- hostkey, err := GetOrGenerateHostKey(host_key_store_path, 2028)
- if err != nil {
- return nil, err
- }
- return &ZSshRpcServerCfg{
- HostKey: hostkey,
- NoClientAuth: false,
- MaxAuthTries: 5,
- PasswordCallback: defaultPasswordCallback,
- PublicKeyCallback: defaultPubkeyCallback,
- KeyboardInteractiveCallback: defaultKeyIntCallback,
- AuthLogCallback: defaultAuthLogCb,
- ServerLogger: defaultServerLoggerFunc,
- Support_AES128_CBC: true,
- OperationHandler: &defaultOperationHandler{},
- IOBlockSize: 1024,
- }, nil
- }
- func defaultPasswordCallback(conn ssh.ConnMetadata, passwd []byte) (*ssh.Permissions, error) {
- return nil, errors.New("method not support")
- }
- func defaultPubkeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
- return nil, errors.New("method not support")
- }
- func defaultKeyIntCallback(conn ssh.ConnMetadata, cli ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) {
- return nil, errors.New("method not support")
- }
- func defaultAuthLogCb(conn ssh.ConnMetadata, method string, err error) {
- }
- type defaultOperationHandler struct {
- }
- func (this *defaultOperationHandler) HandleOperation(request ZSshRpcOperationRequest) ZSshRpcOperationResponse {
- return ZSshRpcOperationResponse{
- StatusCode: ResponseStatusCode_NOT_FOUND,
- ResponseJSON: "{}",
- }
- }
- func defaultServerLoggerFunc(level int, msg string, err error) {
- }
- func (this *ZSshRpcServerCfg) UsePasswordAuth(callback PasswdCb) {
- this.PasswordCallback = callback
- }
- func (this *ZSshRpcServerCfg) UsePublicKeyAuth(callback PubKeyCb) {
- this.PublicKeyCallback = callback
- }
- func (this *ZSshRpcServerCfg) UseKeyboardInteractiveAuth(callback KeyIntCb) {
- this.KeyboardInteractiveCallback = callback
- }
- func (this *ZSshRpcServerCfg) UseAuthLogger(callback AuthLogCb) {
- this.AuthLogCallback = callback
- }
- func (this *ZSshRpcServerCfg) UseLogger(logfunc SvrLogFunc) {
- this.ServerLogger = logfunc
- }
- func (this *ZSshRpcServerCfg) SetHandler(handler ZSshRpcOperationHandler) {
- this.OperationHandler = handler
- }
- func GetOrGenerateHostKey(key_store_path string, key_length_to_gen int) (ssh.Signer, error) {
- if IsFileExists(key_store_path) {
- hostkeydata, err := ioutil.ReadFile(key_store_path)
- if err != nil {
- return generateHostKey(key_store_path, key_length_to_gen)
- }
- hostkey, err := ssh.ParsePrivateKey(hostkeydata)
- if err != nil {
- return generateHostKey(key_store_path, key_length_to_gen)
- }
- return hostkey, nil
- } else {
- return generateHostKey(key_store_path, key_length_to_gen)
- }
- }
- func generateHostKey(keypath string, len int) (ssh.Signer, error) {
- prikey, err := rsa.GenerateKey(rand.Reader, len)
- if err != nil {
- return nil, err
- }
- privateKeyFile, err := os.Create(keypath)
- defer privateKeyFile.Close()
- if err != nil {
- return nil, err
- }
- privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(prikey)}
- if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
- return nil, err
- }
- hostkeydata, err := ioutil.ReadFile(keypath)
- if err != nil {
- return nil, err
- }
- hostkey, err := ssh.ParsePrivateKey(hostkeydata)
- if err != nil {
- return nil, err
- }
- return hostkey, nil
- }
|